李媛媛
(南京康尼機(jī)電股份有限公司, 江蘇 南京 210013)
為了避免在進(jìn)行程序更新、 升級(jí)過程中拆除門控器,通過仿真器將應(yīng)用程序更新到處理器中的這種繁瑣、費(fèi)時(shí)、耗力的工作,需要研究通過串行總線、USB 口或其它總線以及相應(yīng)的通訊協(xié)議實(shí)現(xiàn)在線升級(jí)。 在更新過程中,可靠性是開發(fā)過程中首要考慮因素。為了應(yīng)對(duì)程序更新出錯(cuò)的意外狀況,采取在開始更新、更新過程中以及更新完成后讀寫同一塊地址不同標(biāo)志的策略增強(qiáng)程序的可靠性。
本文著重研究基于TMS570LS0714 處理器UART 總線Bootloader 的設(shè)計(jì)與實(shí)現(xiàn), 采用Ymodem 協(xié)議實(shí)現(xiàn)文件傳輸, 通過實(shí)驗(yàn)說明設(shè)計(jì)的Bootloader 可以實(shí)現(xiàn)應(yīng)用程序在線更新。
應(yīng)用Flash 程序存儲(chǔ)器的一種編程方式稱為在線應(yīng)用編程IAP(In-Application Programming),它能夠在應(yīng)用程序正常運(yùn)行過程中, 借助特定的IAP 程序讀/寫另一段程序的Flash 空間,甚至可以讀/寫某段、某頁甚至某個(gè)字節(jié), 這使得程序的在線升級(jí)和數(shù)據(jù)存儲(chǔ)有了很大的便捷性和靈活性[1]。
為了實(shí)現(xiàn)IAP 功能, 通常Flash 內(nèi)部要?jiǎng)澐譃閮蓧K,一塊叫做Boot 區(qū),專門用來存儲(chǔ)Bootloader 程序,一塊稱為存儲(chǔ)區(qū),用來存儲(chǔ)應(yīng)用程序。 處理器TMS570 上電之后首先在Boot 區(qū)運(yùn)行,如果有滿足外部改寫程序的條件,則先擦除原有程序數(shù)據(jù), 并通過UART 總線下載待升級(jí)程序到Flash,再拷貝到RAM 中運(yùn)行;如果不滿足改寫程序的條件,則程序指針跳轉(zhuǎn)到存儲(chǔ)區(qū),執(zhí)行應(yīng)用程序,這就是IAP 功能實(shí)現(xiàn)原理[2]。
TMS570LS0714 處理器, 是TI 公司的一款安全控制芯片,符合功能安全要求的微控制器,具有雙核校驗(yàn)、RAM和FLASH 的ECC 校驗(yàn)等系統(tǒng)可靠性保障手段,可以識(shí)別出系統(tǒng)運(yùn)行過程中的各類異常并執(zhí)行用戶預(yù)置的異常處理程序[3]。
TMS570LS0714 對(duì)用戶可操作的Flash 范圍是0x0000_0000~0x000B_FFFF,共768K[3]。 通常會(huì)安排Bootloader 代碼處于Flash 的開始區(qū)域0x0000_0000, 而應(yīng)用程序代碼緊隨其后。Bootloader 實(shí)現(xiàn)的功能就是升級(jí)加載應(yīng)用程序,應(yīng)本著可靠、簡化的原則,占用的存儲(chǔ)空間不應(yīng)過大, 本文分配Bootloader 存放地址為0x0000_0000~0x0001_FFFF,共128K。剩下的Flash 空間用0x0000_0000~0x000B_FFFF 來存放應(yīng)用程序。
本模塊通過UART 接口使用Ymodem 通信協(xié)議傳輸文件。 Ymodem 協(xié)議在發(fā)送方發(fā)送完成一包數(shù)據(jù)之后,需要等待接收方的確認(rèn),如果發(fā)生方收到“ACK”信號(hào),則可以發(fā)送新的數(shù)據(jù)包,如果收到“NAK”信號(hào),則需要重發(fā)或者錯(cuò)誤退出。
Ymodem 協(xié)議是廣泛使用的異步文件傳輸協(xié)議之一,它是Xmodem 的改進(jìn)版協(xié)議,相較于Xmodem 協(xié)議,Ymodem 協(xié)議允許批處理文件傳輸,傳輸效率、可靠性更高,一幀可以傳輸128*8bite 或1024*8bite, 一次傳輸可發(fā)送或接收幾個(gè)文件,使用CRC 校驗(yàn)技術(shù)對(duì)發(fā)送數(shù)據(jù)包進(jìn)行數(shù)據(jù)校驗(yàn)確保數(shù)據(jù)傳輸正確性。每發(fā)送一個(gè)數(shù)據(jù)包后,會(huì)等待接收端回應(yīng),直到接收到“ACK”信號(hào)后,下一個(gè)數(shù)據(jù)包才會(huì)繼續(xù)傳輸,確保數(shù)據(jù)被接收完成。
本模塊定義的傳輸波特率是115200bit/s,8 個(gè)數(shù)據(jù)位,1 個(gè)停止位,偶校驗(yàn)。
本協(xié)議接收方和發(fā)送方約定的收發(fā)過程中的一些標(biāo)記信號(hào)定義見表1。
表1 收發(fā)過程約定符號(hào)定義
文件傳輸過程為[4]:
(1) 開啟是由接收方的處理器發(fā)送一個(gè)大寫字母“C”開啟傳輸,之后等待發(fā)送方發(fā)送“SOH”,如果接收不到回應(yīng),則一直向上位機(jī)發(fā)送“C”,若超過5S 上位機(jī)還沒有回應(yīng),則處理器會(huì)向上位機(jī)連續(xù)發(fā)送兩個(gè)“CAN”,然后超時(shí)退出。
(2)發(fā)送方開始時(shí)處于等待過程中,等待“收到“C”以后,發(fā)送文件名數(shù)據(jù)包,然后進(jìn)入等待“ACK”狀態(tài)。
(3)接收方收到數(shù)據(jù)包之后,對(duì)數(shù)據(jù)包進(jìn)行CRC 校驗(yàn),校驗(yàn)成功則發(fā)送“ACK”信號(hào)。 發(fā)送方接收到“ACK”,又重新進(jìn)入等待“C”的狀態(tài)。
(4)至此文件名數(shù)據(jù)包傳輸完成,此后文件傳輸正式開啟,Ymodem 支持每個(gè)數(shù)據(jù)包以128 字節(jié)以“SOH”開始或者1024 字節(jié)以 “STX” 開始, 本文規(guī)定每個(gè)數(shù)據(jù)包為1024 字節(jié)。
接收方開始準(zhǔn)備接收文件又發(fā)出一個(gè)“C”信號(hào),然后進(jìn)入等待“STX”狀態(tài)。
(5)發(fā)送接收到“C”以后,發(fā)送數(shù)據(jù)包(詳見3.5 章節(jié)數(shù)據(jù)格式),等待接收方的“ACK”信號(hào)。
(6)發(fā)送方發(fā)出“EOT”信號(hào)表示文件發(fā)送完成,接收方回應(yīng)“ACK”信號(hào)。
緊接著發(fā)送方發(fā)出一個(gè)全“0”數(shù)據(jù)包,接收方回應(yīng)“ACK”,正式結(jié)束此次通訊。
Ymodem 通信協(xié)議接收數(shù)據(jù)格式,第一包數(shù)據(jù)只是傳輸文件的文件名和文件大小信息, 之后傳輸?shù)臄?shù)據(jù)包才是文件的內(nèi)容。 若最后一包內(nèi)容不足1024 字節(jié), 則以0補(bǔ)齊。 具體傳輸格式如下:
第一包:
圖1 第一包發(fā)送數(shù)據(jù)格式
第二包:
圖2 第二包發(fā)送數(shù)據(jù)格式
之后每一包依次類推下去。
接收方以一個(gè)大寫字母“C”開啟傳輸,收到發(fā)送來的數(shù)據(jù)以后,CRC 校驗(yàn)滿足,則發(fā)送“ACK”應(yīng)答信號(hào),CRC 校驗(yàn)不滿足,則連續(xù)發(fā)送兩個(gè)“CAN”信號(hào),表示取消該次傳輸。
接收方接收數(shù)據(jù)成功以后, 開始寫入flash 操作,如果寫入失敗,則連續(xù)發(fā)送兩個(gè)“CAN”信號(hào),如果寫入成功,則發(fā)送一個(gè)“ACK” 應(yīng)答信號(hào)。
接收數(shù)據(jù)過程中,如果連續(xù)收到兩個(gè)“CAN”信號(hào),則表示取消傳輸,發(fā)送方以發(fā)送“ACK”應(yīng)答;如果連續(xù)到一個(gè)“EOT”信號(hào),則表示文件傳輸結(jié)束,發(fā)送方以發(fā)送“ACK”應(yīng)答。
配置Bootloader 的CMD 文件是應(yīng)用程序能否被正確升級(jí)的關(guān)鍵,CMD 文件的兩大主要功能是通過MEMORY偽指令來指示存儲(chǔ)空間和通過SECTIONS 偽指令來分配段到存儲(chǔ)空間,CMD 文件就是由這兩部分內(nèi)容構(gòu)成的。
在控制器復(fù)位以后, 啟動(dòng)程序?qū)⒀b載引導(dǎo)程序的Flash API 從FLASH 中復(fù)制到RAM 中, 并在RAM 中執(zhí)行裝載引導(dǎo)程序??梢栽贑MD 文件中劃分一段用以設(shè)置RAM 的載入和運(yùn)行地址,定義輸出段將被裝載到哪里的關(guān)鍵字、輸出段從哪里開始運(yùn)行的關(guān)鍵字、API 從哪里開始下載、API 從哪里開始運(yùn)行以及API 的長度等信息[5]。
串口IAP 的實(shí)現(xiàn)流程見圖3 所示,控制器復(fù)位以后,首先是在Flash 起始地址運(yùn)行Bootloader 程序。Bootloader程序執(zhí)行的任務(wù)就是檢測是否升級(jí)應(yīng)用程序, 通過判斷Flash EEPROM block1 上的值是否是約定標(biāo)志A,若block1 上的值不是A, 則表示要進(jìn)行更新, TMS570 向上位機(jī)發(fā)送請求執(zhí)行代碼升級(jí)函數(shù), 同時(shí)驅(qū)動(dòng)數(shù)碼管顯示“CC”。
圖3 IAP 實(shí)現(xiàn)流程
若block1 中的值滿足約定條件, 則說明分配的應(yīng)用程序地址空間(0x0002_0000~0x000B_FFFF)里有完整的應(yīng)用程序, 不需要進(jìn)行升級(jí)操作, 直接跳轉(zhuǎn)到用戶代碼段,即起始地址0x0002_0000 執(zhí)行應(yīng)用程序。
定義運(yùn)行Bootloader 程序, 門控器數(shù)碼管顯示“CC”指示Flash 中沒有應(yīng)用程序,數(shù)碼管顯示“FE”指示正在升級(jí),數(shù)碼管顯示“FF”指示升級(jí)完成。
在程序升級(jí)過程中,為了防止誤升級(jí)錯(cuò)誤的文件,或者是升級(jí)過程中出現(xiàn)意外導(dǎo)致升級(jí)失敗, 升級(jí)標(biāo)志在不同階段寫不同值。
即在正常運(yùn)行應(yīng)用程序時(shí),收到上位機(jī)的升級(jí)請求,應(yīng)用程序首先向Flash EEPROM block1 寫需要升級(jí)標(biāo)志B,然后關(guān)閉定時(shí)器引起復(fù)位操作,CPU 復(fù)位后進(jìn)入Bootloader,重復(fù)4.1 節(jié)的操作,進(jìn)入升級(jí)流程,在升級(jí)流程里,首先讀取block1 中的標(biāo)志是否是B,若是B,則向block1中寫正在升級(jí)標(biāo)志C,然后正式啟動(dòng)升級(jí)操作。 升級(jí)完成后,跳轉(zhuǎn)到應(yīng)用程序段執(zhí)行應(yīng)用程序,應(yīng)用程序在執(zhí)行正常功能之前,先讀block1 中的標(biāo)志是否是A,按照上述思路,這個(gè)時(shí)候block1 中存放的是標(biāo)志C,而不是A,這時(shí)候CPU 立即向block1 中寫標(biāo)志A,然后復(fù)位重啟,重復(fù)4.1 節(jié)操作。
這樣略顯繁瑣的操作, 恰好能規(guī)避誤升級(jí)錯(cuò)誤文件的操作。 若正常升級(jí)過程出現(xiàn)意外導(dǎo)致升級(jí)失敗, 重啟CPU,Bootloader 上電檢測block1 無標(biāo)志A, 再次進(jìn)入升級(jí)流程升級(jí)即可。
本章節(jié)設(shè)計(jì)了四個(gè)試驗(yàn),通過配套上位機(jī)軟件發(fā)送應(yīng)用APP 程序數(shù)據(jù)流到TMS570 并運(yùn)行, 測試上文設(shè)計(jì)的Bootloader 能否實(shí)現(xiàn)預(yù)期的升級(jí)功能。 該APP 程序運(yùn)行起來后循環(huán)檢測有無升級(jí)請求, 并控制數(shù)碼管顯示“00”,輸出口O0 紅色指示燈以1HZ 頻率閃爍, 以方便用戶觀察APP 程序是否得以正確并完整升級(jí),是否能夠正常運(yùn)行。
Flash 中只有Bootloader,應(yīng)用程序段是空的,啟動(dòng)上位機(jī)發(fā)送升級(jí)請求, 觀察升級(jí)過程中數(shù)碼管及指示燈情況見表2。 表中的數(shù)碼管及指示燈顯示情況表明該升級(jí)過程沒有出現(xiàn)數(shù)據(jù)丟失情況,Bootloader 能完整的解碼上位機(jī)發(fā)送的數(shù)據(jù)并寫到相應(yīng)Flash 上,升級(jí)成功。
表2 Flash 中只有Bootloader 升級(jí)APP
繼5.1 節(jié)之后,控制器輸出口O0 閃爍過程中, 啟動(dòng)上位機(jī)發(fā)送升級(jí)請求, 觀察升級(jí)過程中數(shù)碼管及指示燈見情況見表3。
表3 Flash 中有Bootloader 和APP 升級(jí)APP
該試驗(yàn)結(jié)果表明設(shè)計(jì)的Bootloader 能夠?qū)崿F(xiàn)過程升級(jí)。
繼5.1 節(jié)之后,控制器輸出口O0 閃爍過程中,啟動(dòng)上位機(jī)發(fā)送升級(jí)請求,但是發(fā)送的不是和Bootloader 配套的APP 程序, 該APP 程序沒有實(shí)時(shí)檢測升級(jí)的功能,也沒有點(diǎn)亮輸出口的功能,即錯(cuò)誤APP。觀察升級(jí)過程中數(shù)碼管及指示燈情況見表4。
表4 升級(jí)錯(cuò)誤APP
該實(shí)驗(yàn)表明升級(jí)了錯(cuò)誤APP 后,Bootloader 不會(huì)跳轉(zhuǎn)到錯(cuò)誤APP 程序執(zhí)行,會(huì)一直等待升級(jí), 直到升級(jí)了正確APP 后,才會(huì)跳轉(zhuǎn)執(zhí)行APP 程序,能有效防護(hù)誤升級(jí)錯(cuò)誤APP。
在升級(jí)過程中,斷開上位機(jī)與控制器的連接,制造升級(jí)過程出錯(cuò)的現(xiàn)象,觀察上位機(jī)顯示升級(jí)超時(shí)出錯(cuò),重啟控制器,數(shù)碼管顯示“CC”,指示Flash 中沒有APP 程序。該實(shí)驗(yàn)表明Bootloader 能夠有效防護(hù)升級(jí)過程出錯(cuò)。
本文設(shè)計(jì)并實(shí)現(xiàn)了基于Ymodem 協(xié)議的Bootloader,在開發(fā)過程中增加防錯(cuò)處理, 有效防止升級(jí)錯(cuò)誤的執(zhí)行文件及升級(jí)失敗。經(jīng)過試驗(yàn)證明Bootloader 能正確引導(dǎo)程序運(yùn)行,下載數(shù)據(jù)完整、無誤、快速,沒有出現(xiàn)數(shù)據(jù)丟失、錯(cuò)誤等現(xiàn)象。