胡權,張宏寬,周伯濤,樓勇亮,舒信陽
數源科技股份有限公司,浙江 杭州,310012
公共交通智能化是當前的大趨勢,安裝于村鎮道路旁的城鄉公交站牌顯示終端能實時顯示公交車到離站信息,到站距離,能極大地方便老百姓的公交出行。傳統的升級方式通過預留的升級接口,通過切換BOOT模式使用串口或者JLINK接口來進行升級。城鄉公交站牌安裝點位偏遠、分散,要實現設計缺陷修補、功能改進或性能提升等需求,需要到現場拆卸設備,增加了維護成本[1]。
本設計在利用城鄉公交站牌顯示終端現有的數據鏈路的基礎之上,通過協議的擴展,實現遠程升級固件。提高了嵌入式設備的可維護性,并通過多服務器協同和嚴格的權限管理機制,提升了升級過程中的安全性,通過CRC加密算法和斷點續傳機制,保證了升級文件的可靠性[2-3]。
本文的升級系統由業務服務器、站牌顯示終端和升級服務器三部分組成。業務服務器通過與站牌顯示終端的網絡連接,實現車輛到站信息的發布;升級服務器在業務服務器發起升級請求后,響應站牌顯示終端的升級請求,實現升級數據的下發。站牌顯示終端通過4G網絡登錄業務服務器,接收業務服務器下發的數據。系統整體框架圖如圖1所示。

圖1 系統整體框圖
城鄉公交站牌顯示終端由微控制器(MCU GD32F103RB)、4G無線模塊(移遠EC20)、數碼管顯示驅動單元、實時時鐘、供電單元等組成,主要實現上報數據和接收服務器下發的車輛到離站信息等功能。終端功能框架圖如圖2所示。

圖2 終端功能框圖
遠程升級功能是利用城鄉公交站牌顯示終端本身具有的網絡連接特性,通過網絡協議的接口,實現對站臺顯示終端的固件程序的更新:即更新微控制器MCU內部的程序,以達到改進和提升的目的。
GD32F330 MCU是兆易創新公司推出的基于Cortex?-M4內核的微控制器[3][4],是國產自主品牌的32位MCU,集成外設單元豐富、性能強勁,成本低廉,是替換STM32系列MCU的首選。本文選擇GD32F330RB作為站牌顯示終端的主控MCU。
微處理器的編程方法通常有兩種:通過串口或者JTAG等接口進行編程的在系統編程(In System Programming,ISP)模式、在應用程序控制下的在應用編程(In Application Programming,IAP)模式[6]。本設計采用的預先將Bootloader程序+應用程序通過ISP方式下載到終端作為出廠程序。出廠后通過IAP模式對程序進行升級。IAP是用戶自己的程序在運行過程中對User Flash的部分區域進行燒寫。本系統設計兩個程序[7]:Bootloader(引導加載程序)和App(應用程序)。Bootloader程序不執行應用的功能操作,只負責在開機啟動時對系統升級數據進行更新,并跳轉到對應的App程序。App程序為用戶功能代碼,執行用戶功能操作,同時接收服務器的升級請求,將升級代碼數據保存到特定的FLASH位置[8][9]。
本系統中使用的芯片GD32F330RB的FLASH存儲器大小是128K,此空間被劃分為三大塊,分別用于運行Bootloader程序,App程序1,App程序2,其中0x801E000-0x801f000這4K空間用來存儲升級相關的環境變量,包括升級標志、數據長度,CRC32校驗后的校驗碼。FLASH空間劃分如圖3所示。

圖3 FLASH 存儲器空間分配
Bootloader程序是本方案的核心,需要完成升級文件檢測、程序校驗、固件更新以及程序跳轉等功能。需要極高的穩定性,在遇到突發情況導致的異常后,能夠重新實現App重刷,保證設備能夠穩定運行。本方案的Bootloader運行流程如圖4所示。

圖4 BootLoader 程序流程圖
Bootloader程序運行的主要步驟如下。
①在圖4所示流程中初始化GD32F330RB微處理器上電/復位后,從地址0x08000000開始運行Bootloader程序。
②Bootloader完成MCU的初始化,然后從0x801E000地址讀取環境變量。
③根據環境變量中的升級標志位來判斷是否要進入程序升級模式。
④如不需要升級,讀出需要跳轉的程序入口地址,執行程序跳轉操作,跳轉到0x08002000(App1程序區)處開始運行應用App;如需要升級,進入升級流程,進行App代碼的更新。
⑤在升級流程中,首先讀取環境變量中的待升級程序的長度和CRC校驗碼,并計算App2程序區地址中的存儲的程序的CRC32的校驗碼,與環境變量中的校驗碼進行比對。
⑥校驗碼一致的話進入FLASH操作流程,根據需要對FLASH扇區進行擦除,然后從App2對應的位置讀取程序數據寫入App1對應的位置;校驗碼不一致的話,放棄升級。
⑦升級完成或者升級失敗均需要清除升級標志位,然后軟復位MCU。
與服務器通信,需要遵循一定的通信協議,才能正確的進行升級[10]。當前采用的連接為TCP長連接,大端模式的網絡字節序,數據包格式定義如表1所示。

表1 數據包格式定義
命令標志定義如表2所示。

表2 命令標志定義
升級數據端元定義如表3所示。

表3 升級數據端元定義
為了降低遠程傳輸數據出現的誤碼率,把升級固件分成小包進行傳輸。固件數據包的分包長度設置為256個字節,分包序號表示當前傳輸的數據包是第幾包,當出現傳輸錯誤,幀數據包校驗不正確時,會返回錯誤接收的數據包給服務器,服務器根據分包序號,重新發送此分包的數據包。終端正確接收了當前的分包,給服務器返回成功的應答信號,服務器發送下一個分包,直到固件數據發送完成[11]。
App程序是實現終端功能的軟件。本終端主要實現的功能是驗證登錄業務服務器和接收服務器下發的車輛到離站信息,并在終端的LED上顯示公交車到站距離。
將App2區的(0x0801E000)開始的一個扇區用來存儲升級程序的環境變量,主要包括程序是否需要升級的標志信息,程序的長度和校驗碼。Bootloader運行后首先讀取0x801E000位置處的環境變量,判斷程序是否需要升級。如果程序需要升級,就需要根據環境變量中存儲的程序長度和校驗碼對App2區的程序進行CRC校驗,判斷校驗碼是否與環境變量中的校驗碼一致,若不一致,則清除環境變量的升級標志,跳轉到App1執行,若一致,則擦除App1程序區,將App2程序區的數據拷貝到App1程序區. 拷貝完成以后,清除環境變量的升級標志,跳轉到App1執行。具體的流程圖如圖5所示。
固件升級的安全關系到整個系統的安全,因為固件將徹底的替換掉終端正在運行的程序。因此需要從幾個方面來保證新的固件程序在下發升級以后,不會造成系統的大面積崩潰。
①需要保證新版本的固件程序經過了嚴格的測試才能上傳到服務器中。
②要保證新版本的固件程序擁有再次升級的功能,這樣在出現bug或者錯誤以后,可以迅速進行升級補救。
③分批次進行升級,保證升級后的設備運行穩定,無故障,再擴大升級規模。
④固件程序升級過程中,實行Bin文件加密校驗,保證升級固件的完整性。
⑤提升服務器的安全等級,防范內部或者外部的惡意攻擊。
終端開機后主動連接業務服務器,根據JT808協議,完成終端設備的注冊、登錄,并根據業務服務器下發的到站信息數據,在本地LED上實現車輛信息的顯示。如果需要對新版本的固件進行升級,則開啟升級流程,流程圖如圖5所示。

圖5 系統升級流程圖
①上傳經過測試的BIN文件到業務服務器,業務服務器經過身份認證和密碼驗證,確認上傳的文件合法,并將BIN文件同步到升級服務器。
②在業務服務器的終端升級管理頁面選擇需要升級的終端設備,下發升級命令,根據待升級終端的數量來進行身份認證。在大于5臺待升級設備時,需要請求更高的系統權限。
③業務服務器給終端發送升級命令,包括升級服務器的IP和端口號。
④終端主動斷開與業務服務器的網絡連接,根據下發的升級服務器IP和端口號,連接升級服務器,連接過程中會發送自己的終端ID和當前版本給升級服務器。
⑤升級服務器確認終端的版本與待升級的版本都正確無誤后,發送新版本固件程序的固件程序大小,CRC校驗碼等信息給終端,在收到終端的確認信息后,開始分包發送固件信息給終端。
⑥終端根據協議,對分包數據進行校驗,校驗無誤后,寫入FLASH中對應的存儲區域。每接收完一幀數據,向升級服務器請求下一段數據。若是校驗數據出錯或者是網絡中斷,將會重復請求未接收完成的數據,實現斷點續傳。
⑦在終端接收到最后一幀數據并寫入FLASH之后,將根據最開始接收到的程序大小和CRC校驗碼對整個寫入FLASH的程序文件進行校驗。在校驗無誤后,置位環境變量中升級標志。
⑧斷開與升級服務器的網絡連接,軟復位MCU。復位后執行Bootloader里的程序更新操作,程序更新后,跳轉到App1程序運行。
⑨終端連接業務服務器,在注冊登錄過程中上報自己的終端ID和版本信息。并根據業務服務器下發的命令實現基本功能。此時在業務服務器上將顯示當前終端的版本信息。
本項目已在城鄉公交站牌上進行了驗證測試,首批50個城鄉公交站牌,穩定運行了6個月。在下發升級測試后,每個站臺都在5分鐘之內完成了程序的升級。期間更新了多次版本,站牌能穩定在線運行。
業務服務器在線狀態如圖7所示。

圖7 業務服務器在線狀態
本文在滿足基礎的業務功能需求的基礎上,保證終端設備安全運行,固件程序安全完整,升級流程權限化管理,升級過程安全可控,設計了本升級方案。通過對升級管理的權限化管理,從服務器端保證升級過程的安全。對Flash進行合理分區,通過CRC校驗保證更新的App程序的完整。對升級服務器的IP地址隱藏,從源頭上防止了網絡攻擊的影響。該方案已在實際應用中得到了驗證,安全穩定運行了較長時間,對其他相似的遠程升級設計有一定的參考價值。