
工程师笔记 | ES32快速连接阿里云
物联网平台提供了安全可靠的设备连接通信能力。设备可以与云端交互数据。此外,物联网平台也提供方便快捷的设备管理能力:支持物模型定义、数据结构化存储和远程控制。
阿里云为国内常见的物联网平台之一。RT-Thread基于阿里提供的 iotkit-embedded C-SDK,制作了连接阿里云 IoT 平台的软件包。所以只需要补充网络的连接部分,就能连接阿里云了。
本文将将要介绍在 ES32 平台上,基于 RT-Thread bsp 连接阿里云的方法。
☞ 开启本实验前,读者需要首先了解基础的软硬件环境配置和ES-CodeMaker使用方法。详细请查看(点击直接打开):工程师笔记 | ES-CodeMaker for RT-Thread (一)快速上手
☞ ES-CodeMaker for RT-Thread软件的获取方法,在文本的最后给出。
1.硬件配置
需求:ES-PDS-ES32F3696LX开发板、ESP8266 WiFi模块。


ESP8266 WiFi模块与ES-PDS-ES32F3696LX开发板的连接如下:
| ESP8266 WiFi模块接口 | ES-PDS-ES32F3696LX开发板管脚 | 管脚功能 |
|---|---|---|
| RXD | PB6 | UART4_TX |
| TXD | PB7 | UART4_RX |
| IO_0 | VDD | 固定高电平 |
| GND | GND | 电源地 |
| VCC | 5V | 电源5V |
| RST | 浮空或VDD | 固定高电平 |
2.驱动配置
通过CodeMaker可实现可视化的管脚功能配置
-
新建工程
选择芯片:ES32F3696LX
填写工程名称和路径,选择模板 pkg-example-http:

-
开启UART2功能和对应的管脚作为RT-Thread的控制台功能
-
开启UART4的管脚 PB6, PB7,并选择相应的UART功能,可以设置uart设备的名称,设备配置为波特率115200,无校验,1个停止位。

硬件部分的配置到这里就完成了,接下来进行系统和驱动相关的配置。
3.RT-Thread配置
接下来配置RT-Thread驱动,开启外设功能并配置参数,以下以Keil+ENV配置为例说明如何进行配置
1 . 在bsp的根目录打开ENV工具。
2 . 输入menuconfig配置工程。
-
rt-thread 内核配置
RT-Thread Kernal -> Kernel Device Object进行内核设备对象设置。将控制台的设备名改为“uart2”。

-
rt-thread 组件配置
RT-Thread Components -> Device Drivers进行设备驱动设置。修改Set RX buffer size增大serial设备的接收缓存,建议增大到1024。因为MCU与ESP8266通信过程中可能收发大量数据。

-
rt-thread 软件包 AT DEVICE 配置
RT-Thread online packages -> IoT -> Internet of things -> AT DEVICE:RT...device开启 AT DEVICE 软件包。AT DEVICE 包含不同 AT 设备的移植文件和示例代码。可通过 AT 命令实现标准 socket 编程接口,完成 socket 通讯的功能。
RT-Thread online packages -> IoT -> Internet of things -> AT DEVICE:RT...device -> Espressif ESP8266进入esp8266详细的设置界面,可配置wifi账号密码、与esp8266通信的uart的设备名等。(红线部分为配置选项的路径,之后不再用红线标出)

-
rt-thread 软件包 Ali-iotkit 配置
RT-Thread online packages -> IoT -> Internet of things -> IoT Cloud -> Ali-iotkit:Ali...for RT-Thread开启 Ali-iotkit 软件包。Ali-iotkit 是用于连接阿里云 IoT 平台的软件包。基础 SDK 是阿里提供的 iotkit-embedded C-SDK。在该界面可配置产品名、产品密码、设备名、设备密码等。可参考 实验说明章节。

-
rt-thread 软件包 cJSON 配置
RT-Thread online packages -> IoT -> Internet of things -> cJSON:Utra...in ANSI C开启 cJSON 软件包。cJSON 是超轻量级的 C 语言 json 解析库。Ali-iotkit 软件包依赖 cJSON 软件包。

-
UART 配置
Hardware Drivers Config -> On-chip Peripheral Drivers -> UART Drivers 开启uart2,uart4。

-
开启阿里云样例程序
Hardware Drivers Config -> Pkgs Support Example -> HTTP -> ALI_YUN_EXAMPLE_MQTT开启阿里云示例程序。

3 . 输入pkgs --update命令更新软件包。然后根据 额外说明 优化软件包的部分接口。
4 . 输入scons --target=mdk5命令生成keil5工程。(使用IAR等其他平台指定--target=xxx即可)
5 . 使用MDK5打开工程,编译并下载。
4.实验说明
1 . 先在阿里云上设置产品和设备。
首先创建产品,如下图所示:


点击确认后,即可创建产品。然后查看已经创建的产品,如图所示:

可以获得:产品唯一码( ProductKey )和产品密码( ProductSecret )。
然后往产品里添加设备,如图所示:

点击确认后,即可添加设备。然后查看已经添加的设备,如图所示:

可以获得:设备名( DeviceName)和设备密码( DeviceSecret)
2 . 设备端的程序流程
wifi模块(ESP8266)的驱动会在系统初始化阶段,尝试通过AT指令与wifi模块通信,并用账号密码连接,如果成功,会显示成功连接的提示,并尝试和阿里云进行连接。
上电后,程序流程图如下:

在流程中:topic1 = /产品名/设备名/user/get
topic2 = /产品名/设备名/user/update
具体的topic请根据阿里云产品的topic定义。

5.实验现象
实验将演示mqtt设备的订阅topic和发布topic功能。控制台会打印当前mqtt设备的状态。在阿里云的日志服务也能监视设备的行为。
下载程序后,会先联网,并与阿里云建立连接。控制台的具体现象如下图所示:

云端日志服务将显示:1.设备online。2.上传mqtt设备中阿里云的C-SDK版本。3.设备订阅topic1(/产品名/设备名/user/get)。4.上传设备的固件版本,供阿里云ota功能做参考。如下图所示:

每隔10秒,设备从topic2(/产品名/设备名/user/update)发布消息“hello”。在云端的日志上的显示如下图所示:

查看云端接收到的消息,与设备发送的一致,如下图所示:

然后在云端对topic(设备已经订阅)发送消息。打开当前设备,发现设备已经订阅了topic1(/产品名/设备名/user/get)。如下图所示:

对设备订阅的topic进行发布,看设备是否能接收topic的发布。

在云端的topic发布后,可以在云端日志看到:云端发送消息到设备。显示如下图。

设备接收到topic发布的信息,且内容一致。控制台显示如下:

6.额外说明
1 . Ali-iotkit软件包修改(版本:3.0.1)。
具体修改如下:
修改原因:软件包与 rt-thread 4.0.4 适配
在文件 ali-iotkit-v3.0.1\ports\rtthread\HAL_TCP_rtthread.c 中加入
#include <sys/errno.h>
2 . at_device软件包修改(版本:2.0.4)。
具体修改如下:(修改前的代码 + 修改后的代码)
修改原因:软件包与 rt-thread 4.0.4 适配(rt_delayed_work 被删除了)
修改文件 packages\at_device-v2.0.4\at_device_esp8266.c 。
修改部分1
修改前:
rt_uint32_t dhcp_stat = 0;
struct rt_delayed_work *delay_work = (struct rt_delayed_work *)work;
struct at_device *device = (struct at_device *)work_data;
struct netdev *netdev = device->netdev;
struct at_client *client = device->client;
if (delay_work)
{
rt_free(delay_work);
}
修改后:
rt_uint32_t dhcp_stat = 0;
struct at_device *device = (struct at_device *)work_data;
struct netdev *netdev = device->netdev;
struct at_client *client = device->client;
if (work != RT_NULL)
{
rt_free(work);
}
修改部分2
修改前:
static void esp8266_netdev_start_delay_work(struct at_device *device)
{
struct rt_delayed_work *net_work = RT_NULL;
net_work = (struct rt_delayed_work *)rt_calloc(1, sizeof(struct rt_delayed_work));
if (net_work == RT_NULL)
{
return;
}
rt_delayed_work_init(net_work, esp8266_get_netdev_info, (void *)device);
rt_work_submit(&(net_work->work), RT_TICK_PER_SECOND);
}
修改后:
static void esp8266_netdev_start_delay_work(struct at_device *device)
{
struct rt_work *net_work = RT_NULL;
net_work = (struct rt_work *)rt_calloc(1, sizeof(struct rt_work));
if (net_work == RT_NULL)
{
return;
}
rt_work_init(net_work, esp8266_get_netdev_info, (void *)device);
rt_work_submit(net_work, RT_TICK_PER_SECOND);
}
7. 如何获取 ES-CodeMaker for RT-Thread?
扫描下方二维码关注“东软载波微电子”微信公众号,发送口令 CodeMaker 即可获取下载链接。


