Blackfin處理器Second-stage Loader的應(yīng)用程序在線升級(jí)設(shè)計(jì)方案
本文主要介紹了ADI Blackfin處理器的啟動(dòng)流程、LDR文件的格式和一些高級(jí)的啟動(dòng)技術(shù),最后通過(guò)一個(gè)實(shí)際的例子說(shuō)明如何使用SSL (second-stage loader) 實(shí)現(xiàn)應(yīng)用程序的在線升級(jí)。
對(duì)于嵌入式開(kāi)發(fā)者來(lái)說(shuō),一種快速方便的在線升級(jí)方法不僅能夠節(jié)約升級(jí)帶來(lái)的額外成本,還可以提高升級(jí)效率。
隨著集成電路技術(shù)的快速發(fā)展,系統(tǒng)的硬件方案已經(jīng)變得越來(lái)越相似,一個(gè)嵌入式應(yīng)用的價(jià)值和特點(diǎn)往往都是由應(yīng)用程序來(lái)決定的。因此用戶希望嵌入式系統(tǒng)的功能可以不斷地完善和增強(qiáng),這使得應(yīng)用程序的升級(jí)變得非常普遍。
圖1 Blackfin處理器啟動(dòng)流程
通用Blackfin的啟動(dòng)流程和LDR文件分析
通用Blackfin處理器的啟動(dòng)流程
Blackfin處理器的啟動(dòng)可以看作是從靜態(tài)存儲(chǔ)器上讀取啟動(dòng)碼流(LDF文件格式)到Blackfin內(nèi)部的L1和SDRAM存儲(chǔ)器的過(guò)程。啟動(dòng)工作全部由存儲(chǔ)在Blackfin ROM中的啟動(dòng)代碼完成的。每款Blackfin處理器的ROM大小有所不同,但啟動(dòng)過(guò)程總是從ROM的起始地址0xEF00 0000開(kāi)始。
Blackfin處理器的啟動(dòng)代碼可以分為新舊兩種版本,分別針對(duì)BF54x、BF52x、BF51x、BF561和BF53x。新版本啟動(dòng)代碼以處理器的啟動(dòng)模式為基礎(chǔ)來(lái)構(gòu)建程序,一個(gè)通用的啟動(dòng)內(nèi)核負(fù)責(zé)處理的啟動(dòng)碼流的解析、裝載和異常錯(cuò)誤的處理。本文以新版的啟動(dòng)代碼為基礎(chǔ)進(jìn)行分析和構(gòu)建實(shí)例,用戶可以參考已經(jīng)發(fā)布的應(yīng)用筆記EE-240和EE-314來(lái)學(xué)習(xí)BF53x和BF561的啟動(dòng)過(guò)程。
本文以圖1為例講解Blackfin處理器的啟動(dòng)流程。處理器復(fù)位后會(huì)從ROM的起始地址開(kāi)始執(zhí)行,啟動(dòng)代碼首先讀取啟動(dòng)碼流最開(kāi)始的8個(gè)字節(jié),它們只是頭信息的一部分,內(nèi)核通過(guò)分析包含在這8個(gè)字節(jié)中的DMACODE位來(lái)確定DMA通道的寬度和步長(zhǎng)。一旦DMA的配置完成后,啟動(dòng)碼流將以子塊為單位進(jìn)行讀取。啟動(dòng)代碼根據(jù)頭信息中的目標(biāo)地址和子塊長(zhǎng)度將啟動(dòng)碼流的每個(gè)子塊傳輸?shù)街付ǖ拇鎯?chǔ)器位置。當(dāng)所有的塊傳輸完成后,啟動(dòng)代碼會(huì)自動(dòng)跳轉(zhuǎn)到應(yīng)用程序的起始地址開(kāi)始執(zhí)行,默認(rèn)的地址是0xFFA0 0000。這個(gè)過(guò)程就是Blackfin的啟動(dòng)。
LDR文件格式
LDR文件,即可裝載文件,包含著全部的啟動(dòng)碼流并保存在靜態(tài)存儲(chǔ)器中供啟動(dòng)使用。它可以非常容易地通過(guò)Visual DSP(VDSP)的ELFLOADER功能生成。ELFLOADER解析輸入的可執(zhí)行DXE文件,生成帶有頭信息的啟動(dòng)碼流,過(guò)程如圖2所示。
圖2 LDR文件生成過(guò)程
LDR文件由多個(gè)子塊組成,每個(gè)子塊可以分為頭部和負(fù)載兩個(gè)部分,但有部分特殊子塊只有頭部,沒(méi)有負(fù)載區(qū)。頭部區(qū)共有16個(gè)字節(jié),分別存儲(chǔ)著頭部的CRC校驗(yàn)數(shù)據(jù)、標(biāo)志符、目的地址、塊大小和塊參數(shù),如圖3所示,用戶可以使用LDR VIEWER工具查看LDR文件。啟動(dòng)代碼每次都會(huì)對(duì)頭部16字節(jié)進(jìn)行異或校驗(yàn), BLOCK CODE的低16位用于儲(chǔ)存頭部區(qū)的校驗(yàn)和。一旦頭部信息校驗(yàn)失敗,啟動(dòng)代碼就會(huì)調(diào)用錯(cuò)誤處理函數(shù),默認(rèn)的情況是將內(nèi)核置于空閑態(tài),不處理任何后續(xù)數(shù)據(jù)。但是用戶可以在初始化函數(shù)中自行替換錯(cuò)誤處理函數(shù)。
圖3 啟動(dòng)碼流頭部區(qū)
頭部的標(biāo)志符共有16比特,如圖4所示。這里需要著重指出的是BFLAG_FINAL、BFLAG_FIRST、BFLAG_INIT和BFLAG_FILL四個(gè)標(biāo)志符,它們分別指出當(dāng)前的子塊為結(jié)束塊、開(kāi)始?jí)K、初始化塊和填充塊。一般情況下每個(gè)LDR文件都會(huì)存在這四個(gè)標(biāo)志符,而且具有其中任何一個(gè)標(biāo)志符的子塊都沒(méi)有的負(fù)載區(qū)。一旦啟動(dòng)碼流解析到標(biāo)志符中有BFLAG_FINAL或BFLAG_INIT,它會(huì)馬上調(diào)用入口地址存儲(chǔ)在EVT1寄存器中的函數(shù),這個(gè)地址通常是0xFFA0 0000。也就是說(shuō),在默認(rèn)的情況下,應(yīng)用程序的起始位置和初始化函數(shù)的起始地址都是0xFFA0 0000。DMACODE用來(lái)配置DMA通道的寬度和傳輸步長(zhǎng),但一般只在啟動(dòng)開(kāi)始的時(shí)候設(shè)置一次。
圖4 標(biāo)志符低16位
Blackfin的高級(jí)啟動(dòng)功能
內(nèi)核數(shù)據(jù)結(jié)構(gòu)
新版的啟動(dòng)代碼使用了一種新的數(shù)據(jù)結(jié)構(gòu),叫做ADI_BOOT_DATA。通過(guò)在初始化函數(shù)中修改這個(gè)數(shù)據(jù)結(jié)構(gòu)中的成員變量,用戶可以定義自己的啟動(dòng)過(guò)程,這里簡(jiǎn)要介紹升級(jí)過(guò)程中用到的成員。
? pSource:?jiǎn)?dòng)碼流在FLASH存儲(chǔ)器中的起始地址,默認(rèn)情況下是0x0。但用戶可以通過(guò)修改這個(gè)成員,使啟動(dòng)代碼從FLASH存儲(chǔ)器的其它地址開(kāi)始讀取啟動(dòng)碼流。
? pLogBuffer:?jiǎn)?dòng)記錄存儲(chǔ)區(qū),默認(rèn)的起始地址位于0xFFB0 0400。因?yàn)檫@個(gè)臨時(shí)數(shù)據(jù)存儲(chǔ)區(qū)不能被DMA訪問(wèn),所以多作為應(yīng)用程序的堆棧。該緩沖區(qū)記錄了啟動(dòng)碼流的每個(gè)子塊的頭信息及一些同啟動(dòng)過(guò)程密切相關(guān)的重要信息,具體內(nèi)容可參考BF51x的硬件手冊(cè)。這些記錄信息的主要用于啟動(dòng)調(diào)試。
? dFlags:低15位是當(dāng)前正在處理的啟動(dòng)碼流子塊的頭信息標(biāo)志符(圖4),高15位是啟動(dòng)數(shù)據(jù)結(jié)構(gòu)的標(biāo)志符,如圖5所示。當(dāng)SPI FLASH的類型已經(jīng)確定后,用戶通過(guò)設(shè)置BFLAG_TYPE,BFLAG_NOAUTO和BFLAG_ALTERNATE三個(gè)標(biāo)志位可以使啟動(dòng)代碼跳過(guò)SPI地址檢測(cè)。
圖5 標(biāo)志符高16位
可用于啟動(dòng)過(guò)程的API函數(shù)
為了方便開(kāi)發(fā)者定義客戶化的啟動(dòng)過(guò)程,啟動(dòng)的ROM提供了11個(gè)API函數(shù)供用戶使用,它們的接口參數(shù)請(qǐng)?jiān)斠?jiàn)BF51x硬件手冊(cè),這里介紹將會(huì)用到的BFROM_SPIBOOT,BFROM_CRC32和BFROM_CRC32POLY函數(shù)。
BFROM_SPIBOOT函數(shù)的C語(yǔ)言原型是:
s32 bfrom_SpiBoot (s32 dSpiAddress,
s32 dFlags,
s32 dBlockCount,
ADI_BOOT_HOOK_FUNC* pCallHook);
SPI啟動(dòng)代碼需要四個(gè)參數(shù),分別是啟動(dòng)碼流在SPI FLASH內(nèi)存中的起始位置,啟動(dòng)標(biāo)志符(圖5和圖4)、子塊數(shù)量(非負(fù)數(shù)時(shí)正常啟動(dòng))和回調(diào)函數(shù)。通過(guò)使用這個(gè)函數(shù),SPI啟動(dòng)代碼可以裝載已經(jīng)存儲(chǔ)在SPI FLASH的啟動(dòng)碼流。利用回調(diào)函數(shù),用戶可以修改SPI的波特率,SPI的slave select pin等配置,加快啟動(dòng)速度。
BFROM_CRC32POLY函數(shù)的C語(yǔ)言原型是:
s32 bfrom_Crc32Poly (unsigned s32 *pLut,
s32 dPolynomial);
該函數(shù)根據(jù)用戶提供的多項(xiàng)式建立CRC校驗(yàn)需要的查詢表,多項(xiàng)式可從LDR文件的INIT塊中找到(必須使用-CRC32選項(xiàng)生成LDR文件)。查詢表要在使用bfrom_Crc32函數(shù)之前建立好。
BFROM_CRC32函數(shù)的C語(yǔ)言原型是:
s32 bfrom_Crc32 (s32 *pLut,
void *pData,
s32 dByteCount,
s32 dInitial);
該函數(shù)用于校驗(yàn)LDR文件的負(fù)載區(qū),頭部信息已經(jīng)有頭部區(qū)的校驗(yàn)和來(lái)保證正確性。使用該函數(shù)之前需要建立CRC校驗(yàn)查詢表。函數(shù)會(huì)返回每個(gè)子塊負(fù)載區(qū)的CRC值。
基于SSL的在線升級(jí)方法
當(dāng)前的升級(jí)方法多是基于ping-pong的方法,每次都會(huì)更新最舊的版本,這樣的設(shè)計(jì)保證了即使升級(jí)失敗,系統(tǒng)也能夠正常啟動(dòng)。但是使用這種方法,系統(tǒng)需要啟動(dòng)碼流兩倍大小的FLASH存儲(chǔ)器,增加了系統(tǒng)成本。
本節(jié)將根據(jù)前面介紹的Blackfin處理器啟動(dòng)流程和高級(jí)啟動(dòng)技術(shù),使用SSL來(lái)構(gòu)建一個(gè)在線升級(jí)的方案。通過(guò)使用SSL,用戶能夠控制升級(jí)和啟動(dòng)過(guò)程,即使出現(xiàn)升級(jí)失敗,也不會(huì)導(dǎo)致系統(tǒng)癱瘓,而且不需要增加額外的FLASH存儲(chǔ)器空間。這個(gè)例子基于BF518處理器,但也可以推廣到BF54x或BF52x處理器。本文選用比較通用的SPI FLASH作為SSL和應(yīng)用程序的存儲(chǔ)介質(zhì),同時(shí)BF518工作在external SPI boot的模式。SSL通過(guò)串口接收升級(jí)數(shù)據(jù),同上位機(jī)進(jìn)行通訊。
SSL的工作原理
SSL主要包括兩部分功能,啟動(dòng)碼流的接收和升級(jí)。接收部分通過(guò)串口從上位機(jī)接收LDR文件,然后存儲(chǔ)到SDRAM中,使用Blackfin提供的bfrom_Crc32函數(shù)校驗(yàn)接收到的碼流。升級(jí)部分將SDRAM中的LDR文件燒寫(xiě)到SPI閃存中,并更新文件狀態(tài)。升級(jí)過(guò)程如圖6所示。
圖6 升級(jí)過(guò)程
升級(jí)應(yīng)用程序首先需要軟/硬重啟系統(tǒng)來(lái)加載SSL。SSL啟動(dòng)后首先初始化系統(tǒng)硬件,向上位機(jī)發(fā)出是否升級(jí)的確認(rèn)信息。如果在5秒內(nèi)沒(méi)有得到上位機(jī)的回復(fù),系統(tǒng)將進(jìn)行正常的啟動(dòng)流程。用戶也可以自定義等待時(shí)間(不超過(guò)10秒)。如果SPI FLASH中沒(méi)有有效的啟動(dòng)碼流,SSL會(huì)強(qiáng)制讓用戶升級(jí)新的應(yīng)用程序。得到確認(rèn)升級(jí)的消息后,SSL要求上位機(jī)發(fā)送啟動(dòng)碼流。當(dāng)上位機(jī)發(fā)送完成全部碼流后,它要發(fā)送一個(gè)用戶定義的結(jié)束標(biāo)志符(不要和LDR文件中的數(shù)據(jù)重合)通知SSL傳輸過(guò)程完成。然后SSL對(duì)緩存在SDRAM中的數(shù)據(jù)進(jìn)行CRC校驗(yàn)并將結(jié)果反饋到上位機(jī)。如果校驗(yàn)失敗,SSL會(huì)讓用戶選擇重新升級(jí),還是放棄升級(jí)后啟動(dòng)上一次使用的應(yīng)用程序。CRC校驗(yàn)成功后,SSL將更新SPI FLASH中LDR文件和狀態(tài)標(biāo)志位。全部過(guò)程結(jié)束后SSL直接調(diào)用bfrom_SpiBoot函數(shù)加載應(yīng)用程序,不需要重新啟動(dòng)系統(tǒng)。
SSL和應(yīng)用程序的LDR文件生成和FLASH燒寫(xiě)
應(yīng)用程序的LDR文件生成如下圖7所示,需要增加-CRC32選項(xiàng)使ELFLOADER生成帶有校驗(yàn)多項(xiàng)式的文件(請(qǐng)參考VDSP幫助文檔獲得該選項(xiàng)的具體信息)。SSL需要單獨(dú)生成一個(gè)LDR文件,并燒寫(xiě)到SPI FLASH起始地址0x0。一般SPI FLASH的最小擦除單位是扇區(qū),所以應(yīng)用程序要從SSL后面的第二個(gè)扇區(qū)開(kāi)始燒寫(xiě),并且要空出頭4個(gè)字節(jié)用來(lái)保存當(dāng)前LDR文件的狀態(tài)標(biāo)志位。
圖7 Load Option配置
總結(jié)
本文首先介紹了BF51x處理器的啟動(dòng)過(guò)程,LDR文件的解構(gòu)和一些高級(jí)的啟動(dòng)技術(shù),并在這些知識(shí)的基礎(chǔ)上實(shí)現(xiàn)了一個(gè)基于SSL的應(yīng)用程序在線升級(jí)。本文描述的SSL只實(shí)現(xiàn)了一個(gè)基本的程序升級(jí)要求,根據(jù)實(shí)際應(yīng)用的需要,嵌入式開(kāi)發(fā)者可以繼續(xù)擴(kuò)展SSL的功能,比如支持網(wǎng)絡(luò)升級(jí)等或定制自己的SSL。通過(guò)使用SSL,嵌入式開(kāi)發(fā)者可以非常迅速方便地升級(jí)應(yīng)用程序,節(jié)約升級(jí)成本,為客戶提供額外的產(chǎn)品價(jià)值。
評(píng)論
查看更多