羅 博,仇 傲
(中海油田服務股份有限公司,河北三河 065201)
一般情況下,MC9S12X 系列單片機進行代碼升級需使用BDM 仿真器,如果電路板在汽車或者其他工業設備里,就需要拆卸設備,拆出電路板,操作繁瑣,耗時較多。在石油隨鉆儀器、航空航天、兵器等電路系統中,電路工作環境惡劣,震動劇烈,為增強抗震動沖擊及絕緣性能,電路板需要灌封膠[1-5],如果使用BDM 仿真器更新程序,選擇去除封膠直接下載程序,則很容易損傷電路板,選擇在接口引出程序下載線則會浪費寶貴的接口。如果可以通過原有通信總線完成程序升級,則可節約時間,簡化操作,降低成本。
Code Warrior 是一款集成開發平臺,可用于MC9S12X 系列芯片的工程開發,具有實際應用開發所需的IDE、編譯器、鏈接器、調試器等[6]。PE(Processor Expert)是一款革命性的編程工具,可與CW開發平臺相結合,作為其內部菜單實用,使用時只需要圖形化添加需要的模塊即可生成對應代碼。PE的選項式初始化操作簡單、快捷、方便,對于不同的飛思卡爾單片機,只要是相同的模塊,PE的初始化配置屬性就基本相同。PE 還可以自動生成中斷向量表,自動聲明中斷服務函數[7-9]。使用PE 編寫飛思卡爾系列嵌入式芯片程序,開發時間短,效率高,不易出錯。對于PE 開發的工程,如果可以用Bootloader在線升級程序,則將大大減少開發和維護時間。
Bootloader 固化在芯片中,是上電后首先運行的程序,其主要功能是在電路系統初始化后,從ROM、Flash 等非易失存儲器上加載用戶應用程序(APP)代碼,然后引導APP 運行[10-13],使電路系統正常工作。
Bootloader的開發,首先需要對單片機的存儲空間進行合理的分配。把Flash的程序存儲空間分為Bootloader 區域以及APP 區域。APP 區域是用戶應用程序代碼存放的區域。Bootloader 固化在相應的Flash 區域中,不能修改,通過BMD 仿真器下載后可一直使用,但是APP 區域可以重復由Bootloader 修改更新。Bootloader 區域存放的代碼控制存放APP 代碼的區域。上電后,Bootloader 與上位機建立通信成功后,通過串口、CAN 等通信方式接收APP 代碼,將其存放在相應的Flash 區域,完成修改后可以跳出Bootloader,執行APP 區域的代碼,完成更新程序。
文中方案使用MC9S12X 單片機的SCI 模塊進行串口通信,選擇RS-485 總線作為通信方式,RS-485總線采用半雙工工作方式,可進行多節點、遠距離通信,抗干擾能力強,在工業中使用廣泛。SCI 模塊連接到RS485 數據收發芯片來進行串口通信,芯片選擇TI 公司的SN65HVD11Q,最大速率為10 Mbps,最高溫度為125 ℃[14],可滿足石油、汽車等行業要求。
有多種方式決定上電時先進入Bootloader 還是APP。一般根據MC9S12X 系列單片機的PP0 引腳狀態決定,如果PP0引腳接地,則上電后進入Bootloader;若PP0 引腳為高電平,則上電時進入APP[15]。
文中方案選擇PP0 引腳接地,電路圖如圖1 所示。剛上電時進入Bootloader 狀態,在一定時間內,如果收到在線升級命令,則繼續停留在Bootloader,等待上位機發送APP 代碼,接收完成后對APP 代碼進行修改,如果超過此時間,未收到在線升級命令,則進入APP,正常工作。

圖1 PP0引腳連接
Bootloader 簡要工作流程如圖2 所示。

圖2 Bootloader簡要工作流程
由于上電后PP0 引腳為0,因此首先進入Bootloader,完成初始化;然后,在較短時間內決定繼續停留在Bootloader 狀態還是進入用戶應用程序,時間選擇為3 s。判斷依據為存儲在EEPROM 區域的數據B_flag,如果上電后第三秒時B_flag 為0,則跳轉執行用戶應用程序;如果B_flag 為1,則停留在Bootloader 狀態,等待接收其他命令。MCU 收到命令后,判斷命令是否合法,不合法則繼續等待,合法則執行相應命令。在上電后3 s 內,上位機可以通過RS-485 總線向MCU 發送命令,改變B_flag的值。如果收到擦除APP 命令,則擦除存儲App的Flash 區域,并向上位機發送擦除成功命令,上位機收到命令后,發送s19文件,Bootloader 接收s19 文件完畢后,進行校驗,如果正確,則將代碼寫入對應的Flash 區域,寫入成功后,向上位機發送更新代碼成功消息,上位機收到消息后,如果發送進入App 命令,則跳轉進入APP,否則繼續停留在Bootloader 狀態,等待接收其他命令。
單片機通過SCI 模塊與上位機通信和下載APP代碼,對傳輸準確率要求高,對速率要求不高,因此,雖然目前RS-485 總線大數據量傳輸速率可以達到1 Mbps,但考慮到速率過高會導致電路工作時總線抗干擾能力差,從穩定性考慮,波特率不需設置過高,通過SCIBDH 和SCIBDL 兩個寄存器將波特率最高設置為115 200 即可。幀格式設置包括1 個起始位、8 數據位、1 停止位。
Bootloader 擦除APP 代碼如圖3 所示。不同的芯片,其內存空間不同,存儲APP的Falsh 區域也不同。根據內存空間區別,NXP 公司為每一種MC9S12系列單片機分配對應的Part ID,Part ID 為16 位數據,高8 位固化在地址0x001A,低8 位固化在地址0x001B[16]。所以,收到擦除App 命令后,讀取Part ID值,判斷屬于哪種芯片,然后擦除該芯片對應的FLASH 區域,將存儲的App 代碼擦除,不可擦除用戶重置向量和Bootloader[15]。

圖3 Bootloader擦除APP代碼
Bootloader 擦除APP 區域成功后才可接收新的APP 代碼。Code Warrior 生成工程的Project.abs.s19文件不能直接發送給Bootloader。Bootloader 接收的s19 文件要求是全局(線性)地址,且數據必須對齊為32 字節,數據長度也為32 字節。轉換s19 文件使用NXP官方提供的SRecCvt-GUI.exe即可[15],如圖4所示。

圖4 轉換s19文件
Bootloader 接收完s19 文件后,根據Part ID 判斷s19 文件中地址是否與芯片匹配,如果地址正確,則向對應的FLASH 區域寫入APP 代碼,每次寫入32 個字節。代碼如圖5 所示。

圖5 將APP代碼寫入Flash
Bootloader 代碼與APP 代碼存儲區域不能重疊。Bootloader 代碼存放在地址0xF000~0xFFFF的區域,APP的重置向量存儲在地址0xEFE0~0xEFFF的區域,每個中斷向量地址為16 位,因此需要把ROM_C000的地址范圍從原來的0xC000~0xFEFF 改成0xC000~0xEFDF。
在Processor Expert的Build Option 中,點 擊Memery segments,再點擊ROM/RAM segments,選擇ROM_C000 區域,此處可設置ROM_C000 區域的各項參數,只需要將size 修改為2FE0 即可,這樣結束地址就變為0xEFDF,如圖6 所示。

圖6 修改ROM_C000長度
0x7F10~0x7FFF 會被用于重定位中斷向量表,所以需要把ROM_4000的地址從原來的0x4000~0x7FFF 改成0x4000~0x7F0F。
在Processor Expert 中選擇ROM_4000 區域,將size 修改為0x3F10 即可,這樣結束地址就變為0x7F0F,如圖7 所示。

圖7 修改ROM_4000長度
用戶中斷向量原存儲地址范圍為0xFF10~0xFFF8,每個向量為16 位地址,因為地址范圍0xF000~0xFFFF的區域要存放BootLoader,所以必須改變用戶中斷向量存儲地址范圍,改為0x7F10~0x7FF8。在Processor Expert的Properties 中選擇Internel resource mapping,然后選擇Interrupt/Reset vector table,最后在Interrupt vector table 中將Address修改為0x7F10,長度0xEA,最后一個用戶中斷向量地址變為0x7FF8,如圖8 所示。

圖8 修改中斷向量地址
Reset vector table 不能修改,其包括3 個地址分別為0xFFFA(COP Watchdog Timeout),0xFFFC(Clock Monitor Fail)和0xFFFE(Reset)的系統重置向量,其中地址為0xFFFE的Reset 向量包括引腳復位、上電復位、低電壓復位、非法地址復位4 種功能[16]。MC9S12X 系列單片機上電后先從地址0xFFFE 處讀取第一條指令,如果該地址改變,則上電后Bootloader 將無法工作。
在Code Warrior 生成的代碼中,3 個系統重置向量與其他中斷向量地址一起存放在vectors_s12xep.c文件中的tIsrFunc _vect[ ]中,將IVBR 修改為0x7F,中斷向量表起始地址從0xFF10 改為0x7F10,其他中斷向量基地址從0xFF 變為0x7F,但對這3 個系統重置向量無影響,其地址(0xFFFA~0xFFFE)不會改變,并不影響上電后Bootloader的正常運行[16]。但在Processor Expert 中,修改這3 個系統重置向量的地址時,其地址會改變,使Bootloader 無法正常工作,導致上電后芯片無法正常工作。
使用傳統方式進入Bootaloader 狀態時,必須重新上電,然后根據PP0 引腳是否為高電平進入Bootaloader。如果系統統一供電,則重新上電會影響系統其他子系統工作,如果單獨控制供電,則增加電路復雜性和成本。因此,可以在用戶程序中添加代碼,增加用戶程序進入Bootloader 功能,不需要重新上電。上位機通過RS-485 總線向單片機發送進入Bootloader 命令,命令校驗通過后,B_flag 賦值為1,然后重啟單片機。因為PP0 引腳一直接地,所以單片機重啟后進Bootloader 狀態,如果在3 s 內沒有收到上位機命令,則將B_flag 值變為0,停留在Bootloader狀態,可以更新用戶程序。
為了給Bootloader 發送s19 文件,開發上位機軟件。按照RS-485 通信協議,使用Visual C++開發,完成與Bootloader 握手、讀取MCU 狀態、發送s19 文件、切換至用戶應用程序等功能。
傳統MC9S12X 系列單片機的在線升級均基于Code Warrior 生成代碼,代碼開發時間較長。文中設計的BootLoader 實現方式可以使用PE 圖形化方式完成用戶代碼開發,編程基礎差和沒有系統訓練編程的開發人員也可編寫應用代碼,開發和維護效率高,不易出錯,利用系統本身的RS-485 總線更新程序,電路系統不用重新上電也可準確方便地實現代碼的現場更新升級,方便實際應用。通過對中海油服自研隨鉆測井工具和旋轉導向鉆井工具的實際應用表明,該方案至少可節約50%以上的開發和維護時間,大大減輕了科研人員負擔。