譚文陽(yáng),李軍偉,朱青松
山東理工大學(xué) 交通與車(chē)輛工程學(xué)院,山東 淄博 255049
作為重型拖拉機(jī)控制的核心,重型拖拉機(jī)控制器控制策略直接決定重型拖拉機(jī)的性能和能量利用率,因此控制策略的升級(jí)維護(hù)技術(shù)成為當(dāng)前重型拖拉機(jī)控制器發(fā)展的關(guān)鍵。由于傳統(tǒng)的OSJTAG仿真工具對(duì)軟件進(jìn)行更新需要拆開(kāi)控制器殼體,對(duì)控制器程序進(jìn)行直接操作,存在更新過(guò)程繁瑣和程序泄露等問(wèn)題?;诳刂破骶钟蚓W(wǎng)絡(luò)(controller area network, CAN)的引導(dǎo)加載程序技術(shù)對(duì)應(yīng)用程序進(jìn)行更新升級(jí),可以避免拆卸控制器殼體等損壞硬件的操作,通過(guò)重型拖拉機(jī)自身的CAN網(wǎng)絡(luò)即可實(shí)現(xiàn)程序的更新,因此可以避免對(duì)程序的直接操作,提高安全性。
相對(duì)文獻(xiàn)[1]中的基于MPC5634M單片機(jī)的引導(dǎo)加載程序設(shè)計(jì),本文中充分利用MPC5744P的Flash支持同時(shí)讀寫(xiě)(read-while-write,RWW)的特點(diǎn),在下載程序時(shí)無(wú)需將引導(dǎo)加載程序移入隨機(jī)存取存儲(chǔ)器(random access memory,RAM),避免因下載程序時(shí)掉電而丟失引導(dǎo)加載程序的問(wèn)題,同時(shí)省去對(duì)電可擦可編程只讀存儲(chǔ)器(electrically erasable programmable read only memory,EEPROM)進(jìn)行模擬等繁瑣設(shè)計(jì),直接對(duì)Flash進(jìn)行操作,能夠解決文獻(xiàn)[1]掉電丟失引導(dǎo)加載程序的問(wèn)題。
在嵌入式系統(tǒng)內(nèi)核運(yùn)行之前,將引導(dǎo)加載程序存放在MPC5744P單片機(jī)的LOW Flash塊中,完成對(duì)MPC5744P單片機(jī)軟硬件的初始化,實(shí)現(xiàn)MPC5744P單片機(jī)用戶程序的啟動(dòng)與固件的更新[2-3]。MPC5744P單片機(jī)設(shè)計(jì)機(jī)制可分為2種模式,啟動(dòng)加載模式與下載模式。由于MPC5744P單片機(jī)啟動(dòng)加載模式需要將引導(dǎo)加載程序加載到RAM中運(yùn)行,為節(jié)約RAM資源,本文中對(duì)引導(dǎo)加載程序的設(shè)計(jì)機(jī)制采用下載模式。上位機(jī)刷寫(xiě)工具通過(guò)CAN總線向MPC5744P單片機(jī)發(fā)送更新應(yīng)用程序的控制命令,并實(shí)時(shí)反饋MPC5744P單片機(jī)的更新?tīng)顟B(tài)。MPC5744P單片機(jī)依據(jù)上位機(jī)通過(guò)CAN總線發(fā)送的命令,將應(yīng)用程序存儲(chǔ)入MPC5744P單片機(jī)的256 KiByte Flash中。程序刷寫(xiě)的基本原理如圖1所示。
圖1 上位機(jī)與BootLoader通信原理圖
通過(guò)對(duì)FlexCAN模塊進(jìn)行初始化配置與通信協(xié)議的制定,實(shí)現(xiàn)重型拖拉機(jī)控制器的引導(dǎo)加載程序與上位機(jī)的通信[4-5]。本文中MPC5744P控制器的CAN模塊使用的是8 MHz的時(shí)鐘,500 kbit/s的波特率。使用CAN0通道的消息緩存區(qū)0(message buffer 0,MB[0])作為發(fā)送數(shù)據(jù)緩存區(qū)給上位機(jī)發(fā)送代碼,設(shè)置其發(fā)送MB的身份標(biāo)識(shí)符(identity document,ID)為0x520。使用CAN0通道的MB[4]MB[8]MB[31]作為接收數(shù)據(jù)緩存區(qū)接收上位機(jī)的命令與S19文件,分別設(shè)置其MB只接收ID為0x521、0x550、0x555的報(bào)文。FlexCAN的初始化配置如圖2所示。
圖2 CAN模塊初始化配置
MPC5744P的2.5 MiB的Flash內(nèi)存劃分為4個(gè)16 KiByte的LOW Flash,2個(gè)32 KiByte的MID Flash,6個(gè)64 KiByte的HIGN Flash以及8個(gè)256 KiByte的Flash,作用分別是:存儲(chǔ)引導(dǎo)加載程序、存儲(chǔ)應(yīng)用程序的啟動(dòng)地址、存儲(chǔ)應(yīng)用程序。
Flash驅(qū)動(dòng)主要用于擦除與寫(xiě)入程序。MPC5744P在擦除Flash內(nèi)存數(shù)據(jù)時(shí),只支持以Flash塊為最小單位擦除;而在寫(xiě)入數(shù)據(jù)時(shí),一次最多只能寫(xiě)入4頁(yè)(1024 bits)Flash內(nèi)存數(shù)據(jù),超出的數(shù)據(jù)會(huì)被截取。本文中的引導(dǎo)加載程序存儲(chǔ)于LOW Flash中。對(duì)Flash的擦除與寫(xiě)入分別通過(guò)程序?qū)崿F(xiàn)。
以MPC5744P的一個(gè)Flash塊擦除操作為例,具體流程如圖3所示。對(duì)Flash進(jìn)行擦除操作需要通過(guò)C55FMC模塊下的LOCK寄存器解鎖對(duì)應(yīng)的Flash;SEL寄存器選擇要進(jìn)行擦除的Flash;MCR寄存器的ERS位由0變?yōu)?啟動(dòng)一個(gè)擦除序列,由1變?yōu)?結(jié)束一個(gè)擦除序列;寄存器MCR的EHV位使能高壓操作進(jìn)行Flash內(nèi)存的擦除;等待MCR的DONE位置1,則高壓擦除完成。
對(duì)MPC5744P的Flash寫(xiě)入過(guò)程如圖4所示。對(duì)Flash進(jìn)行寫(xiě)入操作同樣通過(guò)LOCK寄存器解鎖對(duì)應(yīng)的Flash,MCR寄存器的PGM位由0變?yōu)?,啟動(dòng)一個(gè)寫(xiě)入序列,由1變?yōu)?結(jié)束一個(gè)寫(xiě)入序列,然后為對(duì)應(yīng)地址寫(xiě)入數(shù)據(jù)。在此需注意MPC5744P的Flash只支持4 byte或8 byte對(duì)齊寫(xiě)入,并且只能使用一種方式,本文中采用4 byte對(duì)齊方式寫(xiě)入數(shù)據(jù);MCR寄存器的EHV位與DONE位與擦除時(shí)作用一致。
圖3 Flash模塊的擦除配置 圖4 Flash模塊的寫(xiě)入配置
由于MPC5744P在單芯片啟動(dòng)時(shí),會(huì)從低到高搜索8個(gè)帶有啟動(dòng)標(biāo)志位的Flash塊(Boot location 0~7),每個(gè)Boot location的第一個(gè)地址RCHW若存儲(chǔ)了BOOT_ID(0x5A),則此塊即為啟動(dòng)分區(qū),同時(shí)作為啟動(dòng)分區(qū)的RCHW偏移4個(gè)地址存儲(chǔ)的數(shù)據(jù)即為程序代碼的起始地址。中斷向量表依據(jù)此原理進(jìn)行重定位。通常工程建立時(shí)存儲(chǔ)BOOT_ID的RCHW默認(rèn)為0x00FA0000,本文中的BootLoader通過(guò)修改鏈接文件flash.ld的RCHW為0x00F98000來(lái)改變中斷向量表所處的Flash,同時(shí)確定整個(gè)程序代碼的運(yùn)行起始地址。程序復(fù)位后運(yùn)行流程如圖5所示。
圖5 程序復(fù)位后運(yùn)行流程
通過(guò)SECTIONS函數(shù)對(duì)Flash進(jìn)行具體劃分中斷向量表位置,部分代碼如下:
SECTIONS{
.intc_vector_table: ALIGN(4096)
{
KEEP(*(.intc_vector_table))
} > m_text
}
通過(guò)以下命令實(shí)現(xiàn)啟動(dòng)時(shí)重定位中斷向量表:
int32_t__attribute__((section(".cpu0_reset_vector")))RCHW2= (uint32_t)ENTRY_POINT。
通過(guò)上述程序?qū)崿F(xiàn)應(yīng)用程序與引導(dǎo)加載程序的中斷向量表在內(nèi)存中地址的設(shè)置。
S19文件的正確解析是程序下載成功的關(guān)鍵,S19文件的格式如表1所示。
表1 S19文件格式
表1中所述記錄類(lèi)型S0表示文件名等文件信息,存儲(chǔ)數(shù)據(jù)無(wú)需寫(xiě)入Flash內(nèi)存;記錄類(lèi)型S1、S2、S3表示存儲(chǔ)數(shù)據(jù)地址分別為2 byte、3 byte、4 byte;記錄類(lèi)型S4、S5、S6用來(lái)標(biāo)注S19文件中S1、S2、S3記錄類(lèi)型的數(shù)量,非文件必需,無(wú)實(shí)際作用;記錄類(lèi)型S7、S8、S9為S19文件結(jié)束的標(biāo)志[6-7]。
MPC5744P是32位微控制器,所以采用的記錄類(lèi)型為S3。S19文件的解析與驗(yàn)證(即程序的完整性校驗(yàn))過(guò)程如圖6所示。
運(yùn)行MPC5744P的一般程序時(shí),首先從默認(rèn)地址0x00FA0000中檢測(cè)到BOOT_ID標(biāo)志位,然后跳轉(zhuǎn)到主函數(shù)開(kāi)始運(yùn)行。運(yùn)行本文中設(shè)計(jì)的引導(dǎo)加載程序時(shí),首先從地址0x00F98000中檢測(cè)到BOOT_ID標(biāo)志位,然后跳轉(zhuǎn)到引導(dǎo)加載程序開(kāi)始運(yùn)行。整個(gè)程序的具體運(yùn)行過(guò)程見(jiàn)圖7。
圖6 S19文件解析與驗(yàn)證
圖7 BootLoader運(yùn)行流程
上位機(jī)的主要作用是通過(guò)某公司USBCAN自帶的二次開(kāi)發(fā)函數(shù)實(shí)現(xiàn)與引導(dǎo)加載程序之間的交互,從而實(shí)現(xiàn)程序的更新升級(jí)[8-9],因此對(duì)上位機(jī)的設(shè)計(jì)分為上位機(jī)界面設(shè)計(jì)和與控制器通信協(xié)議制定。
利用具有直觀可視化界面的Python外部工具PyQt5對(duì)上位機(jī)界面進(jìn)行設(shè)計(jì),隨后自動(dòng)生成代碼,將生成的界面代碼與CAN卡的庫(kù)函數(shù)在Python中鏈接來(lái)實(shí)現(xiàn)上位機(jī)界面的功能[10-11]。本文中用到的庫(kù)函數(shù)見(jiàn)表2。
表2 CAN卡的庫(kù)函數(shù)
除表2用到的接口庫(kù)函數(shù)外,同時(shí)用到接口庫(kù)函數(shù)的結(jié)構(gòu)體CAN_OBJ與INIT_CONFIG。CAN_OBJ結(jié)構(gòu)體表示幀的數(shù)據(jù)結(jié)構(gòu),被用來(lái)存儲(chǔ)發(fā)送與接收函數(shù)的幀信息;INIT_CONFIG結(jié)構(gòu)體對(duì)CAN進(jìn)行初始化配置。
為提高引導(dǎo)加載程序的安全性,防止被隨意更改,制定自定義通信協(xié)議,通過(guò)上位機(jī)與MPC5744P單片機(jī)的通信,實(shí)現(xiàn)上位機(jī)控制單片機(jī)運(yùn)行應(yīng)用程序或進(jìn)行引導(dǎo)加載程序功能的選擇以及擦除Flash數(shù)據(jù)并向Flash寫(xiě)入數(shù)據(jù)等功能[12-13]。上位機(jī)的報(bào)文ID分別為0x521、0x550、0x555,控制器發(fā)送報(bào)文的ID為0x520。本文中所用的幀類(lèi)型均為標(biāo)準(zhǔn)格式的數(shù)據(jù)幀,引導(dǎo)加載程序協(xié)議如表3所示。
ID為0x555的報(bào)文控制控制器是否進(jìn)入更新應(yīng)用程序模式,ID為0x550報(bào)文控制是否對(duì)控制器Flash進(jìn)行擦除與寫(xiě)入操作,ID為0x521的報(bào)文向控制器發(fā)送S19文件里應(yīng)用程序的數(shù)據(jù),ID為0x520的報(bào)文控制控制器應(yīng)答上位機(jī)是否已完成相應(yīng)操作[14-15]。
表3 BootLoader協(xié)議
上位機(jī)通過(guò)ID為0x555的的報(bào)文向控制器發(fā)送更新程序的數(shù)據(jù)命令2,控制器接收到上位機(jī)發(fā)送的更新程序命令后,通過(guò)ID為0x520的報(bào)文向上位機(jī)返回?cái)?shù)據(jù)2,表示控制器已進(jìn)入引導(dǎo)加載程序準(zhǔn)備更新程序??刂破鬟M(jìn)入引導(dǎo)加載程序之后,上位機(jī)通過(guò)ID為0x550的報(bào)文向控制器發(fā)送數(shù)據(jù)0xAA,控制器接收到此命令后,對(duì)Flash塊進(jìn)行擦除,等待擦除完成后,控制器通過(guò)ID為0x520的報(bào)文向上位機(jī)發(fā)送數(shù)據(jù)3,表示對(duì)Flash塊的擦除操作完成。擦除操作完成后,上位機(jī)通過(guò)ID為0x550的報(bào)文向控制器發(fā)送數(shù)據(jù)0xBB,控制器接收到此命令后,進(jìn)入等待上位機(jī)發(fā)送需寫(xiě)入的S19文件數(shù)據(jù)狀態(tài)。最后上位機(jī)通過(guò)ID為0x521的報(bào)文向控制器發(fā)送要寫(xiě)入Flash的數(shù)據(jù),控制器接收到此數(shù)據(jù)后,開(kāi)始向Flash寫(xiě)入,當(dāng)對(duì)Flash寫(xiě)入數(shù)據(jù)完成后,控制器通過(guò)ID為0x520的報(bào)文向上位機(jī)發(fā)送數(shù)據(jù)4,表示對(duì)Flash寫(xiě)入操作完成。
為驗(yàn)證設(shè)計(jì)的引導(dǎo)加載程序與上位機(jī)的在線升級(jí)功能,同時(shí)為更直觀觀測(cè)設(shè)計(jì)結(jié)果,通過(guò)下載小燈程序進(jìn)行驗(yàn)證。
上位機(jī)界面主要分為CAN卡的發(fā)送配置、運(yùn)行狀態(tài)顯示、程序下載3部分。發(fā)送配置界面通過(guò)“波特率”按鈕設(shè)置CAN通信的波特率,通過(guò)打開(kāi)“CAN卡”按鈕對(duì)CAN卡進(jìn)行調(diào)用與初始化配置,通過(guò)“復(fù)位CAN卡”按鈕對(duì)CAN卡進(jìn)行復(fù)位,通過(guò)“關(guān)閉CAN卡”按鈕斷開(kāi)CAN卡與上位機(jī)的連接。運(yùn)行狀態(tài)界面顯示CAN通信過(guò)程中程序運(yùn)行的具體狀態(tài),上位機(jī)CAN卡初始化界面如圖8所示。程序下載界面分為下載功能界面與CAN接收/發(fā)送數(shù)據(jù)界面。下載功能界面中,“進(jìn)入app”按鈕表示復(fù)位后MPC5744P單片機(jī)進(jìn)入應(yīng)用程序,“準(zhǔn)備更新”按鈕表示復(fù)位后MPC5744P單片機(jī)進(jìn)入引導(dǎo)加載程序,“擦除數(shù)據(jù)”按鈕表示對(duì)MPC5744P單片機(jī)Flash中的數(shù)據(jù)進(jìn)行擦除,“開(kāi)始更新”按鈕表示進(jìn)入程序刷寫(xiě),“加載程序”按鈕表示將S19文件上傳到上位機(jī),“CAN接收/發(fā)送數(shù)據(jù)”界面顯示具體的S19文件,程序更新完成界面如圖9所示。
圖8 上位機(jī)CAN卡初始化 圖9 程序更新完成界面
圖10 MPC5744P開(kāi)發(fā)板實(shí)測(cè)圖
MPC5744P開(kāi)發(fā)板實(shí)測(cè)圖如圖10所示。上位機(jī)通過(guò)USBCAN卡與MPC5744P單片機(jī)的通信對(duì)小燈程序下載后,圖中所示小燈皆亮,表示程序下載成功。
針對(duì)重型拖拉機(jī)控制器的引導(dǎo)加載程序以及對(duì)應(yīng)的上位機(jī)進(jìn)行了設(shè)計(jì)開(kāi)發(fā)。對(duì)涉及引導(dǎo)加載程序的FlexCAN通信模塊、Flash閃存模塊、S19文件解析、中斷向量表重映射進(jìn)行了配置,同時(shí)對(duì)上位機(jī)界面與上位機(jī)的CAN通信進(jìn)行設(shè)計(jì),通過(guò)小燈程序?qū)υO(shè)計(jì)開(kāi)發(fā)的引導(dǎo)加載程序和上位機(jī)軟件進(jìn)行測(cè)試驗(yàn)證。測(cè)試結(jié)果表明,所設(shè)計(jì)的引導(dǎo)加載程序與上位機(jī)能夠滿足對(duì)重型拖拉機(jī)控制器程序的更新與升級(jí)。