本文介绍HAL相关说明。
设备端C-SDK分层
+---------------------------+
| |
| C-SDK Example Program |
| |
+---------------------------+
| |
| C-SDK Interface Layer |
| |
| IOT_XXX_YYY() APIs |
| |
+---------------------------+
| |
| C-SDK Core Implements |
| : => |
| : You SHOULD NOT Focus |
| : on this unless |
| : you're debugging SDK |
| |
+---------------------------+
| |
| Hardware Abstract Layer |
| |
| HAL_XXX_YYY() APIs |
| |
| : You MUST Implement |
| : this part for your |
| : target device first |
+---------------------------+
设备端C-SDK分为三层,如上所示。
第一层
Link Kit Interface Layer
称为SDK接口声明层。是C函数的原型声明,SDK跨平台移植完成之后,可以用于编写业务逻辑和阿里云服务器通信API。
在
examples
目录提供了丰富的示例程序使用API做业务逻辑。只要填入设备信息,即可以在Linux主机上运行体验。第二层
Link Kit Core Implements
称为SDK内核实现层。第三层
Hardware Abstract Layer
称为硬件平台抽象层,简称为HAL层
。
C-SDK的核心实现部分,基于HAL层接口完成了MQTT/CoAP通道等的功能封装。包括MQTT的连接建立、报文收发、CoAP的连接建立、报文收发、OTA的固件状态查询、OTA的固件下载等。
抽象不同的嵌入式目标板上操作系统对SDK的支撑函数,包括网络收发、TLS/DTLS通道建立和读写、内存申请释放、互斥量加锁解锁等。
在任何跨平台移植时,都需要实现硬件平台抽象层。
V2.3.0及以前版本
所有HAL层函数的声明都在
include/iot_import.h
头文件中列出。各功能点引入的HAL层接口依赖在
include/imports/iot_import_*.h
中列出。include/imports
目录下的子文件,都在include/iot_import.h
中包含。函数声明,对应在
src/ref-impl/hal/os/ubuntu/
中提供的Ubuntu
桌面系统上的参考实现,会被编译成output/release/lib/libiot_hal.a
。
HAL层接口列表
全部接口列表
以下命令可以列出所有跨平台移植时需要实现的HAL层接口。
include$ grep -ro "HAL_[_A-Za-z0-9]*(" *|awk -F':' '{ print $NF }'|awk '{ print $NF }'|sed 's!(!!g'|sort -u|awk '{ printf("%03d %s\n", NR, $0); }'
001 HAL_Aes128_Cbc_Decrypt
002 HAL_Aes128_Cbc_Encrypt
003 HAL_Aes128_Cfb_Decrypt
004 HAL_Aes128_Cfb_Encrypt
005 HAL_Aes128_Destroy
006 HAL_Aes128_Init
016 HAL_Config_Read
017 HAL_Config_Write
018 HAL_DTLSSession_create
019 HAL_DTLSSession_free
020 HAL_DTLSSession_read
021 HAL_DTLSSession_write
022 HAL_Firmware_Persistence_Start
023 HAL_Firmware_Persistence_Stop
024 HAL_Firmware_Persistence_Write
025 HAL_Free
026 HAL_GetChipID
027 HAL_GetDeviceID(在2.3.1及以后版本中不需要实现)
028 HAL_GetDeviceName
029 HAL_GetDeviceSecret
030 HAL_GetFirmwareVersion
031 HAL_GetModuleID
032 HAL_GetPartnerID
033 HAL_GetProductKey
034 HAL_GetProductSecret
035 HAL_GetTimeStr(在2.3.1及以后版本中不需要实现)
036 HAL_Kv_Del
037 HAL_Kv_Erase_All
038 HAL_Kv_Get
039 HAL_Kv_Set
040 HAL_Malloc
041 HAL_MutexCreate
042 HAL_MutexDestroy
043 HAL_MutexLock
044 HAL_MutexUnlock
045 HAL_Printf
046 HAL_Random
047 HAL_Reboot
048 HAL_RF433_Get_Rssi_Dbm
049 HAL_SemaphoreCreate
050 HAL_SemaphoreDestroy
051 HAL_SemaphorePost
052 HAL_SemaphoreWait
053 HAL_SetDeviceName
054 HAL_SetDeviceSecret
055 HAL_SetProductKey
056 HAL_SetProductSecret
057 HAL_SleepMs
058 HAL_Snprintf
059 HAL_Srandom
060 HAL_SSL_Destroy
061 HAL_SSL_Establish
062 HAL_SSL_Read
063 HAL_SSL_Write
064 HAL_Sys_Net_Is_Ready
065 HAL_Sys_reboot(在2.3.0及以后版本中不需要实现)
066 HAL_TCP_Destroy
067 HAL_TCP_Establish
068 HAL_TCP_Read
069 HAL_TCP_Write
070 HAL_ThreadCreate
071 HAL_ThreadDelete
072 HAL_ThreadDetach
073 HAL_Timer_Create
074 HAL_Timer_Delete
075 HAL_Timer_Start
076 HAL_Timer_Stop
077 HAL_UDP_bindtodevice
078 HAL_UDP_close
079 HAL_UDP_close_without_connect
080 HAL_UDP_connect
081 HAL_UDP_create
082 HAL_UDP_create_without_connect
083 HAL_UDP_joinmulticast
084 HAL_UDP_read
085 HAL_UDP_readTimeout
086 HAL_UDP_recv
087 HAL_UDP_recvfrom
088 HAL_UDP_send
089 HAL_UDP_sendto
090 HAL_UDP_write
091 HAL_UptimeMs
092 HAL_UTC_Get
093 HAL_UTC_Set
094 HAL_Vsnprintf
095 HAL_Wifi_Enable_Mgmt_Frame_Filter
096 HAL_Wifi_Get_Ap_Info
097 HAL_Wifi_Get_IP
098 HAL_Wifi_Get_Mac
099 HAL_Wifi_Get_Os_Version
100 HAL_Wifi_Get_Rssi_Dbm
101 HAL_Wifi_Low_Power
102 HAL_Wifi_Scan
103 HAL_Wifi_Send_80211_Raw_Frame
实现函数请参考src/ref-impl/hal/os/ubuntu
和src/ref-impl/hal/os/win7
已经写好的示例代码。
src/ref-impl/hal$ tree -A
.
+-- CMakeLists.txt
+-- iot.mk
+-- iotx_hal_internal.h
+-- os
| +-- macos
| | +-- HAL_Crypt_MacOS.c
| | +-- HAL_OS_MacOS.c
| | +-- HAL_TCP_MacOS.c
| | +-- HAL_UDP_MacOS.c
| +-- ubuntu
| | +-- base64.c
| | +-- base64.h
| | +-- cJSON.c
| | +-- cJSON.h
| | +-- HAL_Crypt_Linux.c
| | +-- HAL_OS_linux.c
| | +-- HAL_TCP_linux.c
| | +-- HAL_UDP_linux.c
| | +-- kv.c
| | +-- kv.h
| +-- win7
| +-- HAL_OS_win7.c
| +-- HAL_TCP_win7.c
+-- ssl
+-- itls
| +-- HAL_TLS_itls.c
+-- mbedtls
| +-- HAL_DTLS_mbedtls.c
| +-- HAL_TLS_mbedtls.c
+-- openssl
+-- HAL_TLS_openssl.c
基础
函数名 | 是否必选 | 说明 |
| 是 | 申请一片堆上内存。 |
| 是 | 释放一片堆上内存。 |
| 是 | 睡眠函数,使当前执行线程睡眠指定的毫秒数。 |
| 是 | 打印函数,向内存缓冲区格式化构建一个字符串,请参考C99标准库函数 |
| 是 | 打印函数,用于向串口或其它标准输出打印日志或调试信息。 |
| 是 | 字符串打印函数,将 |
| 是 | 时钟函数,获取本设备从加电以来到目前时间点已经过去的毫秒数。 |
| 是 | 写入指定KV数据。 |
| 是 | 读取指定KV数据。 |
| 是 | 删除指定KV数据。 |
| 是 | 擦除所有的KV数据。 |
多线程
函数名 | 是否必选 | 说明 |
| 否 | 创建一个互斥量,用于同步控制。对于仅支持单线程应用,可实现为空函数。 |
| 否 | 销毁一个互斥量,用于同步控制。对于仅支持单线程应用,可实现为空函数。 |
| 否 | 加锁一个互斥量,用于同步控制。对于仅支持单线程应用,可实现为空函数。 |
| 否 | 解锁一个互斥量,用于同步控制。对于仅支持单线程应用,可实现为空函数。 |
| 否 | 按照指定入参创建一个线程,对于仅支持单线程应用,可实现为空函数。 |
| 否 | 结束指定的线程,对于仅支持单线程应用,可实现为空函数。 |
| 否 | 设置指定的线程为 |
| 否 | 创建一个计数信号量,对于仅支持单线程应用,可实现为空函数。 |
| 否 | 销毁一个计数信号量,对于仅支持单线程应用,可实现为空函数。 |
| 否 | 在指定的计数信号量上做自增操作,解除其它线程的等待,对于仅支持单线程应用,可实现为空函数。 |
| 否 | 在指定的计数信号量上等待并做自减操作,对于仅支持单线程应用,可实现为空函数。 |
MQTT和HTTP通道功能
函数名 | 是否必选 | 说明 |
| 否 | 销毁一个TLS连接,用于MQTT功能、HTTPS功能。 |
| 否 | 建立一个TLS连接,用于MQTT功能、HTTPS功能。 |
| 否 | 从一个TLS连接中读数据,用于MQTT功能、HTTPS功能。 |
| 否 | 向一个TLS连接中写数据,用于MQTT功能、HTTPS功能。 |
| 否 | 销毁一个TLS连接,用于MQTT功能、HTTPS功能。 |
| 否 | 建立一个TCP连接,包含了域名解析的动作和TCP连接的建立。 |
| 否 | 在指定时间内,从TCP连接读取流数据,并返回读到的字节数。 |
| 否 | 在指定时间内,向TCP连接发送流数据,并返回发送的字节数。 |
| 否 | 随机数函数,接受一个无符号数作为范围,返回0到该数值范围内的随机无符号数。 |
| 否 | 随机数播种函数,使 |
CoAP通道功能
函数名 | 是否必选 | 说明 |
| 否 | 初始化DTLS资源并建立一个DTLS会话,用于CoAP功能。 |
| 否 | 销毁一个DTLS会话并释放DTLS资源,用于CoAP功能。 |
| 否 | 从DTLS连接中读数据,用于CoAP功能。 |
| 否 | 向DTLS连接中写数据,用于CoAP功能。 |
| 否 | AES128解密,CBC模式,用于CoAP报文加解密。 |
| 否 | AES128加密,CBC模式,用于CoAP报文加解密。 |
| 否 | AES128解密,CFB模式,用于CoAP报文加解密。 |
| 否 | AES128加密,CFB模式,用于CoAP报文加解密。 |
| 否 | AES128反初始化。 |
| 否 | AES128初始化。 |
| 否 | 关闭一个UDP Socket。 |
| 否 | 创建一个UDP Socket。 |
| 否 | 阻塞的从一个UDP Socket中读取数据包,并返回读到的字节数。 |
| 否 | 在指定时间内,从一个UDP Socket中读取数据包,返回读到的字节数。 |
| 否 | 阻塞的向一个UDP Socket中发送数据包,并返回发送的字节数。 |
本地通信功能
函数名 | 是否必选 | 说明 |
| 否 | 创建一个本地UDP Socket,但不发起任何网络交互。 |
| 否 | 销毁指定的UDP Socket,回收资源。 |
| 否 | 在指定的UDP Socket上发送加入组播组的请求。 |
| 否 | 在指定的UDP Socket上发送指定缓冲区的指定长度,阻塞时间不超过指定时长,且指定长度若发送完需提前返回。 |
| 否 | 从指定的UDP句柄接收指定长度数据到缓冲区,阻塞时间不超过指定时长,且指定长度若接收完需提前返回,源地址保存在出参中。 |
设备信息设置与获取
函数名 | 是否必选 | 说明 |
| 是 | 获取芯片ID。 |
| 是 | 获取设备ID。 说明 在2.3.1及以后版本中不需要实现。 |
| 是 | 获取固件版本号。 |
| 是 | 获取模组ID,用于紧密合作伙伴,一般客户只需要在此可实现为空函数。 |
| 是 | 获取合作伙伴ID,用于紧密合作伙伴,一般客户只需要在此可实现为空函数。 |
| 是 | 获取DeviceName,必须实现。 |
| 是 | 获取DeviceSecret,必须实现。 |
| 是 | 获取ProductKey,必须实现。 |
| 是 | 获取ProductSecret,必须实现。 |
| 是 | 设置DeviceName,必须实现。 |
| 是 | 设置DeviceSecret,必须实现。 |
| 是 | 设置ProductKey,必须实现。 |
| 是 | 设置ProductSecret,必须实现。 |
OTA功能
函数名 | 是否必选 | 说明 |
| 否 | 固件持久化开始,包含OTA功能时必须实现。 |
| 否 | 固件持久化结束,包含OTA功能时必须实现。 |
| 否 | 固件持久化写入,包含OTA功能时必须实现。 |
本地定时任务功能
函数名 | 是否必选 | 说明 |
| 否 | 设置UTC时间,单位ms。 |
| 否 | 获取UTC时间,单位ms。 |
WIFI配网功能
函数名 | 是否必选 | 说明 |
| 否 | 在设备的持久化外部存储器,例如Flash,从配置区域起始位置读取数据到指定的内存缓冲区中。 |
| 否 | 在设备的持久化外部存储器,例如Flash,把指定的内存缓冲区向配置区域起始位置写入。 |
| 否 | 获取RF433的接收信号强度( |
| 否 | 检查系统网络是否可用。 |
| 否 | 在站点( |
| 否 | 获取所连接的热点( |
| 否 | 获取Wi-Fi网口的IP地址,点分十进制格式保存在字符串数组出参。二进制格式则作为返回值,并以网络字节序表达。 |
| 否 | 获取Wi-Fi网口的MAC地址,格式为 |
| 否 | 获取Wi-Fi模块上的操作系统版本字符串。 |
| 否 | 获取Wi-Fi的接收信号强度( |
| 否 | 使Wi-Fi模组进入省电模式,并持续一段时间。 |
| 否 | 启动一次Wi-Fi的空中扫描,该API是一个阻塞操作。所有的AP列表收集完成后,通过回调函数告知C-SDK。 |
| 否 | 在当前信道( |