闲暇之时,移植TencentOS-tiny玩玩,听说这个系统占用资源比较少。好了,我们正面了解一下这个RTOS系统。
本文章有点长,需要耐心阅读,谢谢各位看官,在百忙之中,抽出时间来到这里共同学习。本人水平有限,定会有错误的地方,
如有发现,请大家指出,第一时间更新,谢谢!!
1、资源占用极少
TencentOS tiny 最少资源占用:RAM 0.8KB,ROM 1.8KB;在类似烟感和红外等实际场景下,TencentOS tiny 的资源占用仅 为:RAM 2.69KB、ROM 12.38KB。资源占用之少业界领先。
2、高效功耗管理框架
完整包含 MCU 和外围设备功耗管理,用户可以根据业务场景选择可参考的低功耗方案,有效降低设备耗电,延长设备寿命。
3、自动移植工具
TencentOS tiny 提供多种编译器快速移植指南和移植工具,可实现向新硬件开发板的一键移植,省时省力,有效提升开发效 率。
4、最后一屏调试工具
TencentOS tiny 可以自动获取故障现场信息,并保持在端侧存储设备中,触发重启后会自动上传故障信息,可有效解决远程物 联网设备故障信息获取难题,提升故障分析解决效率。
5、安全分级方案
TencentOS tiny 提供了多个等级的 IoT 安全方案。您可以根据业务场景和成本要求选择合适的安全解决方案,方便客户在安全 需求和成本控制之间进行有效平衡。
1、MCU芯片/IOT模组
TencentOS tiny 支持主流的 MCU 芯片,如 STM32 NXP 等,支持主流通信模组,如 ESP8266 wifi、LoraWAN 模组、NB-IoT 模组等。
2、物联网终端设备厂家
TencentOS tiny 提供完整的终端软件栈,简单易用的端云 SDK 缩短设备厂家的开发周期,进而节省终端产品开发成本。
3、物联网解决方案
TencentOS tiny 提供一站式软件解决方案,方便各种物联网设备快速接入腾讯云,可支撑智慧城市、智能水表、智能家居、智慧农业、智能穿戴、车联网等多种行业应用。
闲暇之时,利用一点点时间移植一下TencentOS-tiny系统玩玩。
硬件(MCU):STM32L051C8T6
目前来说TencentOS-tiny比起LiteOS还有一些不足的地方(组件还没有LiteOS完善),但是它占用flash确实是小些,比起LiteOS。
直接进入话题,其实,我已在前一个月就移植好了,现在就是做个记录。
好啦!其实移植很简单,官方已经给我们写了移植步骤,只需一步步按照步骤来进行即可。
不过移植时要注意一些小小地方。
移植前需要做几个步骤:
1、使用STM32CubeMx工具生成demo工程,我的工程名叫STM32L051C8T6
1)新建工程页面:
根据你手上的板子芯片型号来选择,对应的芯片,即可。
2)时钟配置界面:
3)GPIO管脚配置页面:
配置好后,接着点击生成代码按键,在当前窗口右上角"GENERATE CODE",点击它即可。
自动启动Keil IDE 工具
测试该工程结果
以确保本工程是可以正常运行,继续往下前行。
2、就是在TencentOS-tiny官方下载源码。(现在几乎每天都在更新源码,不断完善中)
1)源码的地址:https://github.com/Tencent/TencentOS-tiny
2)克隆源码:
注:下载代码,可以使用(GitHub Desktop工具克隆源码) ,这个过程很漫长,需要耐心等待。
3、在这我是基于keil IDE开发的环境,所以我是按照官网教程步骤如下:
如图所示,新建TencentOS_tiny主目录,并在主目录下添加四个子目录,其中arch、kernel、osal从代码仓直接拷贝过来即可,而board目录下则放入我前面使用STM32CubeMX 工具生成的裸机工程代码,如下图所示:
引入TencentOS-tiny中的arch文件
1:arch\arm\arm-v7m\common\tos_cpu.c
2:arch\arm\arm-v7m\cortex-m0+\armcc\port_c.c 和 arch\arm\arm-v7m\cortex-m0+\armcc\port_s.S
tos_cpu.c是TencentOS tiny 的CPU适配文件,包括堆栈初始化,中断适配等,如果您的芯片是ARM Cortex M核,该文件可以不 做改动,M0、M3 、M4、M7是通用的,其他IP核需要重新适配;
port_s.S 文件是TencentOS tiny的任务调度汇编代码,主要做弹栈压栈等处理的,port_c.c适配systick等,这两个文件 每个IP核和编译器都是不一样的,如果您的芯片是ARM Cortex M核,我们都已经适配好,比如现在我们移植的芯片是STM32L073RZ,是ARM Cortex M0+核,使用的编译器是KEIL,所以我们选择arch\arm\arm-v7m\cortex-m0+\armcc下的适配代码,如果你的开发板是STM32F429IG,M4核,编译器是GCC,则可以选择arch\arm\arm-v7m\cortex-m4\gcc目录下的适配文件。
把kernel目录下中的core和pm两个文件夹所有.c文件添加进来即可,其中Core下为基础内核,如何还没涉及
到低功耗,这个pm目录下的.c文件可以不用添加。如下如所示:
cmsis os已经帮我们考虑到兼容问题,所以弄了个抽象层OS,这样移植TencentOS tiny的工作量。
cmsis_os.c文件路径:osal\cmsis_os\cmsis_os.c
在工程目录下,新建一个TOS_CONFIG文件夹,同时创建一个tos_config.h文件,用来存放TencentOS tiny的配置头文件。
如下图所示:
#ifndef _TOS_CONFIG_H_
#define _TOS_CONFIG_H_
#include "stm32l0xx.h" // 目标芯片头文件,用户需要根据情况更改
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
#define TOS_CFG_ROUND_ROBIN_EN 0u // 配置TencentOS tiny的内核是否开启时间片轮转
#define TOS_CFG_OBJECT_VERIFY_EN 1u // 配置TencentOS tiny是否校验指针合法
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 1u // TencentOS tiny 动态任务创建功能宏
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
#define TOS_CFG_MMBLK_EN 1u //配置TencentOS tiny是否开启内存块管理模块
#define TOS_CFG_MMHEAP_EN 1u //配置TencentOS tiny是否开启动态内存模块
#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN 1u // TencentOS tiny 默认动态内存池功能宏
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100 // 配置TencentOS tiny默认动态内存池大小
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
#define TOS_CFG_MESSAGE_QUEUE_EN 1u // 配置TencentOS tiny是否开启消息队列模块
#define TOS_CFG_MAIL_QUEUE_EN 1u // 配置TencentOS tiny是否开启消息邮箱模块
#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 1u // 配置TencentOS tiny是否开启优先级消息队列模块
#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 1u // 配置TencentOS tiny是否开启优先级消息邮箱模块
#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块
#define TOS_CFG_PWR_MGR_EN 0u // 配置TencentOS tiny是否开启外设电源管理模块
#define TOS_CFG_TICKLESS_EN 0u // 配置Tickless 低功耗模块开关
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 1u // 配置TencentOS tiny是否开启任务栈深度检测
#define TOS_CFG_FAULT_BACKTRACE_EN 0u // 配置TencentOS tiny是否开启异常栈回溯功能
#define TOS_CFG_IDLE_TASK_STK_SIZE 128u // 配置TencentOS tiny空闲任务栈大小
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
#define TOS_CFG_CPU_CLOCK (SystemCoreClock) // 配置TencentOS tiny CPU频率
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
#endif
1. 修改部分代码
修改stm32l0xx_it.c的中断函数,在stm32l0xx_it.c文件中包含 tos_k.h 头文件
如果不去掉这个选择,那就要在stm32l0xx_it.c文件中的PendSV_Handler函数前添加__weak关键字才行。
同时在SysTick_Handler函数中添加TencentOS tiny的调度处理函数,如下图所示:
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
if(tos_knl_is_running())
{
tos_knl_irq_enter();
tos_tick_handler();
tos_knl_irq_leave();
}
/* USER CODE END SysTick_IRQn 1 */
}
在usart.c文件
在mian.c 中添加TencentOS tiny 头文件,编写任务函数
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "cmsis_os.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
//task1
#define TASK1_STK_SIZE 256
void task1(void *pdata);
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
//task2
#define TASK2_STK_SIZE 256
void task2(void *pdata);
osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);
void task1(void *pdata)
{
int count = 1;
while(1)
{
printf("\r\nHello world!\r\n###This is task1 ,count is %d \r\n", count++);
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
osDelay(2000);
}
}
void task2(void *pdata)
{
int count = 1;
while(1)
{
printf("\r\nHello TencentOS !\r\n***This is task2 ,count is %d \r\n", count++);
osDelay(1000);
}
}
/* USER CODE END PTD */
/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 */
.
.
.
/* USER CODE BEGIN 1 */
/*printf() 重定向输出到串口*/
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /*__GNUC__*/
PUTCHAR_PROTOTYPE
{
/*通过串口1发送一个字符,ch为字符的存储地址,0xffff为超时时间*/
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
/* USER CODE END 1 */
继续在main.c 的mian函数中硬件外设初始化代码后添加TencentOS tiny的初始化代码:
osKernelInitialize(); //TOS Tiny kernel initialize
osThreadCreate(osThread(task1), NULL);// Create task1
osThreadCreate(osThread(task2), NULL);// Create task2
osKernelStart();//Start TOS Tiny
5、运行结果:
代码链接
源码链接:Git