摘要:針對(duì)NB-IoT物聯(lián)網(wǎng)燃?xì)獗碓谌霊羰褂煤箅y以進(jìn)行固件升級(jí)的問題,為了滿足系統(tǒng)軟件的升級(jí)需求,本文設(shè)計(jì)了一種基于NB-IoT網(wǎng)絡(luò)的物聯(lián)網(wǎng)燃?xì)獗磉h(yuǎn)程升級(jí)系統(tǒng)。該系統(tǒng)以STM8L微控制器為核心,利用NB-IoT網(wǎng)絡(luò)實(shí)現(xiàn)數(shù)據(jù)傳輸,通過對(duì)存儲(chǔ)芯片內(nèi)部空間進(jìn)行合理劃分,增加IAP功能,實(shí)現(xiàn)對(duì)NB-IoT物聯(lián)網(wǎng)燃?xì)獗淼倪h(yuǎn)程升級(jí)功能。
關(guān)鍵詞:NB-IoT;物聯(lián)網(wǎng);STM8L;燃?xì)獗?/p>
中圖分類號(hào):TP393 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2024)24-0107-03
開放科學(xué)(資源服務(wù))標(biāo)識(shí)碼(OSID)
0 引言
隨著近些年NB-IoT技術(shù)的不斷普及,傳統(tǒng)的設(shè)備終端變得越來越智能化。在傳統(tǒng)燃?xì)獗砩显黾覰B-IoT功能,不僅提高了燃?xì)夤镜男?,也大大方便了用戶的使用[1],由于燃?xì)獗淼奶厥庑?,安裝后被廣泛分散到不同的用戶家里,當(dāng)出現(xiàn)設(shè)計(jì)缺陷或需要升級(jí)增加新功能時(shí),加入了互聯(lián)網(wǎng)之后的NB-IoT物聯(lián)網(wǎng)燃?xì)獗硎沟眠@一切變得簡(jiǎn)單可行。本文基于NB-IoT技術(shù)設(shè)計(jì)了一種安全、簡(jiǎn)單、可靠的物聯(lián)網(wǎng)燃?xì)獗磉h(yuǎn)程升級(jí)方案。
1 系統(tǒng)設(shè)計(jì)
本文設(shè)計(jì)的NB-IoT物聯(lián)網(wǎng)燃?xì)獗硗ㄟ^NB-IoT網(wǎng)絡(luò)與后臺(tái)系統(tǒng)聯(lián)動(dòng),結(jié)合手機(jī)App、微信公眾號(hào)等方式實(shí)現(xiàn)NB-IoT物聯(lián)網(wǎng)燃?xì)獗淼闹悄苡?jì)量、遠(yuǎn)程監(jiān)控、遠(yuǎn)程閥控、遠(yuǎn)程充值等功能。其中,NB-IoT物聯(lián)網(wǎng)燃?xì)獗碛蒘TM8L微控制器、NB-IoT通信單元(Narrow-Band Internet of Things)、基本計(jì)量單元、閥門控制單元、LCD顯示單元(Liquid Crystal Display)、按鍵單元、紅外通信單元、存儲(chǔ)單元等部分組成[2],NB-IoT物聯(lián)網(wǎng)燃?xì)獗碚w的系統(tǒng)結(jié)構(gòu)如圖1所示。其中,計(jì)量單元通過兩個(gè)霍爾傳感器實(shí)現(xiàn)基本計(jì)量功能,存儲(chǔ)單元通過24LC512芯片實(shí)現(xiàn),用于計(jì)量數(shù)據(jù)、歷史用氣情況的存儲(chǔ)以及固件升級(jí)數(shù)據(jù)的存儲(chǔ)。按鍵用于查詢用氣情況和啟動(dòng)數(shù)據(jù)的上報(bào),短按按鍵LCD液晶將輪顯用氣情況等數(shù)據(jù),長(zhǎng)按按鍵三秒以上,NB-IoT物聯(lián)網(wǎng)燃?xì)獗韺?dòng)主動(dòng)上報(bào)功能,實(shí)現(xiàn)數(shù)據(jù)的遠(yuǎn)程上傳。同時(shí),NB-IoT物聯(lián)網(wǎng)燃?xì)獗砻刻鞎?huì)在凌晨時(shí)間段錯(cuò)峰向云平臺(tái)上傳數(shù)據(jù),用以實(shí)現(xiàn)數(shù)據(jù)的上報(bào)和云平臺(tái)指令的接收等功能,而遠(yuǎn)程升級(jí)功能就是利用NB-IoT物聯(lián)網(wǎng)燃?xì)獗砼c云平臺(tái)的交互來實(shí)現(xiàn)更新NB-IoT物聯(lián)網(wǎng)燃?xì)獗韮?nèi)部固件的功能,以達(dá)到彌補(bǔ)NB-IoT物聯(lián)網(wǎng)燃?xì)獗砉碳毕莼蛏?jí)新功能的需求。
2 升級(jí)原理
STM8L MCU 是意法半導(dǎo)體公司推出的一款超低功耗的8位微控制器。該系列微控制器集高性能和超低功耗于一身,尤其適合電池供電的系統(tǒng)。因此,本文選擇 STM8L052R8芯片作為NB-IoT物聯(lián)網(wǎng)燃?xì)獗淼闹骺匦酒?/p>
應(yīng)用編程IAP(In Application Programming),是用戶自己的程序在運(yùn)行過程中對(duì)內(nèi)部的Flash區(qū)域進(jìn)行編程燒寫,更新后可以執(zhí)行剛剛燒寫的新的應(yīng)用程序[3],從而實(shí)現(xiàn)芯片內(nèi)部的程序升級(jí)。這里把NB-IoT物聯(lián)網(wǎng)燃?xì)獗沓绦蛟O(shè)計(jì)成 Bootloader和App兩個(gè)獨(dú)立的代碼,兩個(gè)代碼通過編譯分別生成不同的hex文件,將兩個(gè)hex文件合并后生成一個(gè)新的hex文件,出廠時(shí)將這個(gè)hex文件燒錄到芯片內(nèi)部[4],這樣NB-IoT物聯(lián)網(wǎng)燃?xì)獗砭蛯?shí)現(xiàn)了計(jì)量、顯示、通信、固件升級(jí)等功能。
固件升級(jí)的基本過程:每天凌晨NB-IoT物聯(lián)網(wǎng)燃?xì)獗矶紩?huì)主動(dòng)向云平臺(tái)上報(bào)數(shù)據(jù)。云平臺(tái)根據(jù)NB-IoT物聯(lián)網(wǎng)燃?xì)獗砩蠄?bào)的版本號(hào),決定是否下發(fā)升級(jí)指令,如果需要升級(jí),NB-IoT物聯(lián)網(wǎng)燃?xì)獗砭蜁?huì)主動(dòng)從云平臺(tái)分包接收升級(jí)的固件包,同時(shí)把接收到的數(shù)據(jù)包存儲(chǔ)在存儲(chǔ)芯片內(nèi)部,直到所有包接收完畢,并經(jīng)校驗(yàn)無誤后,NB-IoT物聯(lián)網(wǎng)燃?xì)獗韺腁pp程序跳轉(zhuǎn)到Bootloader程序,啟動(dòng)內(nèi)部更新程序,實(shí)現(xiàn)固件的自動(dòng)更新。更新完成后調(diào)用重啟功能進(jìn)入新的App程序,至此NB-IoT物聯(lián)網(wǎng)燃?xì)獗砩?jí)完成。
3 IAP功能實(shí)現(xiàn)
3.1 BootLoader引導(dǎo)程序設(shè)計(jì)
為了實(shí)現(xiàn)STM8L單片機(jī)的固件升級(jí)功能,必須有一個(gè)BootLoader引導(dǎo)程序來實(shí)現(xiàn)程序的跳轉(zhuǎn)和更新功能,這段程序要盡量做到代碼精簡(jiǎn),邏輯清晰,還需要有異常處理功能。Bootloader 程序主要完成數(shù)據(jù)包的校驗(yàn)、固件的更新和程序的跳轉(zhuǎn)等功能,當(dāng)固件更新完成后,Bootloader 程序會(huì)強(qiáng)制從Bootloader程序跳轉(zhuǎn)到App程序,其中,NB-IoT物聯(lián)網(wǎng)燃?xì)獗淼幕居?jì)量、顯示、控制和數(shù)據(jù)上報(bào)等功能都是在App程序中實(shí)現(xiàn)的。
當(dāng)STM8L單片機(jī)上電或重啟后程序會(huì)首先執(zhí)行BootLoader這段引導(dǎo)程序,這段程序具體的工作流程如下:BootLoader程序首先會(huì)判斷固件更新的標(biāo)志位有沒有置位,如果沒有置位,就代表固件不需要更新,此時(shí)程序會(huì)直接跳轉(zhuǎn)到App應(yīng)用程序執(zhí)行NB-IoT燃?xì)獗淼挠?jì)量、顯示、閥控、數(shù)據(jù)上報(bào)等功能,而如果經(jīng)判斷固件更新的標(biāo)志位置位了,就代表有最新的固件需要更新,這個(gè)時(shí)候BootLoader程序就會(huì)進(jìn)入升級(jí)模式,此時(shí)STM8L就會(huì)從指定的存儲(chǔ)地址開始分包讀取固件數(shù)據(jù),在每一包數(shù)據(jù)讀取完成后會(huì)計(jì)算當(dāng)前這一包數(shù)據(jù)的CRC16值,并將這一值與每包接收到的CRC16值進(jìn)行比較,如果計(jì)算的CRC16值和讀取的CRC16值一致,就代表當(dāng)前這一包數(shù)據(jù)正確,如果這一包數(shù)據(jù)驗(yàn)證無誤后便會(huì)進(jìn)行下一包數(shù)據(jù)的讀取和CRC16的校驗(yàn),以此循環(huán),直至所有的數(shù)據(jù)包都讀取并校驗(yàn)無誤以后,BootLoader程序才會(huì)認(rèn)為之前存儲(chǔ)的每一包數(shù)據(jù)單包都沒有問題,在此,為了保證數(shù)據(jù)的進(jìn)一步完整可靠,在進(jìn)行分包校驗(yàn)完成后,同時(shí)增加了整個(gè)固件代碼的整體CRC16校驗(yàn),將整個(gè)固件的所有數(shù)據(jù)計(jì)算一個(gè)CRC16值,并與系統(tǒng)下發(fā)的整個(gè)固件的總的CRC16值進(jìn)行比較,如果CRC16值一致,才會(huì)認(rèn)為之前接收的整個(gè)數(shù)據(jù)包都沒有問題。如果經(jīng)過以上的雙重校驗(yàn)確認(rèn)數(shù)據(jù)完整無誤后,系統(tǒng)便會(huì)進(jìn)入固件更新模式,此時(shí)系統(tǒng)便會(huì)分包讀取數(shù)據(jù),并將讀取的數(shù)據(jù)寫入STM8L內(nèi)部指定的Flash地址,直至所有的數(shù)據(jù)寫入完成,并驗(yàn)證無誤后,系統(tǒng)便會(huì)清除固件更新的標(biāo)志位,并調(diào)用跳轉(zhuǎn)指令將代碼跳轉(zhuǎn)到App應(yīng)用程序,從而執(zhí)行NB-IoT燃?xì)獗淼挠?jì)量、顯示、閥控、數(shù)據(jù)上報(bào)等功能,至此固件更新的整個(gè)過程完成,其中,更新過程中的具體工作流程如圖2所示,以下代碼是Bootloader程序的部分代碼,該部分代碼主要實(shí)現(xiàn)了數(shù)據(jù)的校驗(yàn)、Flash的擦寫等功能。
if((w_CRC[0] == w_CRC_rcv1) && (w_CRC[1] == w_CRC_rcv2))//總幀校驗(yàn)正確
{
for (i = 0; i < 3; i++)
{
for (n = 0; n < 3; n++)
{
m=0;
ProgramBlock(pAppSrcBlock, MAIN_USER_RESET_ADDR, pAppSrc+i*128);
while ((FLASH->IAPSR & (uint8_t)FLASH_FLAG_HVOFF) == RESET){}
for (pAppSrcIndex = 0; pAppSrcIndex < FLASH_BLOCK_BYTES; pAppSrcIndex++)
{ /*!< Read flash byte */
//pApp_Addr=pAppSrcBlock * FLASH_BLOCK_BYTES + MAIN_USER_RESET_ADDR;
pApp_Addr = pAppSrcBlock;
pApp_Addr *= FLASH_BLOCK_BYTES;
pApp_Addr+=MAIN_USER_RESET_ADDR;
if ((*(PointerAttr uint8_t *)(MemoryAddressCast)(pAppSrcIndex + pApp_Addr)) != pAppSrc[pAppSrcIndex+i*128])
{
if(n==2)
{
/*for (i = 0; i < 200; i++)
{
GPIO_SetBits(GPIOD, GPIO_Pin_7);//低電
delay_ms(5);
GPIO_ResetBits(GPIOD, GPIO_Pin_7);//低電
delay_ms(5);
}
while(((GPIOG->IDR) & GPIO_Pin_1) == 0);//按鈕未按下*/
asm("LDW X, SP ");
asm("LD A, $FF");
asm("LD XL, A ");
asm("LDW SP, X ");
asm("JPF $9000");
}
m=1;
break;
}
}
if(m==0) break;
}
pAppSrcBlock += 1;
pAppLen -= FLASH_BLOCK_BYTES;
delay_ms(10);
pAppTry = 3;
if(pAppLen);
else break;
}
}
3.2 App程序設(shè)計(jì)
App程序是用來實(shí)現(xiàn)NB-IoT物聯(lián)網(wǎng)燃?xì)獗碛?jì)量、LCD顯示、閥控、存儲(chǔ)、數(shù)據(jù)上傳、網(wǎng)絡(luò)充值等功能的代碼,遠(yuǎn)程升級(jí)功能也是通過NB-IoT技術(shù)實(shí)現(xiàn)數(shù)據(jù)的分包傳輸,具體的工作流程如下:應(yīng)用程序每次與云平臺(tái)交互的時(shí)候都會(huì)主動(dòng)上報(bào)自己的表號(hào)和目前的固件版本號(hào),云平臺(tái)收到NB-IoT物聯(lián)網(wǎng)燃?xì)馍蠄?bào)的表號(hào)和版本號(hào)并進(jìn)行分析,如果需要更新便會(huì)在NB-IoT物聯(lián)網(wǎng)燃?xì)馍蠄?bào)數(shù)據(jù)之后給NB-IoT物聯(lián)網(wǎng)燃?xì)庀掳l(fā)一條遠(yuǎn)程升級(jí)的啟動(dòng)指令,NB-IoT物聯(lián)網(wǎng)燃?xì)馐盏缴?jí)指令后,會(huì)主動(dòng)向售氣系統(tǒng)發(fā)送請(qǐng)求獲取第一包數(shù)據(jù)的指令,云平臺(tái)收到請(qǐng)求數(shù)據(jù)指令后,會(huì)將預(yù)先生成的bin格式的固件包數(shù)據(jù)進(jìn)行分包,并根據(jù)上傳上來的包號(hào)將對(duì)應(yīng)的數(shù)據(jù)打包后下發(fā)給NB-IoT燃?xì)獗?,這里數(shù)據(jù)包的獲取采用的是主動(dòng)向云平臺(tái)獲取的方式,這樣做的好處是升級(jí)過程可控,而且最大程度減小了云平臺(tái)的壓力,通信過程中每包數(shù)據(jù)的最后兩個(gè)字節(jié)跟的是當(dāng)前整個(gè)數(shù)據(jù)包的CRC16值[5],這樣做的目的是在執(zhí)行BootLoader引導(dǎo)程序時(shí)能夠?qū)︻A(yù)先存儲(chǔ)的數(shù)據(jù)進(jìn)行校驗(yàn),進(jìn)一步保證數(shù)據(jù)的準(zhǔn)確可靠。而且當(dāng)所有的數(shù)據(jù)包都傳輸完成后,云平臺(tái)會(huì)再次將整個(gè)固件里的所有數(shù)據(jù)計(jì)算一個(gè)總的CRC16值下發(fā)給燃?xì)獗?,燃?xì)獗硎盏胶?,?huì)將這個(gè)值存起來,用于數(shù)據(jù)的二次校驗(yàn),直到所有的包都接收完成后,固件數(shù)據(jù)的接收過程也就完成了。NB-IoT物聯(lián)網(wǎng)燃?xì)獗碓诮邮展碳?shù)據(jù)的過程中,由于NB-IoT信號(hào)不好或者服務(wù)器響應(yīng)慢等問題,會(huì)造成NB-IoT物聯(lián)網(wǎng)燃?xì)獗斫邮詹坏皆破脚_(tái)下發(fā)的升級(jí)數(shù)據(jù),或者出現(xiàn)接收數(shù)據(jù)不完整的情況,所以App應(yīng)用程序在設(shè)計(jì)的時(shí)候如果長(zhǎng)時(shí)間接收不到云平臺(tái)的數(shù)據(jù),就需要主動(dòng)再次向云平臺(tái)請(qǐng)求當(dāng)前數(shù)據(jù)包,但是如果多次請(qǐng)求后,仍然接收不到數(shù)據(jù),則認(rèn)為此次升級(jí)失敗,這時(shí)便將目前升級(jí)的進(jìn)度存儲(chǔ)在存儲(chǔ)芯片內(nèi)部,待下次再次連接后繼續(xù)完成升級(jí)過程。其中,通信過程中每一幀數(shù)據(jù)包的數(shù)據(jù)格式如表1所示:
首先,數(shù)據(jù)包的第1個(gè)字節(jié)是幀頭,也就是幀起始符,這里使用十六進(jìn)制的0xFE表示,幀頭表示這一幀數(shù)據(jù)的開始,第2個(gè)字節(jié)是這一幀數(shù)據(jù)的總長(zhǎng)度,這個(gè)長(zhǎng)度是從幀長(zhǎng)度到幀尾的幀數(shù)據(jù)的長(zhǎng)度,第3個(gè)字節(jié)是這一幀數(shù)據(jù)的功能碼,這里我們將數(shù)據(jù)升級(jí)指令的功能碼定義為十六進(jìn)制的0x55,接下來,從第4個(gè)字節(jié)到第9個(gè)字節(jié)表示的是當(dāng)前NB-IoT物聯(lián)網(wǎng)燃?xì)獗淼谋硖?hào),這個(gè)是用來區(qū)分不同的NB-IoT燃?xì)獗砩蟼鞯臄?shù)據(jù)的,從第10個(gè)字節(jié)開始為這一幀數(shù)據(jù)的數(shù)據(jù)域,數(shù)據(jù)域包含了NB-IoT燃?xì)獗懋?dāng)前的固件版本號(hào)、當(dāng)前的包數(shù)和總包數(shù),以及傳輸?shù)墓碳?shù)據(jù)等內(nèi)容,接下來跟在數(shù)據(jù)域后面的兩個(gè)字節(jié)是CRC16的校驗(yàn)碼,用于數(shù)據(jù)的校驗(yàn),進(jìn)一步確保數(shù)據(jù)的準(zhǔn)確可靠,緊接著跟在校驗(yàn)位后面的一個(gè)字節(jié)是這一幀數(shù)據(jù)的結(jié)束符,這里使用十六進(jìn)制的0x16表示,代表這一幀數(shù)據(jù)的結(jié)束。這就是固件升級(jí)過程中,數(shù)據(jù)通信的格式,NB-IoT燃?xì)獗砩?jí)過程中應(yīng)嚴(yán)格遵循這樣的數(shù)據(jù)格式進(jìn)行數(shù)據(jù)的傳輸。
4 系統(tǒng)測(cè)試
通過對(duì)國內(nèi)某燃?xì)夤疽咽褂玫?00臺(tái)NB-IoT物聯(lián)網(wǎng)燃?xì)獗磉M(jìn)行驗(yàn)證測(cè)試,在凌晨NB-IoT物聯(lián)網(wǎng)燃?xì)獗頂?shù)據(jù)錯(cuò)峰上報(bào)的同時(shí),通過云平臺(tái)給NB-IoT物聯(lián)網(wǎng)燃?xì)獗硐掳l(fā)啟動(dòng)升級(jí)功能,經(jīng)測(cè)試,100臺(tái)NB-IoT物聯(lián)網(wǎng)燃?xì)獗碇幸淮紊?jí)成功的有96臺(tái),升級(jí)失敗的有4臺(tái),經(jīng)過第二次的升級(jí),剩下的4臺(tái)設(shè)備也全部升級(jí)成功。
5 結(jié)論
本文針對(duì)NB-IoT物聯(lián)網(wǎng)燃?xì)獗砉碳?jí)難的問題,提出了一種基于NB-IoT網(wǎng)絡(luò)的遠(yuǎn)程升級(jí)方法,并完成了代碼的設(shè)計(jì),遠(yuǎn)程升級(jí)功能也已經(jīng)在實(shí)際應(yīng)用中得到了驗(yàn)證,同時(shí),該方案對(duì)于基于NB-IoT網(wǎng)絡(luò)的嵌入式設(shè)備的遠(yuǎn)程升級(jí)也具有一定的參考價(jià)值。
參考文獻(xiàn):
[1] 鄭紅立,劉航,胡洋.NB-IoT技術(shù)在物聯(lián)網(wǎng)智能燃?xì)獗眍I(lǐng)域的應(yīng)用與推廣[J].城市燃?xì)猓?021,558(8):6-11.
[2] 高柱榮,蔣昌茂,劉洪林.物聯(lián)網(wǎng)燃?xì)獗磉h(yuǎn)程升級(jí)的研究與實(shí)現(xiàn)[J].自動(dòng)化儀表,2021,42(5):27-31.
[3] 文豐,溫倩,武慧軍.基于IAP的嵌入式系統(tǒng)在線編程設(shè)計(jì)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2022,22(12):37-41.
[4] 陳以安,李鵬,車慢行.基于Wi-Fi的STM32固件遠(yuǎn)程升級(jí)系統(tǒng)[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2022,22(7):46-50.
[5] 趙二剛,張紅賓,王志紅,等.基于LoRa技術(shù)的STM32處理器無線程序升級(jí)系統(tǒng)設(shè)計(jì)[J].南開大學(xué)學(xué)報(bào)(自然科學(xué)版),2020,53(6):18-21.
【通聯(lián)編輯:梁書】