物联网RTOS新贵-TencentOS tiny入门

作者:绿森林雨景

本文获得作者:绿森林雨景 授权发表。

1 前沿

    让我们先简单回顾下物联网(The Internet Of Things)的历史,

1999年,物联网概念第一次被提出;

2009年,“感知中国”的概念被提出,物联网被正式列入国家新兴战略性产业之一;

2013年,Semtech LoRa技术商用;

2016年,NB-IoT R13核心技术标准的冻结,全球运营商有了基于标准化的物联网专有协议,窄带物联网迎来规模商用;

2017年,以NB-IoT、LoRa为代表的「LPWAN」物联网技术异军突起与迅猛发展,LPWAN的技术特性让万物互联场景的实现变成了可能;

2019年,5G商用正式拉开序幕,将为物联网产业的发展搭建一条高速公路…..

同时伴随着十几年互联网技术发展,大数据、云计算、人工智能(机器学习)、IoT通信技术等多种技术的成熟与不断融合,物联网的愿景再一次进化——让万物互联照进现实。

全球权威的信息提供商IHS、IDC、Gartner公司的分析报告都指出到2020年,全球可连接设备数将超过200~300多亿。面对如此海量的连接设备,物联网再一次成为了群雄逐鹿的赛场。同时,面对物联网高度碎片化的特点,各路大佬们纷纷摇旗呐喊,不约而同打造物联网生态。

2016年,HUAWEI CONNECT 大会上,华为正式发布了以IoT联接管理平台为核心的OceanConnect IoT平台。

2017年开始,腾讯云全面布局物联网,为行业客户提供加速物联网+的基础服务,包括:基础云服务、智能化的AI大数据服务,以及物联PaaS服务。

2017年底,华为确定了与IoT紧密相关的新愿景:“把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界”。

2018云栖大会·深圳峰会阿里云总裁胡晓明宣布:阿里巴巴将全面进军物联网领域,IoT是阿里巴巴集团继电商、金融、物流、云计算后新的主赛道。

2018年3月,阿里云发布支持LoRa协议的LinkWAN平台。

2019年7月,腾讯发布一站式物联网开发平台:腾讯云IoT Explorer,或将为物联网应用的爆炸式增长扫除最后一道门槛。

物联网RTOS作为IoT终端侧的基础软件,在一定程度上可以破解物联网下游的碎片化困局,加快下游物联网应用的开发进程,同时海量的物联网应用爆发与普及也会带动芯片存储等成本持续降低,正如同早些年的IoT WiFi芯片,现在的IoT BLE芯片,规模效应后,单片成本已经探底,成本承压也会变得不太敏感,进而可进一步释放物联网终端侧的硬件资源瓶颈。各路大佬布局物联网RTOS,卡位数据入口,使得RTOS插上物联网翅膀,在万物互联时代再一次起飞翱翔…

接下来,我们来尝鲜一下物联网RTOS新贵——TencentOS tiny

1.1 IoT RTOS的新贵TencentOS tiny

TencentOS作为IoT RTOS的后起之秀,具备了物联网RTOS几大典型特征:

    • 扩芯片平台
    • 硬实时内核、多任务、IPC通信…
    • 小的FLASHRAM开销
    • 低功耗
    • 多种联网、上云能力
    • 安全能力
    • 丰富组件…

下文学习如何基于MDK与STM32L4实现第一个TencentOS tiny应用程序——串口输出“Hello World”,作为TencentOS tiny入门的第一个里程碑,打开TencentOS tiny知识的大门。

PS:本文代码基于TencentOS tiny 1.0版本(2019.09.18正式对外开源版本)

1.2 内容提要

下文主要内容涉及了TencentOS tiny入门知识、基于MDK的开发环境搭建、TencentOS tiny内核启动过程、main入口与应用层代码入口、helloworld应用示例等。

    • TencentOS tiny入门知识
      • TencentOS tiny系统架构
      • TencentOS tiny源代码目录树
    • 基于MDK的开发环境搭建
    • 基于MDK的TencentOS tiny启动流程
      • TencentOS tiny main函数入口
      • 应用程序入口
    • TencentOS tiny 第一个应用helloworld

2 TencentOS tiny入门知识

2.1 TencentOS tiny系统架构

物联网RTOS新贵-TencentOS tiny入门

TencentOS tiny系统架构符合分层架构设计与组件化架构设计原则。TencentOS tiny架构至下(层)而上(层),分别是

物联网RTOS新贵-TencentOS tiny入门

2.2 TencentOS tiny文件夹目录树

TencentOS tiny系统架构体现在源代码文件组织结构,如下图所示

物联网RTOS新贵-TencentOS tiny入门

TencentOS tiny源代码一级文件夹目录树

物联网RTOS新贵-TencentOS tiny入门

物联网RTOS新贵-TencentOS tiny入门

物联网RTOS新贵-TencentOS tiny入门

物联网RTOS新贵-TencentOS tiny入门

物联网RTOS新贵-TencentOS tiny入门

物联网RTOS新贵-TencentOS tiny入门

3 开发环境搭建

开发环境主要取决于使用的硬件芯片平台与个人开发习惯。

TencentOS tiny目前主要支持Cortex-M、Risc-V的32位MCU,当前支持BSP里面都提供了KEIL(MDK)示例工程,部分也同时提供了IAR、GCC,对于习惯在Window开发Cortex-M产品的小伙伴会比较熟悉。

针对开发环境,简单对比下国内另外两款非常火的IoT RTOS:

    • RT-Thread4.0.x这块会更完善,提供了基于Python & Scons且无需安装的Env工具,通过简单修改Kconfig与SConscript文件,就可以非常快速生成MDK、IAR提供,工具用熟以后,移植是非常高效的,另外RT-Thread发展历史悠久,积累支持的BSP也非常多。
    • AliOS Things2.1.x同样提供了基于Python & Scons的AOS-Cube工具,可快速生成MDK、IAR工程,但目前支持的BSP尚不太多,还正在完善中。

3.1 基于MDK与STM32L4的开发环境搭建

查看下 TencentOS tinyboard 是否有与目标主芯片相似的示例工程

      1. 如果是已有相似平台的话,接拷贝该示例工作为项目原型,然后根据实际硬件,重新配置,移植也会相对简单高效。比如本文平台目标芯片为STM32L476VGT6,STM32同系列芯片可以共用相同底层代码,因此这里直接修改TencentOS tinyboardNUCLEO_STM32L476RG

物联网RTOS新贵-TencentOS tiny入门

    1. 如果是新的平台的话,可参考官方移植文档,具体可如“6 参考”章节相关内容。

4 基于MDK的TencentOS tiny内核启动流程

在嵌入式系统(MCU)中,启动文件(比如startup_stm32l476xx.s)是芯片上电最先运行的一段程序,是整个系统软件非常关键的部分,如果启动文件出现错误,则整个系统就跑不起来。

4.1 MCU的启动过程

MCU上电后,启动文件会自动进行一些MCU芯片底层的初始化,构建程序运行必要的环境,包括:

      • 堆栈空间定义与初始化

        -变量初始化

        -申请与定义中断向量表

        -定义复位中断函数(Reset_Handler)

      • 用SystemInit()函数来初始化系统的各种时钟、向量表偏移,然后调用(跳转到)__main()函数

__main()调用库函数初始化堆栈

其他中断异常服务函数定义(弱[WEAK]申明)

通常,芯片原厂都提供了MDK对应内核芯片(比如ST STM32L4xx…)启动文件,启动文件由汇编程序编写,一般命名为startup_xxx.s,xxx为支持的芯片型号,比如startup_stm32l476xx.s。     物联网RTOS新贵-TencentOS tiny入门    基于MDK开发,一般可直接使用芯片原厂提供的启动文件,不需要涉及启动文件的修改。

4.2 内核启动过程

通过“4.1 MCU的启动过程”完成了MCU从系统上电开始运行到系统进入应用程序主代码(main函数)的准备工作。接下来便是TencentOS tiny内核启动。

下文结合TencentOS tiny与boardNUCLEO_STM32L476RG的开发板示例进行说明。

4.2.1 TencentOS tiny的main程序入口

TencentOS tiny的main()函数主要完成以下工作:

    1. board_init()板级初始化,初始化系统时钟(system clock)、相关外设初始化(TencentOS tiny目前没有提供设备驱动框架,因此这块跟裸机开发一样,直接使用STM32CubeMX生成代码)
    2. 调用osKernelInitialize,调用内核相关初始化操作,用户根据实际项目通过boardNUCLEO_STM32L476RGTOS_CONFIGtos_config.h相关宏定制内核服务等
      1. 在这里面会创建系统IDLE任务
    1. 调用osThreadCreate,创建一个application_entry任务,application_entry()任务中会开始执行应用层代码。application_entry()默认采用__weak弱定义,用户重新自定义application_entry()即可。
    2. 最后调用osKernelStart,启动系统调度

TencentOS tiny内核启动流程,如下所示:

物联网RTOS新贵-TencentOS tiny入门

从TencentOS tiny实际代码看看:

  1. main()函数所处的位置位于硬件平台的BSP文件夹中,比如boardNUCLEO_STM32L476RGmain.c。
int main(void){    board_init();    printf("Welcome to TencentOS tinyrn");    osKernelInitialize(); // TOS Tiny kernel initialize    osThreadCreate(osThread(application_entry), NULL); // Create TOS Tiny task    osKernelStart(); // Start TOS Tiny}
  1. boardLR_STM32L476RGBSPSrcmcu_init.c定义了硬件平台的系统时钟、GPIO、串口等MCU外设初始化
void board_init(void){  HAL_Init();  SystemClock_Config();  MX_GPIO_Init();  MX_USART2_UART_Init();}

4.2.2 应用程序入口

TencentOS tiny默认通过弱定义的application_entry()任务作为应用层代码的入口,用户根据实际项目重新自定义application_entry(),并添加应用层代码。

应用层参考代码放在example目录下,在application_entry()函数中实现应用代码,如“5章节” Hello Word示例应用。

__weak void application_entry(void *arg){    while (1) {        printf("This is a demo task,please use your task entry!rn");        tos_task_delay(1000);    }}

5 第一个应用 HelloWorld

TencentOS tiny的hello world应用程序放在TencentOS-tiny\examples\hello_world\hello_world.c

#define TASK1_STK_SIZE    512void task1(void *arg);osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
#define TASK2_STK_SIZE    512void task2(void *arg);osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);
void task1(void *arg){    int count = 1;    while (1) {        printf("###This is task1,Hello World %drn", count++);        osDelay(2000);    }}
void task2(void *arg){    int count = 1;    while (1) {#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u        k_err_t rc;        int depth;
        rc = tos_task_stack_draught_depth(K_NULL, &depth);        printf("%d  %dn", rc, depth);#endif
        printf("***This is task2,Hello World %drn", count++);        osDelay(1000);    }}
void application_entry(void *arg){    osThreadCreate(osThread(task1), NULL); // Create task1    osThreadCreate(osThread(task2), NULL); // Create task2}

使用Doxygen生成的函数调用关系,可以比较清楚看到函数之间的调用逻辑,如下图所示

物联网RTOS新贵-TencentOS tiny入门application_entry系统调用图

物联网RTOS新贵-TencentOS tiny入门application_entry系统调用图(局部放大)

物联网RTOS新贵-TencentOS tiny入门

task1函数调用图

物联网RTOS新贵-TencentOS tiny入门

task2函数调用图

通过Jlink等下载到STM32L4硬件板子上,并运行,实际效果如下:

物联网RTOS新贵-TencentOS tiny入门

串口Hello World示例

6 参考

  • TencenOS tiny开源代码库
  • TencenOS tiny简介
  • TencentOS tiny官网
  • TencentOS tiny-代码目录说明
  • TencentOS tiny移植指南(KEIL版本) 

  https://github.com/Tencent/TencentOS-tiny/blob/master/doc/TencentOS-tiny-porting-keil.md

  • TencentOS tiny移植指南(IAR版本)

         https://github.com/Tencent/TencentOS-tiny/blob/master/doc/TencentOS-tiny-porting-iar.md

  • TencentOS tiny移植指南(GCC版本)
       https://github.com/Tencent/TencentOS-tiny/blob/master/doc/TencentOS-tiny-porting-gcc.md
赶快来分享关注吖

物联网RTOS新贵-TencentOS tiny入门

2+

发表评论