小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub

1. 参考文档

  • TencentOS-tiny 正式开源,全网首发评测,带你极速上手体验!
  • TencentOS tiny端云对接开发指南(IoTHub)

2. 云端配置

登录腾讯云, 搜索"云产品"下的"物联网通信"产品, 或直接访问:

https://console.cloud.tencent.com/iotcloud

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第1张图片

2.1. 创建新产品

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第2张图片

对于认证方式, 指定了设备通过何种方式和云端进行双向认证. 默认的证书方式相对于密钥认证安全性高一点, 但是问题在于证书方式需要在嵌入式设备端存储证书同时实现证书的相关处理, 对设备的RAM和ROM要求较高, 相对而言, 密钥认证的方式资源占用量就小点, 由于我们主要支持的设备都是小型嵌入式设备, 因此选用密钥认证。

数据格式指的是设备和云端进行数据交互时候使用的格式, json格式为文本字符串, 可读性高, 并且便于解析, 对于功能复杂的设备交互而已比较理想, 但是对于小型设备或是定制设备, 数据单一, 或是有自定义的格式(二进制或是文本), 这种时候, 用自定义的数据格式, 一方面节约流量, 另一方面比较灵活.。

创建成功后,获取到产品ID:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第3张图片

2.2. 创建新设备

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第4张图片
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第5张图片
添加完设备后, 会告知设备对应的密钥. 该密钥将会用于之后设备与平台通信时的认证:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第6张图片
为了实现设备间的通信, 我们还需要创建第二个设备, 操作同上, 将其命名为"dev2":
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第7张图片

2.3. 设置Topic

可以在"权限列表"中看到Topic对应的操作权限:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第8张图片

平台默认配置了三类的Topic, 用于执行发布和订阅.,这里之所以是三类而不是三个, 是因为Topic里使用了变量.。

  • WDRRDCF1TE实际上是productID;
  • ${deviceName}为平台设置的变量, 即设备名;
  • controldata以及event为Topic名字.;

所以, 在我们创建了2个设备dev1和dev2的情况下, 在 BearPiTest 产品下, 即存在6个Topic, 分别为:

  • WDRRDCF1T/dev1/control 订阅权限
  • WDRRDCF1T/dev1/data 发布和订阅权限
  • WDRRDCF1T/dev1/event 发布权限
  • WDRRDCF1T/dev2/control 订阅权限
  • WDRRDCF1T/dev2/data 发布和订阅权限
  • WDRRDCF1T/dev2/event 发布权限

这里默认的Topic已经足够我们使用, 不需要额外添加Topic和权限了。

2.4. 设置规则引擎

规则引擎本身不属于MQTT协议的范畴, 但是平台侧出于安全角度考虑添加了规则引擎, 实现了Topic之间的转发操作, 我们需要合理的设置规则引擎才能实现多个设备之间的数据收发, 由于理解起来比较复杂, 我们这里简要讲解下为什么需要规则引擎, 规则引擎的作用, 如何设置规则引擎.

  1. 为什么需要规则引擎

    在上节的Topic中, 我们知道, 在平台侧, 对于不同的Topic, 规定了不同的权限, 例如, 对于25KCIUIR1G/dev1/event这个Topic, 只具有发布权限, 而对于25KCIUIR1G/dev1/control这个Topic, 只具有订阅权限. 对于设备dev1, 很自然的, 会朝25KCIUIR1G/dev1/event这个Topic发送数据, 并且订阅25KCIUIR1G/dev1/control这个Topic的消息. 但是这里就会涉及到, event的数据最后到哪去, control的数据从哪里来的问题.

    在本文的例子中, 我们希望dev1和dev2发生交互, 即相互收发消息. 由于MQTT是基于Topic的发布订阅机制, 因此, dev1想要获得dev2的数据, 直觉上, 需要订阅dev2发布消息的那个Topic. 假定dev2朝25KCIUIR1G/dev2/eventTopic上发送数据, 那么dev1想要获得dev2发布的消息, 最直接的办法是订阅同样的Topic, 即25KCIUIR1G/dev2/event, 但是这里存在几个问题, 首先, event Topic只具有发布权限, 没有订阅权限, 其次, 在平台侧, 规定了, 不允许跨设备发布或是订阅Topic, 也就是说, 对于dev1, 只能看到或只允许访问25KCIUIR1G/dev1这个Topic以及其下属的Topic, 不能访问25KCIUIR1G/dev2及其下属Topic.

    平台侧添加不允许跨设备访问Topic的规则虽然不直观, 但却是合理的. 如果不添加这条限制, 那么一个设备可以不加限制的订阅同一个产品下所有其他设备的Topic, 获取其上报的消息, 这存在潜在的安全漏洞.

  2. 规则引擎的作用

    因为不允许直接跨设备访问Topic, 所以需要依靠"规则引擎"来手动添加规则, 将指定的Topic消息转发到另一个Topic上, 实现不同设备之间的通信.

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第9张图片

上图介绍了规则引擎的主要作用"republish", 即将一个Topic下的消息republish到另一个Topic下. 从图中我们可以看到, 规则引擎将WDRRDCF1TE/dev2/event的消息republish到了WDRRDCF1TE/dev1/control下. 将WDRRDCF1TE/dev1/event的消息republish到了WDRRDCF1TE/dev2/control下。

这样, 对于dev1而言, 只需要订阅WDRRDCF1TE/dev1/control就可以接收来自25KCIUIR1G/dev2/event的消息了,dev2同理。

  1. 设置规则引擎

在物联网通信界面选择"规则引擎"–“新建规则”, 随意指定一个规则名称, 我们这里不妨设置为"1to2":
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第10张图片
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第11张图片

这里, 我们看到规则的详细设置信息, 主要包括"筛选数据"和"行为操作"。

“筛选数据"针对指定Topic接收到的消息内容进行进一步的筛选, 比如匹配消息中的字段来决定是否执行之后的设置的"行为操作”.,而"行为操作"则是指定对通过匹配的消息进行何种操作, 主要的操作有"数据转发到另一个Topic(Republish)", "转发到第三方服务(Forward)"以及转发到腾讯云各个对应组件中。

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第12张图片

上图是设置好的规则, 这里, 我们将"筛选数据"部分的筛选字段设置为*, 筛选的Topic为WDRRDCF1T/dev1/event, 条件设置为空, 即不筛选数据, 全部匹配,然后, 执行的操作是将数据转发到WDRRDCF1T/dev2/control, 设置完这条规则, 就实现了dev2通过订阅control就能收到dev1发送到event的数据。

关于"筛选数据"的设定:

由于我们在新建产品, 设置数据格式的时候选择了自定义数据格式, 在自定义数据格式的情况下, 当前平台将其当做二进制流来处理, 也就无法通过匹配字段进行数据筛选.

如果在进行产品的时候, 使用数据格式是json, 那么此处就可以根据json中的字段进行SQL的匹配和筛选.

同理, 我们再设置新的一个规则"2to1", 实现WDRRDCF1T/dev2/eventWDRRDCF1T/dev1/control的转发:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第13张图片

规则引擎都设置好后,记得点启用按钮,这样, 在平台侧dev1到dev2的双向数据通路就打通了:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第14张图片

2.5. 云日志

在平台侧都设置好后, 我们在之后的测试过程或是通信过程中, 往往还需要查看平台是否收到了设备发送上来的消息, 对消息执行了哪些操作, 消息的具体内容(payload)是什么. 腾讯云提供了物联网通信产品的"云日志"功能和腾讯云组件"消息队列CMQ"。

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第15张图片

日志中可以看到日志记录了设备的连接, 连接断开, 发布, 订阅等行为, 也记录了规则引擎的操作, 还有CMQ队列的一些行为日志.。

2.6. 消息队列CMQ

可以在产品列表中找到"消息队列"选项, 设置队列所想要接收的消息类型后保存配置, 即可将平台侧收到的设备消息额外发送到腾讯云消息队列CMQ组件中:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第16张图片

在密钥认证下, 消息的内容(payload)是经过base64编码的, 所以在平台侧看到的数据类似乱码实际上是经过编码后的结果, 想要查看具体的内容, 可以在linux下, echo | base64 --decode.

3. 设备终端配置

腾讯 TencentOS tiny 集成了对MQTT和腾讯云的支持, 开发者只需要通过简单的设置即可实现与腾讯云的通信, 整体步骤主要包含:

  • 项目工程中添加MQTT组件相关文件
  • 适配AT HAL层串口及网络接口函数
  • 执行脚本生成MQTT配置头文件
  • 调用OS提供的接口完成和腾讯云的对接

3.1. 在项目工程中添加MQTT组件相关文件

可以参考TencentOS_tiny\board\TencentOS_tiny_EVB_MX\KEIL\tencent_os_mqtt工程。

先准备一份移植好TencentOS tiny的helloworld工程,复制出来一份开始添加。

在工程中新建deviceshalatmqtt组, 并添加下列源文件:

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第17张图片
还要添加mqtt_example.c文件:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第18张图片
上述文件分别位于TencentOS-tiny\devices\esp8266TencentOS_tiny\net\at, TencentOS_tiny\components\connectivity\Eclipse-Paho-MQTTTencentOS_tiny\platform\hal\st\stm32l4xx\srcTencentOS-tiny\examples\tencent_os_mqtt目录下。

再将这些文件包含的头文件路径也添加:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第19张图片

3.2. 适配AT HAL层串口及网络接口函数

上层MQTT的操作最终都会转为为对底层通信设备的socket操作, OS集成了sal_module_wrapper层, 但是由于各个开发板硬件不同, 因此需要对sal_module_wrapper进行适配. 适配过程的核心数据结构为sal_module_t, 在TencentOS_tiny\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 (*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, char *ip, char *port, void *buf, size_t len);
    int (*recvfrom_timeout)(int sock, char *ip, char *port, void *buf, size_t len, uint32_t timeout);
    int (*close)(int sock);
}sal_module_t;

在使用的时候, 并不需要全部实现, 只需实现下列几个核心的接口即可:

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.c中都已经实现。

该结构填充完后, 需要在使用MQTT之前, 调用一下初始化接口注册串口和网络API函数:

esp8266_sal_init(hal_uart_port_t uart_port);

在mqtt_example.c中,已经指定了esp8266_sal的串口为lpuart1:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第20张图片

并且调用了初始化函数:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第21张图片
修改ESP8266连接的AP信息:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第22张图片

3.3. 修改MQTT配置

从之前介绍腾讯云端配置的章节中可以知道, 在MQTT客户端, 所需要的核心信息只包含:

  • Product ID
  • Device Name
  • Device Password
  • Client id
  • mqtt username
  • mqtt password

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第23张图片

修改MQTT配置文件mqtt_config.h
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第24张图片

3.4. 一些额外的修改

之前移植的Helloworld工程中,没有做lpuart1的接收中断处理,所以进行如下操作。

修改usart.c,添加开启接收中断配置:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第25张图片

至此,移植OK,编译下载即可。

4. 实验现象

在云端查看:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第26张图片
下发一条命令测试:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第27张图片

小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第28张图片
查看上报的云日志:
小熊派移植TencentOS-tiny+ESP8266+MQTT对接腾讯云平台IoThub_第29张图片

后续篇:

  • 小熊派移植 TencentOS-tiny+M26/EC20+MQTT 对接腾讯云平台IoThub

接收更多精彩文章及资源推送,欢迎订阅我的微信公众号:『mculover666』。

你可能感兴趣的:(TencentOS-tiny)