孫 瑞, 徐建國, 馬 偉, 楊玉柱
(上海采埃孚轉(zhuǎn)向系統(tǒng)有限公司, 上海 201821)
在某款車用網(wǎng)關(guān)控制器的開發(fā)過程中,為了方便實現(xiàn)網(wǎng)關(guān)控制器的實車調(diào)試和程序更新,需要設(shè)計出一種通過CAN總線即可刷寫應(yīng)用程序的軟件.CAN(Controller Area Network)總線是一種主流的車用現(xiàn)場總線,具備標準化的通信格式,其信號傳輸?shù)膶崟r性、可靠性和準確性等優(yōu)點使其獲得汽車行業(yè)內(nèi)的廣泛認可.因此,CAN總線成為本文設(shè)計BootLoader系統(tǒng)的首選通信介質(zhì).在CAN總線協(xié)議與S19文件協(xié)議的基礎(chǔ)上,本文又引入了一個自定義的通信協(xié)議,以實現(xiàn)BootLoader與上位機之間的命令和狀態(tài)傳遞.該BootLoader系統(tǒng)簡單、可靠,無需應(yīng)用程序本身做任何適應(yīng)性更改,因此同樣適用于以XET256為平臺的其他控制器開發(fā)項目.
Bootloader稱為系統(tǒng)的引導(dǎo)加載程序,是系統(tǒng)加電或復(fù)位后執(zhí)行的第一段代碼[1],其主要作用是實現(xiàn)應(yīng)用程序的更新以及引導(dǎo)應(yīng)用程序的執(zhí)行.基于這一基本思路,在設(shè)計BootLoader時首先要考慮的問題是BootLoader與應(yīng)用程序在Flash中應(yīng)如何劃分,以保證二者所占用的存儲空間不能相互沖突.其次,控制器上電后,應(yīng)該首先執(zhí)行BootLoader,由BootLoader決定是進行程序的更新還是進入應(yīng)用程序執(zhí)行.然后,在控制器上電后,BootLoader開始執(zhí)行時,應(yīng)以操作員即上位機的指令為判斷依據(jù),來控制程序執(zhí)行的方向.在應(yīng)用程序刷寫過程中,還應(yīng)對上位機的命令及命令執(zhí)行情況進行反饋,以使操作員明確應(yīng)用程序是否成功更新.最后,BootLoader應(yīng)能夠根據(jù)規(guī)定好的協(xié)議,將通過CAN總線接收到的應(yīng)用程序數(shù)據(jù)準確地寫入.
設(shè)計BootLoader時需充分考慮對ECU存儲器的分配[2],在飛思卡爾編譯器CodeWarrior中,程序和數(shù)據(jù)存儲空間的劃分工作是在prm文件中完成的.以關(guān)鍵字SEGMENTS和END為標志.Flash存儲空間的關(guān)鍵字為READ_ONLY.
XET256中P-Flash地址范圍為0x4000~0xFFFF[3].其中,0xFF0F~0xFFFF為中斷向量區(qū),0xFF00~0xFF0E為Flash配置區(qū),主要用于P-Flash寫保護等功能.剩下的地址范圍0x4000~0xFEFF開放給用戶,用于存儲用戶程序代碼.受限于16位尋址能力,P-Flash被分為非分頁區(qū)(unpagedFlash)和分頁區(qū)(paged Flash).非分頁區(qū)(0x4000~0x7FFF與0xC000~0xFFFF)可直接用16位地址尋址.而分頁區(qū)(0x8000~0xBFFF)則必須用24位地址尋址.
為了給網(wǎng)關(guān)控制器應(yīng)用程序提供更多的代碼空間,以及便于實現(xiàn)BootLoader寫保護等目的,將BootLoader程序安排在從0xFEFF開始往上數(shù)的一段區(qū)域,其大小可根據(jù)具體代碼量調(diào)整,本文將其定義為3.75K,即地址范圍為0xF000~0xFEFF.
在對P-Flash擦除與寫入操作的時候,不允許同時對其進行讀取,否則可能導(dǎo)致Flash的損壞[4].本著這一原則,對Flash的擦除、寫入以及CAN中斷信號的處理代碼,應(yīng)復(fù)制到RAM中運行.這一功能可通過關(guān)鍵字RELOCATE_TO實現(xiàn).因此,在劃分Flash的同時也應(yīng)對RAM進行劃分,以實現(xiàn)這一功能.定義RAM的關(guān)鍵字為READ_WRITE.P-Flash與RAM的實際劃分如圖1和圖2所示.
圖1 P-Flash劃分圖
圖2 RAM劃分圖
如前所述,非分頁區(qū)Flash的地址唯一,可直接采用16位邏輯地址進行尋址.但0x8000~0xBFFF這一分頁區(qū)共由14頁組成,具體尋址到哪一頁取決于PPAGE寄存器.其地址變?yōu)榱?位頁地址加16位具體地址,即24位地址.如PPAGE寄存器的默認值為0xFE,則邏輯地址0xFE_8000表示0xFE這一頁的0x8000地址.
由于存在以上地址表示方式的不同(16位與24位),在對Flash進行擦寫時,如果直接采用邏輯地址,不僅關(guān)系復(fù)雜,而且容易出錯.而采用全局地址,可使表示方式單一,容易尋址.所謂全局地址是由頁寄存器PPAGE的值以及邏輯地址按一定關(guān)系組成的24位地址.這種表示方式使得Flash存儲單元的地址線性且唯一,便于操作.邏輯地址轉(zhuǎn)換為全局地址的關(guān)系式為
GA=0x400000|((((dword)(PA))<<14)|
(LA&0x3FFF))
(1)
式中,LA表示邏輯地址,PA表示PPAGE寄存器值,GA表示全局地址.當邏輯地址位于0x4000~0x7FFF時,PA的值為0xFD;當邏輯地址位于0xC000~0xFFFF時,PA的值為0xFF;當邏輯地址位于分頁區(qū)時,PA的值取決于具體頁,默認值為0xFE.
采用全局地址后,F(xiàn)lash在全局地址表示方式下的劃分如圖3所示.由于劃分Flash時只需關(guān)注分界線,因此,在prm文件中,依然采用邏輯地址進行劃分.從圖3可以看出,XET256的256K Flash是由不連續(xù)的兩個Block(0/1)組成的,每一個Block為128K.
圖3 全局地址表示下的Flash劃分
飛思卡爾16位單片機在復(fù)位后總是從優(yōu)先級最高的中斷向量地址0xFFFE處取第一條執(zhí)行指令[4].因此,BootLoader可執(zhí)行代碼的首地址應(yīng)安排在此處,以保證上電后BootLoader的首先執(zhí)行.這可以通過在prm文件中定義VECTOR 0來實現(xiàn),即將VECTOR 0定義為BootLoader程序的入口地址.然而,網(wǎng)關(guān)應(yīng)用程序在編寫時也會對VECTOR 0進行定義,以實現(xiàn)在單片機上電后直接執(zhí)行應(yīng)用程序的目的.由于存在這一中斷資源沖突,因此,BootLoader在刷寫時需要對網(wǎng)關(guān)應(yīng)用程序的中斷向量表進行重新分配.
默認情況下,XET256的中斷向量表位于0xFF0F~0xFFFF區(qū)間[3].這一特性是由中斷向量基址寄存器IVBR在上電后總是默認為0xFF所確定的.一條可執(zhí)行的中斷向量地址是由基址(IVBR寄存器的值)加偏移組成的.如復(fù)位中斷向量地址0xFFFE,即表示IVBR的值為0xFF,該中斷向量的偏移為0xFE.在一款特定的單片機中,任一硬件中斷向量相對于基址的偏移總是確定的.因此,通過改變IVBR寄存器的值,即可實現(xiàn)中斷向量表的更改.本文設(shè)計的BootLoader在引導(dǎo)進入應(yīng)用程序之前將應(yīng)用程序中斷向量表基址IVBR更改為0xEF,即經(jīng)過BootLoader重新分配后,應(yīng)用程序中斷向量表位于0xEF0F~0xEFFF.在刷寫應(yīng)用程序時,若BootLoader檢測到地址為0xFF0F~0xFFFF的代碼數(shù)據(jù),則將其地址更改為0xEF0F~0xEFFF,然后在新的地址上將數(shù)據(jù)寫入.由于存在這一安排,應(yīng)用程序非中斷向量代碼的存儲不得位于0xEF0F以下,這也是本文設(shè)計的BootLoader對應(yīng)用程序的唯一要求.
在對P-Flash進行擦除與寫入的過程中,所使用的硬件資源CAN通道依然在進行正常工作,當其接收到有效數(shù)據(jù)后,即可使單片機自行進入中斷處理服務(wù).單片機將從所選CAN通道的中斷服務(wù)地址處讀取CAN中斷服務(wù)代碼的首地址.如前所述,P-Flash在擦除過程中不允許對其進行讀取,因此,這種由CAN通道中斷所導(dǎo)致的操作應(yīng)加以避免.本設(shè)計采取的解決方案是BootLoader進入刷寫程序后,在擦除與寫入P-Flash之前將中斷向量表更改至RAM中.本文將IVBR更改為0x3F,即在BootLoader執(zhí)行刷寫程序時,實際中斷向量表為0x3F00~0x3FF0.
為實現(xiàn)BootLoader與上位機之間的命令和狀態(tài)傳輸,本文在標準的CAN協(xié)議基礎(chǔ)上,定義了一套簡單的通信協(xié)議.該協(xié)議中所使用的命令和狀態(tài)均以報文ID表示,即每一個ID代表一個特定的命令或狀態(tài).根據(jù)本文所涉及項目的相關(guān)要求,刷寫過程中使用的報文ID不能與整車網(wǎng)絡(luò)中其他節(jié)點用到的ID相同,因此本協(xié)議報文ID的選擇范圍為0x500~0x5FF.具體選擇報文ID及協(xié)議見表1.
表1通信協(xié)議表
在系統(tǒng)上電后,BootLoader將初始化堆棧、配置系統(tǒng)時鐘,并初始化所選CAN通道.當CAN通道正常工作后,BootLoader將等待20ms,如果在這段時間內(nèi)接收到上位機進入刷寫程序的指令或檢測到應(yīng)用程序不存在,則執(zhí)行應(yīng)用程序更新操作;否則,跳轉(zhuǎn)至應(yīng)用程序執(zhí)行.如直接跳轉(zhuǎn)至應(yīng)用程序執(zhí)行,則應(yīng)首先配置中斷寄存器基址,然后,將單片機指針更改為應(yīng)用程序復(fù)位向量地址,本文設(shè)計為0xEFFE.采用這一策略無需應(yīng)用程序配合,但要求操作員如需更新應(yīng)用程序,則應(yīng)在系統(tǒng)上電前將上位機啟動,以保證BootLoader能接收到相應(yīng)指令.BootLoader工作流程如圖4所示.
圖4 BootLoader工作流程圖
若執(zhí)行應(yīng)用程序更新操作,首先應(yīng)配置P-Flash時鐘,使其工作頻率為用戶手冊推薦的0.8~1.05MHz[3],這可以通過設(shè)置FCLKDIV寄存器的值來實現(xiàn).P-Flash的時鐘源為外部晶振,本文所選的外部晶振頻率為16MHz,查用戶手冊將FCLKDIV寄存器的值設(shè)置為0x0F.然后,將P-Flash中定義好的BootLoader擦/寫/中斷處理代碼拷貝至RAM中劃分好的區(qū)間0x3D00~0x3EFF處.接著,將中斷向量表配置到RAM中.當所有BootLoader更新應(yīng)用程序所需的環(huán)境都準備好后,就可以對P-Flash進行擦除與寫入操作.應(yīng)用程序更新操作流程圖如圖5所示.
圖5 應(yīng)用程序更新流程圖
應(yīng)用程序擦除代碼存儲在P-Flash中,在執(zhí)行時拷貝到RAM中執(zhí)行.XET256支持將P-Flash以Sector(每個Sector的大小為1K)和Block為單位進行擦除.對于Block1(0x78_0000~0x79_FFFF)可按Block為單位整體擦除.而對于Block0應(yīng)只擦除屬于應(yīng)用程序的部分,即0x7E_0000~0x7F_EFFF的區(qū)間,此處應(yīng)以Sector為單位進行擦除.擦除過程如圖6所示,首先等待其它Flash命令執(zhí)行完畢,然后清除Flash狀態(tài)寄存器中的故障碼,之后即可通過配置Flash控制寄存器FCCOB的值來選擇擦除命令與擦除區(qū)域.
圖6 應(yīng)用程序擦除操作
Flash控制寄存器FCCOB由6個字組成,通過選擇寄存器FCCOBIX可分別對6個字進行配置[3].其中,F(xiàn)CCOB第1個字的高8位代表具體Flash命令,如0x09表示執(zhí)行按Block擦除命令;0x0A表示執(zhí)行按Sector擦除命令;0x06表示寫Flash命令.FCCOB第1個字的低8位代表全局地址的高8位.FCCOB第2個字表示全局地址的低16位.FCCOB的第3到第6個字則用于存放需要寫入的數(shù)據(jù),擦除操作時不需要,但執(zhí)行寫入操作時需要.Flash控制寄存器配置好后,即可通過將Flash狀態(tài)寄存器的最高位寫1來執(zhí)行FCCOB中存儲的命令和數(shù)據(jù).之后,利用Flash狀態(tài)寄存器來判斷操作是否成功執(zhí)行完畢.
BootLoader成功將P-Flash擦除后,即向上位機發(fā)送成功擦除信號,通知上位機發(fā)送新的應(yīng)用程序數(shù)據(jù).上位機傳輸給BootLoader的數(shù)據(jù)格式采用S19文件協(xié)議,而且每一個地址或數(shù)據(jù)等信息均以字符的形式發(fā)送.
4.4.1 S19協(xié)議解析
S19文件是飛思卡爾推薦使用的標準程序下載文件,該文件格式由記錄類型、記錄長度、存儲地址、代碼數(shù)據(jù)和校驗碼5個部分組成[5].S19文件的每一行總是以“S”開始,其后的一位數(shù)字表示該行記錄的類型.如S0表示該行記錄為說明性信息,非程序數(shù)據(jù);S1表示該行記錄為程序數(shù)據(jù)且地址為16位地址,S2則表示該行記錄為程序數(shù)據(jù)且地址為24位地址;S9表示該行為整個S19文件的結(jié)束行.由于本文在擦、寫時采用全局地址,所以經(jīng)式(1)轉(zhuǎn)化后的S19文件只包括S0、S2和S9.記錄類型之后的一個字節(jié)表示其后該行記錄所包含的字節(jié)長度.緊接著的3個字節(jié)表示目標地址,之后是寫入目標地址的數(shù)據(jù).最后一個字節(jié)為該行記錄的校驗碼,校驗碼加代表信息長度、目標地址、寫入目標地址數(shù)據(jù)的所有字節(jié)的和為0xFF.
BootLoader通過CAN中斷接收到ID為0x50F的S19數(shù)據(jù)幀后,會將數(shù)據(jù)依次存入指定緩存中,然后周期性地對緩存數(shù)據(jù)進行組織和解析.由于上位機發(fā)過來的數(shù)據(jù)全部為字符的形式,因此,首先應(yīng)將字符轉(zhuǎn)化為16進制數(shù),然后整理成以字節(jié)為單位的有效數(shù)據(jù).如在解析信息長度時,應(yīng)連續(xù)讀取兩個字符,將其分別轉(zhuǎn)化為16進制數(shù)后,第1個數(shù)左移4位加第2個數(shù),這樣即可整理為一個有效的字節(jié)數(shù)據(jù).
在對S19文件進行解析時,首先判斷接收到的第一個字節(jié)是否為'S'以及第二個字節(jié)是否為'0'、'2'或'9',如果不符合則舍棄該條信息.若符合則開始對信息長度、地址、數(shù)據(jù)和校驗碼的解析,然后按照S19協(xié)議對校驗碼進行校驗,如果校驗結(jié)果為有效則將目標地址、寫入目標地址的數(shù)據(jù)放到相應(yīng)的緩存中.至此,一條S19信息被成功解析.
4.4.2 P-Flash數(shù)據(jù)寫入
當一條有效的S19信息被接收并成功解析后,還應(yīng)對該信息做進一步判斷.如果接收的是S9或接收過程中有錯誤,則直接退出數(shù)據(jù)寫入程序;如果是S0,則予以忽略;如果是S2,則按照解析出的目標地址,將程序數(shù)據(jù)寫入.
在數(shù)據(jù)寫入之前,應(yīng)對目標地址進行判斷.若目標地址位于中斷向量區(qū),則首先按第3節(jié)所述對其進行更改,然后再執(zhí)行數(shù)據(jù)寫入程序;若目標地址不位于中斷向量區(qū),但超出了第2節(jié)所規(guī)定的應(yīng)用程序區(qū)域,則拒絕執(zhí)行寫入程序.
Codewarrior編譯器生成的S19文件連續(xù)地址之差為32的整數(shù)倍,即每一條S19信息涵蓋32個字節(jié)的P-Flash數(shù)據(jù)信息,即使轉(zhuǎn)化成全局地址后,這一規(guī)則依然不變.FCCOB寄存器中有4個字,即8個字節(jié)用于存放程序數(shù)據(jù).因此,每一條S19信息中的數(shù)據(jù)可以分4次寫入,每一次的寫入方法如4.3所述.
BootLoader系統(tǒng)中的上位機基于Labview開發(fā),其基本工作原理是:首先讀取S19文件,然后按行將S19文件中的十六進制數(shù)轉(zhuǎn)換為相應(yīng)的字符串數(shù)組,并補以行結(jié)束符.整合好的字符串數(shù)組會以8個字符為一組通過PEAK CAN工具轉(zhuǎn)成CAN信號發(fā)送給網(wǎng)關(guān)控制器(最后一次不足8個的字符串發(fā)送實際字符長度).
由于本文設(shè)計的BootLoader系統(tǒng)無需應(yīng)用程序做適應(yīng)性更改,因此,上位機必須在跳轉(zhuǎn)到應(yīng)用程序之前啟動.上位機啟動后即向網(wǎng)關(guān)控制器發(fā)送握手指令,若后者沒有反饋,上位機將連續(xù)10s發(fā)送該指令.這一策略要求操作員應(yīng)在啟動上位機后10s內(nèi)將網(wǎng)關(guān)控制器上電或復(fù)位.若BootLoader接收到握手指令,并成功進行反饋,上位機將退出握手環(huán)節(jié),并進入等待刷寫環(huán)節(jié).握手成功后,BootLoader將自行進入環(huán)境配置及擦除P-Flash過程,擦除成功后將向上位機發(fā)送擦除成功信號.上位機接收到該信號即退出等待,逐條發(fā)送S19文件.BootLoader接收并解析S19文件,寫入成功后向上位機發(fā)送寫入成功信號.若上位機在發(fā)送完最后一條S19信息后一段時間內(nèi)沒有接收到寫入成功信號,則默認為本次程序更新失敗.程序更新成功后,需操作員手動復(fù)位網(wǎng)關(guān)控制器,從而執(zhí)行新的應(yīng)用程序.整個操作過程及系統(tǒng)狀態(tài)均會在上位機中實時顯示.BootLoader系統(tǒng)上位機工作流程如圖7所示.
圖7 BootLoader系統(tǒng)上位機工作流程
本文設(shè)計的BootLoader系統(tǒng)幾乎無需應(yīng)用程序做任何適應(yīng)性更改,因此可直接在其他以XET256為平臺的產(chǎn)品上運行.試驗證明,該系統(tǒng)操作方便、實現(xiàn)簡單、運行可靠,能夠正確地實現(xiàn)網(wǎng)關(guān)應(yīng)用程序更新,從而大大方便了網(wǎng)關(guān)控制器的實車調(diào)試,加快了項目進度.
[1] 王伏,張忠能,杭勇.基于CAN總線的電控單元程序引導(dǎo)加載功能開發(fā)[J].微型電腦應(yīng)用,2011,27(2):30-32.
[2] 奚英澤,于健楠,徐鳳.基于飛思卡爾MPC5634M單片機的Bootloader設(shè)計[C]//中國汽車工程學會.2013中國汽車工程學會年會論文集.北京:中國學術(shù)期刊電子出版社,2013:566-569.
[3] Freescale.MC9S12XEP100RMV1(1.25)[M/OL].(2013-02)[2014-03-28]. http://www.freescale.com/files/microcontrollers/doc/data sheet/MC9S12XEP100RMV1.pdf.
[4] 羅峰,孫澤昌.汽車CAN總線系統(tǒng)原理、設(shè)計與應(yīng)用[M].北京:電子工業(yè)出版社,2010.
[5] 張夕杰,李清政,王喬.MPC5534單片機在線程序更新系統(tǒng)研制[J].國外電子測量技術(shù),2013(12):49-52.