作者 | strongerHuang
微信公眾號 | strongerHuang
之前從應用的角度給大家分享過Bootloader相關的文章,今天從底層原理來給大家描述ARM處理器如何編寫Bootloader。
1關于Bootloader
Bootloader顧名思義就是引導加載程序,是在操作系統或應用程序運行之前的一段程序,是在系統上電后執行的一段程序代碼。
BootLoader是嚴重地依賴于硬件而實現的,特別是在嵌入式平臺。因此,在嵌入式平臺里建立一個通用的BootLoader幾乎是不可能的。盡管如此,我們仍然可以對bootloader歸納出一些通用的概念來,以指導用戶特定的BootLoader設計與實現。
---來源百度百科
Bootloader在手機、電腦、眾多嵌入式系統中都存在,它的作用有很多,比如:初始化底層應用驅動、加載應用程序、更新應用程序等。
不同的設備,Bootloader可能差異很大,通常來說Bootloader比較依賴底層硬件和實際項目需求。
2如何編寫bootloader
bootloader是一段引導加載程序代碼,它更新用戶的應用程序代碼,可以使用很多硬件下載通道(例如USB、網絡端口)獲得新代碼。
在執行引導ROM之后,將執行bootloader程序,并在需要時進行更新,然后執行最終用戶應用程序。
引導加載程序和用戶應用程序應作為兩個獨立的Project或Object進行編寫和編譯,從而產生兩個獨立且可執行的(bin/hex)文件。
引導加載程序的主要任務是在必要時對用戶應用程序進行重新編程/替換,并跳轉至用戶應用程序以執行該程序,應用程序不一定需要知道引導加載程序的存在。
引導加載程序通常位于芯片閃存基址,下面通過一張圖來描述內存和Flash代碼映射關系:
有很多方法可以引導bootloader進入編程模式,以將用戶應用程序重新編程到Flash中,或者直接跳轉到現有的用戶應用程序來執行。最簡單的方法是檢查GPIO引腳以確定是否應進入編程模式。
大多數芯片供應商為用戶提供了一種方便的方式,例如 ISP 和 IAP 接口,bootloader將使用它們來更新閃存內容。
當Flash內容已更新或已經是最新時,引導加載程序將跳轉到用戶應用程序。在執行用戶應用程序之前,這需要許多步驟:
1.確保CPU處于特權模式。
2.禁用NVIC中所有啟用的中斷。
3.禁用所有可能產生中斷請求的使能外設,并清除這些外設中的所有未使用中斷標志。
4.清除NVIC中所有未使用的中斷請求。
5.禁用SysTick并清除其異常掛起位。
6.如果引導加載程序使用了單個故障處理程序,請禁用它們。
7.如果發現內核當前與PSP一起運行,則激活MSP(由于編譯器可能仍在使用堆棧,因此在此之前需要將PSP復制到MSP)。
8.將用戶應用程序的向量表地址加載到SCB-》 VTOR寄存器中。確保地址符合對齊要求。
9.最后一部分是將MSP設置為用戶應用程序向量表中找到的值,然后將用戶應用程序的重置向量值加載到PC中,也就是跳轉功能。
比如通過調用下面的示例BootJump()這樣的函數來完成此操作:
static void BootJump(uint32_t *Address){ //1.確保CPU處于特權模式。 if( CONTROL_nPRIV_Msk & __get_CONTROL()) { /* not in privileged mode */ EnablePrivilegedMode() ; } //2.禁用NVIC中所有啟用的中斷。 Disable_All_Peripherals(); //3.禁用所有可能產生中斷請求的使能外設,并清除這些外設中的所有未使用中斷標志。 NVIC-》ICER[ 0 ] = 0xFFFFFFFF; NVIC-》ICER[ 1 ] = 0xFFFFFFFF; NVIC-》ICER[ 2 ] = 0xFFFFFFFF; NVIC-》ICER[ 3 ] = 0xFFFFFFFF; NVIC-》ICER[ 4 ] = 0xFFFFFFFF; NVIC-》ICER[ 5 ] = 0xFFFFFFFF; NVIC-》ICER[ 6 ] = 0xFFFFFFFF; NVIC-》ICER[ 7 ] = 0xFFFFFFFF; //4.清除NVIC中所有未使用的中斷請求。 NVIC-》ICPR[ 0 ] = 0xFFFFFFFF; NVIC-》ICPR[ 1 ] = 0xFFFFFFFF; NVIC-》ICPR[ 2 ] = 0xFFFFFFFF; NVIC-》ICPR[ 3 ] = 0xFFFFFFFF; NVIC-》ICPR[ 4 ] = 0xFFFFFFFF; NVIC-》ICPR[ 5 ] = 0xFFFFFFFF; NVIC-》ICPR[ 6 ] = 0xFFFFFFFF; NVIC-》ICPR[ 7 ] = 0xFFFFFFFF; //5.禁用SysTick并清除其異常掛起位。 SysTick-》CTRL = 0; SCB-》ICSR |= SCB_ICSR_PENDSTCLR_Msk; //
6.如果引導加載程序使用了單個故障處理程序,請禁用它們。 SCB-》SHCSR &= ~( SCB_SHCSR_USGFAULTENA_Msk | \ SCB_SHCSR_BUSFAULTENA_Msk | \ SCB_SHCSR_MEMFAULTENA_Msk ) ; //7.如果發現內核當前與PSP一起運行,則激活MSP if( CONTROL_SPSEL_Msk & __get_CONTROL()) { /* MSP is not active */ __set_MSP( __get_PSP()) ; __set_CONTROL( __get_CONTROL() & ~CONTROL_SPSEL_Msk); } //8.將用戶應用程序的向量表地址加載到SCB-》 VTOR寄存器中。 SCB-》VTOR = ( uint32_t )Address ; //9.跳轉 BootJumpASM( Address[ 0 ], Address[ 1 ]);}
再次說明bootloader與底層硬件和實際需求有關,以上代碼僅供參考,主要是提供思路,方便大家理解。
責任編輯:haq
-
芯片
+關注
關注
455文章
50714瀏覽量
423158 -
ARM
+關注
關注
134文章
9084瀏覽量
367390 -
程序
+關注
關注
117文章
3785瀏覽量
81004 -
keil
+關注
關注
68文章
1212瀏覽量
166843
發布評論請先 登錄
相關推薦
評論