在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

bootloader的原理及實現過程詳解

嵌入式應用開發 ? 來源:嵌入式應用開發 ? 作者:嵌入式應用開發 ? 2022-06-18 17:57 ? 次閱讀

一、背景

嵌入式操作系統中,BootLoader是在操作系統內核運行之前運行。可以初始化硬件設備、建立內存空間映射圖,從而將系統的軟硬件環境帶到一個合適狀態,以便為最終調用操作系統內核準備好正確的環境。在嵌入式系統中,通常并沒有像BIOS那樣的固件程序

二、實現思路

bootloader其實就是一段啟動程序,它在芯片啟動的時候首先被執行,它可以用來做一些硬件的初始化,當初始化完成之后跳轉到對應的應用程序中去。

我們可以將內存分為兩個區,一個是啟動程序區(0x0800 0000 - 0x0800 2000 )大小為8K Bytes,剩下的為應用程序區(0x0800 2000 - 0x0801 0000)。

芯片上電時先運行啟動程序,然后跳轉到應用程序區執行應用程序。

三、程序跳轉

bootloader一個主要的功能就是首先程序的跳轉。在STM32中只要將要跳轉的地址直接寫入PC寄存器,就可以跳轉到對應的地址中去。

怎么實現呢?

當我們實現一個函數的時候,這個函數最終會占用一段內存,而它的函數名代表的就是這段內存的起始地址。當我們調用這個函數的時候,單片機會將這段

內存的首地址(函數名對應的地址)加載到PC寄存器中,從而跳轉到這段代碼來執行。那么我們也可以利用這個原理,定義一個函數指針,將這個指針指向我們

想要跳轉的地址,然后調用這個函數,就可以實現程序的跳轉了。

代碼如下:

#define  APP_ADDR  0x08002000   //應用程序首地址定義 
typedef void (*APP_FUNC)(); //函數指針類型定義

APP_FUNC jump2app; //定義一個函數指針

jump2app = ( APP_FUNC )(APP_ADDR + 4); //給函數指針賦值
jump2app(); //調用函數指針,實現程序跳轉

上面的代碼實現了我們要的跳轉功能,但是為什么要跳轉到(APP_ADDR + 4) 這個地址,而不是APP_ADDR.

首先我們要了解主控芯片的啟動過程。以STM32為例,在芯片上電的時候,首先會從內存地址位0x0800 0000(由啟動模式決定)的地方加載棧頂地址(4字節),從0x0800 0004的地方加載程序復位地址(4字節),然后跳轉到對應的復位地址去執行。

所以上面的程序會中,jump2app這個函數指針的地址為(APP_ADDR + 4),調用這個函數指針的時候,芯片內核會自動跳轉到這個指針指向的內存地址,也即是應用程序的復位地址。

四、加載棧地址

實際運行會發現,上面的程序可能會出現問題。因為我們還缺少了一個棧地址的加載過程,也就是芯片上電的第一個動作。這里要用到一點匯編的知識:

__asm void MSR_MSP(uint32_t addr)
{
    MSR MSP, r0
    BX r14;
}
__asm void MSR_MSP(uint32_t addr) 是MDK嵌入式匯編形式。

MSR MSP, r0 意思是將r0寄存器中的值加載到MSP(主棧寄存器,復位時默認使用)寄存器中,r0中保存的是參數值,即addr的值

BX r14 跳轉到連接寄存器保存的地址中,即退出函數,跳轉到函數調用地址

完整的程序如下:

#define APP_ADDR 0x08002000 //應用程序首地址定義 
typedef void (*APP_FUNC)(); //函數指針類型定義

/**
  * @brief
  * @param
  * @retval
  */
__asm void MSR_MSP(uint32_t addr)
{
    MSR MSP, r0
    BX r14;
}


/**
  * @brief
  * @param
  * @retval
  */
void run_app(uint32_t app_addr)
{
    uint32_t reset_addr = 0;
    APP_FUNC jump2app;
    
    /* 跳轉之前關閉相應的中斷 */
    NVIC_DisableIRQ(SysTick_IRQn);
    NVIC_DisableIRQ(LPUART_IRQ);
    
    /* 棧頂地址是否合法(這里sram大小為8k) */
    if(((*(uint32_t *)app_addr)&0x2FFFE000) == 0x20000000)
    {
        /* 設置棧指針 */
        MSR_MSP(app_addr);
        /* 獲取復位地址 */
        reset_addr = *(uint32_t *)(app_addr+4);
        jump2app = ( APP_FUNC )reset_addr;
        jump2app();
    }
    else
    {
        printf("APP Not Found!n");
    }
}

五、編譯設置

我們需要在設置界面將默認(0x8000000)改為我們的應用程序地址(0x8002000)

poYBAGKtoIGAOtpZAAGKkMPFU-E907.png

六、中斷向量表重映射

完成了上面的工作,實際測試發現程序還是無法正確運行。原因是我們沒有進行中斷向量表的重映射。向量表映射?什么時候有做過這個工作,我們來看一下:

.s文件里有如下代碼:

; Reset handler routine
Reset_Handler    PROC
                 EXPORT  Reset_Handler                 [WEAK]
        IMPORT  __main
        IMPORT  SystemInit  
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

這代碼表示,程序在執行main函數之前,會先執行SystemInit這個函數。下面看看這個函數:

/**
  * @brief  Setup the microcontroller system.
  * @param  None
  * @retval None
  */
void SystemInit (void)
{
/*!< Set MSION bit */
  RCC->CR |= (uint32_t)0x00000100U;

  /*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], MCOSEL[2:0] and MCOPRE[2:0] bits */
  RCC->CFGR &= (uint32_t) 0x88FF400CU;

  /*!< Reset HSION, HSIDIVEN, HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFF6U;

  /*!< Reset HSI48ON  bit */
  RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;

  /*!< Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFFU;

  /*!< Reset PLLSRC, PLLMUL[3:0] and PLLDIV[1:0] bits */
  RCC->CFGR &= (uint32_t)0xFF02FFFFU;

  /*!< Disable all interrupts */
  RCC->CIER = 0x00000000U;

  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

從上面的代碼可以看到,這個函數主要是做了時鐘的初始化和中斷初始化,還有就是中斷向量表的映射,就是最后那一段代碼

poYBAGKtoMKAO1bzAAD8OXA5lO8440.png

再看看FLASH_BASE 和 VECT_TAB_OFFSET的定義:

poYBAGKtoOCAIUjEAAEZB3-GFsQ012.png

這里默認映射地址就是FLASH的初始地址,所以只要將其改成我們程序的起始地址就行了: SCB->VTOR = 0x08002000

編譯,運行,下載.

七、總結

程序跳轉完成,對于bootloader來說也就完成了一大半。剩下的就是根據自己的需求去完善相應功能了,比如我的在線升級功能,就要在bootloader里做固件接收和校驗的功能。這里有一點需要特別注意的是,跳轉程序之前最好把你用到的中斷都關了,不然跳轉之后的程序沒有對應的中斷處理函數,那就又可能使得程序進入死循環中。

審核編輯:符乾江

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5082

    文章

    19123

    瀏覽量

    305150
  • Boot
    +關注

    關注

    0

    文章

    149

    瀏覽量

    35837
收藏 人收藏

    評論

    相關推薦

    自定義RISC V的bootloader-v2

    在生成SoC時,會生成一個預定義bootloader .bin文件,用于指定soc的工程運行的地址,這包括在flash的存儲地址 ,加載到外存中的運行地址及在外存中分配的存儲空間的大小 。下面我們
    的頭像 發表于 10-31 12:37 ?616次閱讀
    自定義RISC V的<b class='flag-5'>bootloader</b>-v2

    SATA主機協議的物理層的實現過程

    這里講解SATA主機協議的物理層的實現過程
    的頭像 發表于 10-22 15:17 ?295次閱讀
    SATA主機協議的物理層的<b class='flag-5'>實現</b><b class='flag-5'>過程</b>

    bootloader和應用程序之間共享FEE塊

    電子發燒友網站提供《在bootloader和應用程序之間共享FEE塊.pdf》資料免費下載
    發表于 10-10 09:18 ?0次下載
    在<b class='flag-5'>bootloader</b>和應用程序之間共享FEE塊

    如何開發不帶Flash API 的Bootloader實現在線升級

    電子發燒友網站提供《如何開發不帶Flash API 的Bootloader實現在線升級.pdf》資料免費下載
    發表于 09-12 09:41 ?0次下載
    如何開發不帶Flash API 的<b class='flag-5'>Bootloader</b><b class='flag-5'>實現</b>在線升級

    簡述拉曼散射效應的實現過程

    拉曼散射效應,作為一種重要的光學現象,其實現過程涉及光與物質之間復雜的相互作用。以下將詳細闡述拉曼散射效應的實現過程,包括基本原理、實驗觀察、理論解釋以及應用等方面。
    的頭像 發表于 08-16 17:08 ?551次閱讀

    PLC對模擬量信號的處理過程及方法 詳解

    )。 PLC通過計算轉換,將這些模擬量信號轉換為內部的數值信號。從而實現系統的監控及控制。從現場的物理信號到PLC內部處理的數值信號,有以下幾個步驟: 從以上PLC模擬量的信號輸入流程可以看到,在自動化過程控制系統中,模擬量信號的輸入是非
    的頭像 發表于 07-30 16:31 ?419次閱讀
    PLC對模擬量信號的處理<b class='flag-5'>過程</b>及方法 <b class='flag-5'>詳解</b>版

    YTM32的HA系列微控制器啟動過程詳解

    見,以確保信息安全的需要。然而,開發者在自行編譯固件時,需要配合BOOT ROM中的bootloader,才能正常地引導到用戶應用程序,完成啟動過程
    的頭像 發表于 07-15 09:24 ?424次閱讀
    YTM32的HA系列微控制器啟動<b class='flag-5'>過程</b><b class='flag-5'>詳解</b>

    LwIP協議棧源碼詳解—TCP/IP協議的實現

    電子發燒友網站提供《LwIP協議棧源碼詳解—TCP/IP協議的實現.pdf》資料免費下載
    發表于 07-03 11:22 ?3次下載

    IDF-4.4.2在修改boot過程中,編譯有提示bootloader受到partition-table offset的限制,為什么?

    我在 IDF-4.4.2在修改boot過程中,編譯有提示bootloader受到partition-table offset的限制,如下圖 可當我用menuconfig修改后,發現從0XC000
    發表于 06-14 06:27

    如何才能將Bootloader和Application關聯起來

    接下來,我們要利用該Bootloader調試目標Application Project,如何才能將Bootloader和Application關聯起來呢?就需要借助剛才提到的Bootloader Project Build所生成
    的頭像 發表于 06-12 14:32 ?698次閱讀
    如何才能將<b class='flag-5'>Bootloader</b>和Application關聯起來

    請問STM32的bootloader怎么制作?

    我對STM32也算是比較熟悉了,但是呢, 沒有弄過 STM32的bootloader。也不知道怎么弄的。像,Linux,藍牙等 都有 類型的demo 供你學習和開發。 請問,STM32的bootloader 官方有Demo嗎?謝謝!
    發表于 03-07 07:50

    STM32案例:BootLoader是怎么跳到App

    BootLoader項目程序和App項目程序是分開的,所以需要分別搭建對應的項目工程文件,分開搭建文件是為了好配置,同時也是方便對項目進行管理。
    發表于 03-04 09:35 ?4271次閱讀
    STM32案例:<b class='flag-5'>BootLoader</b>是怎么跳到App

    關于bootloader與bootloadable img合并的問題求解

    我們實現bootloader功能時, app0 當作bootloader, app1 當作bootloadable image,我們想讓app0和app1 訪問同一片EEPROM 8K的空間。但我
    發表于 02-21 08:17

    STM32無法進入片上Bootloader的處理方法

    STM32無法進入片上Bootloader的處理方法? 當STM32芯片無法進入片上Bootloader時,我們需要采取一系列的處理方法來解決這個問題。以下將詳細介紹一些常見的處理方法。 1.編程器
    的頭像 發表于 02-02 14:33 ?2084次閱讀

    請問IMC101T-038是否支持bootloader下載程序?

    想請問一下,038這款MCU是否支持bootloader下載程序呢?現在用這款芯片作為內置的風機驅動板,但用戶后期想升級程序,請問一下可以怎么實現呢?如果這個實現不了,有沒有其他型號的產品可以進行替換呢?只要能
    發表于 01-23 07:07
    主站蜘蛛池模板: 欧美xxx69| 2021色噜噜狠狠综曰曰曰| 亚洲haose在线观看| 8844aa在线毛片| 黄免费看| 色噜噜狠狠网站| 亚洲成人精品在线| 日韩一区二区视频| 激情五月婷婷在线| 综合五月天婷婷丁香| 久草资源站在线| h黄视频在线观看| 亚洲最大黄色网址| 人人射人人插| 爱爱免费网址| 欧美一级免费| 真人午夜a一级毛片| 在线黄色免费观看| 农村三级毛片| 午夜视频1000部免费看| 俺来也俺来也天天夜夜视频| 激情九月| 九九九色| 日日干狠狠干| 在线a亚洲老鸭窝天堂新地址| 日韩三级免费| 天天操你| 男人j进女人j视频| 日韩免费毛片视频| 手机午夜视频| 蝌蚪自拍网二区| 欧美久操| 色欲情狂| 亚洲精品美女在线观看| sihu在线| 国产免费啪啪| 色婷婷在线观看视频| freesexvideo性欧美2| 亚洲一区在线视频| 日韩一级在线| 久久国产免费福利永久|