陳 峰,劉鵬飛,徐明陽,伍 能,邢宇鵬,謝 征
(中國電子科技集團公司第三十四研究所,廣西 桂林 541004)
STM32系列微控制器具備性能高、成本低、功耗低、兼備實時功能和數字信號處理等特點,使其成為嵌入式應用設計的首要選擇,以高集成度和開發簡單著稱的ARM Cortex-M0、M3、M4以及M7內核的控制器,已在消費電子、網絡應用、工業控制和安全產品等場景中被廣泛應用[1-5]。STM32F103系列是ST公司發布的基于ARM Cortex-M3 32位內核的微控制器芯片。其中STM32F103RCT6是增強型微控制器,高達72 MHz的工作主頻,是同類產品中性能高好的產品,片內Flash和RAM的容量分別為256 k和48 k,具有64個IO端口以及集成SPI、UART、ADC和TIMER等模塊,同時具備十分豐富實用的外設[1-3],可滿足一般工業設計和生產對微控制器經濟性和實用性需求,使其成為微控制器中的理想器件。
RS-485總線是一種串行總線推薦性標準(RS,rcommended standard),采用平衡驅動器與差分接收器的方式進行信號傳輸[5]。由于RS-485總線具有布線簡單、傳輸距離遠、支持節點多(32個)、傳輸線成本低以及抑制共模干擾能力強的特性,使得RS-485成為工業應用中數據傳輸的首選標準,被廣泛應用在汽車電子、電信設備局域網、航空電子、智能控制、環境監測等領域中[16-21]。然而當RS-485總線節點上的STM32設備需要進行軟件升級或軟件維護時,將設備一一拆裝,逐一采用編程器進行嵌入式軟件更新,將會十分耗費人力、物力和時間。更為致命的是,有些設備一旦集成完畢后,甚至不允許拆卸,就算將每臺設備的下載口都連接到設備外殼上,由于使用環境因素的制約,有時候人工已經無法觸及到設備,這將給設備的升級維護帶來極大的困難與挑戰。為了解決RS-485總線上設備固件更新困難的問題,本文提出基于RS-485總線,采用應用內編程IAP(in-application programming)的方式[6-12]對設備進行遠程固件更新的方法,為STM32控制器在線升級提供一個方便快捷、穩定可靠的解決方案。
RS-485串行總線允許一對雙絞線上一個發送器驅動多個負載設備,由于發送和接收共用同一組物理信道,在任何時刻只允許一臺設備處于發送狀態,其它設備必須在總線上信號已經發送完成后才能進行應答。在本系統中,PC端為主設備,即主機,經USB轉RS-485模塊后連接到485總線上。其余設備為從設備,從設備出廠時自帶有系統內部唯一的設備流水號,根據系統容量,流水號分別固化為1到N。主設備需要與從設備進行通信時,所有的從設備都接收到主設備發送的數據信息,由于通信協議上攜帶設備流水號信息,只有流水號正確的設備才能進行響應。基于485總線的系統構成如圖1所示。

圖1 系統構成示意圖
在基于RS-485總線的系統中,傳輸路徑上如果存在不連續阻抗或者出現阻抗不匹配的現象,極易引起信號傳輸過程中的電磁反射,反射的電磁場與原磁場疊加,將使傳輸信號出現畸變,極易導致通信過程出現誤碼。因此,需要在總線遠端線路上增加端接電阻,通常端接電阻的阻值為120 Ω,利用端接電阻來吸收噪聲并減少電磁反射,可以大幅度提高RS-485通信的可靠性[5]。
由于RS-485為半雙工通信方式,采用主-從結構方式進行通信時,總線通信受主機控制,從設備不能主動發送命令或數據,所有的通信都應由主機發起,各從設備之間也不能相互進行通信。這種通信方式限制了不能對系統中的設備進行統一集中升級。因此,在對系統中設備進行固件在線升級時,只能逐一對設備進行升級,且在升級過程中不能對其它設備進行操作,否則有可能會引起RS-485總線競爭,導致遠程固件更新不成功。
通常對STM32進行固件更新的方式有以下3種。
1)在電路內編程ICP(in-circuit programming):ICP是STM32電路調試時最為常用的,一般有兩種調試方式,分別是JTAG仿真調試和串行單線調試SWD。標準的JTAG協議接口需要4根信號線(TDO、TDI、TCK、TMS)和硬件復位RST信號,JTAG主要用于芯片內部測試;而SWD需要2根信號線,分別為SWCLK和SWDIO。由于SWD方式具備調試速度快、占用IO口少的特點,因此,在電路板調試時,通常利用MDK等編譯工具以及STM32 ST-LINK Utiliyt下載助手等工具,便可實現通過SWD協議接口下載器更新固件。
2)在系統內編程ISP(in-system programming):使用ISP方式更新固件不需要下載器,是使用STM32系統存儲器中自帶的自舉引導程序(bootloader)進行燒錄,可以通過STM32控微制器的接口,例如USB/UART/SPI/I2C/RS-485/CAN等,利用微控制器接口接收數據并將其內部的APROM、數據閃存(DataFlash)和用戶配置(Config)區域進行更新。無論是電路板上的空白控制器還是已經編程過的微控制器,都可以通過系統內編程的方式達到固件更新的目的。
3)在應用內編程IAP(in-application programming):通過通信接口實現在線固件更新,它不需要使用任何工具,僅僅是通過軟件的方法來更新FLASH中的數據,即利用用戶編寫的引導程序在運行過程中對User Flash的部分區域進行在線電擦除和再編程[9]。因此,IAP需要在程序設計時編寫兩個項目工程,第一個項目程序作為更新引導程序,執行對第二部分真正用戶代碼的更新或超時跳轉至用戶程序,以實現器件固件更新功能以及用戶程序的正常啟動[7-16]。
使用ICP升級固件時,需要將常用的下載工具,比如JLINK、ULINK、CMSIS-DAP、STLINK等通過下載線纜連接到目標器件的下載接口上,該方法是硬件調試階段較為合理的器件固件更新方法。當硬件調試結束封裝成模塊或設備后,后期如果需要再次更新固件時,就必須對設備進行拆裝或者將每一個設備的下載口引到設備機殼外部,這樣都不利于總線上設備的高效升級。ISP的優勢是不需要編程器就可以實現STM32的設計和開發,該技術通過器件出廠時自帶的升級引導程序,原則上支持遠程固件更新,但是在升級時需要對器件啟動模式進行選擇,不可避免地引入對硬件的物理連接操作。一般ISP的步驟為:電腦通過USB轉232線連接控制器的USART1,打開下載軟件,設置跳線或使用按鍵,使控制器的BOOT0為高電平,BOOT1為低電平,從而復位控制器使其進入bootloader模式,通過下載軟件更新程序,程序更新完畢后,再將BOOT0設置為低電平,確保器件重啟后從內部FLASH啟動程序。ISP模式的引導程序是器件出廠時自帶的,使用固定的硬件接口,用戶無法對其進行修改和重定義,這也在一定程度上限制了ISP方式的大量應用。而IAP遠程固件更新則完全不需要對器件進行任何額外的硬件連接操作,IAP技術從結構上將Flash存儲器劃分成兩個相互獨立的存儲區域,一個區域用來存放升級引導程序Bootloader,另外一個區域用來存放用戶應用程序。IAP升級引導程序是由用戶編寫的,可根據實際使用需求選擇不同的硬件外設以及自定義數據傳輸協議,相對ISP的方式,IAP方式在升級時,顯得更加靈活方便。IAP的一般實現過程為:設備上電后首先進入引導程序,引導程序在確認無固件更新需求后跳轉到用戶應用程序。當需要對總線上的某一臺設備進行固件更新時,可向該設備發送軟件重啟命令,使其再次進入升級引導程序,接收來自主機的待升級固件數據,并寫入控制器指定的Flash區域,待所有數據接收完畢并編程成功后跳轉到新程序入口地址,執行新寫入的程序,達到遠程固件更新的目的。
2.2.1 IAP實現技術原理
IAP的實現技術原理如圖2所示,其IAP實現過程如下。
1)STM32微控制器在復位后,首先從基地址0x0800 0000開始啟動,然后從內部閃存地址0x0800 0004取出復位中斷向量的地址,并跳轉到IAP復位中斷服務程序[2-4],在運行完復位中斷服務程序之后跳轉到IAP中main(void)函數。IAP的main(void)函數的主要功能是啟用時鐘、初始化串口以及解除存儲區域的寫保護等,當需要升級固件時按協議規范接收固件數據并寫到相應的FLASH區域;當不需要升級時跳轉至0x0800 0004+N+M處執行真正的用戶APP(User-application)程序;
2)IAP代碼執行結束之后,即新的用戶APP代碼已成功寫入STM32的FLASH中,此時,用戶程序的復位中斷向量表起始地址變為0x0800 0004+N+M,取出新程序的復位中斷向量表的地址,并跳轉執行新程序的復位中斷服務程序,隨后跳轉至用戶APP的main(void)函數[2-4];
3)在用戶APP的main(void)函數執行過程中,如果微控制器得到一個新的中斷請求,PC指針仍強制跳轉到地0x0800 0004中斷向量表處,而不是用戶程序的0x0800 0004+N+M中斷向量表處[2-4];
4)執行完步驟1)后,程序再根據設置的中斷向量表偏移量,跳轉到對應中斷源新的中斷服務程序中,在執行完新的中斷服務程序后,程序返回用戶程序main(void)函數繼續運行程序[2-4]。

圖2 IAP實現技術原理圖
2.2.2 Flash空間分配
將STM32啟動模式配置為用戶Flash啟動,控制器Flash區域劃分如圖3所示。根據IAP和用戶程序占用空間大小,將IAP升級引導程序存放于0x0800 0000起始的12 kB地址空間中,當系統上電后,先從0x0800 0000進入IAP升級引導程序,等待升級固件確認信號,在規定時間內設備接收到升級信號,則進入升級處理程序,否則將程序跳轉至用戶應用程序。升級引導程序和用戶程序Flash空間分配具體設置如下。
1)引導程序空間設置:在MDK編譯器的Target options-Target標簽下的IROMl的起始地址設置為0x0800 0000,空間大小配置為0x2FFF;
2)用戶程序空間設置:在MDK編譯器中將IROMl的起始地址設置為0x08003000,并將剩余空間分配為用戶程序區,最重要的是在用戶程序main()函數中添加中斷向量表地址偏移量:NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x3000),或者在system_stm32f10x.c文件下重新定義中斷向量表偏移量:#define VECT_TAB_OFFSET 0x3000,以確保用戶程序部分從0x8003000開始啟動,不會與IAP程序空間造成沖突。

圖3 Flash區域劃分示意圖
2.2.3 數據傳輸協議設計
在數據傳輸時使用自定義通信協議,以提高固件更新過程中的抗誤碼性能。傳輸協議見表1和表2。其中,上位機到設備端通信協議中,第1、2字節為幀頭,第3、4字節為待傳輸數據包總長度,第5、6字節為當前傳輸幀序號,第7字節為設備流水號,第8字節為命令字,用命令字定義所需要執行的具體操作,第9到N字節為所攜帶的數據,傳輸升級固件數據時,數據段固定長度為256字節,其它類型數據長度根據實際需求確定,以避免不必要的開銷。然后是校驗位,采用和校驗的方式,將第3到N字節數據進行和校驗,最后兩個字節為幀尾。設備到上位機通信協議與上位機到設備通信協議基本一致,不同之處在于第9字節表示命令執行結果標識,用0x00表示命令執行失敗,0xFF表示命令執行成功。

表1 上位機到設備通信協議

表2 設備到上位機通信協議
固件更新時主機向待升級設備發送一幀數據,等待設備返回信息或返回信息超時。設備根據幀頭、幀尾以及校驗位判斷當前幀是否接收成功,并將執行結果上報主機。如果當前幀接收正確,主機將發送下一幀數據,否則將當前數據幀重新發送,當同一數據幀發送次數大于5時,終止發送,此時判斷設備或通信出現故障。當固件更新過程中出現異常情況時,用戶程序區域有可能已遭受破壞,此時將無法正常啟動用戶程序。但是,由于升級過程中不會對引導程序部分區域進行操作,因此可通過斷電重啟設備的形式,對設備再次進行更新升級即可。
2.2.4 上位機軟件設計
Visual C++6.0在可視化編程和數據管理方面功能十分強大,它以類和事件驅動為核心,具有程序框架自動生成、代碼編寫和界面設計集成交互操作的優點,非常適合于嵌入式軟件人員進行上位機軟件的編程[18-22]。因此上位機控制程序采用VC++6.0設計,利用Microsoft公司提供的簡化Windows下串行通信編程的ActiveX控件,各個控件的觸發轉換為相應的協議數據處理,實現串口通信功能。通信接口具體配置為:波特率:9 600,校驗位:無,數據位:8位,停止位:1位。上位機控制軟件主要實現的功能包括通信串口號配置、設備流水號設置、確認更新、下載或上傳固件、啟動用戶程序、軟件重啟、發送文件、執行用戶程序以及一些升級過程中的關鍵輔助信息提示。上位機程序操作界面如圖4所示,程序界面簡潔直觀,指引性強,易于操作,即便是對軟件、硬件一點都不熟悉的人員,都能通過該界面輕易地實現設備的遠程固件更新。

圖4 上位機程序操作界面
2.2.5 生成目標下載固件
MDK編譯器將嵌入式程序代碼經編譯后一般生成AXF格式文件,經配置編譯選項后,也可以生成HEX和BIN格式文件。AXF文件是編譯器默認生成的目標代碼文件,它不僅包含了有效代碼數據,而且還包含了全部調試信息,通常在MDK進行在線調試時使用該文件。一般情況下,AXF格式文件并不適合用來當作待升級固件文件。而HEX和BIN文件都是由AXF格式文件生成的,屬于AXF文件的簡化版本,HEX格式文件的數據內容如圖5(a)所示。HEX文件使用十六進制符號表示的數據記錄,其數據具體定義見表3。以圖5(a)第二行為例,表明該行數據長度為0x10字節(N=0x10),地址偏移量為0x3000,數據類型為0x00,表示該數據為普通數據,從0xD0到0x08的16個字節為數據內容,即需要寫到0x8003000起始地址的具體數據值,最后一個字節是校驗和,用來檢驗數據的準確性。

表3 HEX文件數據定義
由于HEX格式文件在數據上增加了額外的開銷,數據量較多、文件所占空間通常較大,而BIN文件是最小可運行的文件,其包含了最直接的代碼映像,BIN格式文件數據內容如圖5(b)所示。從第一行可以看出,其第一個數據字節是0xD0,第十六個字節為0x08,剛好與HEX文件中第二行的數據部分完全一致。因此,固件程序文件選擇BIN文件,以盡量減少升級過程中傳輸的數據量,提高升級效率。由AXF到BIN文件轉換需要在MDK編譯器上添加類似如下命令:fromelf--bin-o".in_file@L.bin" "#L"。值得注意的是,固件選用BIN格式文件時,由于BIN格式文件不攜帶地址信息,燒寫數據時,必須從設置好的地址偏移量開始燒錄,否則將會導致升級后的程序無法正常運行。

圖5 HEX和BIN格式文件構成
2.2.6 固件更新詳細流程
STM32遠程固件更新詳細流程如圖6所示。在點對點通信模式下,設備上電后初始化系統,首先進入IAP升級引導程序,向主機發送開機提示操作信息并檢測串口輸入,等待主機發送確認升級固件字符“Y”。如果在3秒時間內主機沒有返回執行信息或返回的信息不是字符“Y”,則執行超時操作,自動切換到用戶程序運行。在規定的時間內一旦接收到確認升級字符,程序跳轉到固件更新主菜單,提示下一步操作選項,可選擇固件更新、固件上傳或切換到用戶程序。

圖6 IAP固件更新流程圖
若主機回復“1”,選擇固件更新,則設備端按照通信協議按幀接收固件數據,對數據進行校驗,并將接收成功與否信息返回主機。當某一數據幀接收失敗或檢驗失敗時,重傳該幀,重傳次數不大于5次。由于所使用STM32的Flash每一頁的大小為2 k,因此每校驗完2 k的數據,便將該數據按頁寫入對應的Flash地址空間。當所有的數據接收完畢后從設備回復主機接收成功信息,否則回復主機接收失敗。
若主機回復“2”,選擇固件上傳,則將0x0800 3000開始的數據讀出,并按照上位機到設備的通信協議上傳數據,以獲取當前設備內部的程序備份。
若主機回復“3”,選擇切換到用戶程序,設備跳轉至0x0800 3000處執行用戶應用程序軟件,系統將正常啟動設備。
在RS-485總線模式下,需要對設備進行固件更新時,首先發送指令使待升級設備軟件重啟,然后微控制器強制從復位中斷向量0x0800 0004處進入IAP程序,提示主機執行下一步操作。由于在通信協議中包含了設備流水號信息,因此只有被選擇固件更新的設備才正常響應主機的命令,并與主機建立通信連接,再利用點對點的通信模式實現固件更新。
IAP遠程更新RS-485總線上STM32設備固件的具體操作步驟和方法如下。
1)固件更新前準備工作:從電腦上打開上位機軟件,檢查確認當前電腦與設備通信所使用的串口號,在上位機軟件的串口配置中選擇正確的串口號,并打開該串口。此時,上位機軟件將經電腦通過USB轉RS-485總線與設備建立物理通道連接關系,固件更新準備工作就緒;
2)選擇待升級設備:當總線上的設備需要升級固件時,上位機軟件首先選擇該設備對應的流水號,例如需要升級5號設備的固件,將設備流水號“5”寫入串口配置里的流水號空白框中,選擇軟件重啟,將重啟5號設備;
3)5號設備重啟后,首先進入IAP升級引導程序,設備初始化完成后向上位機發送升級主菜單提示信息,如圖7(a)所示,為防止誤升級,設備返回升級主菜單中包括了該設備的SN碼,流水號等信息,并提示是否需要對該設備進行升級。在核對設備的流水號信息無誤后,在規定時間內點擊“確認更新:Y”按鍵進行確認升級操作;
4)設備接收到確認升級的回復后,將返回下載菜單操作提示信息,如圖7(b)所示。提示本次操作是固件更新、固件上傳還是啟動用戶程序。根據下載提示信息,此時應選擇“1、固件更新”選項,等待發送固件數據;
5)在文件選擇選項中添加待更新固件.BIN文件所在目錄,然后選擇發送文件,上位機將按照已定義的傳輸協議將固件數據分包下發,并在接收到正確接收回復后發送下一數據包,控制軟件在信息提示框中打印數據包發送及接收的狀態信息,同時通過進度條顯示固件更新的實時進度情況。固件更新過程如圖7(c)所示。待固件數據全部更新完成后,設備發送接收成功通知,并再次返回下載菜單,此時可以選擇“執行用戶程序”或斷電、軟件重啟設備,設備將按照新固件運行用戶程序,至此固件更新完畢。

圖7 遠程固件更新操作過程示意圖
由上述遠程固件更新操作流程可知,通過IAP遠程固件更新技術,利用編寫的上位機控制軟件,對RS-485總線上設備遠程升級的過程操作簡單、方便快捷,僅僅需要幾個簡單的人機交互過程就可以實現在線設備的固件更新,不但省去了拆裝設備、接插線纜等操作所帶來的麻煩,而且提高了設備升級維護的效率。經長期驗證考核表明,使用該遠程固件更新方案,包文傳輸出錯幾率極低,固件升級成功可靠性高,取得了良好的實用效果。
本文介紹了RS-485總線及STM32控制器在應用中編程的技術原理和技術特點,設計了STM32控制器固件在線更新的技術方案,編寫了遠程固件更新上位機控制軟件,解析了編譯器生成的程序文件具體數據形式,確定了待更新固件的格式,采用自定義串口傳輸通信協議,確保了數據傳輸過程中的有效性,實現了STM32微控制器的遠程固件更新和維護。實踐應用表明,通過VC++編寫的上位機控制軟件,結合自定義串口通信協議實現的IAP遠程固件更新,固件更新過程操作簡單便捷,程序運行穩定可靠,解決了RS-485總線上STM32設備固件更新困難的問題,具有極為廣泛的應用前景。