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