推荐阅读:自建MQTT迁移阿里云物联网平台指南
本实践案例介绍使用物联网平台提供的C语言设备端SDK,将搭载实时操作系统(RTOS)的微控制单元(MCU)的设备接入阿里云物联网平台。
原有的工业自动化设备、数据采集设备、实时控制设备、家电等使用的是搭载实时操作系统(RTOS)的微控制单元(MCU)。在对此类设备进行物联网改造时,可以使用阿里云物联网平台提供的C语言设备端SDK,将此类设备接入物联网平台。
接入方案
将MCU与通信模组相连,MCU与通信模组间通过AT指令进行连接和通信。在通信模组上,使用C语言设备端SDK实现与物联网平台的连接和通信。
准备软硬件
本示例中,使用了如下MCU、通信模组开发板和软件开发环境。
MCU为ST公司生产的STM32F103,其开发板为NUCLEO-F103RB。
通信模组为SIMCom公司(芯讯通无线科技有限公司)生产的SIM800C,其开发板为SIM800C mini V2.0。
开发环境为IAR Embedded Workbench for ARM。
实现过程
创建产品和设备
首先,在物联网平台控制台创建产品和设备,获取设备证书信息(ProductKey、DeviceName和DeviceSecret)。设备证书信息需配置到设备端SDK中。当设备请求连接物联网平台时,物联网平台会根据设备证书信息进行设备身份验证。
操作步骤
- 登录物联网平台控制台。
- 创建产品。
在左侧导航栏,选择设备管理 > 产品。
在产品管理页,单击创建产品,填入产品信息,然后单击保存。
- 在产品下,创建设备。
在左侧导航栏,选择设备管理 > 设备。
在设备管理页,单击添加设备,在新创建的产品下添加设备。
执行结果
设备创建成功后,会弹出设备证书信息。您也可以在设备管理页,单击设备对应的查看,进入设备详情页查看设备证书信息。
搭建设备端开发环境
将MCU与通信模组开发板相连,搭建软件开发环境,创建工程项目,导入SDK,完成SDK配置。
背景信息
本示例中使用了两个开发板示意图如下。
开发板NUCLEO-F103RB
引脚示意图如下。
SIM800C mini v2.0
引脚示意图和说明如下。
引脚说明
PWR-开关机引脚。默认为自动开机。
STA-状态监测引脚。
GND-电源接地引脚。
RXD-接收串口引脚。
TXD-发送串口引脚。
EN-电源使能引脚。
VIN-5~18V电源输入。
连接硬件
将两个开发板的接收和发送串口连接,作为AT指令通道。如下图所示
搭建开发环境
本示例开发工具为STM32CubeMX。使用详情,请参见STM32Cube Ecosystem。
- 打开STM32CubeMX,并选择新建项目。
- 在Board Seletor中,搜索NUCLEO-F103RB,并单击STM32F103RBTx。
- 单击右上角Start Project。
- 在左侧Connectivity菜单中,勾选串口USART1作为MCU与模组通信的端口,并进行以下配置。
- 设置Mode为Asynchronous。
- 在Configuration栏,完成以下设置。
在GPIO Settings下,确认Pin为PA9和PA10。
在NVIC Settings下,将USART1 global interrupt设置为Enable。
- 在Middleware下,选择FREERTOS,并配置为使用计数信号量和堆大小,用于给每个线程分配栈。
- 在Project Manager页签下,完成Project设置。
- 单击右上角GENERATE CODE,生成代码工程。
开发设备端
使用的C语言Link Kit SDK将通信模组接入物联网平台。
其他硬件平台也可以在上述SDK获取文档中获取相关SDK自主调试。
设备端SDK配置
- 单击这里下载C语言Link Kit SDK 3.0.1版。
- 从下载包中提取SDK代码。本文以Linux系统操作为例。
运行make menuconfig。
选中ATM Configurations,单击Select。
选中AT HAL Configurations,单击Select。
配置如下项目。
FEATURE_PLATFORM_HAS_STDINT=y
FEATURE_PLATFORM_HAS_OS=y
FEATURE_INFRA_STRING=y
FEATURE_INFRA_NET=y
FEATURE_INFRA_LIST=y
FEATURE_INFRA_LOG=y
FEATURE_INFRA_LOG_ALL_MUTED=y
FEATURE_INFRA_LOG_MUTE_FLW=y
FEATURE_INFRA_LOG_MUTE_DBG=y
FEATURE_INFRA_LOG_MUTE_INF=y
FEATURE_INFRA_LOG_MUTE_WRN=y
FEATURE_INFRA_LOG_MUTE_ERR=y
FEATURE_INFRA_LOG_MUTE_CRT=y
FEATURE_INFRA_TIMER=y
FEATURE_INFRA_SHA256=y
FEATURE_INFRA_REPORT=y
FEATURE_INFRA_COMPAT=y
FEATURE_DEV_SIGN=y
FEATURE_MQTT_COMM_ENABLED=y
FEATURE_MQTT_DEFAULT_IMPL=y
FEATURE_MQTT_DIRECT=y
FEATURE_DEVICE_MODEL_CLASSIC=y
FEATURE_ATM_ENABLED=y
FEATURE_AT_TCP_ENABLED=y
FEATURE_AT_PARSER_ENABLED=y
FEATURE_AT_TCP_HAL_SIM800=y
配置完成后,运行./extract.sh提取代码。
提取的代码位于output/eng目录。
其中,各子目录分别包含的代码如下。
atm -- AT指令收发模块
dev_sign -- 设备身份认证模块
infra -- 内部实现模块
mqtt -- MQTT协议模块
wrappers -- HAL对接模块
在wrappers目录下,新建文件wrappers.c,该文件中的代码需实现以下HAL函数。
int32_t HAL_AT_Uart_Deinit(uart_dev_t *uart)
int32_t HAL_AT_Uart_Init(uart_dev_t *uart)
int32_t HAL_AT_Uart_Recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout)
int32_t HAL_AT_Uart_Send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout)
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN])
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN])
int HAL_GetFirmwareVersion(char *version)
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN])
void *HAL_Malloc(uint32_t size)
void HAL_Free(void *ptr)
void *HAL_MutexCreate(void)
void HAL_MutexDestroy(void *mutex)
void HAL_MutexLock(void *mutex)
void HAL_MutexUnlock(void *mutex)
void *HAL_SemaphoreCreate(void)
void HAL_SemaphoreDestroy(void *sem)
void HAL_SemaphorePost(void *sem)
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms)
int HAL_ThreadCreate(void **thread_handle,
void *(*work_routine)(void *),
void *arg,
hal_os_thread_param_t *hal_os_thread_param,
int *stack_used)
void HAL_SleepMs(uint32_t ms)
void HAL_Printf(const char *fmt, ...)
int HAL_Snprintf(char *str, const int len, const char *fmt, ...)
uint64_t HAL_UptimeMs(void)
单击这里下载wrappers.c文件的代码Demo。
在代码Demo中,替换设备证书信息为您的设备证书信息。
说明 如果您不是使用NUCLEO-F103RB通信模组开发板,需在配置时,设置FEATURE_AT_TCP_HAL_SIM800=n。且wrappers.c文件中代码需实现以下HAL函数。
int HAL_AT_CONN_Close(int fd, int32_t remote_port)
int HAL_AT_CONN_Deinit(void)
int HAL_AT_CONN_DomainToIp(char *domain, char ip[16])
int HAL_AT_CONN_Init(void)
int HAL_AT_CONN_Send(int fd, uint8_t *data, uint32_t len, char remote_ip[16], int32_t remote_port, int32_t timeout)
int HAL_AT_CONN_Start(at_conn_t *conn)
int32_t HAL_AT_Uart_Deinit(uart_dev_t *uart)
int32_t HAL_AT_Uart_Init(uart_dev_t *uart)
int32_t HAL_AT_Uart_Recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout)
int32_t HAL_AT_Uart_Send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout)
int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN])
int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN])
int HAL_GetFirmwareVersion(char *version)
int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN])
void *HAL_Malloc(uint32_t size)
void HAL_Free(void *ptr)
void *HAL_MutexCreate(void)
void HAL_MutexDestroy(void *mutex)
void HAL_MutexLock(void *mutex)
void HAL_MutexUnlock(void *mutex)
void *HAL_SemaphoreCreate(void)
void HAL_SemaphoreDestroy(void *sem)
void HAL_SemaphorePost(void *sem)
int HAL_SemaphoreWait(void *sem, uint32_t timeout_ms)
int HAL_ThreadCreate(void **thread_handle,
void *(*work_routine)(void *),
void *arg,
hal_os_thread_param_t *hal_os_thread_param,
int *stack_used)
void HAL_SleepMs(uint32_t ms)
void HAL_Printf(const char *fmt, ...)
int HAL_Snprintf(char *str, const int len, const char *fmt, ...)
uint64_t HAL_UptimeMs(void)
- 将SDK整合到IAR工程中。
如下图所示。
- 运行SDK,进行测试。
运行成功后,设备端本地日志如下图。
在物联网平台控制台,监控运维 > 日志服务中,也可查看设备上报数据到云端的日志。
阿里云物联网平台公共实例,18元/年起:点此购买
物联网平台专属实例,1万台设备接入低至9.5元/天,更划算:查看文档
按用量付费6折起:点此购买