(蘇州大學 計算機科學與技術學院,江蘇 蘇州 215006)
隨著人工智能的進一步發展,數據的價值變得彌足珍貴。萬物互聯的時代即將來臨,物聯網正在引發第四次工業革命,各種物聯網創新應用也在不斷涌現[1]。嵌入式設備作為物聯網技術的重要物理載體,其功能的穩定性和適應性面臨著巨大挑戰,隨之也帶來了頻繁的程序更新需求。
傳統的程序更新操作是通過基于JTAG協議的調試器完成的。JTAG(聯合測試工作組)協議是IEEE(電氣和電子工程師協會)于1990年對1149.1-1990號文檔標準化得到的國際標準測試協議,主要用于芯片內部測試和程序調試[2]。該方法可以很好地提供程序燒錄和調試功能,但是有如下缺點:① 需要有調試器支持,價格昂貴;② 傳輸距離有限;③ 更新過程不可控,若燒錄的程序存在問題,設備可能直接死機。
為避免這些缺點,目前主要是利用MCU的Flash存儲器在線編程功能[3],采用在BootLoader程序中增加數據通信驅動,并實現數據接收和燒錄的功能。BootLoader程序為MCU上電之后運行的一小段程序,可由編程人員自行編寫。BootLoader程序中的數據通信方式主要有兩種:有線通信和無線通信,無線通信由于脫離了線的束縛,可以做到傳輸距離更遠和密封性更好,但是,由于無線通信存在抗干擾能力弱、信息出錯概率大、易遭受攔截和篡改、安全性差和信息傳輸可能需要付費等缺點,故選擇了有線通信作為研究對象。有線通信方式包括:串口通信、SPI通信、I2C通信、CAN通信等。幾乎所有的MCU都提供串口通信功能,而且通信速度、容錯性、安全性都很好,在搭配了RS485或RS232之后,還可以實現遠距離傳輸。因此,本文提出了一種基于串行通信技術的嵌入式終端程序更新技術。
提出并實現了一套基于串口通信的遠程更新系統,可大大延長更新終端程序的限制距離,而且無需購買專門的調試器。串口更新系統的整體框架主要包括3個部分:終端(UE)、信息郵局(MPO)和上位機管理(HCM),它們的對應關系如圖1所示。

圖1 串口更新系統框架
本系統的硬件部分為基于KL36芯片自行設計的開發板。KL36芯片為恩智浦公司開發的一款ARM Cortex-M0+內核的微控制器,主頻可達48 MHz[4]。軟件部分包括終端程序的BootLoader程序和User程序,以及上位機的串口更新程序HCM。
圖1中,User程序為用戶程序,設備為用戶提供的所有功能均在該程序中實現。因此,對用戶來說,終端程序更新即為User程序更新。BootLoader程序中包含終端設備的基礎硬件驅動,它通過串口接收上位機管理HCM程序發送來的更新數據,并使用Flash存儲器在線編程技術覆蓋原有的User程序,從而完成串口更新操作。
BootLoader程序為固化在Flash中,是不容更改的程序,向User程序提供最底層、最直接的硬件配置和控制接口,并提供更新User程序的功能。User程序為嵌入式終端的功能程序,負責實現嵌入式終端所需的功能。在存儲上,BootLoader和User通過劃分存儲區域,實現共存。終端的Flash和RAM存儲映像如圖2所示。

圖2 終端Flash和RAM存儲映像
MCU上電之后至執行main函數的流程為:在MCU上電之后,芯片內部機制將把Flash中0x00000000~0x00000003地址的4個字節內容賦給內核寄存器SP(堆棧指針),然后把Flash中0x00000004~0x00000007地址的4個字節內容賦給內核寄存器PC(程序計數器)。Flash中0x00000004~0x00000007地址中一般存儲啟動函數的地址,具體內容查詢芯片的啟動文件,本系統中的啟動文件為“startup_MKL36Z4.S”。至此,PC寄存器中的內容為啟動函數地址,因此,MCU會執行啟動函數。啟動函數中一般將執行如下操作:① 根據設置開關看門狗;② 初始化系統時鐘;③ 開啟GPIO(通用輸入輸出)端口時鐘門;④ 將Flash中的初始化數據(一般存儲在data段)拷貝至RAM中;⑤ 清零未初始化的bss段;⑥ 跳轉到main函數或_START函數(_START函數為系統函數,會自動跳轉到main函數)。至此,MCU啟動完成,并進入了main函數[5]。
由圖2可知,MCU上電之后默認執行的程序為BootLoader程序,該程序的執行流程如圖3所示。
BootLoader程序首先進行初始化操作,之后將會判斷當前Flash中是否已經燒錄了User程序。User程序與BootLoader程序在物理上是分開的,BootLoader程序很難判斷User程序是否存在并且完整。但是,經過研究發現,可以通過判斷User程序的MSP指針(該指針位于程序起始地址的第4~7個字節)是否正確來判斷是否有User程序。
若存在User程序,則需要判斷User程序是否需要更新。判斷是否需要進行程序更新的方法有很多種,如:① 文獻[6]和文獻[7]提出了重啟時等待更新命令一段時間的方法,該方法需要手動重啟,且每次上電均需要等待一段時間,既不方便操作,也大大增加了開機時間;② 文獻[8]提出了通過讀取引腳狀態決定是否需要程序更新的方法,該方法需要在更新前設置好引腳狀態,不方便應用;③ 文獻[9]提出了基于CAN總線的程序升級方法,但CAN總線功能僅部分終端支持,不具有普適性。

圖3 BootLoader程序執行流程圖
基于對以前文獻等資料的總結和實踐經驗,提出了基于RAM在熱復位時數據不丟失特點實現的在線串口更新方法。由圖2可知,0x1FFF_F800~0x1FFF_F80B是一段既不屬于BootLoader程序又不屬于User程序的RAM。因此,在熱復位時,該段數據可以保存。當終端UE接收到上位機管理程序HCM更新命令之后,將更新命令寫入該段RAM并重啟,在重啟的時候只需要判斷該段RAM中的數據是否為更新命令即可知道是否需要更新程序。
至此,BootLoader程序完成了串口更新所需要的功能。下面將闡述技術的實現方案:終端的外設驅動都已經包含在BootLoader程序的工程中,因此,在燒錄BootLoader程序之后,這些驅動將會被存儲在終端的Flash中。為了在User程序中可以使用燒錄在Flash中的驅動程序,需要在BootLoader程序中將這些驅動的接口(即入口函數)存儲在Flash的指定區域中。User程序將從Flash中的該區域將這些驅動的接口讀出并轉化為函數指針,然后User程序即可通過函數指針使用固化在Flash中的驅動。
上電之后,在BootLoader程序處理完相應操作后將會跳轉至User程序。跳轉方法為:將當前MSP指針更改為User程序的MSP指針,同時將User程序第4~7字節的數據作為函數指針并調用,該操作將使得MCU進入User程序的復位函數中。User程序的執行流程如圖4所示。

圖4 User程序的執行流程
本系統實現了無需手動重啟的嵌入式終端串口更新功能。該功能是在串口中斷中實現的,串口中斷的服務例程位于BootLoader程序中,通過將中斷向量表拷貝至RAM的指定位置,使得User程序中觸發串口中斷時依然能夠進入BootLoader程序區的中斷服務例程,從而觸發更新操作。
同時,利用函數指針,本系統將終端基礎硬件資源的驅動存儲在BootLoader程序區中,并對外提供簡單的調用方法,達到了降低User程序編程難度和防止驅動被惡意修改的目的。
在完成終端程序的編碼之后,通過編譯系統,可以將程序編譯生成HEX文件。程序的燒錄過程即為解析HEX文件的含義,并將指定的數據寫入到終端設備的指定Flash中。這一過程需要由計算機程序完成,即本系統中的上位機管理HCM程序。
HCM程序將HEX文件進行解析,并按照與BootLoader程序約定好的數據幀協議進行組幀,然后將數據逐幀發送至BootLoader程序,由BootLoader程序完成更新User程序的操作。HCM程序主要的執行流程如圖5所示。
HEX文件是可以燒寫到單片機中,被單片機執行的一種文件格式。HEX文件以行為單位,每行為一條HEX記錄,每條記錄以冒號開始,共包含6段數據,如表1所示[10]。
由于通信過程的復雜性,使得數據通信過程中有一定概率造成數據的丟失、錯位和錯誤等情況。數據通信協議是為保證通信雙方能夠進行有效且可靠的數據通信而制定的一系列約定[11]。本系統采用固定位置的通信協議,即固定位置的數據具有固定的意義。

圖5 上位機程序的執行流程

字段長度/B內容開始標記1字符“:”數據長度1數據區字節數偏移量2數據區中數據應存儲的空間地址,記錄類型為數據記錄時有效記錄類型100:數據記錄;01:文件結束記錄;02:擴展段地址;03:開始段地址;04:擴展線性地址;05:鏈接開始地址數據區n取決于記錄類型校驗和1除開始標記和校驗和之外的所有字段的所有字節之和的補碼
為了保證協議的可復用性,本系統將通信協議分為兩部分:通用數據幀協議和更新數據幀協議。通用數據幀協議如表2所示。

表2 通用數據幀協議
本協議用于實現上位機管理程序HCM與終端UE之間的數據通信,為了防止數據在傳輸過程中出現錯誤導致誤操作,在協議中增加了CRC校驗(循環冗余校驗)來保證數據的完整性。CRC是一種多用于同步通信方式中的差錯檢出方式。在這種方式中,將所傳數據序列看成為高次多項式G(x),將此多項式用預先規定的生成多項式P(x)去除,再將其余數碼附加在所傳數據的尾部一并傳送。在接收方,用同樣的生成多項式去除,若除得的結果余數值為零,則說明接收到的數據是正確的[12]。
當command為4時,發送的有效數據為更新數據,其幀協議如表3所示。

表3 更新數據幀協議
更新數據是通過通用數據幀協議進行通信的,即更新數據幀的全部內容為通用數據中的有效數據。
將所設計的串口更新系統應用在KL36硬件平臺上,并進行性能評測。本次評測的主要目的是檢測所設計系統的可靠性、穩定性和更新速度。為了方便快捷地檢測本系統,編寫了一套自動燒錄1000次的上位機程序,程序界面如圖6所示。
上位機管理程序HCM主要有4個功能區,具體功能區的含義如表4所示。

表4 功能區功能表
基于該測試程序做了兩項測試:可靠性測試和更新速度測試,具體如下。
(1) 可靠性測試。取3個終端設備(命名為A,B,C)。其中,A放置于室內環境中,B放置于潮濕的環境中,C放置于電磁干擾嚴重且周圍有大功率電器的環境中。分別使用本測試程序和JTAG調試器將User程序燒錄至設備。使用的User程序的HEX文件大小為57 KB,被上位機管理程序HCM切割為53幀。記錄燒錄的成功次數、失敗次數和成功率。測試結果如表5所示。

表5 可靠性測試結果

圖6 串口更新系統測試程序
由表5可知,本系統的可靠性要優于JTAG調試器。本系統在3個終端設備上燒錄1000次,未出現任何失敗,而使用JTAG燒錄1000次會有燒錄失敗的情況。由此說明,本系統具有極高的可靠性,這得益于本系統設計的合理性以及多種防錯機制的結合。
(2) 更新速度測試。為了評測本系統的更新速度性能,使用JTAG調試器和本系統分別將同一User程序(與可靠性測試使用相同的User程序)燒錄至同一終端設備,并記錄燒錄使用的時間。測試結果如表6所示。

表6 更新速度測試結果
由表6可知,JTAG的更新速度要優于本系統,這說明JTAG調試器在速度性能上存在一定優勢。但是,本系統的更新耗時在可承受范圍之內,而且,本系統具有如下優勢:① 省去額外購買硬件的開銷;② 傳輸距離更遠,可實現遠程更新;③ 更新過程可控,能保證程序的穩定性和可靠性;④ 硬件驅動固化在BootLoader程序中,減少了User程序的代碼量。因此,速度的犧牲是值得的。
為了解決使用JTAG調試器燒錄程序所存在的弊端,設計并實現了一套基于串口通信的程序更新系統。該系統在物理結構上將終端程序分為BootLoader和User。BootLoader固化在Flash中,不對外提供源代碼,User實現用戶需要的功能并對外提供源代碼。BootLoader提供了通過串口更新User的功能,并集成了終端設備基礎硬件資源的驅動,使得用戶可以直接通過接口進行調用,而不用知道其源代碼和實現過程。這既保證了串口更新的可靠性,又保證了基礎硬件資源的驅動不會被惡意修改。本系統已經在本實驗室的PLC遠程監控系統項目中得到了成功應用,目前,該項目運行良好,更新系統工作正常。