常 浩,王 彬,王云飛
(中科芯集成電路有限公司,江蘇無錫 214072)
隨著電子技術(shù)的飛速發(fā)展,嵌入式終端廣泛應(yīng)用于工業(yè)控制、消費(fèi)電子等各種領(lǐng)域。為滿足不同客戶的需求以及系統(tǒng)的功能升級(jí)或修復(fù)原有系統(tǒng)的缺陷,嵌入式終端產(chǎn)品對(duì)固件進(jìn)行升級(jí)幾乎成了必備功能之一。在應(yīng)用編程(In Application Programming,IAP)在用戶程序運(yùn)行的過程中對(duì)Flash 的部分區(qū)域進(jìn)行燒寫,目的是產(chǎn)品發(fā)布后可以方便地通過預(yù)留的通信口對(duì)產(chǎn)品的固件進(jìn)行升級(jí)[1]。本文以CKS32F103CBT6 處理器為平臺(tái)給出了IAP 方案的設(shè)計(jì)原理和設(shè)計(jì)流程,解決了傳輸過程中意外中斷、傳輸數(shù)據(jù)誤碼等關(guān)鍵性技術(shù)問題,保證了系統(tǒng)內(nèi)部應(yīng)用程序的正確運(yùn)行。
傳統(tǒng)單片機(jī)IAP 的原理是在用戶程序正常運(yùn)行時(shí),接收到升級(jí)指令后,程序指針重新指回Bootloader中的IAP 程序,將接收到的新的應(yīng)用程序(Application,APP)數(shù)據(jù)寫入到控制擦除APP 所在的Flash 區(qū)域,完成后程序復(fù)位,經(jīng)Bootloader 的引導(dǎo),使新的APP 得以運(yùn)行[2]。
在沒有任何意外發(fā)生的情況下,傳統(tǒng)的IAP 升級(jí)方案可以正常運(yùn)行,但是存在3 個(gè)比較嚴(yán)重的問題:(1)如果升級(jí)過程中被打斷,可能會(huì)導(dǎo)致整個(gè)應(yīng)用程序都無法運(yùn)行,產(chǎn)品所有功能異常;(2)如果升級(jí)發(fā)生中斷,重新發(fā)起傳輸時(shí)需要再從頭開始發(fā)包升級(jí),在傳輸不穩(wěn)定的情況下升級(jí)時(shí)間大大加長;(3) 數(shù)據(jù)采用明文傳輸,數(shù)據(jù)在傳輸過程中容易被竊取[3]。
串口糾錯(cuò)協(xié)議Ymodem 是Xmodem 的改進(jìn)版協(xié)議,具有傳輸快速、穩(wěn)定的特點(diǎn),每包數(shù)據(jù)可以達(dá)到1024 B,是一種非常高效的文本傳輸協(xié)議。Ymodem 是一種發(fā)送并等待的協(xié)議,發(fā)送一個(gè)數(shù)據(jù)包后,等待接收方確認(rèn)。如果是應(yīng)答(Acknowledgment,ACK)信號(hào)則可以發(fā)送新的包。如果是否定應(yīng)答(Negative Acknowledgement,NAK)信號(hào),則重發(fā)或者錯(cuò)誤退出[4]。
需要固件升級(jí)的設(shè)備收到升級(jí)指令后,向上位機(jī)發(fā)送字符“C”,表示設(shè)備已經(jīng)準(zhǔn)備好接收固件了,上位機(jī)收到“C”字符開始傳輸固件的頭幀,頭幀包含SOH、數(shù)據(jù)塊編號(hào)、固件名稱、大小等數(shù)據(jù),不足128 B 用0x00 補(bǔ)齊,接收方收到數(shù)據(jù)后發(fā)送ACK 然后發(fā)送字符“C”,發(fā)送方收到字符“C”后開始傳輸固件數(shù)據(jù)幀[5]。Ymodem 協(xié)議數(shù)據(jù)幀格式如表1 所示。
表1 Ymodem 協(xié)議數(shù)據(jù)幀格式
IAP 上位機(jī)程序按幀格式順序發(fā)送需升級(jí)固件的數(shù)據(jù),終端設(shè)備收到固件后寫入Flash 更新區(qū),每幀數(shù)據(jù)大小為1024 B。終端收到每幀數(shù)據(jù)后,會(huì)對(duì)幀數(shù)據(jù)進(jìn)行CRC 校驗(yàn),校驗(yàn)正確寫入升級(jí)固件存儲(chǔ)區(qū)。
將Flash 空間劃分為3 個(gè)區(qū)域,第一個(gè)區(qū)域?yàn)锽ootloader 引導(dǎo)區(qū),第二個(gè)區(qū)域?yàn)锳PP 1 區(qū),即客戶應(yīng)用程序運(yùn)行區(qū),第三個(gè)區(qū)域?yàn)锳PP 2 區(qū),即升級(jí)固件儲(chǔ)存區(qū),升級(jí)中收到的固件數(shù)據(jù)先存入到APP 2 區(qū),這樣即使固件傳輸意外中斷后,整個(gè)系統(tǒng)也能按照之前客戶應(yīng)用程序運(yùn)行區(qū)的程序運(yùn)行[6]。
IAP 方案內(nèi)部Flash 區(qū)規(guī)劃如圖1 所示。上位機(jī)將需要升級(jí)的固件發(fā)送給終端,傳統(tǒng)IAP 在收完固件后立馬進(jìn)行程序跳轉(zhuǎn),跳轉(zhuǎn)到用戶程序區(qū),但是如果接收到的數(shù)據(jù)出錯(cuò)或者受到干擾寫入錯(cuò)誤,可能會(huì)導(dǎo)致整個(gè)程序跑飛。為了進(jìn)一步保證固件升級(jí)數(shù)據(jù)的安全性,終端收到固件后先將數(shù)據(jù)寫入到APP 2 區(qū),在固件完全接收成功后,會(huì)將寫入APP 2 區(qū)的數(shù)據(jù)按照順序進(jìn)行讀出,與傳輸中保存的校驗(yàn)數(shù)據(jù)進(jìn)行對(duì)比,校驗(yàn)成功后將APP 2 區(qū)的程序拷貝到APP 1 區(qū),再進(jìn)行程序跳轉(zhuǎn),保證了整個(gè)系統(tǒng)的安全[7]。如果固件升級(jí)過程中出現(xiàn)異常,導(dǎo)致升級(jí)失敗,程序會(huì)跳轉(zhuǎn)至原APP 1區(qū)運(yùn)行,不影響正常程序運(yùn)行。
圖1 IAP 方案內(nèi)部Flash 區(qū)規(guī)劃
斷點(diǎn)續(xù)傳即在上一次傳輸被意外中斷處繼續(xù)進(jìn)行固件的傳輸,因外界干擾較大導(dǎo)致固件傳輸中斷的環(huán)境下,利用斷點(diǎn)續(xù)傳可以極大地提高升級(jí)的效率,即使多次發(fā)生中斷,也可以實(shí)現(xiàn)固件續(xù)傳[8]。斷點(diǎn)續(xù)傳流程見圖2。
圖2 斷點(diǎn)續(xù)傳流程
上位機(jī)將固件傳輸進(jìn)行分幀處理,每一幀的數(shù)據(jù)大小為1024 B,傳輸時(shí)對(duì)每一幀數(shù)據(jù)進(jìn)行編號(hào)傳輸。終端在收到每一幀數(shù)據(jù)校驗(yàn)完成后,保存固件接收的幀狀態(tài)數(shù)據(jù)到外部的EEPROM 中,將接收到的固件數(shù)據(jù)依次寫入指定的Flash 地址中,并回復(fù)ACK 給上位機(jī),上位機(jī)收到ACK 指令后繼續(xù)進(jìn)行下一幀數(shù)據(jù)的傳輸。當(dāng)傳輸發(fā)生意外中斷后,如果需要將固件進(jìn)行斷點(diǎn)續(xù)傳,終端會(huì)從外部EEPROM 中讀取上一次中斷時(shí)的幀狀態(tài)數(shù)據(jù),在上一次的中斷處繼續(xù)接收相應(yīng)固件數(shù)據(jù),接收到的固件幀數(shù)據(jù)依次寫入到中斷前Flash 操作后面的區(qū)域,從而保證固件升級(jí)繼續(xù)進(jìn)行。
傳統(tǒng)IAP 升級(jí)數(shù)據(jù)傳輸使用明文傳輸,固件升級(jí)時(shí)傳輸數(shù)據(jù)容易被監(jiān)聽,從而導(dǎo)致固件被竊取。本設(shè)計(jì)采用了一種密鑰池加密方法,密鑰池是255 B 的隨機(jī)數(shù)容器,上位機(jī)和終端里都存放著此密鑰池,每次傳輸都可以從中隨機(jī)抽取若干數(shù)據(jù)進(jìn)行運(yùn)算組成通信密鑰。
上位機(jī)根據(jù)導(dǎo)入的升級(jí)固件的6 B 名稱數(shù)據(jù),從對(duì)應(yīng)密鑰池里選擇6 組密鑰進(jìn)行運(yùn)算得到本次通信的新密鑰,終端在接收到固件名稱數(shù)據(jù)后,同樣從密鑰池里選擇6 組密鑰進(jìn)行運(yùn)算得到相同的密鑰,這樣交互雙方即確定了本次通信的密鑰。上位機(jī)將固件數(shù)據(jù)通過通信密鑰加密后傳輸,終端接收到加密數(shù)據(jù)后,進(jìn)行解密并寫入到對(duì)應(yīng)的Flash 區(qū)。由于每次傳輸?shù)墓碳Q不同,即每次通信采用了密鑰池里不同的密鑰進(jìn)行數(shù)據(jù)加密,密鑰選擇是隨機(jī)進(jìn)行的,毫無規(guī)律可查,從而增加了固件傳輸被破解的難度。為了保證IAP 升級(jí)系統(tǒng)密鑰池的安全,可以按照產(chǎn)品的批次更新密鑰池。
中科芯集成電路有限公司設(shè)計(jì)的CKS32F103CBT6 標(biāo)準(zhǔn)型MCU 使用高性能ARM?Cortex?M3 32 位RISC 內(nèi)核,工作頻率為72 MHz,具有高達(dá)128 kB 的閃存和20 kB 的SRAM。其中包含2個(gè)12 位ADC、3 個(gè)通用16 位定時(shí)器和1 個(gè)PWM 定時(shí)器,多達(dá)2 個(gè)I2C 接口和SPI 接口、3 個(gè)USART 接口。MCU 最小系統(tǒng)原理見圖3。
圖3 MCU 最小系統(tǒng)原理
系統(tǒng)上電后,首先運(yùn)行Bootloader 程序,Bootloader 程序放在0x08000000 開始的15 kB 空間。用戶按下按鍵后初始化串口,上位機(jī)顯示選擇菜單。菜單1 為重載固件,菜單2 為斷點(diǎn)續(xù)傳固件,菜單3 為運(yùn)行應(yīng)用程序。Bootloader 引導(dǎo)程序流程見圖4。
圖4 Bootloader 引導(dǎo)程序流程
當(dāng)用戶菜單選擇重載固件時(shí),用戶重新接收新固件并存儲(chǔ)到升級(jí)固件存儲(chǔ)區(qū),接收完成后對(duì)固件存儲(chǔ)區(qū)數(shù)據(jù)進(jìn)行校驗(yàn),校驗(yàn)正確后置位升級(jí)成功標(biāo)志位。當(dāng)用戶菜單選擇斷點(diǎn)續(xù)傳時(shí),從上一次傳輸被意外中斷處繼續(xù)進(jìn)行固件的傳輸,接收完成后對(duì)固件存儲(chǔ)區(qū)數(shù)據(jù)進(jìn)行校驗(yàn),校驗(yàn)正確后置位升級(jí)成功標(biāo)志位。當(dāng)用戶菜單選擇運(yùn)行應(yīng)用程序時(shí),判斷升級(jí)成功標(biāo)志,如果升級(jí)成功標(biāo)志位置位,則把升級(jí)存儲(chǔ)區(qū)代碼復(fù)制到用戶應(yīng)用程序運(yùn)行區(qū),否則直接運(yùn)行用戶應(yīng)用程序運(yùn)行區(qū)代碼。
本文實(shí)現(xiàn)了支持單幀數(shù)據(jù)校驗(yàn)、斷點(diǎn)續(xù)傳、數(shù)據(jù)加密、存儲(chǔ)校驗(yàn)的IAP 系統(tǒng)升級(jí)方案。測(cè)試上位機(jī)界面如圖5 所示,上位機(jī)開發(fā)平臺(tái)采用Visual Studio 程序,開發(fā)語言為C#,波特率可手動(dòng)選擇。配合本文改進(jìn)的IAP 升級(jí)方案,測(cè)試時(shí)通過上位機(jī)打開固件,選擇加密固件進(jìn)行傳輸,傳輸方式可選擇斷點(diǎn)續(xù)傳或者重載固件方式,傳輸時(shí)實(shí)時(shí)顯示固件傳輸?shù)倪M(jìn)度,傳輸完成后顯示成功并記錄升級(jí)時(shí)間。固件下載成功后,上位機(jī)可發(fā)送運(yùn)行應(yīng)用程序相關(guān)指令提示終端進(jìn)入應(yīng)用程序執(zhí)行。
圖5 上位機(jī)界面
測(cè)試升級(jí)固件大小分別為5 kB、10 kB、20 kB、38 kB、54 kB,單個(gè)固件下載次數(shù)均為50 次,測(cè)試成功升級(jí)率為100%。
測(cè)試在外界干擾導(dǎo)致升級(jí)中斷的情況下IAP 方案的耗時(shí)情況,為了減少測(cè)試誤差,上位機(jī)軟件在點(diǎn)擊升級(jí)固件后開始執(zhí)行軟件計(jì)時(shí),減少人工計(jì)時(shí)可能產(chǎn)生的誤差。實(shí)驗(yàn)數(shù)據(jù)如表2 所示,測(cè)試波特率均為115200 bit/s,實(shí)驗(yàn)結(jié)果表明在存在外部干擾導(dǎo)致傳輸中斷的情況下,本文設(shè)計(jì)的斷點(diǎn)續(xù)傳IAP 方案隨著中斷次數(shù)的增加相對(duì)于傳統(tǒng)IAP 方案耗時(shí)大大減少。
表2 外界干擾下傳輸耗時(shí)測(cè)試數(shù)據(jù)
測(cè)試升級(jí)38 kB 固件,測(cè)試在升級(jí)過程中人為干擾導(dǎo)致升級(jí)失敗的情況,測(cè)試次數(shù)為50 次,傳統(tǒng)IAP方案升級(jí)意外中斷后運(yùn)行應(yīng)用程序均出現(xiàn)死機(jī)情況,本文提出的IAP 方案在升級(jí)意外中斷后,系統(tǒng)恢復(fù)應(yīng)用程序之前的工作狀態(tài),系統(tǒng)正常運(yùn)行。
本文以ARM?Cortex?M3 內(nèi)核的微處理器CKS32F103CBT6 為平臺(tái),串口作為通信接口,給出了一種嵌入式的固件升級(jí)方案。該方案引導(dǎo)程序的設(shè)計(jì)實(shí)現(xiàn)了更新代碼區(qū)和運(yùn)行代碼區(qū)的隔離,保障了整個(gè)系統(tǒng)的安全可靠?;赮modem 的串口升級(jí)對(duì)每幀數(shù)據(jù)進(jìn)行CRC 校驗(yàn),且串口傳輸數(shù)據(jù)為加密后的數(shù)據(jù),保證了傳輸?shù)恼_性與安全性,數(shù)據(jù)傳輸完成后對(duì)收到的固件進(jìn)行校驗(yàn),校驗(yàn)一致才進(jìn)行固件升級(jí)。該設(shè)計(jì)可以有效處理升級(jí)過程中意外中斷、數(shù)據(jù)傳輸錯(cuò)誤等異常情況,在由于外部環(huán)境導(dǎo)致升級(jí)失敗時(shí),系統(tǒng)軟件恢復(fù)之前的運(yùn)行狀態(tài),保證了整個(gè)系統(tǒng)能夠正常運(yùn)行。實(shí)驗(yàn)測(cè)試證明,該技術(shù)方案具有較好的可行性、穩(wěn)定性和安全性,可以廣泛應(yīng)用于ARM?Cortex?M3 內(nèi)核的微處理器芯片的固件升級(jí),具有很好的實(shí)際應(yīng)用價(jià)值。