云连接(二)云平台之间的移植
STM32生态系统第七期——云连接(二)
云平台之间的移植
STM32生态系统第四期:云连接(一)基于STM32云连接应用的概览
在之前第四期“基于STM32云连接应用的概览”中,我们从支持的云平台,连接方式,以及应用的角度,介绍了ST的云连接资源。虽然ST已经提供了不少的应用实例,但不同客户的具体实现千差万别,总是会遇到不能直接满足客户需求的情况。比如需要在另一个云平台上实现某个例程的功能,或者换到另一个无线模块等等。在线下的培训和研讨会中,我们也多次讨论这个问题。
那么,在今天这一期的内容中,我们将一起来看看云平台移植的问题,它其实也不那么难。
云平台之间的移植
对于开发者来说,需要关注的不同的云平台之间的区别主要有:支持的协议,设备认证的方式,和支持的功能。
当前大多数云平台都支持MQTT, HTTP协议,部分平台还支持CoAP等协议,或者有些平台使用的是自定义的协议。所以首先需要确认:换云平台时是否需要换接入协议。
即使是同样的协议,例如都是MQTT协议,不同的平台实现设备认证的方式也不一样,有的就是通过MQTT协议的用户名/密码进行认证,而有的需要通过X.509设备证书,这就涉及到是否要实现TLS协议。就算都是通过MQTT协议的用户名/密码进行认证,用户名和密码的产生规则每个云平台也不一样。这些内容都可以在对应云平台的文档中找到说明。
关于云平台支持的功能,各平台都大同小异,在移植时需要注意的是:是否用到了平台SDK 提供的API的这部分代码,如果是的话这部分代码也要做相应的移植。
接下来,我们以“STM32-阿里云物联网应用开发联合课件”中的Paho例程为例,介绍如何移植到百度云物联网平台。
STM32-阿里云物联网应用开发联合课件
首先我们先来了解一下“STM32-阿里云物联网应用开发联合课件”,以及其中Paho例程的系统架构和功能。
该课程以基于STM32的温湿度控制器作为节点端,通过阿里云IoT平台转发数据到用户自己的服务器,并开发了网页端的用户操作界面来监测和控制节点端。
课程涵盖三部分的内容:
• STM32节点端开发:针对资源受限设备和资源丰富的设备提出了两种实现方式:前者使用开源的Paho MQTT开源实现,后者使用阿里云物联网平台的Linkkit SDK
• 阿里云IoT平台使用和设置
• 用户服务器的搭建
课程所涉及到的代码都是开源的,可以登录图中的链接获取更多的详情。
Paho例程的软件架构
课程中的Paho例程的软件架构可以分为三层:
- 底层驱动,这一层包括STM32L4Cube HAL硬件抽象层,传感器驱动以及WIFI模块驱动。HAL硬件抽象层向上层软件提供了使用各个外设的接口函数。上层的中间件,应用程序等可以通过调用这些API函数来操作外设, 这样便不会使得上层的软件依赖于某个特定的MCU。使得程序更具有复用性,并且容易移植到其他的MCU系列上去。
- 中间件:这一层包括Paho MQTT 协议栈,mbedTLS(用到HMAC-SHA1模块),以及ST的网络接口抽象层。网络接口抽象层,对底层的网络驱动函数进行封装,向上提供统一的网络接口函数,从而将应用层的代码与底层实际网络接口分开。改变以太网,wifi, 2G/3G等不同的连接方式时,不会影响应用层的代码。Paho MQTT通过网络接口抽象层向下调用对应的wifi驱动完成网络数据的发送和接收。
- 应用层:包括阿里云MQTT连接适配层和节点端业务程序。阿里MQTT连接适配层根据阿里云IoT平台的要求,依据用户提供的三元组信息构建相应的MQTT连接参数和主题,再调用PahoMQTT提供的API进行MQTT连接和通信。
连接其他平台
课件中Paho例程连接的是阿里云物联网平台,如果要将其移植到其他的平台可以有两种实现方法:
• 还是基于Paho开源实现,根据对应平台的连接要求来实现连接。
• 如果该IoT平台提供的有SDK,可以使用对应的SDK来替代Paho中间件,再基于这个SDK来做应用层的开发。一般云平台的SDK会有和它所支持的功能相关的更丰富的API可使用,并且有一些保证连接可靠性的处理。
- 第一种方法,主要影响应用层中的“阿里云MQTT连接适配层”这一部分代码,主要涉及:Ali_Iotclient.c,Ali_iot_network_wrapper.c和mqtt_msg_handler.c这三个文件。
- 第二种方法,除了“阿里云MQTT连接适配层”这一部分代码以外,还需要替换Paho中间件。
从更加通用的角度考虑,下面我们介绍第一种方法。
在接下来的介绍中,首先我们先演示如何连接到阿里云物联网平台,然后再说明如何修改代码,将开发板连接到百度云物联网平台。
例程需要的硬件
我们先来了解一下例程需要的硬件以及软件环境。
我们需要一块NUCLEO-L4R5ZI开发板,一块X-NUCLEO-IKS01A2 Sensor扩展板以及一块EXT-AT3080 Wifi扩展板。将这三块板子如下图,通过Arduino接口叠加在一起。
此外,还需要一个可以上网的wifi热点,开发板通过该热点可以连接到互联网。一台可以上网的电脑,用来编译和烧录程序,为开发板配置WIFI密码,以及通过浏览器查看云端的数据。一根micro接口的USB线,可以将开发板连接到电脑,给板子供电,进行程序调试等。
硬件环境搭建
例程需要的软件
例程的整个工程代码可以到 www.stmcu.com.cn 网站进行下载。
开发环境使用IARv8.3及以上版本。
最后需要下载串口调试工具Tera term,我们需要通过虚拟串口输入WIFI热点的密码以及三元组信息。
Tera term的配置
为了正常显示和输入串口的数据,Tera term需要按照下面进行配置。
进入阿里云物联网平台
将下载的工程烧录到开发板后,就可以连接阿里云物联网平台了。不过在连接之前,还需要先登录阿里云物联网平台,进入控制台。根据平台的操作说明,或者参考课件第三章第二节的视频(可扫描图中的二维码观看),创建自己的产品和设备。
查看三元组信息
设备创建成功后,我们就会得到由ProductKey, DeviceName和DeviceSecret组成的三元组信息。查看方法见下图。
MQTT主题与消息负载格式
在创建产品时,根据例程需要实现的功能还需要自定义下表中的四个主题:
• ${productKey}/${deviceName}/user/tempThresholdSet, 云端服务器向该主题发布消息,可以修改报警的温度阈值。设备端(STM32)只能订阅该主题。
• ${productKey}/${deviceName}/user/clearAlarm,云端服务器向该主题发布消息,可以清除报警状态。设备端只能订阅该主题,收到该主题的消息后,不再向云端发布报警信息
• ${productKey}/${deviceName}/user/tempAlarm,设备端检测到温度超过阈值后,向该主题发布高温报警信息
• ${productKey}/${deviceName}/user/tempHumUpload,设备端定期向该主题发布检测到的温湿度信息
节点端运行
接下来将已经烧录好Paho例程的NUCLEO-L4R5ZI开发板通过板载的ST-LINK连接到电脑,在电脑上打开Tera term。按下板上的黑色复位键后,在Tera term的窗口中就可以看到启动信息了。
第一次连接WIFI热点时,需要在程序启动后,马上按下蓝色USER按键,然后根据提示输入wifi热点名称和密码。然后开发板会自动连接到热点。在Tera term窗口中看到IP地址,说明WIFI热点已经连接成功。之后需要再次按下蓝色USER按键,然后按提示输入Region ID和设备的三元组信息。输入的信息会有回显,所以我们可以在窗口确认输入的内容是否正确。
所有的信息输入完成后,程序就会自动连接阿里云物联网平台。
运行效果
在接下来的串口信息中,我们可以看到:阿里云IoT平台连接成功后,节点端向云端订阅了“tempThresholdSet”和“clearAlarm”这两个主题,并开始每5秒上报节点的当前温湿度值。这时我们回到云平台的控制台,也可以看到设备上报的信息了。
百度云设备 VS 阿里云设备
我们现在已经成功连接到了阿里云物联网平台,那接下来我们看看如何修改代码来连接到百度云物联网平台。
首先我们来对比一下这两个平台的接入过程的区别。阿里云物联网平台和百度云物联网平台都支持MQTT,所以不存在切换接入协议的情况。而且这两个平台都支持通过MQTT的用户名和密码来进行设备身份认证,所以这样我们需要改动的地方就不多了,需要关心的主要是MQTT连接参数构成的不同,如下表所列出内容。
MQTT是基于TCP之上的协议,它的连接分为两个过程:
先和服务器建立TCP连接,再在TCP连接的基础之上建立MQTT连接。
- 在第一个连接过程中,需要知道服务器的域名,以及端口号。连接阿里云物联网平台时,服务器的域名是根据一定规则由三元组进行构建的,在程序中由get_mqtt_server_addr函数完成,而连接百度云物联网平台时,在注册产品设备后,服务器的域名由平台直接给出。这两个平台在不加密传输时,端口号都是用的1883。
- 第二个连接过程,也就是MQTT连接,需要用到ClientID, UserName和Password等参数。这三个参数对于阿里云物联网平台来说,也是根据一定规则由三元组进行构建的,而百度云物联网平台都是直接给出。相关函数见下表。
连接建立好后,设备端程序运行时会用到四个主题,所以在百度云物联网平台上需要创建对应的主题,并保证和代码中一致。
进入百度云物接入管理平台
分析完,两个平台连接参数的区别。接下来我们就动手开始移植的工作。
首先,我们到百度云物联网平台,先创建项目和用户。这里的项目和用户,我们可以理解成产品系列和具体设备。具体创建步骤这里就不说了,大家可以按照平台的说明进行。
创建用户获得的MQTT连接参数
创建成功后,我们就会得到以下信息:MQTT服务器域名,MQTT连接用户名和MQTT连接密码。 MQTT连接的clientID平台没有给出,我们可以自行指定一个唯一的字符串作为ClientID号。
获得服务器域名函数修改
拿到这些信息后,接下来我们就开始修改代码。前面我们说过,基于Paho例程的移植,主要影响“阿里云MQTT连接适配层”这部分代码,对于我们这次的移植,主要影响的是Ali_Iotclient.c,Ali_iot_network_wrapper.c这两个文件里的函数,函数名已经在前面MQTT连接参数比较的表格中列出。
下面,我们就一个一个进行修改。
获得服务器域名函数修改
获得MQTT用户名函数修改
获得MQTT密码函数修改
构建主题
建立TCP连接函数修改
除此以外,因为连接百度云物联网平台的MQTT参数不需要代码进行构建,直接用从平台获取的字符串就可以。所以在调用相关函数的时候,有些输入参数不再需要,比如RegionID,ProductKey,DeviceName等,所以在下面连接TCP服务器以及MQTT服务器的代码中,去掉这些部分代码,而为了简单起见,直接将函数调用时的这部分输入参数设为NULL。
建立MQTT连接函数修改
其他修改
最后因为不需要输入三元组了,为简单起见,可直接注释掉initPlatform函数中,通过串口输入三元组的函数updateDeviceConfig。
到这里,所有需要修改的地方都已经完成,重新编译代码就可以连接到百度云物联网平台了。
在这一讲中,我们拿阿里云物联网平台和百度物联网平台之间的移植做了一个举例说明。因为程序中MQTT协议用的是通用Paho实现,所以还未涉及到云平台专有SDK API的移植,但基本的思路在本文的开头已经做了说明,可供参考。