一、背景
TobudOS 是一款由腾讯公司推出的面向物联网领域的轻量级嵌入式操作系统,现在已捐赠给开放原子基金会。该系统专为各种低功耗、低成本和低计算能力的设备设计,旨在为设备提供安全、高效的运行环境。Tencent OS Tiny具有极低的资源占用、丰富的组件库、灵活的扩展性以及广泛的硬件支持等特点,使其在物联网行业中具有较高的竞争力。在智能家居、工业自动化、智慧城市等众多应用场景中,Tencent OS Tiny都发挥着关键作用,为物联网设备提供了稳定、可靠的运行支持。
二、目的
-
将 TobudOS 移植到 EVB-AIoT 开发板上
-
在腾讯云的物联网开发平台中新建产品,并上报光强信息,同时使用小程序控制开发板灯光的亮灭
-
探索在 macos 上使用 stm32cube IDE 移植 TobudOS
TobudOS 项目源码:https://atomgit.com/OpenAtomFoundation/TobudOS
KEIL 移植指南:https://atomgit.com/OpenAtomFoundation/TobudOS/blob/master/doc/TobudOS_EVB_AIoT_STM32_Guide.md
三、具体过程
3.1 移植 TobudOS
官方已经提供了 KEIL IDE 的移植源码,本节我们将在 stm32cube IDE 上复现这一过程。KEIL 工程见
https://atomgit.com/OpenAtomFoundation/TobudOS/tree/master/board/TobudOS_EVB_AIoT_STM32/KEIL
首先使用 stm32cube mx 生成基本源码,这点与 KEIL 移植相同。
接着是源文件选择。在 git 仓库中,源码是全量提供的,并未提供 makefile 或其他构建过程的脚本(由 KEIL 的 uvprojx 文件管理)。所以我们需要手工将文件都添加过来。包含四个文件(夹):arch、kernel、osal、tos_config.h。
其中,arch 目录只需要有 cortex-m7/gcc 相关源码即可。
最后,在 SysTick_Handler
中添加 TobudOS 的任务调度;以及设置 PendSV_Handler
为 __weak
。这些与 KEIL 移植相同,不再赘述。添加任务代码后就可以运行 TobudOS 了。
3.2 移植 mqtt client
Mqtt 的移植稍显复杂,主要是官方文档没有讲述组件的移植。
这里还是通过逐个拷贝文件夹的方式来解决。依次将 components/connectivity/mqttclient 和 components/utils/JSON 拷贝到项目目录中;接着拷贝 devices 中的 ec20_200_600 和 esp8266 完成设备驱动的移植;最后还有 net 目录下的 at 组件以及 platform 目录下的 tos_hal_uart 文件。
整个移植过程需要不断尝试编译,根据报错信息找到需要添加的文件和头文件,比较繁琐。
最重要的一点是,mqttclient 依靠串口驱动,串口的发送与接收都需要移植。接收端的代码可以参考 KEIL 源码,贴一部分在这里:
在 stm32h7xx_it.c 中新增串口数据处理,让 AT 组件管理设备。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
extern uint8_t data;
extern uint8_t esp_data;
if (huart->Instance == USART6) {
HAL_UART_Receive_IT(&huart6, &data, 1);
tos_at_uart_input_byte(&ec600s_agent, data);
}
if (huart->Instance == USART2) {
HAL_UART_Receive_IT(&huart2, &esp_data, 1);
tos_at_uart_input_byte(&esp8266_agent, esp_data);
}
}
同时注意对串口使能中断,否则仅能看到发送 AT 指令,设备不响应
在 MX_USART2_UART_Init
函数结束后增加用户代码,使能中断
HAL_UART_Receive_IT(&huart2, &esp_data, 1);
这里使能中断不可以使用 __HAL_UART_ENABLE_IT
,因为它只是简单地使能了UART的接收中断,但没有配置缓冲区和数据长度,也没有关联回调函数 HAL_UART_RxCpltCallback
3.3 与腾讯云对接
在腾讯云中新建物模型,标识符只能是 power_switch
和 lum
,否则和仓库中的代码不适配。
拷贝产品 ID 和密钥到项目中来,编译后下载运行,此时就可以接入云端。
四、实际运行效果
初始化 mqtt
[2023-12-16 16:39:34.39.745]: Welcome to TobudOS(2.5.2)
[2023-12-16 16:39:34.39.750]: Init ec600s ...
AT CMD:
AT
[2023-12-16 16:39:34.39.756]: --->OK
[2023-12-16 16:39:34.39.759]: AT CMD:
ATE0
[2023-12-16 16:39:34.39.765]: --->OK
[2023-12-16 16:39:34.39.769]: AT CMD:
AT+CPIN?
[2023-12-16 16:39:34.39.788]: --->+CPIN: READY
[2023-12-16 16:39:34.39.792]: --->OK
[2023-12-16 16:39:34.39.796]: AT CMD:
AT+CSQ
[2023-12-16 16:39:34.39.814]: --->+CSQ: 28,99
[2023-12-16 16:39:34.39.818]: --->OK
[2023-12-16 16:39:34.39.822]: AT CMD:
AT+CREG?
[2023-12-16 16:39:34.39.839]: --->+CREG: 0,1
[2023-12-16 16:39:34.39.843]: --->OK
[2023-12-16 16:39:34.39.847]: AT CMD:
AT+CGREG?
[2023-12-16 16:39:34.39.865]: --->+CGREG: 0,1
[2023-12-16 16:39:34.39.869]: --->OK
[2023-12-16 16:39:34.39.873]: AT CMD:
AT+QIDEACT=1
[2023-12-16 16:39:34.39.884]: --->OK
[2023-12-16 16:39:34.39.889]: AT CMD:
AT+QICSGP=1,1,"CMNET"
[2023-12-16 16:39:34.39.902]: --->OK
[2023-12-16 16:39:34.39.906]: AT CMD:
AT+QIACT=1
[2023-12-16 16:39:34.39.917]: --->OK
[2023-12-16 16:39:34.39.926]: Init ec600s ok
AT CMD:
AT+QIDNSGIP=1,"Z813G4D3R1.iotcloud.tencentdevices.com"
[2023-12-16 16:39:34.39.937]: --->OK
[2023-12-16 16:39:46.39.172]: Welcome to TobudOS(2.5.2)
[2023-12-16 16:39:46.39.176]: Init ec600s ...
AT CMD:
AT
[2023-12-16 16:39:46.39.182]: --->OK
[2023-12-16 16:39:46.39.186]: AT CMD:
ATE0
[2023-12-16 16:39:46.39.191]: --->OK
[2023-12-16 16:39:46.39.195]: AT CMD:
AT+CPIN?
[2023-12-16 16:39:46.39.214]: --->+CPIN: READY
[2023-12-16 16:39:46.39.218]: --->OK
[2023-12-16 16:39:46.39.222]: AT CMD:
AT+CSQ
[2023-12-16 16:39:46.39.240]: --->+CSQ: 27,99
[2023-12-16 16:39:46.39.244]: --->OK
[2023-12-16 16:39:46.39.248]: AT CMD:
AT+CREG?
[2023-12-16 16:39:46.39.265]: --->+CREG: 0,1
[2023-12-16 16:39:46.39.269]: --->OK
[2023-12-16 16:39:46.39.274]: AT CMD:
AT+CGREG?
[2023-12-16 16:39:46.39.291]: --->+CGREG: 0,1
[2023-12-16 16:39:46.39.295]: --->OK
[2023-12-16 16:39:46.39.300]: AT CMD:
AT+QIDEACT=1
[2023-12-16 16:39:46.39.308]: --->OK
[2023-12-16 16:39:46.39.316]: AT CMD:
AT+QICSGP=1,1,"CMNET"
[2023-12-16 16:39:46.39.325]: --->OK
[2023-12-16 16:39:46.39.330]: AT CMD:
AT+QIACT=1
[2023-12-16 16:39:46.39.340]: --->OK
[2023-12-16 16:39:46.39.350]: Init ec600s ok
AT CMD:
AT+QIDNSGIP=1,"Z813G4D3R1.iotcloud.tencentdevices.com"
[2023-12-16 16:39:46.39.360]: --->OK
[2023-12-16 16:39:46.39.383]: --->+QIURC: "dnsgip",
[2023-12-16 16:39:46.39.392]: --->,1,10
[2023-12-16 16:39:46.39.413]: --->+QIURC: "dnsgip",
[2023-12-16 16:39:46.39.436]: GOT IP: 175.178.30.200
AT CMD:
AT+QISTATE=1,0
[2023-12-16 16:39:46.39.443]: --->OK
[2023-12-16 16:39:46.39.451]: AT CMD:
AT+QIOPEN=1,0,"TCP","175.178.30.200",1883,0,1
[2023-12-16 16:39:46.39.460]: --->OK
[2023-12-16 16:39:46.39.636]: --->+QIOPEN: 0,0
[2023-12-16 16:39:46.39.653]: ../TobudOS/components/connectivity/mqttclient/mqttclient/mqttclient.c:985 mqtt_connect_with_results()... mqtt connect success...
AT CMD:
AT+QISEND=0,166
[2023-12-16 16:39:46.39.659]: --->>
[2023-12-16 16:39:46.39.679]: --->
[2023-12-16 16:39:46.39.686]: --->SEND OK
[2023-12-16 16:39:46.39.761]: --->+QIURC: "recv",
[2023-12-16 16:39:46.39.777]: mqtt connect error is 0
上报光照强度
[2023-12-16 16:42:16.42.474]: Lux=5.83
AT CMD:
AT+QISEND=0,110
[2023-12-16 16:42:16.42.480]: --->>
[2023-12-16 16:42:16.42.495]: --->
[2023-12-16 16:42:16.42.502]: --->SEND OK
[2023-12-16 16:42:16.42.507]: mqtt publish error is 0
[2023-12-16 16:42:16.42.587]: --->+QIURC: "recv",
[2023-12-16 16:42:16.42.739]: -----------------------------------------------------------------------------------
../Core/Src/mqttclient.c:118 tos_topic_handler()...
topic: $thing/down/property/Z813G4D3R1/wenfeng_boa
[2023-12-16 16:42:16.42.761]: rd, qos: 0.
message:
{"method":"report_reply","clientToken":"00000001","code":0,"status":"success"}
-----------------------------------------------------------------------------------
report to Tencent IoT Explorer success
小程序端运行效果
五、经验总结
-
一定要看清楚 KEIL 项目中的源码与 cubemx 生成代码的异同,并将这些差异点同样拷贝到 stm32cube IDE 中,比如我最开始卡在设备没响应,后来发现是没把串口接收的数据传给 AT 组件;紧接着发现是因为没有使能串口中断;
-
Cubemx 生成的代码是 HAL 库,其编程模型相比于标准库发生了挺大变化,需要重新学习才能少走弯路;
-
嵌入式领域的源代码构建过程仍旧集成在 IDE 中,切换 IDE 后需要手工完成项目配置,非常麻烦耗时。如果能以 Makefile 或者 Cmake 作为中转,在 KEIL、stm32cube IDE、gcc 中来回做切换会方便很多;
-
TobudOS 目前没有组件管理脚本,启用组件(mqttclient)均需要手工移植。后续可以增加 kconfig 来实现菜单式选择,加速移植过程