【免费下载链接】TobudOSTobudOS 是面向物联网领域开发的实时操作系统早期版本基于腾讯自研的物联网操作系统TencentOS Tiny2020年由腾讯捐赠到开放原子开源基金会进行孵化2023年正式更名为TobudOSTobudOS具有低功耗低资源占用模块化安全可靠等特点可有效提升物联网终端产品开发效率提供精简的 RTOS 内核内核组件可裁剪可配置可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且基于 RTOS 内核提供了丰富的物联网组件内部集成主流物联网协议栈如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等可助力物联网终端设备及业务快速接入物联网云平台。项目地址https://gitcode.com/openatomfoundation/TobudOS点击查看免费下载本文以 TobudOS前身 TencentOS Tiny为设备端操作系统完整讲解如何将嵌入式终端设备通过 MQTT 协议接入腾讯云物联网通信IoT Hub服务从云端的产品创建、设备创建、Topic 与规则引擎设置到设备端 MQTT 组件的引入、网络层适配、配置生成与收发消息编码实现覆盖设备—云平台双向通信的完整链路。读完本文后你将掌握 TobudOS 的 mqttclient 组件与 sal_module_wrapper 网络抽象层的实际用法能够独立完成任意一块搭载 WiFi/NB-IoT/4G 模组的开发板与腾讯云 IoT Hub 的对接与联调。一、整体架构从 IoT Hub 到 TobudOS 设备的连接模型腾讯云物联网通信IoT Hub是一个安全、稳定、高效的连接平台帮助开发者低成本、快速地实现设备—设备、设备—用户应用、设备—云服务之间可靠、高并发的数据通信。基于该平台可以实现设备之间的互动、设备数据的上报与配置下发还可以借助规则引擎与腾讯云各产品打通便捷地完成海量设备数据的存储、计算与智能分析从而低成本地搭建设备—数据—应用—云服务的物联网应用体系。在上图所示的整体架构中本文聚焦用户设备与腾讯云之间的对接。可以看到用户设备与腾讯云之间基于MQTT或CoAP协议通信因此设备端需要包含连接 SDK 或实现了 MQTT/CoAP 协议的代码。本文以 MQTT 连接方法为主线CoAP 协议流程类似。MQTT 通信模型简述物联网设备必须连接互联网才能与后端服务协作其基础网络协议是 TCP/IP而 MQTT消息队列遥测传输正是构建在 TCP/IP 之上的 IoT 通信事实标准。MQTT 是一个轻量级协议可以在硬件受限的设备上实现同时它支持发送方与接收方在空间和时间上的分离因此能够在不可靠的网络环境中扩展。MQTT 协议基于**发布Publish/订阅Subscribe**模型定义了两种实体消息代理端Broker服务器从客户端接收所有消息并将消息路由到相关的目标客户端客户端Client能够与代理交互以发送和接收消息的任何事物可以是现场的 IoT 传感器也可以是数据中心内处理 IoT 数据的应用程序。Client 与 Broker 之间的发布订阅依据**主题Topic**进行不同的客户端可以向不同主题发布消息设备只有在订阅了某个主题后才能收到该主题的消息。腾讯云 IoT Hub 对 MQTT 协议的实现与标准协议差别不大仅在个别细节上做了扩展因此从技术上来说任何实现了标准 MQTT 客户端的设备都可以与腾讯云正常通信。在 TobudOS 中这一职责由内置的 mqttclient 组件承担。二、云端设置创建产品、设备、Topic 与规则引擎云端设置主要包含创建新产品、创建新设备和配置转发规则。登录腾讯云控制台在云产品中搜索物联网通信并进入产品控制台即可开始操作。2.1 创建新产品在控制台进入产品列表后点击新建产品。添加新产品时有四个关键选项需要注意选项本文推荐值说明产品类型普通产品面向通用终端设备产品名称随意如 my_product仅用于平台侧标识认证方式密钥认证本文示例选择数据格式自定义本文示例选择关于认证方式与数据格式的选择平台有两点设计考量认证方式指定设备通过何种方式与云端进行双向认证。默认的证书认证安全性相对更高但需要在嵌入式设备端存储证书并实现证书处理对设备的 RAM 和 ROM 要求较高密钥认证的资源占用量更小。由于 TobudOS 主要面向小型嵌入式设备因此本文选用密钥认证。数据格式指设备与云端交互数据时使用的格式。json 为文本字符串可读性高、便于解析适合功能复杂的设备而自定义格式二进制或文本对于数据单一或定制设备更节约流量、更灵活。注意数据格式的选择会影响之后规则引擎组件的设置详见 2.4 节。新建产品完成后平台会分配一个productID如文档示例中的25KCIUIR1G它是之后构造 Topic、域名与 MQTT 参数的基础。2.2 创建新设备在产品列表下进入设备列表点击添加设备只需设置设备名称即可。由于创建产品时选择了密钥认证创建设备时平台会提供设备对应的密钥选择默认的使用物联网通信提供的密钥即可。添加完第一个设备如命名为dev1后平台会展示该设备的密钥此密钥将用于之后设备与平台通信时的认证。为了实现设备间的通信还需要以同样方式创建第二个设备dev2。此时产品my_product下就有了dev1与dev2两个设备。2.3 Topic 设置设备通过 MQTT 的发布/订阅机制通信因此还需要在云端配置 Topic。在产品的权限列表中可以查看每个 Topic 对应的操作权限也可以在此处添加新 Topic。平台默认配置了三类Topic 用于发布和订阅之所以说是三类而不是三个是因为 Topic 中使用了变量25KCIUIR1G是 productID${deviceName}是平台变量即设备名control、data、event是 Topic 名字。因此在创建了 dev1、dev2 两个设备后产品下实际存在 6 个 TopicTopic权限25KCIUIR1G/dev1/control订阅权限25KCIUIR1G/dev1/data发布和订阅权限25KCIUIR1G/dev1/event发布权限25KCIUIR1G/dev2/control订阅权限25KCIUIR1G/dev2/data发布和订阅权限25KCIUIR1G/dev2/event发布权限默认的 Topic 已足够本文场景使用无需额外添加。MQTT 的 Topic 本身是普通字符串可由多个层级组成、以/划分这种分层结构使主题的过滤与匹配更灵活并支持两种通配符多层通配符#必须位于最后一个字符匹配多层级。例如25KCIUIR1G/#会匹配25KCIUIR1G/dev1、25KCIUIR1G/dev2、25KCIUIR1G/dev1/control、25KCIUIR1G/dev1/event、25KCIUIR1G/dev2/control、25KCIUIR1G/dev2/event等主题单层通配符匹配单个层级可在主题的任何层级使用。例如25KCIUIR1G//event会匹配25KCIUIR1G/dev1/event与25KCIUIR1G/dev2/event。2.4 规则引擎打通设备间的双向数据通路规则引擎不属于 MQTT 协议范畴但平台出于安全角度添加了它来实现 Topic 之间的转发操作。要理解规则引擎需要先明白三个问题。为什么需要规则引擎在 2.3 节的 Topic 权限表中可以看到25KCIUIR1G/dev1/event只有发布权限25KCIUIR1G/dev1/control只有订阅权限。对于设备 dev1很自然地会向dev1/event发布数据、订阅dev1/control的消息但 event 的数据最终去哪、control 的数据来自哪里就需要规则引擎来回答。在本例中我们希望 dev1 与 dev2 相互收发消息dev1 想获得 dev2 的数据直觉上应订阅 dev2 发布消息的 Topic即25KCIUIR1G/dev2/event但存在两个障碍其一event Topic 只有发布权限、没有订阅权限其二平台规定不允许跨设备发布或订阅 Topic——对于 dev1只能访问25KCIUIR1G/dev1及其下属 Topic不能访问dev2及其下属 Topic。这条限制虽然不够直观但却是合理的如果没有它一个设备就可以不加限制地订阅同一产品下所有其他设备的 Topic获取其上报的消息存在潜在安全漏洞。规则引擎的作用是什么由于不允许直接跨设备访问 Topic需要依靠规则引擎手动添加规则将指定 Topic 的消息转发republish到另一个 Topic从而实现不同设备之间的通信。如上图所示产品 ID 以实际为准规则引擎将25KCIUIR1G/dev2/event的消息 republish 到25KCIUIR1G/dev1/control将25KCIUIR1G/dev1/event的消息 republish 到25KCIUIR1G/dev2/control。这样dev1 只需订阅25KCIUIR1G/dev1/control即可收到来自25KCIUIR1G/dev2/event的消息dev2 同理。如何设置规则引擎在物联网通信界面选择规则引擎—新建规则随意指定规则名称本文设置为1to2。规则详情包含两部分筛选数据针对指定 Topic 接收到的消息内容进行进一步筛选例如匹配消息中的字段来决定是否执行后续的行为操作行为操作指定对通过匹配的消息执行何种操作主要有数据转发到另一个 TopicRepublish、转发到第三方服务Forward以及转发到腾讯云各个对应组件。设置规则1to2时筛选字段设为*筛选 Topic 为25KCIUIR1G/dev1/event条件为空即不筛选数据、全部匹配执行的操作是转发到25KCIUIR1G/dev2/control。设置完成后dev2 通过订阅 control 就能收到 dev1 发到 event 的数据。再以同样方式新建规则2to1实现25KCIUIR1G/dev2/event到25KCIUIR1G/dev1/control的转发。两条规则都设置好后记得点击启用按钮平台侧 dev1 与 dev2 的双向数据通路即打通。关于筛选数据的设定由于新建产品时选择了自定义数据格式平台会将其当作二进制流处理无法通过匹配字段进行数据筛选如果产品使用 json 数据格式此处就可以根据 json 字段进行 SQL 式的匹配和筛选。2.5 云日志与消息队列 CMQ在平台侧设置完成后测试或通信过程中往往需要确认平台是否收到了设备上报的消息、对消息执行了哪些操作、消息的具体内容payload是什么。腾讯云为此提供了物联网通信产品的云日志功能和腾讯云组件消息队列 CMQ。云日志在产品列表下找到云日志点击搜索即可显示对应的行为日志。日志会记录设备的连接、断开、发布、订阅等行为也记录规则引擎的操作以及 CMQ 队列的行为日志。但设备发布的消息内容无法在云日志中查看需要借助消息队列 CMQ。消息队列 CMQ在产品列表中找到消息队列设置队列所希望接收的消息类型后保存配置即可将平台侧收到的设备消息额外发送到腾讯云消息队列 CMQ 组件中。随后在云产品中搜索 CMQ 找到对应队列点击开始接收消息即可查看消息内容其中带有PayloadLen和Playload字段的即为具体消息内容。在密钥认证下消息的内容payload是经过 base64 编码的因此在平台侧看到的类似乱码的数据实际上是编码后的结果。想要查看具体内容可以在 Linux 下执行echo payload | base64 --decode。三、设备终端设置TobudOS 侧的 MQTT 对接设备终端与腾讯云之间采用 MQTT 协议通信需要消息代理端与客户端相互配合因此终端设备上需要实现一个 MQTT Client。TobudOS 集成了对 MQTT 与腾讯云的支持开发者只需简单设置即可完成对接整体步骤如下项目工程中添加 MQTT 组件相关文件适配 AT HAL 层串口及网络接口函数执行脚本生成 MQTT 配置头文件调用 OS 提供的接口完成与腾讯云的对接。3.1 工程中添加 MQTT 组件相关文件在工程中添加 hal、at、devices 和 mqttclient 源码。MQTT 客户端组件位于仓库的 components/connectivity/mqttclient 目录网络抽象层位于 net/sal_module_wrapperAT 框架位于 net/at具体通信模组驱动位于 devices 目录。仓库中提供了可直接参考的完整工程例如board/TencentOS_Tiny_EVB_MX_Plus/KEIL/mqttclient_iot_explorer含 demo 源码与 KEIL 工程文件board/BearPi_STM32L431RC/KEIL/mqttclient_iot_explorer。3.2 适配 AT HAL 层串口及网络接口函数上层 MQTT 的操作最终都会转化为对底层通信设备的 socket 操作。TobudOS 集成了 sal_module_wrapper 抽象层但由于各开发板硬件不同需要针对具体模组进行适配。适配过程的核心数据结构是sal_module_t定义在 net/sal_module_wrapper/sal_module_wrapper.h 中typedef struct sal_module_st { int (*init)(void); int (*get_local_mac)(char *mac); int (*get_local_ip)(char *ip, char *gw, char *mask); int (*parse_domain)(const char *host_name, char *host_ip, size_t host_ip_len); int (*connect)(const char *ip, const char *port, sal_proto_t proto); int (*connect_with_size)(const char *ip, const char *port, sal_proto_t proto, size_t socket_buffer_size); int (*send)(int sock, const void *buf, size_t len); int (*recv_timeout)(int sock, void *buf, size_t len, uint32_t timeout); int (*recv)(int sock, void *buf, size_t len); int (*sendto)(int sock, char *ip, char *port, const void *buf, size_t len); int (*recvfrom)(int sock, void *buf, size_t len); int (*recvfrom_timeout)(int sock, void *buf, size_t len, uint32_t timeout); int (*close)(int sock); } sal_module_t;使用时不要求全部实现只需实现与连接模式相关的核心接口即可。以 ESP8266 WiFi 模组为例其实例在 devices/esp8266/esp8266.c 中定义sal_module_t sal_module_esp8266 { .init esp8266_init, .connect esp8266_connect, .send esp8266_send, .recv_timeout esp8266_recv_timeout, .recv esp8266_recv, .sendto esp8266_sendto, .recvfrom esp8266_recvfrom, .recvfrom_timeout esp8266_recvfrom_timeout, .close esp8266_close, .parse_domain esp8266_parse_domain, };这里接口对应的esp8266_xxx函数需要开发者根据硬件上实际使用的通信模组进行适配。该结构填充完成后需要在使用 MQTT 之前调用初始化接口注册串口和网络 API 函数esp8266_sal_init(hal_uart_port_t uart_port);从源码实现看devices/esp8266/esp8266.cesp8266_sal_init内部依次完成了三件事通过tos_at_init初始化 AT 代理并注册 AT 事件解析通过tos_sal_module_register将sal_module_esp8266注册为 sal 模块再通过tos_sal_module_init完成模块初始化。也就是说设备驱动的注册与网络抽象层的打通都由该初始化函数一次性完成。仓库 devices 目录下还提供了其他通信模组的适配实现如 NB-IoT 模组bc35_28_95devices/bc35_28_95、4G 模组ec600sdevices/ec20_200_600、air724devices/air724、l610devices/l610、ml302devices/ml302等其初始化函数同样以xxx_sal_init(HAL_UART_PORT_x)的形式调用开发者可参照实现。3.3 生成 MQTT 配置头文件从云端设置章节可以知道MQTT 客户端所需要的核心信息只有六项Product IDDevice NameDevice PasswordClient idmqtt usernamemqtt password仓库在 tools/mqtt_config_gen.py 提供了配置生成脚本。运行脚本后依次输入 product id、device name、password、订阅 topic默认control与发布 topic默认event脚本会自动完成三件事拼接出client_idproduct_id dev_name生成带过期时间戳的username形如client_id;21010406;12365;4294967295其中4294967295即 2^32-1 的过期时间使用设备的密钥对 username 做 HMAC-SHA1 签名生成带算法标识的password形如sign;hmacsha1。最终脚本会在当前目录输出mqtt_config.h包含完整的宏定义头文件与mqtt_connect_demo.c包含可直接粘贴的对接代码片段。开发者也可以在终端节点开发过程中自行修改 MQTT 配置参数配置宏示例如下#define IOTHUB_MQTT_IP 111.230.189.156 #define IOTHUB_MQTT_PORT 1883 #define IOTHUB_MQTT_CLIENT_ID KHHIXM0JJ5dev001 #define IOTHUB_MQTT_USERNAME KHHIXM0JJ5dev001;12010126;9K3WO;1647628324 #define IOTHUB_MQTT_PASSWD 53696f22a061ed2524b1de185815ad2fcae7739afd3f395cb6131521da7f0bb7;hmacsha256 #define IOTHUB_MQTT_PUB_TOPIC KHHIXM0JJ5/dev001/data #define IOTHUB_MQTT_SUB_TOPIC KHHIXM0JJ5/dev001/control如上所示需要根据腾讯云设备信息自行修改Product ID、Device Name和Password以及MQTT_USR_NAME、MQTT_PASSWORD、MQTT_SUBSCRIBE_TOPIC、MQTT_PUBLISH_TOPIC。订阅/发布 Topic 如果采用默认的 control 和 data 即可也可以自行设置。开发者可将这些宏放置到自己的工程目录下任意位置并在工程中添加头文件引用。仓库中 board/BearPi_STM32L431RC/TOS-CONFIG/mqtt_config.h 是一个完整的 MQTT 组件配置示例其中还包含MQTT_KEEP_ALIVE_INTERVAL保活间隔单位秒、MQTT_THREAD_STACK_SIZEMQTT 线程栈大小、MQTT_THREAD_PRIO线程优先级、MQTT_NETWORK_TYPE_NO_TLS关闭 TLS 使用明文连接等运行参数。3.4 调用 TobudOS 提供的接口完成对接以下是与腾讯云对接并收发信息的完整例程对应文档示例可直接作为任务入口代码/* Tencent IoThub Device Info */ #define IOTHUB_MQTT_IP 111.230.189.156 #define IOTHUB_MQTT_PORT 1883 #define IOTHUB_MQTT_CLIENT_ID KHHIXM0JJ5dev001 #define IOTHUB_MQTT_USERNAME KHHIXM0JJ5dev001;12010126;9K3WO;1647628324 #define IOTHUB_MQTT_PASSWD 53696f22a061ed2524b1de185815ad2fcae7739afd3f395cb6131521da7f0bb7;hmacsha256 #define IOTHUB_MQTT_PUB_TOPIC KHHIXM0JJ5/dev001/data #define IOTHUB_MQTT_SUB_TOPIC KHHIXM0JJ5/dev001/control static void tos_topic_handler(void* client, message_data_t* msg) { (void) client; MQTT_LOG_I(-----------------------------------------------------------------------------------); MQTT_LOG_I(%s:%d %s()...\ntopic: %s, qos: %d. \nmessage:\n\t%s\n, __FILE__, __LINE__, __FUNCTION__, msg-topic_name, msg-message-qos, (char*)msg-message-payload); MQTT_LOG_I(-----------------------------------------------------------------------------------\n); } void mqttclient_task(void) { int error; char buf[100] { 0 }; mqtt_client_t *client NULL; mqtt_message_t msg; memset(msg, 0, sizeof(msg)); #ifdef USE_ESP8266 esp8266_sal_init(HAL_UART_PORT_0); esp8266_join_ap(Mculover666, mculover666); #endif #ifdef USE_NB_BC35 int bc35_28_95_sal_init(hal_uart_port_t uart_port); bc35_28_95_sal_init(HAL_UART_PORT_0); #endif #ifdef USE_EC600S ec600s_sal_init(HAL_UART_PORT_0); #endif mqtt_log_init(); client mqtt_lease(); mqtt_set_port(client, IOTHUB_MQTT_PORT); mqtt_set_host(client, IOTHUB_MQTT_IP); mqtt_set_client_id(client, IOTHUB_MQTT_CLIENT_ID); mqtt_set_user_name(client, IOTHUB_MQTT_USERNAME); mqtt_set_password(client, IOTHUB_MQTT_PASSWD); mqtt_set_clean_session(client, 1); error mqtt_connect(client); MQTT_LOG_D(mqtt connect error is %#x, error); mqtt_subscribe(client, IOTHUB_MQTT_SUB_TOPIC, QOS0, tos_topic_handler); MQTT_LOG_D(mqtt subscribe error is %#x, error); memset(msg, 0, sizeof(msg)); for (;;) { sprintf(buf, welcome to mqttclient, this is a publish test, a rand number: %d ..., random_number()); msg.qos QOS0; msg.payload (void *) buf; error mqtt_publish(client, IOTHUB_MQTT_PUB_TOPIC, msg); tos_task_delay(4000); } } void application_entry(void *arg) { mqttclient_task(); while (1) { printf(This is a mqtt demo!\r\n); tos_task_delay(1000); } }代码中使用的 mqttclient 核心 API 都声明在 components/connectivity/mqttclient/mqttclient/mqttclient.h 中其主要调用流程为mqtt_lease()租用一个 mqtt_client_t 客户端实例mqtt_set_port / mqtt_set_host / mqtt_set_client_id / mqtt_set_user_name / mqtt_set_password / mqtt_set_clean_session分别设置连接端口、服务器地址、Client ID、用户名、密码与是否清理会话示例中clean_session 1mqtt_connect(client)发起 TCP 连接并完成 MQTT 握手CONNECT/CONNACKmqtt_subscribe(client, topic, qos, handler)订阅主题并注册消息回调tos_topic_handler收到消息时回调中通过message_data_t拿到topic_name、qos与payloadmqtt_publish(client, topic, msg)以指定 QoS 向主题发布消息示例中周期性发布并tos_task_delay(4000)间隔 4 秒。关于 QoSmqtt_qos_t枚举定义了QOS0 0、QOS1 1、QOS2 2、SUBFAIL 0x80示例使用 QOS0即最多一次的交付语义适合对时延敏感、可容忍偶发丢失的上报场景。仓库中还提供了另一份可直接编译运行的参考实现 examples/mqttclient_iothub/mqttclient_iothub.c其通过域名iotcloud-mqtt.gz.tencentdevices.com连接展示了 TCP/IP 协议栈初始化TCPIP_Init后的同款对接流程。四、源码纵深mqttclient 组件的实现细节4.1 组件目录与分层结构mqttclient 组件位于 components/connectivity/mqttclient其内部按功能分层组织mqttclient客户端核心实现包括mqttclient.c、mqttclient.h、默认配置mqtt_defconfig.hmqttMQTT 协议报文编解码基于 MQTTPacketnetwork网络抽象将 socket 操作与具体传输AT 模组或 lwIP解耦platformOS 平台适配层线程、互斥锁、定时器、内存等使组件可跨 RTOS 移植common通用工具链表、随机数、错误码、日志等。4.2 默认配置项与运行参数mqtt_defconfig.h 定义了组件的默认运行参数均可通过mqtt_config.h覆盖宏默认值含义MQTT_TOPIC_LEN_MAX64Topic 名称最大长度字节决定message_data_t.topic_name缓冲大小MQTT_ACK_HANDLER_NUM_MAX64最大 ACK 处理器数量MQTT_DEFAULT_BUF_SIZE1024默认收发缓冲区大小MQTT_DEFAULT_CMD_TIMEOUT4000命令默认超时msMQTT_KEEP_ALIVE_INTERVAL100保活间隔秒板级配置中常调小为 50MQTT_VERSION4MQTT 协议版本4 即 MQTT 3.1.1MQTT_RECONNECT_DEFAULT_DURATION1000断线重连间隔msMQTT_THREAD_STACK_SIZE4096MQTT 内部线程栈大小MQTT_THREAD_PRIO5MQTT 内部线程优先级MQTT_NETWORK_TYPE_NO_TLS—定义后使用明文 TCP1883不定义则启用 TLS8883从 mqttclient.c 的实现可以看到客户端内部维护了读缓冲、写缓冲、ACK 处理器链表与消息处理器链表mqtt_connect成功后组件会启动独立的保活线程依据MQTT_KEEP_ALIVE_INTERVAL定期发送 PINGREQ并在收到下行消息时按 Topic 匹配调用注册的回调函数mqtt_read_packet负责按 MQTT 报文格式解析剩余长度并分派到各处理器。若定义了MQTT_NETWORK_TYPE_NO_TLS网络层将直接走明文 socket若未定义则通过组件内集成的 mbedTLS位于 components/security/mbedtls建立 TLS 加密通道此时端口应使用 8883 并配置 CA 证书参考 examples/mqttclient/mqttclient.c 中mqtt_set_ca的用法。4.3 与 IoT Explorer 对接的扩展示例仓库中的 board/TencentOS_Tiny_EVB_MX_Plus/KEIL/mqttclient_iot_explorer/demo/mqttclient_iot_explorer.c 展示了同一套 mqttclient API 对接腾讯云物联网开发平台IoT Explorer的写法其关键差异在于通过tos_sal_module_parse_domain(productID.iotcloud.tencentdevices.com, host_ip, sizeof(host_ip))将产品域名解析为 IP 后再mqtt_set_host订阅/发布使用$thing/down/property/productID/devName与$thing/up/property/productID/devName物模型主题回调中使用 cJSON 解析平台返回的status字段并通过tos_event_post事件机制将上报结果反馈给业务任务report_success/report_fail随后tos_event_pend等待结果后延时 5 秒再上报。该示例也由 tools/mqtt_config_gen.py 生成的MQTT_SERVER_DOMAIN、MQTT_SUBSCRIBE_TOPIC_DOWN、MQTT_PUBLISH_TOPIC_UP等宏支撑可作为后续开发的重要参考。五、联调与问题排查完成云端与设备端设置后建议按照以下顺序验证链路确认平台侧收到消息在产品列表的云日志中搜索查看设备是否产生了连接、发布、订阅等行为日志若规则引擎生效日志中还会出现对应的转发操作记录。确认消息内容正确云日志中看不到 payload 内容需在消息队列中配置 CMQ 接收消息类型然后在 CMQ 队列中点击开始接收消息查看带PayloadLen与Playload字段的消息。密钥认证下 payload 经过 base64 编码可在 Linux 下执行echo payload | base64 --decode解码查看原文。检查 Topic 与权限确认设备订阅的 Topic 具有订阅权限、发布的 Topic 具有发布权限且 Topic 中的 productID 与设备名与云端一致跨设备收发时必须依赖规则引擎直接订阅其他设备的 Topic 会被平台拒绝。检查规则引擎状态规则创建后必须点击启用按钮否则转发不会生效自定义数据格式下筛选数据字段应设为*并留空条件全部匹配。检查设备端连接参数核对IOTHUB_MQTT_CLIENT_ID、IOTHUB_MQTT_USERNAME、IOTHUB_MQTT_PASSWD三项——Client ID 通常为productID deviceName拼接username 为Client ID 签名参数 过期时间戳的分号拼接串password 为签名值 算法名如;hmacsha256或;hmacsha1。任一项与平台分配不一致都会导致 CONNACK 失败。检查网络可达性确认模组已通过esp8266_join_ap等接口接入网络、串口波特率与 AT 事件解析正常且服务器 IP/端口默认 1883TLS 为 8883可访问。六、总结本文以腾讯云物联网通信IoT Hub为云端目标完整走通了云端产品/设备/Topic/规则引擎配置 → 设备端 mqttclient 组件引入 → sal_module_wrapper 网络适配 → 配置生成 → 收发消息编码的端云对接全流程。核心要点可以概括为设备端只需实现标准 MQTT Client 即可与腾讯云通信TobudOS 通过 mqttclient 组件与 sal_module_wrapper 抽象层屏蔽了底层模组差异开发者仅需适配sal_module_t中少量核心接口、填写六项设备参数并调用mqtt_connect/subscribe/publish三个核心 API。跨设备通信必须借助云端规则引擎的 republish 转发排查问题时可借助云日志与 CMQ 消息队列定位平台侧行为。基于同样的组件也可以平滑迁移到腾讯云物联网开发平台IoT Explorer的物模型通信进一步构建数据上报、属性下发等更完整的业务闭环。赞分享【免费下载链接】TobudOSTobudOS 是面向物联网领域开发的实时操作系统早期版本基于腾讯自研的物联网操作系统TencentOS Tiny2020年由腾讯捐赠到开放原子开源基金会进行孵化2023年正式更名为TobudOSTobudOS具有低功耗低资源占用模块化安全可靠等特点可有效提升物联网终端产品开发效率提供精简的 RTOS 内核内核组件可裁剪可配置可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且基于 RTOS 内核提供了丰富的物联网组件内部集成主流物联网协议栈如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等可助力物联网终端设备及业务快速接入物联网云平台。项目地址https://gitcode.com/openatomfoundation/TobudOS点击查看免费下载相关推荐TobudOS 物联网接入实战腾讯云 IoT Hub 设备端 C-SDK 的目录解析、编译运行与单元测试指南TobudOS 物联网接入实战腾讯云 IoT Hub 设备端 C SDK 的目录解析、编译运行与单元测试指南 腾讯云物联网设备端 C SDK 依托安全且性能强TobudOSTencentOS TinyCH32V307 RISC-V 开发板入门与腾讯云 IoT Explorer 对接实战指南TobudOSTencentOS TinyCH32V307 RISC V 开发板入门与腾讯云 IoT Explorer 对接实战指南 本文是 CH32V_E基于 STM32G0 与 TencentOS Tiny 的物联网智能灯实战腾讯云 IoT Explorer 全流程接入指南基于 STM32G0 与 TencentOS Tiny 的物联网智能灯实战腾讯云 IoT Explorer 全流程接入指南 本篇技术指南围绕 TobudOS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考