一, 前言
在上一篇中, 我们利用 MCUXpresso Config Tools 生出来一个 Hello World 的裸机工程, 这一篇将在 Keil 环境下移植 TencentOS tiny 到这个裸机工程, 并移植对接腾讯云的工程.
源码中也有相关工程参考
二, 前期准备
本系列文章第一篇中安装的软件环境
在第一篇文章中使用 MCUXpresso Config Tools 搭建的 Hello World 裸机工程
TencentOS-Tiny-AIoT 开发板硬件资料 (比赛微信群公告中的资料包中文件)
NXP_RT1062_TencentOS_Tiny_AIoT.rar(比赛微信群公告中的资料包中文件)
TencentOS-tiny 源码 (可在 GitHub 代码仓 \ 码云代码仓 https://gitee.com/Tencent/TencentOS-tiny 下载)
三, 移植 TencentOS tiny
3.1. 准备文件
将 NXP_RT1062_TencentOS_Tiny_AIoT 里面的 TencentOS_Tiny 文件夹复制到自建工程根目录下 (也从官方源码中复制文件, 都可以)
主要使用文件如下表
一级目录 | 二级目录 | 说明 |
---|---|---|
arch | arm | TencentOS tiny 适配的 IP 核架构(含 M 核中断、调度、tick 相关代码) |
board | NUCLEO_L073RZ | 移植目标芯片的工程文件 |
kernel | core | TencentOS tiny 内核源码 |
pm | TencentOS tiny 低功耗模块源码 | |
osal | cmsis_os | TencentOS tiny 提供的 cmsis os 适配 |
效果如图
3.2. 配置工程
打开 keil 工程, 这里建议从 hello_world1 flexspi_nor_debug 与 hello_world1 flexspi_nor_sdram_debug 选择一个作为后续开发工程. 这两个配置都是把程序固化到 flash 里面的, 其中 hello_world1 flexspi_nor_debug 是没有在 DCD 初始化好 SDRAM 的 hello_world1 flexspi_nor_sdram_debug 是在 DCD 中初始化好 SDRAM 的. 简单可以理解为, 如果后续开发不使用 SDRAM 就用第一个, 使用的话就用第二个, 这里后期也是能自由切换的. 这里笔者就使用 hello_world1 flexspi_nor_sdram_debug 作为演示.
3.3. 添加相关文件
添加 arch 平台代码
添加 kernel/core 下所有. c 文件 (pm 为低功耗组件, 可不用添加)
添加 cmsis 抽象层 osal\cmsis_os\cmsis_os.c 文件
为方便后期修改配置, 可添加 tos_config\tos_config.h 文件
3.4. 添加头文件目录
3.5. 编写代码
打开 source\hello_world.c 文件, 写个程序试试水
- #include "fsl_device_registers.h"
- #include "fsl_debug_console.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "board.h"
- #include "tos_k.h"
- void SysTick_Handler(void)
- {
- if (tos_knl_is_running())
- {
- tos_knl_irq_enter();
- tos_tick_handler();
- tos_knl_irq_leave();
- }
- }
- #define TASK1_STK_SIZE 1024
- k_task_t task1;
- uint8_t task1_stk[TASK1_STK_SIZE];
- #define TASK2_STK_SIZE 1024
- k_task_t task2;
- uint8_t task2_stk[TASK2_STK_SIZE];
- void task1_entry(void *arg)
- {
- while (1) {
- PRINTF("###I am task1\r\n");
- tos_task_delay(2000);
- }
- }
- void task2_entry(void *arg)
- {
- while (1) {
- PRINTF("***I am task2\r\n");
- tos_task_delay(1000);
- }
- }
- int main(void)
- {
- char ch;
- /* Init board hardware. */
- BOARD_ConfigMPU();
- BOARD_InitBootPins();
- BOARD_InitBootClocks();
- BOARD_InitDebugConsole();
- SystemCoreClockUpdate();
- tos_knl_init(); // TencentOS Tiny kernel initialize
- tos_task_create(&task1, "task1", task1_entry, NULL, 4, task1_stk, TASK1_STK_SIZE, 0); // Create task1
- tos_task_create(&task2, "task2", task2_entry, NULL, 3, task2_stk, TASK2_STK_SIZE, 0);// Create task2
- tos_knl_start();
- }
3.6. 编译下载, 打开串口助手查看现象
四, 对接腾讯云 IoT
4.1. 配置引脚
打开工程的 MCUXpresso Config Tools 配置文件
参考 IO 表, 配置 uart2 与 LED
具体配置如下图 (注意重命名)
点击更新源代码
4.2. 准备文件
大部分文件都在第三步准备好了
拷贝 NXP_RT1062_TencentOS_Tiny_AIoT\source 里 main.c 与 mqttclient_iot_explorer.c 到自建工程 source 目录下
4.3. 添加相关文件
这里因为 Keil 没有二级目录管理, 因此文件夹显得比较多, 按照自己的实际习惯添加即可
TencentOS_Tiny\components\connectivity\mqttclient\common 下的 mqtt_list.c 与 random.c
- TencentOS_Tiny\components\connectivity\mqttclient\mqtt
- TencentOS_Tiny\components\connectivity\mqttclient\mqttclient
- TencentOS_Tiny\components\connectivity\mqttclient\network
- TencentOS_Tiny\components\connectivity\mqttclient\platform\TencentOS-tiny
- TencentOS_Tiny\components\utils\JSON\src
- TencentOS_Tiny\platform\hal\nxp\rt1060\src
- TencentOS_Tiny.NET\at\src
- TencentOS_Tiny.NET\sal_module_wrapper
- TencentOS_Tiny\devices\esp8266
添加这些文件夹下所有. c 文件
为方便后期修改配置, 可添加 tos_config\mqtt_config.h 文件
删除 hello_world.c 添加 main.c 与 mqttclient_iot_explorer.c
4.4. 添加头文件目录
4.5. 修改工程设置
加入 SDK_DEBUGCONSOLE_UART 全局宏, 使代码支持 printf 函数
4.6. 修改代码
*main.c
注释掉 17 行 #include "ec600s.h"
添加
- void SysTick_Handler(void)
- {
- if (tos_knl_is_running())
- {
- tos_knl_irq_enter();
- tos_tick_handler();
- tos_knl_irq_leave();
- }
- }
可以注释掉 LPUART4_IRQHandler 函数
*mqttclient_iot_explorer.c
注释掉第 8 行 #include "ec600s.h"
4.7. 配置云
参考
四. EVB_AIoT 开发板上使用 TencentOS tiny 对接腾讯云 IoT Explorer 进行操作
也可在下载的源码中找到: TencentOS-tiny-master\doc\30.TencentOS_Tiny_EVB_AIoT_QuickStart.md
4.8. 编译下载运行
五, 可能碰到的问题与建议
5.1. 为啥在 3.3 步中添加 arch 平台代码添加的是 GCC 文件下的代码
MDK AC6 在汇编上的语法支持很接近 GCC, 对于工程默认配置来说添加 GCC 文件夹下最简单
如果想添加 armcc 文件夹下的文件, 请按下图修改
5.2. 无法进入任务
检查是否添加下面代码
- void SysTick_Handler(void)
- {
- if (tos_knl_is_running())
- {
- tos_knl_irq_enter();
- tos_tick_handler();
- tos_knl_irq_leave();
- }
- }
5.3. 运行 printf 后卡死
加入 SDK_DEBUGCONSOLE_UART 全局宏
5.4. 出现 FCARM - Output Name not specified, please check 'Options for Target - Utilities'编译提示
检查出现错误的文件类型是否正确, 例如
该图是正确的. h 文件类型
5.5. 出现 source/main.c(115): error: use of undeclared identifier 'BOARD_INITPINS_LED_GPIO'错误
配置并修改 LED 的标签与标识符
5.6.TencentOS tiny 学习建议
可以参考下面两个链接学习
有其他问题可在本文下交流
来源: https://www.qcloud.com/developer/article/1931085