Z-Stack協(xié)議棧有一個(gè)MAC定時(shí)器為操作系統(tǒng)提供計(jì)時(shí)。該定時(shí)器以每1ms為單位,更新系統(tǒng)的定時(shí)器事件鏈表。定時(shí)器事件鏈表如圖5所示,鏈表的每一個(gè)結(jié)點(diǎn)記錄了任務(wù)號(task_id),事件號(event_flag)與計(jì)時(shí)時(shí)間( timeout )和下一個(gè)結(jié)點(diǎn)地址(*next)。圖中ZCL_OTA_MT_READn定義為每個(gè)請求節(jié)點(diǎn)對應(yīng)的事件號,Response Spacing即為節(jié)點(diǎn)請求的響應(yīng)間隔,把兩者添加到鏈表當(dāng)中。當(dāng)計(jì)時(shí)時(shí)間減為0后,系統(tǒng)自動(dòng)設(shè)定對應(yīng)的事件號,從而使OTA服務(wù)器循環(huán)地向OTA應(yīng)用控制臺索取鏡像塊數(shù)據(jù),并向節(jié)點(diǎn)發(fā)送鏡像塊響應(yīng)。
以下是OTA服務(wù)器處理鏡像頁請求的部分代碼段:
typedef struct
{
uint32 SeverfileOffset; //OTA服務(wù)器讀取鏡像的偏移量,與OTA客戶端的同步
afAddrType_t Psourceaddress; //OTA客戶端短地址
zclOTA_FileID_t FileID; //鏡像信息,包括鏡像類型,制造商ID與版本號
uint16 ResponseTime; //響應(yīng)間隔時(shí)間
uint8 Length; //鏡像塊大小
uint8 Count; //鏡像頁計(jì)數(shù)
} zclOTA_Address_Index; //鏡像頁請求屬性結(jié)構(gòu)體
zclOTA_Address_Index Address_index[]; //鏡像頁請求屬性結(jié)構(gòu)體數(shù)組
if ( events & ZCL_OTA_MT_READn ) //處理OTA客戶端鏡像頁請求事件
{
ZStatus_t status = ZFailure; //初始化狀態(tài)值
Address_index[n].Count--; //自減鏡像頁計(jì)數(shù)變量
if(Address_index[n].SeverfileOffset 》= Imagesize) //判斷鏡像偏移量是否超出鏡像大小
{
return ( events ^ ZCL_OTA_MT_READn ); //如果超出直接退出事件處理
}
//OTA服務(wù)器根據(jù)OTA客戶端的鏡像頁請求信息,向應(yīng)用控制臺索取鏡像塊數(shù)據(jù)
Status = MT_OtaFileReadReq(&(Address_index[n].Psourceaddress), &(Address_index[n].FileID), Address_index[n].Length, Address_index[n].SeverfileOffset);
if (status == ZSuccess) //假如索取成功,累加已請求的鏡像偏移量
{
Address_index[n].SeverfileOffset += Address_index[n].Length;
}
if(Address_index[n].Count 》 0) //判斷累計(jì)的請求鏡像塊大小是否超出鏡像頁大小
{
//假如沒超出,把該鏡像頁處理時(shí)間繼續(xù)添加到定時(shí)器鏈表,等待下一輪的處理
osal_start_timerEx(zclOTA_TaskID, ZCL_OTA_MT_READn,Address_index[n].ResponseTime);
}
//結(jié)束處理事件,并清除該事件號
return ( events ^ ZCL_OTA_MT_READn );
}
4. 驗(yàn)證與分析
4. 1功能驗(yàn)證
為了驗(yàn)證OTA功能,在CC2530F256平臺上搭建一個(gè)小型樹狀網(wǎng)絡(luò),并使用Packet Sniffer[13]對OTA更新時(shí)的節(jié)點(diǎn)進(jìn)行抓包分析。如圖6(a)所示,四個(gè)傳感節(jié)點(diǎn)的當(dāng)前固件并沒有添加溫度采集功能,所以溫度顯示為0;在新的固件中添加了溫度采集函數(shù),用于驗(yàn)證OTA更新成功。
對于某些特定應(yīng)用,需要節(jié)點(diǎn)更新固件后能夠保持原來的網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)。內(nèi)部Flash的NV區(qū)能夠保存節(jié)點(diǎn)的網(wǎng)絡(luò)信息,只要在工程添加NV_INIT與NV_RESTORE預(yù)編譯項(xiàng),節(jié)點(diǎn)在掉電后還能恢復(fù)原來網(wǎng)絡(luò)信息。
對四個(gè)傳感節(jié)點(diǎn)進(jìn)行OTA更新。如圖6(b)所示,OTA更新后,溫度采集功能成功添加,而且傳感節(jié)點(diǎn)的網(wǎng)絡(luò)短地址沒有發(fā)生變化,網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)保持完整,驗(yàn)證了進(jìn)行OTA鏡像升級過程中,并不會對NV區(qū)進(jìn)行擦除,有利于節(jié)點(diǎn)網(wǎng)絡(luò)信息的恢復(fù)。
在OTA更新過程中,應(yīng)用層的數(shù)據(jù)幀格式如圖7所示。OTA服務(wù)器被配置為路由器(0x06BC),對傳感節(jié)點(diǎn)(0x0002)進(jìn)行點(diǎn)對點(diǎn)更新。第一條短幀是子路由向OTA服務(wù)器發(fā)送Image Block Request,應(yīng)用層載荷從第4字節(jié)開始記錄了新鏡像的制造商ID(0x5678),鏡像類型(0x1234),版本號(0x00000002)和鏡像塊偏移量。最后1個(gè)字節(jié)記錄了每次傳送最大鏡像塊大?。∣TA_MAX_MTU),默認(rèn)為0x20,即為32字節(jié)。第二條長幀是OTA服務(wù)器發(fā)送的Image Block Response,載荷記錄格式與前者類似,并在最大鏡像塊大小字節(jié)后面附上32字節(jié)鏡像塊信息,從而完成一個(gè)鏡像塊傳輸周期。
評論
查看更多