IoT Pi Pro SDDC 设备开发
本章将介绍如何在 IoT Pi Pro 上使用 MS-RTOS 和 libsddc 及 LittleVGL(一个著名的开源 GUI)开发一个能接入到 EdgerOS 的 Wi-Fi 物联网设备。它通过 SDDC 协议将数据传输到 EdgerOS,用户可以使用 EdgerOS App 监测和控制 IoT Pi Pro 的 LED 灯。
软件准备
IoT Pi Pro 开发环境搭建
参考《IoT Pi Pro 快速入门》,完成以下步骤:
完成 MS-RTOS 开发工具下载和安装
在 MS-RTOS 云开发平台上完成
msrtos_base_sdk
配置和下载,配置 MS-RTOS 时,需要手动勾选 libmsdriver、esp_at_net、fatfs、littlevgl、cjson、mbedtls、 libsddc 这几个组件,如下图所示:在 IoT studio 上完成
msrtos_base_sdk
工程导入和编译在 IoT studio 上完成
bspstm32h7xx
工程的下载、导入在 IoT studio 上完成
bootstm32h7xx
工程的下载、导入和编译,如下图所示:
获取 demo_lvgl_sddc
进入工作空间 workspace
目录,使用 git 工具从 MS-RTOS github 社区 下载 iotpipro_demos
,命令如下:
git clone https://github.com/ms-rtos/iotpipro_demos.git
点击 File > Import... 菜单项,打开工程导入对话框,选择 MS-RTOS Projects 工程类型, 选择 iotpipro_demos 的路径,勾选搜索到的 demo_lvgl_sddc 工程,点击 Finish 按钮完成导入:
工程配置
bspstm32h7xx 配置
Wi-Fi AP 连接模式配置
bspstm32h7xx/src/board/IOT_PI_PRO/iot_pi_cfg.h
文件为 bspstm32h7xx
工程的 IoT Pi Pro 开发板的配置头文件,与 IoT Pi Pro 连接 Wi-Fi AP 相关的配置宏如下:
宏 | 含义 |
---|---|
BSP_ESP8266_AUTO_JOIN | 自动连接模式,尝试连接上一次连接的 Wi-Fi AP |
BSP_ESP8266_SMART_CFG | SmartConfig 模式 |
BSP_ESP8266_MANUAL_CFG | 手动连接模式,连接 ap_list[] 中指定的 Wi-Fi AP |
BSP_CFG_ESP8266_MODE | 连接模式, 以上三种连接模式的组合,默认模式为自动连接模式 |
Wi-Fi AP 列表配置
bspstm32h7xx/src/board/IOT_PI_PRO/iot_pi_pro_init.c
为 IoT Pi Pro 开发板的初始化源文件,在此源文件中的 ap_list[]
变量用于指定手动连接模式下尝试连接到的 Wi-Fi AP 列表:
/**
* WiFi AP list.
*/
static const ms_esp_at_net_ap_t ap_list[] = {
{ "EOS-000041", "123456789" }, // Spirit 1 的 Wi-Fi AP SSID 与密码
};
demo_lvgl_sddc 配置
选中 demo_lvgl_sddc
工程,点击鼠标右键,点击弹出的快捷菜单中的 Poperties 菜单项,将弹出 demo_lvgl_sddc 工程属性配置对话框,选择 MS-RTOS Setting 类,选择工作空间下的 msrtos_base_sdk 工程为 MS-RTOS Base Project,同时将 Debug Level 修改为 debug,最后点击 OK 按钮:
工程编译
bspstm32h7xx 编译
选中 bspstm32h7xx
工程,点击编译按钮,将编译 bspstm32h7xx
工程,编译完成后,会在 Debug
目录生成 bspiotpi.bin
文件:
demo_lvgl_sddc 编译
选中 demo_lvgl_sddc
工程,点击编译按钮,将编译 demo_lvgl_sddc
工程,编译完成后,会在 demo_lvgl_sddc/Debug
目录生成 demo_lvgl_sddc.bin
文件:
功能验证
烧写镜像
使用 MS-RTOS AutoTester 烧写镜像,请参考《IoT Pi Pro 快速入门》完成 bootstm32h7xx.bin
和 bspiotpipro.bin
及 demo_lvgl_sddc.bin
镜像烧写,注意不同的镜像需要烧写到不同的地址,如下表所示:
镜像 | 烧写地址 |
---|---|
bootstm32h7xx.bin | 0x08000000 |
bspiotpipro.bin | 0x90000000 |
demo_lvgl_sddc.bin | 0x90100000 |
IoT Pi Pro 连接 EdgerOS
按下 IoT Pi Pro 开发板的 RESET 按键,MS-RTOS 操作系统启动后,将自动运行 0x90100000 地址处的 demo_lvgl_sddc 程序:
如果在前面配置 bspstm32h7xx
工程时,将 Wi-Fi AP 连接模式配置为手动连接模式,并配置了正确的 Spirit 1 的 Wi-Fi AP SSID 和密码,IoT Pi Pro 开发板将能成功连接 Spirit 1 的 Wi-Fi 网络,接下来请参考《SDDC introduction》章节的添加设备流程去添加 IoT Pi Pro 开发板。
IoT Pi Pro SmartConfig
如果在前面配置 bspstm32h7xx
工程时,没有配置了正确的 Spirit 1 的 Wi-Fi AP SSID 和密码,或在后续使用过程中修改了 Spirit 1 的 Wi-Fi AP SSID 或密码,则可以通过 SmartConfig 方式令 IoT Pi Pro 开发板重新加入 Spirit 1 的 Wi-Fi 网络,操作方式请参考《SDDC introduction》章节的 SmartConfig 流程。
EdgerOS 安装 IoT Pi App
打开爱智世界:
搜索 IoT Pi App:
点击获取安装 IoT Pi App。
安装 IoT Pi App:
等待 IoT Pi App 下载和安装完成。
给 IoT Pi App 分配设备权限
打开设置:
点击隐私设置:
点击设备权限:
选择 IoT Pi Pro 开发板:
给 IoT Pi App 分配设备权限:
退出设置。
使用 IoT Pi App 控制 IoT Pi Pro 开发板
打开 IoT Pi App:
点击 IoT Pi Pro 开发板,进入 IoT Pi Pro 控制界面。
控制 IoT Pi Pro 开发板:
IoT Pi Pro 开发板操作
- IoT Pi Pro 主界面:
主界面展示了板载的温湿度和环境光传感器采集到的数据,点击主界面的灯泡图标可进入 LED 控制界面。
- IoT Pi Pro LED 控制界面:
可以看到当前 LED 状态,并且 IoT Pi App、显示屏、LED 灯三者状态是同步的。可以通过 IoT Pi App、IoT Pi Pro 的三个按键以及显示屏上的开关控制 LED 灯。
demo_lvgl_sddc 代码解析
demo_lvgl_sddc 主要业务逻辑代码位于 demo_lvgl_sddc\src\demo_lvgl_sddc.c
、以及 demo_lvgl_sddc\src\system\system.c
:
int main(int argc, char *argv[])
{
// 系统服务初始化
system_service_init(&guider_ui);
#if LV_USE_LOG > 0
lv_log_register_print_cb(lv_log_print);
#endif
// 异步事件处理初始化
ms_lvgl_async_event_init();
// LVGL 初始化
lv_init();
// 显示初始化
lv_port_disp_init();
// 输入设备初始化
lv_port_indev_init();
// 文件系统初始化
lv_port_fs_init();
// 图形化界面初始化
setup_ui(&guider_ui);
events_init(&guider_ui);
custom_init(&guider_ui);
// 创建主页传感器数据读取任务
lv_task_create(system_sensor_read_task, 500, LV_TASK_PRIO_MID, NULL);
while (MS_TRUE) {
// UI 任务处理和多线程异步事件处理
ms_lvgl_async_event_handler(lv_task_handler());
}
return (0);
}
// 初始化系统服务
int system_service_init(lv_ui * guider_ui)
{
struct ifreq ifreq;
struct sockaddr_in *psockaddrin = (struct sockaddr_in *)&(ifreq.ifr_addr);
char *data;
int ret;
ui = guider_ui;
// 初始化 IoT Pi 的三个 LED 灯
ret = iot_pi_led_init();
sddc_return_value_if_fail(ret == 0, -1);
// 初始化 IoT Pi 的三个 KEY
ret = iot_pi_key_init();
sddc_return_value_if_fail(ret == 0, -1);
// 初始化 IoT Pi 的两个传感器
ret = iot_pi_sensor_init();
sddc_return_value_if_fail(ret == 0, -1);
// 设置网络实现
#ifdef SDDC_CFG_NET_IMPL
ret = ms_net_set_impl(SDDC_CFG_NET_IMPL);
sddc_return_value_if_fail(ret == MS_ERR_NONE, -1);
#endif
// 创建 SDDC 协议对象
sddc = sddc_create(SDDC_CFG_PORT);
sddc_return_value_if_fail(sddc, -1);
// 设置事件响应函数
sddc_set_on_message(sddc, iot_pi_on_message); // 设置接收消息请求时的回调函数
sddc_set_on_message_ack(sddc, iot_pi_on_message_ack); // 设置接收消息确认时的回调函数
sddc_set_on_message_lost(sddc, iot_pi_on_message_lost); // 设置丢失消息时的回调函数
sddc_set_on_invite(sddc, iot_pi_on_invite); // 设置接受邀请请求时的回调函数
sddc_set_on_invite_end(sddc, iot_pi_on_invite_end); // 设置发送邀请后的回调函数
sddc_set_on_update(sddc, iot_pi_on_update); // 设置接收更新请求时的回调函数
sddc_set_on_edgeros_lost(sddc, iot_pi_on_edgeros_lost); // 设置 EdgerOS 断连时的回调函数
// 设置设备密码
#if SDDC_CFG_SECURITY_EN > 0 // SDDC_CFG_SECURITY_EN 宏控制是否支持数据加密通信
ret = sddc_set_token(sddc, "1234567890");
sddc_return_value_if_fail(ret == 0, -1);
#endif
// 创建并设置 Report 报文数据
data = iot_pi_report_data_create();
sddc_return_value_if_fail(data, -1);
sddc_set_report_data(sddc, data, strlen(data));
// 创建并设置 Invite 报文数据
data = iot_pi_invite_data_create();
sddc_return_value_if_fail(data, -1);
sddc_set_invite_data(sddc, data, strlen(data));
// 获取并打印网卡 mac 地址
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
sddc_return_value_if_fail(sockfd >= 0, -1);
ioctl(sockfd, SIOCGIFHWADDR, &ifreq);
sddc_printf("MAC addr: %02x:%02x:%02x:%02x:%02x:%02x\n",
(ms_uint8_t)ifreq.ifr_hwaddr.sa_data[0],
(ms_uint8_t)ifreq.ifr_hwaddr.sa_data[1],
(ms_uint8_t)ifreq.ifr_hwaddr.sa_data[2],
(ms_uint8_t)ifreq.ifr_hwaddr.sa_data[3],
(ms_uint8_t)ifreq.ifr_hwaddr.sa_data[4],
(ms_uint8_t)ifreq.ifr_hwaddr.sa_data[5]);
// 使用网卡 mac 地址设置设备唯一标识 UID
sddc_set_uid(sddc, (const ms_uint8_t *)ifreq.ifr_hwaddr.sa_data);
// 获取并打印 IP 地址
if (ioctl(sockfd, SIOCGIFADDR, &ifreq) == 0) {
char ip[sizeof("255.255.255.255")];
inet_ntoa_r(psockaddrin->sin_addr, ip, sizeof(ip));
sddc_printf("IP addr: %s\n", ip);
} else {
sddc_printf("Failed to get IP address, Wi-Fi AP not online!\n");
}
// 创建 SDDC 线程
ret = ms_thread_create("t_sddc",
iot_pi_sddc_thread,
sddc,
2048U,
30U,
70U,
MS_THREAD_OPT_USER | MS_THREAD_OPT_REENT_EN | MS_THREAD_OPT_FPU_EN,
MS_NULL);
sddc_return_value_if_fail(ret == MS_ERR_NONE, -1);
// 创建按键扫描线程,快速连续按下 KEY 1 按键 三次,IoT Pi 将会进入 SmartConfig 模式
ret = ms_thread_create("t_key",
iot_pi_key_thread,
sddc,
2048U,
30U,
70U,
MS_THREAD_OPT_USER | MS_THREAD_OPT_REENT_EN,
MS_NULL);
sddc_return_value_if_fail(ret == MS_ERR_NONE, -1);
return 0;
}