色欲av一区久久精品_久久综合色综合色88_无码在线观看不卡_色黄视频网站_亚洲国产精品久久久久秋霞66

技巧和竅門——干凈地從引導(dǎo)加載程序跳轉(zhuǎn)到應(yīng)用程序代碼

時(shí)間:2022-06-27

對于網(wǎng)站建設(shè)公司來說,引導(dǎo)加載程序幾乎包含在每個(gè)嵌入式系統(tǒng)中,并提供了一種在現(xiàn)場更新應(yīng)用程序代碼的好方法,而無需訪問編程端口。與引導(dǎo)加載程序一樣重要的是,嵌入式開發(fā)人員在嘗試從引導(dǎo)加載程序跳轉(zhuǎn)到他們的應(yīng)用程序代碼時(shí)經(jīng)常會被出錯(cuò)。跳躍需要干凈利落,但有幾個(gè)因素會導(dǎo)致問題,例如:


  一次寫入寄存器(例如看門狗寄存器)

  時(shí)鐘設(shè)置

  堆棧和程序指針

  外圍設(shè)置


  開發(fā)人員可以通過兩種不同的方式從引導(dǎo)加載程序干凈地過渡到應(yīng)用程序代碼。第一種方法涉及開發(fā)人員仔細(xì)匹配他們的應(yīng)用程序代碼和引導(dǎo)程序設(shè)置。例如,開發(fā)人員將匹配看門狗寄存器、時(shí)鐘設(shè)置,甚至可能匹配UART等外設(shè)。引導(dǎo)加載程序?qū)⑺羞@些組件初始化為已知的系統(tǒng)狀態(tài),并簡單地將程序執(zhí)行交給應(yīng)用程序代碼。這樣做的問題是,應(yīng)用程序代碼中的任何更改也需要在引導(dǎo)裝載程序中進(jìn)行更改。


  處理引導(dǎo)加載程序和應(yīng)用程序代碼之間跳轉(zhuǎn)的第二種也是更干凈的方法是遵循一個(gè)簡單的過程,將引導(dǎo)加載程序所涉及的任何設(shè)置恢復(fù)到它們最初的重置狀態(tài)。這將包括外設(shè),如GPIO、時(shí)鐘,甚至修改堆棧和程序計(jì)數(shù)器。當(dāng)嵌入式開發(fā)人員這樣做時(shí),應(yīng)用程序代碼完全不知道內(nèi)存中正在執(zhí)行另一個(gè)應(yīng)用程序,唯一需要匹配的設(shè)置是只能寫入一次的寄存器!


  準(zhǔn)備從引導(dǎo)程序跳轉(zhuǎn)到應(yīng)用程序代碼的過程很簡單,可以在下面找到:

  確認(rèn)應(yīng)用復(fù)位向量已經(jīng)編程

  驗(yàn)證應(yīng)用程序校驗(yàn)和及安全憑證

  對外設(shè)進(jìn)行去初始化,并將其置于復(fù)位狀態(tài)

  將向量表寄存器設(shè)置為應(yīng)用復(fù)位向量(ARM)

  將堆棧指針寄存器設(shè)置為應(yīng)用程序起始地址

  將程序計(jì)數(shù)器設(shè)置為復(fù)位向量(跳轉(zhuǎn)到應(yīng)用程序)


image.png


  讓我們簡單討論一下每一步。在引導(dǎo)加載程序做任何事情之前,它需要驗(yàn)證應(yīng)用程序的完整性。第一步是驗(yàn)證復(fù)位向量已經(jīng)編程,并且不是0xFFFFFFFF或0x00000000。通常,擦除的閃存會設(shè)置其所有位,因此如果我們看到這種狀態(tài),則引導(dǎo)加載程序知道有問題,應(yīng)該保持在引導(dǎo)加載程序中,這是一種已知的安全狀態(tài)。請記住,我們假設(shè)兩者之間的任何編程值都是正確的,這可能是一個(gè)糟糕的假設(shè),但對于今天嵌入式開發(fā)人員來說已經(jīng)足夠好了。


  接下來,引導(dǎo)裝載程序應(yīng)該對應(yīng)用程序空間執(zhí)行校驗(yàn)和計(jì)算,以確保應(yīng)用程序是有效的。同樣,如果在更新過程中出現(xiàn)問題,可能會有一個(gè)帶有復(fù)位向量的部分程序,如果沒有校驗(yàn)和,就無法知道這一點(diǎn)。最重要的是,引導(dǎo)裝載程序還應(yīng)該檢查任何數(shù)字簽名或安全措施,以確保不僅應(yīng)用程序是完整的,而且其來源也是正確的,它不是惡意軟件或修改過的程序。


  一旦引導(dǎo)裝載程序驗(yàn)證了應(yīng)用程序是完整的并且來自正確的來源,就該回到初始狀態(tài)了。任何被觸摸的非一次寫入的外設(shè)都應(yīng)該被放回到它們的復(fù)位狀態(tài)。最好的方法是查看所用的驅(qū)動器、驅(qū)動器初始化和訪問的寄存器,然后在數(shù)據(jù)手冊中查找這些寄存器。每個(gè)數(shù)據(jù)手冊都顯示了上電復(fù)位寄存器的值。對于每個(gè)被修改的寄存器,它們可以被復(fù)位到這些狀態(tài)。通常,我會避免更改時(shí)鐘寄存器、看門狗和一次寫入寄存器。我只是在應(yīng)用程序和引導(dǎo)裝載程序之間匹配這些狀態(tài)。


  對于網(wǎng)站建設(shè)公司來講,此時(shí),微控制器回到復(fù)位狀態(tài),并準(zhǔn)備運(yùn)行應(yīng)用程序代碼。在此之前,需要更新向量表寄存器,以指向應(yīng)用程序的向量表位置,而不是引導(dǎo)加載程序。中斷向量表可以位于任何地方,因此引導(dǎo)裝載程序和應(yīng)用程序鏈接器文件之間需要協(xié)調(diào)。例如,嵌入式開發(fā)人員將編寫如下單行代碼,其中PROGRAM_FLASH_BASE是應(yīng)用程序的第一個(gè)向量表位置:


  SCB _ VTOR =(uint 32 _ t)PROGRAM _ FLASH _ BASE;


  一旦完成了這些,就該跳到應(yīng)用程序了。開發(fā)人員可以通過幾種不同的方式從引導(dǎo)裝載程序跳轉(zhuǎn)到應(yīng)用程序。一種方法是簡單地取消引用應(yīng)用程序的重置向量位置。這樣做的問題是堆棧指針可能不在正確的位置,從而導(dǎo)致奇怪的行為。理想情況下,開發(fā)人員會設(shè)置堆棧指針,然后設(shè)置程序計(jì)數(shù)器。如何做到這一點(diǎn)將因微控制器而異。幾乎總是需要使用內(nèi)聯(lián)匯編代碼來完成(這是我唯一一次提倡編寫匯編代碼)。對于ARM微控制器,下面是一個(gè)示例代碼片段:


  void Flash _ start application(uint 32 _ t start address)

  {

  asm(" ldr SP,[r0,# 0]");

  asm("ldr PC,[r0,# 4]");

  }


  根據(jù)所使用的編譯器,確切的代碼會略有不同。內(nèi)聯(lián)匯編不是C標(biāo)準(zhǔn),所以每個(gè)編譯器供應(yīng)商都以不同的方式實(shí)現(xiàn)了它,或者在某些情況下根本沒有實(shí)現(xiàn)!讓我們來看看這是怎么回事。


  為了最小化匯編語言代碼,將匯編語言代碼包裝在C函數(shù)中是至關(guān)重要的。原因是當(dāng)startAddress被傳遞到Flash_StartApplication函數(shù)中時(shí),它會自動存儲在寄存器r0中。有了這些知識,就沒有理由添加額外的匯編語言指令來將所需的起始地址加載到寄存器中。(是的,它為我們節(jié)省了一條匯編指令,但這樣做也更容易維護(hù),更靈活)。然后,第一條匯編指令是獲取存儲在寄存器r0中偏移量為0(# 0)的值,并將其復(fù)制到堆棧指針(SP)寄存器。然后,第二條指令告訴處理器將r0中存儲的值加上偏移量4 (#4),并將其復(fù)制到程序計(jì)數(shù)器(PC)寄存器中。偏移量4實(shí)際上是將r0中存儲的值加4。執(zhí)行的下一條指令將是應(yīng)用程序代碼的復(fù)位向量。我們剛剛成功地進(jìn)入了應(yīng)用程序!


  這就是全部了!按照這個(gè)過程,嵌入式開發(fā)人員現(xiàn)在可以很容易地從引導(dǎo)加載程序跳轉(zhuǎn)到你的應(yīng)用程序代碼,并確保它將按照你期望的方式運(yùn)行.。


Copyright ? 2016 廣州思洋文化傳播有限公司,保留所有權(quán)利。 粵ICP備09033321號

與項(xiàng)目經(jīng)理交流
掃描二維碼
與項(xiàng)目經(jīng)理交流
掃描二維碼
與項(xiàng)目經(jīng)理交流
ciya68