1、腾讯物联网开发板开箱
前几天拿到了腾讯汪总赠送的EVB_MX+
以及EVB_LX
开发板,它们长下面这个样子,看起来很轻便,即使是外出我也可以随身带着它随时随地进行玩耍,就和小熊派一样,整体给人感觉就非常舒服。
一看这个开发板外观以及包装盒大家就想到了之前的小熊派,不错,它们可是有血缘关系的!但EVB_MX+的资源更加丰富噢!有关小熊派的评测文章如下:
迫不及待开启评测模式,我们先来看看这两个开发板的基本介绍以及功能分布,最后选取一个入门最快的平台,移植TecentOS tiny,完善最基础的实验。
1、EVB_MX+简介
EVB_MX+
使用STM32L431RCT6作为主控,支持传感器扩展E53接口、支持网络模块扩展WAN接口、具有丰富的扩展接口等等。腾讯TencentOS tiny 团队联合南京厚德物联网有限公司在这个板子上花费了不少心血,参考资料可谓是相当完善,零基础小白看着腾讯的开源文档都能实现手把手移植TencentOS tiny
到相关平台,手把手上手TencentOS tiny
,据说移植TencentOS tiny
到STM32相当容易噢!
2、EVB_LX简介
EVB_LX
使用GD32VF103RBT6
作为主控,一样和EVB_MX+
支持传感器扩展E53接口、支持网络模块扩展WAN接口、具有丰富的扩展接口等等。这是TencentOS tiny 团队联合兆易创新(GD32)、南京厚德物联网有限公司三方合作设计的一款物联网评估板,用于TencentOS tiny 基础内核、RISC-V新IP核架构和IoT组件功能体验和评估。
近年来,随着国际形势日益严峻,国产半导体行业也在不断崛起,而兆易创新可谓是芯片国产化的急行军,它快速借鉴国内以及国外的优势资源,吸取教训,不断完善自己的生态链。在国内已经有不少的厂家开始用上了兆易的芯片做了很多成熟稳定的产品,特别是在工控行业,兆易32位芯片逐步取代国外32位主流控制芯片,相信有朝一日定能与国外的半导体行业一较高下,成为未来芯片设计领域的佼佼者!
那么移植一个TencentOS tiny
到开发板上真的有那么简单吗?我们以将TencentOS tiny
移植到EVB_MX+
为例。
3、TencentOS tiny EVB_MX+初体验
3.1、准备一份裸机工程
以下是我配置的LED、按键、时钟、串口、SWD调试口的裸机工程,这里我们直接借助STM32CubeMX生成就好了:
(1)配置LED、按键
(2)配置时钟
(3)配置串行调试口
(4)配置调试串口
(5)生成基础裸机工程
设置外设以单独的文件生成
最后点击生成代码即可,我是属于Keil环境下进行开发。
3.2、移植TencentOS tiny到EVB_MX+
TencentOS tiny整体架构
从TencentOS tiny开源的Github或者码云仓库下载整个SDK包,如下所示:
TencentOS tiny
Github仓库地址:
https://github.com/Tencent/TencentOS-tiny
TencentOS tiny参考文档地址:
https://cloud.tencent.com/document/product/1098
首先我们重新在别的地方创建一个TencentOS tiny,然后把我们下载到的包里的arch、board、kernel、osal四个文件夹拷贝出来放到我们新创建的TencentOS tiny文件夹,最后我们再手动创建一个TOS_CONFIG,用于放置TencentOS tiny的配置文件,效果如下:
接下来我们把刚刚创建好的裸机工程First_Test放到board文件夹下:
一级目录 | 二级目录 | 说明 |
arch | arm | TencentOS tiny适配的IP核架构(含M核中断、调度、tick相关代码) |
board | First_Test | 移植目标芯片的工程文件 |
kernel | core | TencentOS tiny内核源码 |
pm | TencentOS tiny低功耗模块源码 | |
osal | cmsis_os | TencentOS tiny提供的cmsis os 适配 |
这时候我们的目录架构如上所示,打开First_Test的Keil MDK工程。
(1)添加工程文件
以上需要选择对应芯片架构,详细请参考10.Porting_Manual_for_KEIL.md
文档说明,如果SDK包没有的话则需要自己去移植。
最后可以看到相关文件已经包含进来了:
(2)添加文件路径
这里要注意的是需要添加对应芯片架构的头文件,详细请参考10.Porting_Manual_for_KEIL.md
文档说明。
(3)添加相关代码
打开stm32l4xx_it.c,包含tos_k.h头文件:
在PendSV_Handler前加上__weak关键字,因为PendSV_Handler已经在TencentOS tiny中某些文件重新实现了。
__weak void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ /* USER CODE END PendSV_IRQn 0 */ /* USER CODE BEGIN PendSV_IRQn 1 */ /* USER CODE END PendSV_IRQn 1 */ }
在SysTick_Handler函数中添加TencentOS tiny的调度处理函数在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 */ }
以上这里有几个关键的API的含义在官方文档中可以查询到:
tos_tick_handler是系统用于更新时基用的,源码如下:
__API__ void tos_tick_handler(void) { if (unlikely(!tos_knl_is_running())) { return; } tick_update((k_tick_t)1u); #if TOS_CFG_TIMER_EN > 0u && TOS_CFG_TIMER_AS_PROC > 0u timer_update(); #endif #if TOS_CFG_ROUND_ROBIN_EN > 0u robin_sched(k_curr_task->prio); #endif }
这里首先会判断内核是否已经运行,如果没有运行则返回,如果运行了,那么就调用tick_update
更新系统时基,如果配置了TOS_CFG_TIMER_EN
宏,则调用timer_update();
这样我们就可以使用TencentOS Tiny的软件定时器,如果配置了TOS_CFG_TIMER_AS_PROC
宏,那么会进行时间片相关的逻辑处理,相关的代码逻辑大家可以阅读源码详细分析,不得不说TencentOS Tiny这里的保护做得非常好,设计思路很严谨!
(4)添加OS配置文件
这个文件一般是手动创建的,放在上面我们创建的TOS_CONFIG目录下,配置对应的宏可以开启OS对应的功能,以下是官方给出的一个标准模板,如果还有别的需要添加的话,则需要修改以下文件。
tos_config.h
#ifndef _TOS_CONFIG_H_ #define _TOS_CONFIG_H_ //#include "stm32l0xx.h" // 目标芯片头文件,用户需要根据情况更改 #include "stm32l4xx_hal.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
到这里,TencentOS Tiny就已经在EVB_MX+上移植成功了!接下来我们来测试一下:
(5)添加相关代码
在main.c中添加相关代码:
#include "cmsis_os.h" //定义一个任务 #define TASK1_STK_SIZE 256 void task1(void *pdata); osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE); void task1(void *pdata) { while(1) { printf("Hello TencentOS_tiny_EVB_MX_Plus\n"); HAL_GPIO_TogglePin(DEBUG_LED_GPIO_Port, DEBUG_LED_Pin); osDelay(500); } } /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART2_UART_Init(); /* USER CODE BEGIN 2 */ //初始化内核 osKernelInitialize(); //创建一个任务 osThreadCreate(osThread(task1), NULL); //启动内核 osKernelStart(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
运行结果:
LED调试灯翻转的同时打印LOG信息。
有关TencentOS tiny相关的知识,小伙伴们可以自行下载SDK包,TencentOS tiny技术团队已经给多个开发板编写了相应的高质量软件例程。相信有不少东西值得学习和借鉴。