NBIOT SDK包移植說明文檔
1. 移植背景開發語言:C語言 硬件平臺:STM32F10X 開發環境:KEIL MDK5.23 2. 工程目錄可在該目錄下的main.c下實現NBIOT的例程 在目錄下實現和模組進行通信的驅動,這里實現了串口驅動 實現通信模組的驅動,這里實現了esp8266的驅動 該目錄下實現各種傳感器的驅動 SDK包中JSON報文格式化的接口 SDK包中加解密功能接口,暫不支持 SDK包中Lwm2m和coap協議的具體實現 SDK和ONENET平臺交互的接口實現 和具體硬件平臺有關的底層實現 3. 工程設置在Include Paths處添加頭文件所在的路徑,該路徑為相對于工程所在目錄的相對路徑 在Preprocessor Symbols處添加條件編譯選項,條件編譯選項如下: - NBIOT_DEBUG – 輸出sdk調試日志
- LWM2M_WITH_LOGS – 輸出lwm2m相關的日志
- COAP_WITH_LOGS – 輸出coap相關的日志
- NO_OS-無操作系統的時候選擇
- BIG_ENDIAN – 內存模型為大字節序
- LITTLE_ENDIAN – 內存模型為小字節序
- HAVE_DTLS – 帶dtls加密傳輸
- DTLS_WITH_LOGS – 輸出dtls相關的日志
注:SDK包原版支持win和linux操作系統,STM32F10x平臺本身沒有操作系統,因此需要選擇NO_OS,同時由于STM32屬于小端系統,因此需要選擇LITTLE_ENDIAN,太多的打印會導致系統變慢,擾亂協議棧的時序,從而出現各種問題,因此不建議打開所有的打印。
4. 初始化SDK運行環境與SDK運行環境相關的全局變量如下圖所示,分別是統一資源定位標識符URI,NBIOT服務器地址serv_addr,以及SDK在服務器端進行注冊時候需要用到的鑒權碼auth_code和斷點名endpoint_name。 - void nbiot_init_environment( void )
在該函數中,初始化一切和SDK包運行有關的軟硬件資源,包括內存管理算法初始化、系統時鐘初始化、打印串口初始化、模組通信串口初始化和模組初始化。 - void nbiot_clear_environment( void )
該函數中,需要對當前SDK包的運行環境進行一些清理的工作,包括退出當前的網絡,回收內存資源等動作。 5. Socket接口的實現原SDK包使用socket接口,現在由于使用模組且沒有TCP/IP協議棧,因此SDK不識別任何和socket有關的數據結構和函數接口,需要對這些內容進行移植。 { SOCKET sock; }; 在這里,將SOCKET數據類型修改int型,修改后如下所示: struct nbiot_socket_t { int sock; }; { struct sockaddr_in addr; }; 在這里將struct sockaddr_in addr 修改為char型數組,用來儲存字符串形式的IP地址,修改后如下所示: struct nbiot_sockaddr_t { char addr[20]; }; - int nbiot_udp_create( nbiot_socket_t **sock )
原SDK使用該函數,為sock結構體的sock成員創建了一個實體,上下文中需要使用到該實體資源,因此該接口不需要任何的修改。 - int nbiot_udp_close( nbiot_socket_t *sock )
原SDK使用該函數,調用socket接口關閉了udp連接,這里需要使用模組提供的AT命令實現udp連接的關閉。 - int nbiot_udp_bind( nbiot_socket_t *sock,
const char *addr, uint16_t port ) 原SDK包使用該函數,調用socket接口綁定udp服務器,并實例化了sock結構體里的sock成員,因此需要屏蔽掉綁定的動作,還需要對sock結構體進行賦值,在這里賦值為1 - int nbiot_udp_connect( nbiot_socket_t *sock,
const char *addr, uint16_t port, nbiot_sockaddr_t **dest ) 原SDK包使用該函數,測試設備和UDP服務器之間的連通性,使用了模組后不需要該動作,因此屏蔽掉。
6. 數據發送接口的實現- int nbiot_udp_send( nbiot_socket_t *sock,
const void *buff, size_t size, size_t *sent, const nbiot_sockaddr_t *dest ) 原SDK包使用該函數,調用SOCKET的發送接口,采用非阻塞方式將數據發送出去,在這里則直接調用模組的串口發送接口,將數據發送至模組。 7. 數據接收接口的實現- int nbiot_udp_recv( nbiot_socket_t *sock,
void *buff, size_t size, size_t *read, nbiot_sockaddr_t **src ) 原SDK包使用該函數,調用SOCKET的接口,采用非阻塞的方式接受數據,因此為了模擬非阻塞的方式,盡量不要在該函數中采用輪詢的方式來接收數據,在這里設計了一個接收緩沖區,該函數負責檢查接收緩存區,如果有數據則提交給SDK包進行處理,否則立即返回。 - void USART2_IRQHandler(void)
移植后的SDK包使用串口中斷的方式,以字節為單位對數據進行接收,為了區分出數據包,ESP8266必須使用非透傳模式,同時在接收到一個完整的數據包后,將數據包放進緩存區中,等待SDK包的處理。具體工作流程如下:首先判斷一個數據包的開始,如果是則使能接收空閑中斷;當發生了接收空閑中斷,意味著一個完整的數據包已經接收完成,將該數據包放進緩沖區中。 8. 系統時間的實現- time_t nbiot_time( void )
time_t 類型為long型,在原SDK包中nbiot_time函數返回的是系統當前時間,單位為秒,因此使用STM32系統提供的RTC定時器作為系統滴答定時器,nbiot_time函數讀取定時器里面的值并返回。 - void nbiot_sleep( int milliseconds )
使用了RTC定時器實現了ms級別的精確延時。 9. 內存管理的實現- void *nbiot_malloc( size_t size )
- void nbiot_free( void *ptr )
為了管理sdk運行過程的內存分配與釋放,抽離出以上2個接口函數,便于不同環境下采用合適的內存管理策略,現在暫時使用KEIL 微庫提供的malloc函數和free函數,需要注意以下兩點:
- 在工程配置中,需要選擇Use MicroLIB這個選項
- 在啟動文件中,將Heap_Size的大小進行合理的擴充
10. 其它- coap_content_type_t結構體成員的長度問題
在原SDK包中,使用了LINUX操作系統,默認枚舉類型成員的長度為系統的字長,但在嵌入式系統中,為了節省空間,只要枚舉類型成員的值不超過一個字節,則不會分配兩個字節的空間。為了解決該問題,需要修改coap_content_type_t結構體,否則SDK包發送的數據會被服務器扔掉,修改過程的如下所示: 在該結構體的最后,添加一行,xxx=0xFFFF,則keil編譯器會為該結構體成員分配兩個字節的存儲空間。
完整的Word格式文檔51黑下載地址: |