加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 1 環(huán)境搭建
    • 2 BootLoader工作原理以及常見分區(qū)介紹
    • 3 BootLoader的制作
    • 4 燒錄下載配置
    • 5 運(yùn)行測試
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

STM32 IAP應(yīng)用開發(fā)——自制BootLoader

07/15 16:40
1萬
閱讀需 15 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

實(shí)際上,BootLoader不僅僅在操作系統(tǒng)上使用,在一些內(nèi)存小,功能應(yīng)用較為簡單的單片機(jī)設(shè)備上面也可以通過BootLoader來完成固件升級(jí)。

我之前也有發(fā)過一些關(guān)于STM32遠(yuǎn)程升級(jí)的文章,但用的是第三方BootLoader,而且是基于操作系統(tǒng)實(shí)現(xiàn)的。BootLoader占用的內(nèi)存也比較大,而且不開源。
所以這一講我就來介紹一下如何自己制作一個(gè)簡單的BootLoader程序。

1 環(huán)境搭建

關(guān)于STM32以及Keil的環(huán)境這里就不具體介紹了,網(wǎng)上教程也很多,不懂的同學(xué)自行查閱資料。

2 BootLoader工作原理以及常見分區(qū)介紹

不管用的是什么MCU,要實(shí)現(xiàn)固件升級(jí)都離不開BootLoader,BootLoader是一個(gè)統(tǒng)稱,它其實(shí)只是一段引導(dǎo)程序,在MCU啟動(dòng)的時(shí)候會(huì)先運(yùn)行這段代碼,判斷是否需要升級(jí),如果不需要升級(jí)就跳轉(zhuǎn)到APP分區(qū)運(yùn)行用戶代碼,如果需要升級(jí)則先通過一些硬件接口接收和搬運(yùn)要升級(jí)的新固件,然后再跳轉(zhuǎn)到APP分區(qū)運(yùn)行新固件,從而實(shí)現(xiàn)固件升級(jí)。

請(qǐng)?zhí)砑訄D片描述

常見分區(qū)方式介紹:

1.Application

沒有加入Bootloader之前,我們單片機(jī)內(nèi)部的flash就是一整塊的,所有的應(yīng)用代碼都放在這。

2.Bootloader + Application

在原有的flash區(qū)域里面劃分出兩個(gè)區(qū)域,Bootloader和Application,這種分區(qū)方式的好處在于既可以實(shí)現(xiàn)升級(jí)功能,App區(qū)又可以分到較大的空間,缺點(diǎn)是沒有存放新固件的區(qū)域,需要從外部導(dǎo)入進(jìn)來,而且一旦傳輸?shù)倪^程被異常打斷,那么原有的App代碼也無法正常運(yùn)行了,也就是傳說中的“變磚”。

請(qǐng)?zhí)砑訄D片描述

3.Bootloader + Application + Download

這種分區(qū)方式是比較萬能的一種,優(yōu)點(diǎn)是新固件是先存放到Download區(qū)的,哪怕搬運(yùn)的過程中出現(xiàn)異常中斷的情況,也不會(huì)“變磚”,缺點(diǎn)是需要單獨(dú)劃分一塊內(nèi)存跟APP區(qū)差不多的區(qū)域用來存放新固件,變相的減少了APP區(qū)的空間,對(duì)于內(nèi)存較小的單片機(jī)來說壓力就比較大了。

請(qǐng)?zhí)砑訄D片描述

4.Bootloader + Application1 + Application2

這種方式可以同時(shí)存在兩套App,優(yōu)點(diǎn)在于升級(jí)了新固件以后,還保留了原來的舊版固件,必要的時(shí)候還可以進(jìn)行版本的回退。

請(qǐng)?zhí)砑訄D片描述

5.Bootloader + Setting + Application + Download

這種方式跟第3種基本一樣,只是增加了一個(gè)區(qū)域用來存放升級(jí)相關(guān)的一些參數(shù)以及用戶的一些配置。

在這里插入圖片描述

3 BootLoader的制作

BootLoader的制作需要根據(jù)實(shí)際的需求來做,不同的運(yùn)行方式或者升級(jí)方式在做法上都是有區(qū)別的,包括BootLoader所需要的內(nèi)存空間也不盡相同。

不過不管是用什么方式,Bootloader都應(yīng)該盡可能做的更小更簡潔,這樣的話內(nèi)存的開銷就更小,對(duì)于內(nèi)存較小的MCU來說壓力就沒那么大了。

我下面要做的這個(gè)bootloader是上面講的常見分區(qū)方式里面的第5種。

分區(qū)介紹:

我用的是STM32F103,內(nèi)存是128K的(想用內(nèi)存更小的MCU也是可以的,改下各個(gè)分區(qū)的內(nèi)存分配就行了)。

分區(qū)表如下:

name offset size
boot 0x08000000 0x00003000
setting 0x08003000 0x00001000
app 0x08004000 0x0000E000
download 0x08012000 0x0000E000

功能描述:

運(yùn)行bootloader的時(shí)候先從setting里面讀一些參數(shù),確定是否需要升級(jí),如果需要,則把download分區(qū)的固件搬運(yùn)到app分區(qū),如果不需要升級(jí)則直接跳轉(zhuǎn)到app分區(qū).
至于新固件的下載傳輸過程,我放到App里面去處理了,這跟我的項(xiàng)目實(shí)際需求有關(guān)系,App部分這里就先不往下拓展了,后面我會(huì)專門寫一篇博客來介紹。

各個(gè)功能模塊的具體講解:

1、分區(qū)定義

先把各個(gè)分區(qū)的內(nèi)存地址以及大小定義好,方便后面使用。

#define FLASH_SECTOR_SIZE       1024
#define FLASH_SECTOR_NUM        128    // 128K
#define FLASH_START_ADDR        ((uint32_t)0x8000000)
#define FLASH_END_ADDR          ((uint32_t)(0x8000000 + FLASH_SECTOR_NUM * FLASH_SECTOR_SIZE))

#define BOOT_SECTOR_ADDR        0x08000000     // BOOT sector start address 
#define BOOT_SECTOR_SIZE        0x3000         // BOOT sector size
#define SETTING_SECTOR_ADDR     0x08003000     // SETTING sector start address 
#define SETTING_SECTOR_SIZE     0x1000         // SETTING sector size
#define APP_SECTOR_ADDR         0x08004000     // APP sector start address  
#define APP_SECTOR_SIZE         0xE000         // APP sector size
#define DOWNLOAD_SECTOR_ADDR    0x08012000     // Download sector start address
#define DOWNLOAD_SECTOR_SIZE    0xE000         // Download sector size   

2、程序跳轉(zhuǎn)

Bootloader作為引導(dǎo)程序,最重要的工作之一就是通過內(nèi)存跳轉(zhuǎn)進(jìn)入用戶程序,下面這段代碼可以跳轉(zhuǎn)到任何一個(gè)內(nèi)存地址。

uint8_t jump_app(uint32_t app_addr) 
{
    uint32_t jump_addr;
    jump_callback cb;
    if (((*(__IO uint32_t*)app_addr) & 0x2FFE0000 ) == 0x20000000) 
    {  
        jump_addr = *(__IO uint32_t*) (app_addr + 4);  
        cb = (jump_callback)jump_addr;  
        __set_MSP(*(__IO uint32_t*)app_addr);  
        cb();
        return 1;
    } 
    return 0;
}

3、處理函數(shù)

從setting區(qū)里面讀取process狀態(tài)值,然后進(jìn)行對(duì)應(yīng)的處理,如果需要升級(jí)則把download區(qū)的固件搬運(yùn)到app區(qū),然后再運(yùn)行新APP,如果不需要升級(jí)則直接跳轉(zhuǎn)到APP。

process = get_boot_state();
switch (process) 
{
    case START_PROGRAM:
        printf("start app...rn");
        delay_ms(50);
        if (!jump_app(APP_SECTOR_ADDR)) 
        {
            printf("no programrn");
            delay_ms(1000);
        }
        printf("start app failedrn");
        break;
    case UPDATE_PROGRAM:
        printf("update app program...rn");
        app_addr = APP_SECTOR_ADDR;
        down_addr = DOWNLOAD_SECTOR_ADDR;

        printf("app addr: 0x%08X rn", app_addr);
        printf("down addr: 0x%08X rn", down_addr);

        printf("erase mcu flash...rn");
        mcu_flash_erase(app_addr, APP_ERASE_SECTORS);  
        printf("mcu flash erase successrn");
    
        printf("write mcu flash...rn");
        // memset(down_buf, 0, sizeof(down_buf));
        for (i = 0; i < APP_ERASE_SECTORS * 8; i++)
        {
            mcu_flash_read(down_addr, &down_buf[0], 128);
            delay_ms(5);
            mcu_flash_write(app_addr, &down_buf[0], 128);
            delay_ms(5);
            down_addr += 128;
            app_addr += 128;
        }
        printf("mcu flash write successrn");

        set_boot_state(UPDATE_SUCCESS);
        break;
    case UPDATE_SUCCESS:
        printf("update successrn");
        boot_state = UPDATE_SUCCESS_STATE;
        write_setting_boot_state(boot_state);
        set_boot_state(START_PROGRAM);
        break;
    default:
        break;
}

完整代碼下載地址:https://download.csdn.net/download/ShenZhen_zixian/87462312

4 燒錄下載配置

我們的Bootloader做好以后需要燒錄到MCU里面,可以直接用Keil uVison來下載,也可以用J-Flash或者其他,這個(gè)都沒關(guān)系,但是要注意內(nèi)存的分配,要把固件燒到對(duì)應(yīng)的內(nèi)存地址上。

我這里做出來的bootloader bin只有8K,不過為了方便后續(xù)在這部分增加新功能,我實(shí)際分配了12K的空間,地址區(qū)間是0x08000000-0x08003000。

如果是用keil下載的話,需要注意flash的配置,具體如下:

請(qǐng)?zhí)砑訄D片描述
請(qǐng)?zhí)砑訄D片描述

如果是用J-Flash或者STlink的工具燒錄的話注意燒錄的起始地址是0x08000000就好了。

5 運(yùn)行測試

注:這里我沒講解App部分代碼,你們只看Bootloader部分的log就好了,不影響的,想看APP部分可以看我另外一篇文章,或者下載完整的代碼實(shí)際跑一下也行。APP部分講解:STM32 IAP應(yīng)用開發(fā)——通過USB實(shí)現(xiàn)固件升級(jí)

運(yùn)行結(jié)果:

不需要升級(jí)時(shí)直接跳轉(zhuǎn)到App區(qū),如下圖:

請(qǐng)?zhí)砑訄D片描述

需要升級(jí)時(shí)先從download區(qū)搬運(yùn)新固件到app區(qū),然后再跳轉(zhuǎn)到App區(qū),如下圖:

請(qǐng)?zhí)砑訄D片描述

結(jié)束語

好了,關(guān)于自制BootLoader的介紹就講到這里,本文只是提供一個(gè)思路,不是唯一的方法,關(guān)鍵還是看你自己實(shí)際的需求。

還有App那部分這里沒詳細(xì)講,我單獨(dú)寫了一篇文章,鏈接在下方,合到一起看就比較清晰了?;蛘吣阋部梢韵螺d完整的源碼自己去跑一下,下面的源碼我把BootLoader和APP都上傳了。

APP部分講解:STM32 IAP應(yīng)用開發(fā)——通過USB實(shí)現(xiàn)固件升級(jí)

完整代碼下載地址:https://download.csdn.net/download/ShenZhen_zixian/87462312

如果你有什么問題或者有更好的方法,歡迎在評(píng)論區(qū)留言。

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
3294-15SURC/S400-A6 1 Everlight Electronics Co Ltd Single Color LED, Brilliant Red, Water Clear, T-1, 3mm, ROHS COMPLIANT PACKAGE-2
暫無數(shù)據(jù) 查看
SN74LVC1G08DCKR 1 Texas Instruments Single 2-input, 1.65-V to 5.5-V AND gate 5-SC70 -40 to 125

ECAD模型

下載ECAD模型
$0.26 查看
LFXTAL058124REEL 1 IQD Frequency Products Parallel - Fundamental Quartz Crystal, 24MHz Nom
暫無數(shù)據(jù) 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜