姜曉道,趙紫君
(華東光電集成器件研究所,安徽蚌埠,233000)
在產品開發過程中,對微處理器的調試通常使用專用的仿真調試工具,如ARM系列芯片通常使用J-Link,DSP芯片使用XDS工具,這都需要將調試工具通過線纜連接到產品單板上,通過JTAG接口對微處理器進行仿真和程序下載[1]。此種調試方法在開發階段非常適合于軟件工程師調試產品,然而當軟硬件定型且產品大批量生產之后,這種程序更新方法就顯得效率低下,每次產品升級都需要維保人員現場更新程序,會導致企業維護成本增加。另外,一個企業的產品往往多種多樣,特別是目前芯片壟斷的大背景下,各個廠家都在尋求國產化替代方案,不同產品應用的微處理器可能多種多樣。針對上述產品開發背景,本文提出了一種新型的在線升級方案,基于在線應用編程技術原理,設計一個獨立的引導加載軟件,可利用產品的現有通信端口,對產品的軟件程序進行更新。此方案不僅能夠實現程序代碼的在線更新,還能做到在不同型號微處理器之間進行快捷移植,實現跨平臺應用。
IAP(In Application Programming)即在線應用編程,指的是用戶自己設計的程序在運行過程中可實現對芯片應用程序部分的Flash區域的擦除和燒寫[2]。在后續維護升級時,尤其是產品發布后,IAP可復用現有的通信端口對產品的應用程序進行更新,實現產品軟件版本的升級。因為IAP僅僅使用產品的一組通信接口,所以IAP從技術理論上可實現產品的不拆封調試和遠程調試。
在一款芯片中應用IAP技術中可以實現程序A對程序B的在線更新,意味著芯片存儲程序的Flash至少需要映射為兩個存儲單元[3],分別存儲程序A和B。程序A命名為引導加載(Bootloader)軟件,程序B命名為應用程序(Application)軟件。Bootloader軟件主要實現的功能:
(1)判斷程序執行在線升級功能還是跳轉應用程序執行;(2)通過某種通信方式(USB、CAN、UART、SPI、MODBUS等)接收上位機發送的數據;(3)擦除“應用程序”區的Flash并將接收到的數據寫入“應用程序”區Flash;(4)從引導加載軟件跳轉到應用程序處并執行。
Bootloader軟件必須在出廠前通過JTAG或ISP等方式燒寫到芯片中,并且每臺產品的bootloader軟件僅需在出廠時燒寫一次即可,后續應用程序則可以由Bootloader軟件進行燒寫和更新。
一個完整的產品bootloader功能需要包含的軟件有三部分:bootloader軟件、PC上位機軟件和應用程序軟件。Bootloader軟件和應用程序軟件使用C語言編程,非常方便移植和后續升級;PC上位機軟件采用當前主流的C#語言編程,實現指令下發和通信數據幀的顯示。
本次Bootloader軟件設計背景是基于STM32F407芯片的電機控制器,產品默認配置啟動方式為從內部Flash啟動,產品本身設有的RS232接口,Bootloader軟件可復用RS232端口實現在線升級功能。
對于bootloader軟件,要求上電后立即進入boot區域執行,即系統上電復位后,bootloader軟件從地址為0x8000000處執行,因此Flash起始地址需設置為0x0800000。根據對bootloader軟件的規劃和對應用程序大小的分析評估,應用程序規模不超過400K字節大小,所以bootloader軟件所占用flash大小設置為16K字節,即flash地址從0x8000000處開始,前16k字節存儲bootloader軟件,其余496K字節全部作為應用程序存儲使用,如圖1所示。

圖1 Flash內部區域劃分示意圖
STM32F407芯片編程使用的工具為Keil,Flash區域劃分方法如下:
(1)keil軟件“魔術棒工具”菜單下“Target”頁面中起始地址設置為0x8000000,大小設置為0x3E80。
(2)修改工程文件中的SCT文件,將SCT文件中起始地址和程序大小設置為0x0800000和0x3E80。
Bootloader在線燒錄系統包含上位機控制端軟件和嵌入式終端設備兩部分,上位機控制軟件主要功能是將編譯器編譯完成的應用程序燒寫文件進行處理打包,然后發送至嵌入式設備,嵌入式設備接收后更新應用程序區的Flash,Flash更新完成后,嵌入式設備給上位機發送結束幀命令,并將寫入Flash的數據校驗碼返回給上位機,上位機收到校驗碼并校驗無誤后,結束與嵌入式設備的通信[4]。上位機軟件運行流程如圖2所示。

圖2 上位機軟件運行流程示意圖
要實現在線加載功能,最關鍵部分為bootloader軟件的引導加載設計。對引導加載軟件的功能進行分析,將引導加載軟件整個執行過程分為三大狀態:升級態、跳轉態和空閑態。三種狀態的轉換條件如圖3所示。

圖3 Bootloader軟件狀態遷移圖
其中“空閑態”為系統上電時的狀態,此時bootl oader軟件處于待命狀態,接收上位機的指令。“升級態”主要完成對應用程序區flash擦除和燒寫任務,并重新讀取應用程序區Flash數據,計算出校驗值。“跳轉態”需要完成任務是完成bootloader到應用程序軟件的跳轉。通過對bootloader軟件功能的分析,由升級態到空閑態,跳轉態到空閑態,跳轉態到升級態三種狀態轉換不適應bootloader軟件。最終只保留空閑態轉升級態,空閑態轉跳轉態,升級態轉跳轉態三種狀態轉換。三種狀態轉換的條件如下:
條件①:(1)上位機軟件與Bootloader軟件握手成功;(2)Bootloader 軟件接收到正確的升級命令。
條件②:(1)Bootloader軟件接收到的幀校驗與從應用程序Flash中讀取到的數據計算出的校驗碼一致;(2)Bootloader軟件接收到上位機發送的幀結束命令。
條件③:Bootloader軟件運行后,五秒內沒有收到上位機發送的握手指令。
STM32F407內部劃分為兩個區域,如圖4所示。

圖4 在線燒錄功能系統中斷向量表
STM32的Flash的兩個存儲區分別存儲兩個獨立的程序,同時也包含兩個中斷向量表。程序從起始地址0x08000000處開始運行,運行至地址0x08000004處時取此地址的復位中斷向量,然后跳轉到對應的中斷服務函數中,中斷服務函數運行結束后,跳轉到bootloader軟件的main函數中執行。當Bootloader軟件對應用程序區Flash的擦除和燒寫任務執行完成后,跳轉到應用程序區的復位中斷向量(應用程序的起始地址)處執行,從復位中斷向量中取出新程序的復位中斷向量地址,然后跳轉到新程序的中斷服務函數開始執行,執行完中斷服務函數后跳轉到應用程序區的main函數中執行。
由于STM32芯片硬件的設計,在main函數執行過程中,若CPU得到一個中斷請求,系統的PC指針仍然會跳轉至地址為0x08000004的中斷向量表處,而非應用程序中新的中斷向量表處。因此應用程序中所有的中斷向量地址都需要根據Flash區域的劃分而相應的調整,本系統中應用程序中斷向量表的偏移地址為bootloader軟件占用的Flash大小,即應用程序中斷向量表偏移量需設置為0x3E80。在工程文件中全局搜索:
SCB->VTOR=FLASH_BASE|VECT_TAB_OFFSET
“VECT_TAB_OFFSET”宏定義中定義的是系統的中斷偏移量,將其設置為0x3E80即可完成應用程序中斷向量偏移量的設置。
為了實現bootloader軟件在不同平臺之間的通用性,從通信協議上制定一套完整的與上位機主機的交互協議[5]。上位機向bootloader發送數據幀的協議格式如表1所示。

表1 bootloader軟件接收協議格式
其中,數據類型Type有3種指令格式格式,如表2所示。

表2 數據類型(Type)格式定義
Bootloader解析上位機指令幀后,返回給上位機應答幀格式如表3所示。

表3 bootloader軟件通信發送協議格式
上位機與bootloader之間的通信協議嚴格按照上述協議格式要求執行,不區分通信方式。
根據對bootloader軟件需求的分析,軟件主要需要實現的模塊功能有:
(1)RS232通信;(2)Flash讀寫;(3)Flash絕對地址跳轉。
上述功能模塊采用前后臺設計框架即可實現所有功能,因此無需使用實時操作系統,故bootloader軟件采用前后臺設計框架,即主函數循環執行為后臺,中斷服務函數為前臺。bootloader軟件設計原則為分層架構,即單向逐層調用,針對接口編程。從上到下分為3層,如圖5所示。

圖5 軟件架構分層示意圖
硬件驅動層:包括MCU片內資源驅動代碼與外部各類IC的底層驅動代碼,MCU片內驅動代碼與IC驅動代碼最好也能各自保持獨立。向上提供API接口。
模塊功能層:隔離頂層與底層,實現與提供頂層所需的API接口。
業務邏輯層:具體業務邏輯代碼,也可以說是應用層。
2.6.1 RS232通信
Bootloader軟件與嵌入式設備采用RS232通信,通信收發和解析為前臺中斷收發,后臺循環解析的方式,中斷將上位機軟件下發的數據幀全部接收,在主循環中尋找軟件通信幀中幀頭字節,幀頭字節確認后,按照字節尋址解析數據內容。待所有的數據幀解析完成后,存放于數據緩存數組中等待Flash讀寫使用。
Flash讀寫模塊按照數據幀中的flash地址將數據寫入flash后,需要對寫入的Flash數據進行校驗,然后按照bootloader軟件通信發送協議將寫入flash的結果進行回傳。等待上位機所有的數據幀都下發完成后,bootloader軟件將寫入flash地址的所有數據進行總校驗,并將校驗結果回傳至上位機軟件。若bootloader軟件的校驗和與上位機軟件下發的校驗和一致,bootloader自動執行跳轉函數,跳轉至應用軟件區域執行。若bootloader對flash的總校驗和與app下發的總校驗和不一致,則bootloader軟件將校驗異常結果回傳,提示操作者應用軟件更新失敗,操作者可重新推送應用軟件進行更新。
2.6.2 Flash讀寫
根據bootloader軟件需求分析,STM32的Flash讀寫功能主要包含flash塊擦除、讀指定地址長度數據功能。因此調用ST官方庫函數即可實現Flash讀寫的全部功能。
2.6.3 跳轉函數實現
Bootloader軟件對應用程序區Flash擦除和燒寫完成并且校驗無誤之后,即執行Flash跳轉,從bootloader區跳轉至應用程序區執行,跳轉函數設計思路如下:
(1)檢查棧頂地址是否合法;(2)初始化棧頂指針;(3)跳轉到指定地址執行。
跳轉函數代碼實現如下:
void PhyIAP_Loadapp(u32 ulAppAddr)
{
if(((*(vu32*) ulAppAddr)&0x2FFE0000)==0x20000000)
{
vJumpApp =(vIapFunc)*(vu32*)(ulAppAddr +4);
_MSP(*(vu32*) ulAppAddr);
vJumpApp();
}
}
將Bootloader軟件通過J-Link燒寫到電機控制器中,電機控制器通過USB-232轉換器連接電腦,設置上位機波特率為115200,上位機加載應用程序的燒錄文件并校驗無誤后自動開始燒寫。應用軟件燒錄文件為bin文件,大小為482K字節,通過理論計算,每幀傳輸數據個數為16字節,共需約30125幀字節傳輸整個燒錄文件,每幀數據結合幀頭幀尾等指令字后,結合波特率計算,理論燒寫時間約為59s。實際測試,bootloader加載482K字節的燒寫文件實際花費時間為62s,符合設計要求。
基于IAP技術的通用嵌入式系統在線升級軟件,可在復雜工況條件下對設備產品進行維護升級,其操作僅需一臺電腦就可實現,大大提高了產品維保升級的效率,同時軟件設計時兼顧的可移植性,可在不同產品平臺進行功能移植,也降低了企業開發成本。