一、簡(jiǎn)述
麒麟座開(kāi)發(fā)板代碼例程由OneNET-基礎(chǔ)例程、OneNET-進(jìn)階例程、OneNET-RTOS例程組成,由淺入深地演示如何接入OneNET,從最基本的上傳數(shù)據(jù)點(diǎn),命令接收處理,到網(wǎng)絡(luò)維持,平臺(tái)連接維持,到最后的網(wǎng)絡(luò)錯(cuò)誤處理,一步一步演示如何處理這些事情。
下面先以O(shè)neNET-基礎(chǔ)例程為例,講解如何接入OneNET。
二、OneNET-基礎(chǔ)例程模塊分析
1. 代碼框架說(shuō)明
-
初始化開(kāi)發(fā)板外圍硬件;如LED、蜂鳴器、按鍵等。
-
初始化網(wǎng)絡(luò)模組;開(kāi)發(fā)板板載GSM模組-M6312,可插拔的WIFI-ESP8266-01模組。
-
登錄OneNET。
-
執(zhí)行相關(guān)上下行數(shù)據(jù)處理。
2. 代碼功能簡(jiǎn)述
演示如何接入OneNET,如何處理OneNET推送的數(shù)據(jù)。
不具備網(wǎng)絡(luò)維持能力,掉網(wǎng)后無(wú)法處理。
3. 初始化開(kāi)發(fā)板外圍硬件-Hardware_Init()函數(shù)
根據(jù)不同功能所需要用到的外圍硬件不同,可根據(jù)自己使用的例程查看相應(yīng)的硬件驅(qū)動(dòng)代碼,這里以為例說(shuō)明
麒麟座使用的STM32F103RET6單片機(jī),mini板使用STM32F103C8T6單片機(jī),都是F1系列,編程方式完全一致。
-
先配置單片機(jī)的中斷分組,采用2:2配置;
-
然后初始化systick用來(lái)做阻塞延時(shí);
-
然后初始化串口1和串口2,串口1用來(lái)調(diào)試打印,串口2和網(wǎng)絡(luò)模組通信;
-
然后就是初始化LED,蜂鳴器,按鍵,主要就是GPIO的配置;
-
最后打印一下,提示硬件初始化完成。
4. 初始化網(wǎng)絡(luò)模組-ESP8266_Init()函數(shù)
WIFI模組的初始化比較簡(jiǎn)單:
-
先初始化相關(guān)控制的GPIO。
-
然后先發(fā)送AT,測(cè)試通信是否OK。
-
然后就是設(shè)置WIFI工作模式、登錄路由、連接IP。
-
如果是GSM模組,前兩步相同,初始化控制GPIO、發(fā)送AT測(cè)試通信。然后是注冊(cè)、激活網(wǎng)絡(luò)、連接IP。
5.登錄OneNET -OneNet_DevLink()函數(shù)
主要流程就是獲取登錄數(shù)據(jù),然后發(fā)送出去,等待返回。
獲取登錄數(shù)據(jù):
EDP_PacketConnect1(DEVID, APIKEY,256, &edpPacket)
根據(jù)devid和apikey通過(guò)sdk生成登錄數(shù)據(jù),保存在edpPacket里邊。
發(fā)送:
ESP8266_SendData(edpPacket._data,edpPacket._len);
指明要發(fā)送的數(shù)據(jù)和長(zhǎng)度即可,調(diào)用此函數(shù)就會(huì)發(fā)送到OneNET接入機(jī)。
等待結(jié)果
ESP8266_GetIPD(250):從硬件層判斷時(shí)間是否收到
EDP_UnPacketRecv(dataPtr) ==CONNRESP:
EDP_UnPacketConnectRsp(dataPtr):
從軟件層解析是否接入成功。
6. 執(zhí)行相關(guān)上下行數(shù)據(jù)處理
上行數(shù)據(jù)
執(zhí)行OneNet_SendData()函數(shù),會(huì)調(diào)用相關(guān)上傳功能。
166行,是封裝一個(gè)json,把要上傳的內(nèi)容寫(xiě)在里邊
170行,根據(jù)devid、json格式和json封裝協(xié)議包
175行,將協(xié)議包上傳。
簡(jiǎn)單看看166行的內(nèi)容
其中led_status.xxx,就是我們要上傳的數(shù)據(jù),按照json格式寫(xiě)好即可,如果新增數(shù)據(jù)點(diǎn),復(fù)制高亮三行的任意一行加以擴(kuò)展,然后把箭頭的buf緩存開(kāi)大一點(diǎn)即可。
下行數(shù)據(jù)
先判斷驅(qū)動(dòng)層是否收到數(shù)據(jù),有則調(diào)用OneNet_Re**taPtr)函數(shù)解析相關(guān)功能。
判斷是否是下發(fā)命令,是則回復(fù)這個(gè)命令,然后做相關(guān)命令的處理
三、OneNET-RTOS例程模塊分析
1. 代碼框架說(shuō)明
-
初始化開(kāi)發(fā)板外圍硬件;如LED、蜂鳴器、按鍵等。
-
初始化網(wǎng)絡(luò)模組;開(kāi)發(fā)板板載GSM模組-M6312,可插拔的WIFI-ESP8266-01模組。
-
登錄OneNET。
-
執(zhí)行相關(guān)上下行數(shù)據(jù)處理。
-
網(wǎng)絡(luò)維持,網(wǎng)絡(luò)監(jiān)測(cè)、錯(cuò)誤處理。
2.代碼功能簡(jiǎn)述
完整的開(kāi)發(fā)板功能體驗(yàn),所有傳感器數(shù)據(jù)均上傳,并包含一些監(jiān)測(cè)類(lèi)變量;完備的網(wǎng)絡(luò)維持、監(jiān)測(cè)、錯(cuò)誤處理機(jī)制。
后文以與OneNET通訊、網(wǎng)絡(luò)監(jiān)測(cè)、錯(cuò)誤處理為重點(diǎn)進(jìn)行分析。
3.初始化開(kāi)發(fā)板外圍硬件-Hardware_Init()函數(shù)--main.c
基本流程和基礎(chǔ)例程類(lèi)似,初始化板載硬件,單片機(jī)片內(nèi)外設(shè)等。
這里多了一個(gè)功能,將登陸的devid和apikey保存在eeprom里邊,可以通過(guò)串口1按照資料中的格式進(jìn)行更改而無(wú)需重新下載代碼。
4.初始化網(wǎng)絡(luò)模組- NET_DEVICE_Init ()函數(shù)--net_task.c
這個(gè)函數(shù)不連接具體的ip,僅僅只是讓網(wǎng)絡(luò)模組具備網(wǎng)絡(luò)接入能力即可。
5. 登錄OneNET- -net_task.c
OneNET_GetLinkIP:獲取該協(xié)議當(dāng)前資源最優(yōu)的接入ip和port。
OneNET_ConnectIP:連接ip和port。
OneNET_DevLink:根據(jù)devid和apikey 或者 proid和auth_info登錄OneNET設(shè)備。
6.執(zhí)行相關(guān)上下行數(shù)據(jù)處理--net_task.c
上行數(shù)據(jù)
在net_task.c-- NET_**_Task任務(wù)里,紅框處,是定時(shí)上傳的內(nèi)容,這個(gè)任務(wù)以50ms周期執(zhí)行一次,當(dāng)累計(jì)300次-約15s時(shí),可自行更改,觸發(fā)一次上傳數(shù)據(jù)的標(biāo)志,箭頭所指處。
然后在net_task.c--DATA_P_Task任務(wù)里判斷到標(biāo)志置位,執(zhí)行OneNET_SendData(…)函數(shù)根據(jù)當(dāng)前的data_stream值去打包一個(gè)待上傳的數(shù)據(jù)包,但此時(shí)并不上傳,而是放入一個(gè)單向鏈表里,原因稍后分析,如果上傳成功,則返回值會(huì)改變onenet_info.send_data的值,如果錯(cuò)誤,則會(huì)間隔一段時(shí)間后繼續(xù)回來(lái)打包數(shù)據(jù)。
最終將數(shù)據(jù)發(fā)送出去的的是net_task.c--DATA_S_Task任務(wù)判斷表頭是否為空,且網(wǎng)絡(luò)連接正常,然后獲取表里數(shù)據(jù)和對(duì)應(yīng)長(zhǎng)度,吧數(shù)據(jù)發(fā)往OneNET。
簡(jiǎn)單說(shuō)一下,為什么上傳一包數(shù)據(jù),分了三個(gè)步驟(觸發(fā)、打包、發(fā)送),因?yàn)檫@樣可以在其他地方方便地上傳數(shù)據(jù),只需要改變一個(gè)變量值即可,而不用調(diào)用復(fù)雜的打包、發(fā)送函數(shù),對(duì)函數(shù)堆棧要求降低很多;然后發(fā)送作為一個(gè)單獨(dú)的任務(wù)是為了網(wǎng)絡(luò)模組穩(wěn)定性,wifi和gsm發(fā)送數(shù)據(jù)的時(shí)間間隔不同,wifi可以快一點(diǎn),當(dāng)短時(shí)間內(nèi)有很多包大小不同的數(shù)據(jù)包待上傳時(shí),發(fā)送必須要穩(wěn)定,所以O(shè)neNET_SendData(…)只是打包放入鏈表,發(fā)送函數(shù)以一個(gè)穩(wěn)定的時(shí)間間隔來(lái)一包包的發(fā)出去。
下行數(shù)據(jù)
在net_task.c-- RECV_Task任務(wù)里邊,只有一個(gè)函數(shù)OneNET_CmdHandle
先是調(diào)用NET_DEVICE_Read()函數(shù)判斷驅(qū)動(dòng)層是否收到數(shù)據(jù)。
然后調(diào)用NET_DEVICE_GetIPD(dataPtr)判斷是否具有IPD頭,這里說(shuō)明一下,在絕大多數(shù)網(wǎng)絡(luò)模組里,在指令模式下,如果收到一幀網(wǎng)絡(luò)數(shù)據(jù),則會(huì)以IPD標(biāo)識(shí)(不同網(wǎng)絡(luò)模組這個(gè)頭可能不一樣),如果帶有IPD頭,則說(shuō)明收到OneNET推來(lái)的數(shù)據(jù),進(jìn)入OneNET_RevPro(ipdPtr)函數(shù)進(jìn)行處理。
處理函數(shù)里邊先通過(guò)EDP_UnPacketRecv(cmd)判斷推送數(shù)據(jù)的類(lèi)型,以EDP為例,有連接響應(yīng)、命令下發(fā)、數(shù)據(jù)轉(zhuǎn)發(fā)、心跳回復(fù)等,然后各自處理即可。
最后具體說(shuō)說(shuō)命令下發(fā)的處理機(jī)制。
先調(diào)用EDP_UnPacketCmd(…)函數(shù)解析出uuid、uudi長(zhǎng)度、命令、命令長(zhǎng)度。
然后是調(diào)用EDP_PacketCmdResp(…)函數(shù)打包命令回復(fù)的內(nèi)容。
然后是調(diào)用CALLBACK_Execute(...)函數(shù)處理命令,在cmd_callback.c里邊可以找到處理的過(guò)程
調(diào)用CALLBACK_Find_CallBack(…)找到紅框處XXX的內(nèi)容,這是是命令體,后邊YYY是命令值,后邊會(huì)用到
然后根據(jù)命令體對(duì)應(yīng)的回調(diào)函數(shù),執(zhí)行響應(yīng)的動(dòng)作,比如redled,
調(diào)用CALLBACK_Find_Value(…)函數(shù)找到命令參數(shù)YYY
調(diào)用CALLBACK_Str2Dec(…)函數(shù)轉(zhuǎn)為數(shù)值形式,方便執(zhí)行開(kāi)關(guān)處理。
大家在添加自己的命令和處理內(nèi)容的時(shí)候添加兩個(gè)地方
命令體和命令回調(diào)對(duì)應(yīng)表
然后編寫(xiě)命令回調(diào)函數(shù)即可。
繼續(xù)回到下行數(shù)據(jù)處理上來(lái),處理完命令之后,就是釋放相關(guān)內(nèi)存,然后調(diào)用NET_DEVICE_AddDataSendList(…)函數(shù)吧命令回復(fù)的內(nèi)容加入鏈表,最后置位一下onenet_info.send_data上傳一次數(shù)據(jù),以更新OneNET設(shè)備上的數(shù)據(jù)。
7. 網(wǎng)絡(luò)維持—net_task.c
在NET_**_Task任務(wù)里邊,和數(shù)據(jù)上傳一樣的流程,定時(shí)發(fā)送心跳,然后等待心跳返回正確的結(jié)果,以此判斷網(wǎng)絡(luò)是否通暢
同樣的,在DATA_P_Task任務(wù)里邊調(diào)用OneNET_SendData_Heart()函數(shù)打包心跳數(shù)據(jù)并清除心跳標(biāo)志,在DATA_S_Task任務(wù)里真正發(fā)送出去,在OneNET_RevPro()函數(shù)里邊解析心跳數(shù)據(jù),收到則置位心跳標(biāo)志,然后在OneNET_Check_Heart()來(lái)檢測(cè)心跳標(biāo)志。
如果在規(guī)定時(shí)間內(nèi)檢測(cè)不到心跳標(biāo)志,則會(huì)檢測(cè)當(dāng)前模組狀態(tài),根據(jù)狀態(tài)分配錯(cuò)誤等級(jí),然后會(huì)進(jìn)入相關(guān)錯(cuò)誤處理。
8. 網(wǎng)絡(luò)監(jiān)測(cè)、錯(cuò)誤處理
7中說(shuō)到,心跳標(biāo)志檢測(cè)不到,會(huì)進(jìn)入錯(cuò)誤處理,先看看錯(cuò)誤等級(jí)處理都干了什么:
fault.c--NET_Fault_Process
將相關(guān)標(biāo)志位清零,在任務(wù)里邊檢查到標(biāo)志位變化,會(huì)執(zhí)行對(duì)應(yīng)功能,錯(cuò)誤等級(jí)為1,只是負(fù)責(zé)重新連接一下ip。
錯(cuò)誤等級(jí)2就是走初始化流程,去重新初始化一下網(wǎng)絡(luò)模組了。
錯(cuò)誤等級(jí)3是復(fù)位網(wǎng)絡(luò)模組。
錯(cuò)誤等級(jí)4是給網(wǎng)絡(luò)模組斷電后,等待一會(huì),再打開(kāi)。
那么錯(cuò)誤等級(jí)如何確定,下面一一截圖說(shuō)明
NET_FAULT_LEVEL_1的場(chǎng)景:
net_task.c--OS_TimerCallBack
在網(wǎng)絡(luò)定時(shí)檢測(cè)回調(diào)里,發(fā)送數(shù)據(jù)未得到回應(yīng)次數(shù)超過(guò)規(guī)定次數(shù)時(shí)。
onenet.c--OneNET_CmdHandle
當(dāng)收到網(wǎng)絡(luò)模組返回的連接關(guān)閉提示時(shí)。
onenet.c-- OneNET_Check_Heart
心跳標(biāo)志接收超時(shí),且網(wǎng)絡(luò)模組具備網(wǎng)絡(luò)能力時(shí)。
NET_FAULT_LEVEL_3的場(chǎng)景:
錯(cuò)誤2和3通暢搭配使用,在重新初始化之前,先復(fù)位一下。
net_task.c--OS_TimerCallBack
當(dāng)網(wǎng)絡(luò)斷開(kāi)超過(guò)規(guī)定時(shí)間時(shí)。
onenet.c-- OneNET_Check_Heart
心跳標(biāo)志接收超時(shí),且網(wǎng)絡(luò)模組不具備網(wǎng)絡(luò)能力時(shí)。
fault.c
在錯(cuò)誤等級(jí)1下,在規(guī)定次數(shù)內(nèi)還未連接成功時(shí)。
可以看到,在例程里邊有很多地方都在保障網(wǎng)絡(luò)的通暢性,一旦發(fā)生網(wǎng)絡(luò)錯(cuò)誤,則會(huì)根據(jù)響應(yīng)狀態(tài)制定錯(cuò)誤處理,爭(zhēng)取用最高效的方式重新接入OneNET。
-
物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
2909文章
44713瀏覽量
374276 -
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
5074瀏覽量
97661 -
麒麟
+關(guān)注
關(guān)注
1文章
224瀏覽量
13659 -
OneNET
+關(guān)注
關(guān)注
1文章
51瀏覽量
12824 -
中移物聯(lián)網(wǎng)
+關(guān)注
關(guān)注
0文章
27瀏覽量
4860
原文標(biāo)題:中移物聯(lián)網(wǎng)麒麟座開(kāi)發(fā)板代碼模塊分析
文章出處:【微信號(hào):雨飛工作室,微信公眾號(hào):雨飛工作室】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論