杭萬里,張榮
(中國電子科技集團公司第五十八研究所,江蘇無錫214035)
隨著社會發(fā)展,各行各業(yè)大量使用嵌入式電子設(shè)備,如道路上的高清數(shù)字監(jiān)控攝像頭、遠(yuǎn)程水文監(jiān)控設(shè)備等。這些設(shè)備的軟件升級維護又是常態(tài),而設(shè)備一旦安裝,拆卸十分繁瑣,這就要求其必須能夠遠(yuǎn)程在線升級。嵌入式設(shè)備一般是基于單片機/DSP/ARM開發(fā)的,遠(yuǎn)程在線升級實際是對其程序進行遠(yuǎn)程升級。多數(shù)已發(fā)表的論文是針對某個特定芯片遠(yuǎn)程升級的研究,不具備普遍性[1-2]。文中從遠(yuǎn)程升級的原理,將其分為五個功能環(huán)節(jié),每個環(huán)節(jié)給出一個或多個實現(xiàn)策略,并且某些核心功能代碼可以復(fù)用,從而簡化開發(fā)。實際應(yīng)用中只需根據(jù)使用芯片,在各環(huán)節(jié)選擇實現(xiàn)策略,分別實現(xiàn),最后集成并調(diào)試即可。本文最后章節(jié)對單片機/DSP/ARM各舉一個實際應(yīng)用范例。
注:不包含可以運行l(wèi)inux/andriod操作系統(tǒng)ARM,因其自身已具備遠(yuǎn)程升級功能。
遠(yuǎn)程在線升級包含5個環(huán)節(jié):程序數(shù)據(jù)準(zhǔn)備、程序數(shù)據(jù)傳輸、燒寫環(huán)節(jié)、程序更新方式、用戶程序跳轉(zhuǎn)方式。
嵌入式設(shè)備在線升級的前提,是要準(zhǔn)備好待燒寫程序,這些程序本質(zhì)上也是數(shù)據(jù)。編譯生成的程序一般為HEX格式,里面包含程序數(shù)據(jù)、長度、地址、校驗等信息。實際燒寫只用到程序數(shù)據(jù)本身,其他信息如長度、地址、校驗等信息均不需要。去掉冗余信息后的程序數(shù)據(jù)為BIN格式的文件。HEX格式文件轉(zhuǎn)BIN格式文件是一步必不可少的環(huán)節(jié)。但可以選擇在上位機預(yù)先處理,還是在嵌入式設(shè)備中處理。
程序升級必須將待更新的程序數(shù)據(jù)傳輸?shù)角度胧皆O(shè)備中。傳輸?shù)奈锢韺佑写?、SPI、CAN、IIC、網(wǎng)絡(luò)等,協(xié)議層有CAN通訊協(xié)議、串口通訊協(xié)議、TCP/UPD通訊協(xié)議、TFTP通訊協(xié)議等。這些協(xié)議有些已帶有校驗和數(shù)據(jù)重發(fā)功能,有些沒有??赏ㄟ^定義通用的數(shù)據(jù)幀協(xié)議[3],從而確保這些數(shù)據(jù)的校驗和完整性,而不是依賴于原有的通訊協(xié)議。
程序升級必須將BIN格式的程序數(shù)據(jù)燒寫到指定存儲空間去。所以程序須內(nèi)嵌燒寫功能。程序數(shù)據(jù)的燒寫可以一次性燒寫,也可以分批次進行,相應(yīng)的燒寫程序可以一次性準(zhǔn)備好,也可以分批次準(zhǔn)備。
程序更新方式分為兩種。第一種是程序整體更新,即擦除,再寫入新的程序。就是擦除整個程序所占空間,再寫入新的程序數(shù)據(jù),較為簡單。但中途斷電無法啟動。第二種是將存儲空間上的程序分為兩段,第一段啟動程序功能為接收并更新第二段程序即用戶程序,其始終保持不變,中途掉電不會影響啟動。第二段程序為用戶程序?qū)崿F(xiàn)具體功能,可被擦除更新。本節(jié)著重分析分析第二種方式,即二級啟動及更新原理和更新模式。
1.4.1 基本原理
將程序分為兩部分:啟動程序和用戶程序部分[4-5]。啟動程序(Bootloader)是固定的,包含了數(shù)據(jù)接收、校驗、擦除、燒寫等功能。用戶程序則是實現(xiàn)嵌入式設(shè)備功能的代碼。如圖1所示。
圖1 二級啟動模式
嵌入式設(shè)備上電啟動后,開始運行啟動程序,到結(jié)束時跳轉(zhuǎn)到用戶程序,這兩段程序可以物理相鄰,也可以不相鄰。這兩段程序?qū)嶋H是分別編寫編譯生成,彼此獨立,只是通過跳轉(zhuǎn)語句進行關(guān)聯(lián)。
如果用戶程序中,不涉及中斷,可忽略。但一般嵌入式設(shè)備程序都會涉及中斷。在啟動代碼跳轉(zhuǎn)到用戶程序之前,將系統(tǒng)的中斷向量地址轉(zhuǎn)移到用戶程序中的中斷向量表[6-7],即NVIC2。否則用戶程序發(fā)生中斷后會從啟動代碼的中斷向量表NVIC1查找中斷地址,從而產(chǎn)生錯誤中斷響應(yīng)。
如圖1所示的緩沖(Buffer)是啟動程序中使用的緩沖空間,在運行用戶代碼時,可認(rèn)為沒有使用。
1.4.2 擦除/燒寫/標(biāo)志位
用戶程序更新涉及兩個基本功能:程序和數(shù)據(jù)空間的擦除和寫入。啟動代碼本身是固定不變的,但又需要判別當(dāng)前狀態(tài),所以一般會設(shè)一個的標(biāo)志位,如圖1中的標(biāo)志位FLAG。標(biāo)志位中含有多種狀態(tài):升級態(tài)、擦除態(tài)、燒寫態(tài)、用戶程序就緒態(tài)(有些包含多個,如用戶程序1就緒態(tài)、用戶程序2就緒態(tài)等)。
1.4.3 用戶程序策略
如嵌入式設(shè)備程序代碼過大或存儲空間較小,建議擦除原有用戶空間,再燒寫進新的用戶程序。如圖1所示,先擦除用戶程序空間,再燒寫入新的用戶程序。在升級過程中,一旦擦除之后,發(fā)生錯誤或掉電情況,嵌入式設(shè)備的基本功能將無法實現(xiàn)。但升級功能依然可用。
所以存儲空間足夠時,建議使用多用戶程序策略,如圖2所示。假設(shè)當(dāng)前使用用戶程序1,升級時擦除用戶程序2空間,再將新程序燒寫到用戶程序2空間,最后修改標(biāo)志位,即跳轉(zhuǎn)改到用戶程序2空間。
圖2 接用戶程序策略
這種方法是在燒寫入用戶程序2空間,并完成校驗后再修改標(biāo)志位。如果在升級過程中發(fā)生錯誤或掉電等意外情況,系統(tǒng)依然可以繼續(xù)運行用戶程序1。由此衍生,可以存儲多個用戶程序,只需更改標(biāo)志位,從而可以快速切換用戶程序。
第一種程序更新方式,程序不存在跳轉(zhuǎn)方式的問題。第二種更新方式啟動程序需要跳轉(zhuǎn)到用戶程序。根據(jù)標(biāo)志位跳轉(zhuǎn)到最新的用戶程序的首地址。
遠(yuǎn)程升級方案在上面五個環(huán)節(jié)中,有3個環(huán)節(jié)有多種實現(xiàn)策略,需要根據(jù)實際情況選擇合適的方式實現(xiàn)方式。
HEX文件轉(zhuǎn)換為BIN文件可選擇在上位機或嵌入式設(shè)備中實現(xiàn)[8]。由于上位機實現(xiàn)該功能更為容易、簡便。建議在上位機對HEX進行預(yù)處理,生成所需的BIN文件。
2.2.1 數(shù)據(jù)通訊方式
程序數(shù)據(jù)通過遠(yuǎn)程方式傳輸給嵌入式設(shè)備。常規(guī)模式過多關(guān)注物理層和協(xié)議層,如串口、SPI、網(wǎng)口、TCP、UPD、TFPT協(xié)議。對數(shù)據(jù)協(xié)議幀很少關(guān)注,定義時隨意性大、通用性差,不利于跨平臺使用。制定統(tǒng)一的協(xié)議幀,可以做到跨硬件跨平臺使用,即便單片機/DSP/ARM不能直接與外界交互,也可通過其他設(shè)備對協(xié)議幀進行轉(zhuǎn)發(fā),從而實現(xiàn)數(shù)據(jù)通訊,如圖3所示。
圖3 遠(yuǎn)程通訊模式
下面給出一個簡化版的通信數(shù)據(jù)幀[9]。
實際舉例,待燒寫程序為131 K字節(jié),則程序數(shù)據(jù)存儲在Body[512]中,一共需要后臺服務(wù)器向單片機/DSP/ARM發(fā)送262+1個分包,最后一個為程序校驗包,即總分包數(shù)BlockTotalNum為263。詳細(xì)說明不在這里展開。
通過通訊數(shù)據(jù)幀可以將程序數(shù)據(jù)分包發(fā)送給待升級的嵌入式設(shè)備,從而無需關(guān)注物理層和協(xié)議層是哪種方式。
2.2.2 程序數(shù)據(jù)接收策略
如果用戶程序較小或者緩沖空間很大,可以采用一次性接收待燒寫程序。接收完成后,經(jīng)過完整性校驗,再進行燒寫。如圖4所示。
圖4 整體接收程序策略
如果用戶程序較大,一次性無法全部緩沖存儲,可以采取每接收完一個分包就立刻進行燒寫的策略。如圖5所示,如果存儲空間足夠,建議使用整體接收的方式。
圖5 分包接收燒寫程序策略
燒寫程序根據(jù)不同的芯片有著固定的燒寫方式。
這里分為整體更新和二級啟動及更新模式。在1.4中已詳細(xì)敘述。這里需要注意以下兩點
2.4.1 啟動代碼準(zhǔn)備
啟動代碼正常編譯,并使用JTAG等常規(guī)方式燒寫進存儲空間。
2.4.2 用戶代碼準(zhǔn)備
因為用戶代碼燒寫到的是指定地址,所以在編譯時,必須設(shè)定到相同的地址空間上。編譯生成的HEX文件,可以通過PC程序轉(zhuǎn)換成BIN文件,并進行分包和加入校驗包。
僅僅在二級啟動模式下有用。
本節(jié)中將舉3個實際應(yīng)用范例,由于篇幅關(guān)系,僅涉及部分核心代碼。
這是一顆以8051為核的單片機升級方案[10-12],與外界通訊是通過SPI端口。程序數(shù)據(jù)準(zhǔn)備在上位機完成,程序數(shù)據(jù)傳輸通過數(shù)據(jù)協(xié)議幀方式,燒寫代碼內(nèi)嵌在程序中。更新模式采用二級啟動模式,不含多用戶程序。
在KEIL的內(nèi)存分配框中對啟動代碼和用戶代碼的進行空間分配:
第一條是關(guān)中斷,因為一旦發(fā)生中斷將會跳轉(zhuǎn)到用戶程序的中斷響應(yīng),從而發(fā)生不可知錯誤。第二條是燒寫。第三條跳轉(zhuǎn)到絕對地址。由于8051的中斷向量地址固定不可變,所以用戶程序必須通過二次跳轉(zhuǎn)的方式實現(xiàn)中斷。增加一個JUMP.ASM文件,下面是部分代碼:
其中0x03為外部中斷0地址,0x0B為定時器0溢出地址,當(dāng)發(fā)生外部中斷0時,跳轉(zhuǎn)到地址0x03,然后再跳轉(zhuǎn)到0x801003。即用戶程序發(fā)生中斷時,增加了一次中斷向量地址的跳轉(zhuǎn),從效果上看是和正常的中斷沒有區(qū)別。定時器0中斷和其他中斷地址依次類推。
這是 TI的 TMS320DM642 的升級方案[13,14]。與外界通訊是通過網(wǎng)絡(luò)口。該DSP芯片啟動后由系統(tǒng)自動將NOR FLASH上的1K字節(jié)搬移到SDRAM當(dāng)中,然后運行。通過這1K字節(jié)程序?qū)OR FLASH上的其余內(nèi)容搬移到SDRAM當(dāng)中。
該芯片使用較為復(fù)雜。程序數(shù)據(jù)在上位機使用TI的HEX6X軟件進行數(shù)據(jù)轉(zhuǎn)換。程序數(shù)據(jù)的傳輸通過網(wǎng)絡(luò)采用數(shù)據(jù)協(xié)議幀的方式傳輸?shù)紻SP的SDRAM當(dāng)中。程序的更新模式采用整體擦除,然后整體燒寫的模式。這種方式一旦發(fā)生錯誤或中途掉電,程序不可恢復(fù)。采用方式的部分代碼:
由于整個系統(tǒng)的NOR FLASH整體為4M字節(jié),而SDRAM空間較大,可直接更新整個NOR FLASH。該方案存在一定的風(fēng)險,但由于其主頻為600MHz,速度較快,實際使用中尚未發(fā)生錯誤。
這是ST的STM32F207VCT6的升級方案[15-20]。程序數(shù)據(jù)同樣在上位機處理完成。程序數(shù)據(jù)通過SPI采用數(shù)據(jù)協(xié)議幀方式進行傳輸。程序更新采用二級啟動模式,單用戶程序模式。在KEIL的內(nèi)存分配框中對啟動代碼和用戶代碼的進行空間分配:
本文歸納了單片機/DSP/ARM遠(yuǎn)程升級基本原理,針對程序數(shù)據(jù)準(zhǔn)備、程序數(shù)據(jù)傳輸、程序數(shù)據(jù)燒寫、程序更新方式、用戶程序跳轉(zhuǎn)方式提出了不同的實現(xiàn)方案,并詳細(xì)分析了這些方案的原理和優(yōu)缺點。各環(huán)節(jié)方案相對獨立,易于實現(xiàn)。在實際應(yīng)用中,根據(jù)需求選擇各環(huán)節(jié)的方案組合成最終遠(yuǎn)程方案。最后給出了實際項目中基于單片機、DSP、ARM3個范例,并列出了部分核心代碼。
單片機/DSP/ARM遠(yuǎn)程升級是嵌入式設(shè)備必不可少的功能。本文對遠(yuǎn)程升級開發(fā)具有很強的指導(dǎo)意義。