STM32 IAP应用开发——自制BootLoader

这篇具有很好参考价值的文章主要介绍了STM32 IAP应用开发——自制BootLoader。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32 IAP应用开发——自制BootLoader

前言

什么是IAP?

IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到数据存储区,从而实现固件升级。

什么是BootLoader?

百度百科:在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。

实际上,BootLoader不仅仅在操作系统上使用,在一些内存小,功能应用较为简单的单片机设备上面也可以通过BootLoader来完成固件升级。

我之前也有发过一些关于STM32远程升级的文章,但用的是第三方BootLoader,而且是基于操作系统实现的。BootLoader占用的内存也比较大,而且不开源。
所以这一讲我就来介绍一下如何自己制作一个简单的BootLoader程序。

1 环境搭建

关于STM32以及Keil的环境这里就不具体介绍了,网上教程也很多,不懂的同学自行查阅资料。

2 BootLoader工作原理以及常见分区介绍

不管用的是什么MCU,要实现固件升级都离不开BootLoader,BootLoader是一个统称,它其实只是一段引导程序,在MCU启动的时候会先运行这段代码,判断是否需要升级,如果不需要升级就跳转到APP分区运行用户代码,如果需要升级则先通过一些硬件接口接收和搬运要升级的新固件,然后再跳转到APP分区运行新固件,从而实现固件升级。
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

常见分区方式介绍:
1.Application
没有加入Bootloader之前,我们单片机内部的flash就是一整块的,所有的应用代码都放在这。
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

2.Bootloader + Application
在原有的flash区域里面划分出两个区域,Bootloader和Application,这种分区方式的好处在于既可以实现升级功能,App区又可以分到较大的空间,缺点是没有存放新固件的区域,需要从外部导入进来,而且一旦传输的过程被异常打断,那么原有的App代码也无法正常运行了,也就是传说中的“变砖”。
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

3.Bootloader + Application + Download
这种分区方式是比较万能的一种,优点是新固件是先存放到Download区的,哪怕搬运的过程中出现异常中断的情况,也不会“变砖”,缺点是需要单独划分一块内存跟APP区差不多的区域用来存放新固件,变相的减少了APP区的空间,对于内存较小的单片机来说压力就比较大了。
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

4.Bootloader + Application1 + Application2
这种方式可以同时存在两套App,优点在于升级了新固件以后,还保留了原来的旧版固件,必要的时候还可以进行版本的回退。
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

5.Bootloader + Setting + Application + Download
这种方式跟第3种基本一样,只是增加了一个区域用来存放升级相关的一些参数以及用户的一些配置。
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

3 BootLoader的制作

BootLoader的制作需要根据实际的需求来做,不同的运行方式或者升级方式在做法上都是有区别的,包括BootLoader所需要的内存空间也不尽相同。
不过不管是用什么方式,Bootloader都应该尽可能做的更小更简洁,这样的话内存的开销就更小,对于内存较小的MCU来说压力就没那么大了。

我下面要做的这个bootloader是上面讲的常见分区方式里面的第5种。
分区介绍:
我用的是STM32F103,内存是128K的(想用内存更小的MCU也是可以的,改下各个分区的内存分配就行了)。

分区表如下:

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

功能描述:
运行bootloader的时候先从setting里面读一些参数,确定是否需要升级,如果需要,则把download分区的固件搬运到app分区,如果不需要升级则直接跳转到app分区.
至于新固件的下载传输过程,我放到App里面去处理了,这跟我的项目实际需求有关系,App部分这里就先不往下拓展了,后面我会专门写一篇博客来介绍。

各个功能模块的具体讲解:
1、分区定义
先把各个分区的内存地址以及大小定义好,方便后面使用。

#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、程序跳转
Bootloader作为引导程序,最重要的工作之一就是通过内存跳转进入用户程序,下面这段代码可以跳转到任何一个内存地址。

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、处理函数
从setting区里面读取process状态值,然后进行对应的处理,如果需要升级则把download区的固件搬运到app区,然后再运行新APP,如果不需要升级则直接跳转到APP。

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

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

        printf("erase mcu flash...\r\n");
        mcu_flash_erase(app_addr, APP_ERASE_SECTORS);  
        printf("mcu flash erase success\r\n");
    
        printf("write mcu flash...\r\n");
        // 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 success\r\n");

        set_boot_state(UPDATE_SUCCESS);
        break;
    case UPDATE_SUCCESS:
        printf("update success\r\n");
        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或者其他,这个都没关系,但是要注意内存的分配,要把固件烧到对应的内存地址上。
我这里做出来的bootloader bin只有8K,不过为了方便后续在这部分增加新功能,我实际分配了12K的空间,地址区间是0x08000000-0x08003000。

如果是用keil下载的话,需要注意flash的配置,具体如下:
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件
如果是用J-Flash或者STlink的工具烧录的话注意烧录的起始地址是0x08000000就好了。

5 运行测试

注:这里我没讲解App部分代码,你们只看Bootloader部分的log就好了,不影响的,想看APP部分可以看我另外一篇文章,或者下载完整的代码实际跑一下也行。APP部分讲解:STM32 IAP应用开发——通过USB实现固件升级

运行结果:
不需要升级时直接跳转到App区,如下图:
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

需要升级时先从download区搬运新固件到app区,然后再跳转到App区,如下图:
ota bootloader,OTA,经验分享,单片机相关,stm32,单片机,嵌入式硬件

结束语

好了,关于自制BootLoader的介绍就讲到这里,本文只是提供一个思路,不是唯一的方法,关键还是看你自己实际的需求。
还有App那部分这里没详细讲,我单独写了一篇文章,链接在下方,合到一起看就比较清晰了。或者你也可以下载完整的源码自己去跑一下,下面的源码我把BootLoader和APP都上传了。

APP部分讲解:STM32 IAP应用开发——通过USB实现固件升级
完整代码下载地址:https://download.csdn.net/download/ShenZhen_zixian/87462312

如果你有什么问题或者有更好的方法,欢迎在评论区留言。

更多相关文章:
STM32固件升级系列合集:https://blog.csdn.net/ShenZhen_zixian/article/details/129074047文章来源地址https://www.toymoban.com/news/detail-635730.html

到了这里,关于STM32 IAP应用开发——自制BootLoader的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 IAP应用开发——通过串口/RS485实现固件升级(方式1)

    什么是IAP? IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就

    2024年02月10日
    浏览(30)
  • STM32 IAP应用开发——通过串口/RS485实现固件升级(方式2)

    什么是IAP? IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。在应用编程(IAP)是用户的应用代码对片内Flash存储器进行擦除/编程的方法。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就

    2024年02月14日
    浏览(37)
  • STM32 ——bootloader IAP

    本文使用单片机型号:STM32F104xx IAP(In Application Programming) 是用户自己的程序在运行过程中对 User Flash 的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的通信口对产品中的固件程序进行更新升级。为了实现 IAP 功能,系统将分为 bootloader 和 app 两部分。bo

    2023年04月09日
    浏览(24)
  • STM32/GD32 BootLoader升级 IAP升级

    如果我们的App 程序起始地址在0x08006000 ,并且App 的中断向量表在起始地址,那么BootLoader 程序下载App 后,为了App 程序能正确运行,开始App 程序的运行后第一步,就要把中断向量表重定位到0x08006000 那里。 我们的BootLoader下载App程序后,App程序就需要做同样的事情。主要有三个

    2024年02月11日
    浏览(46)
  • STM32之Bootloader、USB、IAP/DFU下载

    STM32 IAP应用开发——通过内置DFU实现USB升级(方式2) STM32 IAP应用开发——通过内置DFU实现USB升级(方式1) STM32程序下载4:通过STM32CubePro-USB下载 STM32程序下载3:通过STM32CubePro-UART下载 STM32程序下载2:通过STM32CubePro-ST-Link下载 如何使用串口来给STM32下载程序 通过STM32内置的U

    2024年02月02日
    浏览(33)
  • 【STM32】IAP升级01 bootloader实现以及APP配置(主要)

    通过之前的了解 之前的了解,我们知道实现IAP升级需要两个条件: 1.APP程序必须在 IAP 程序之后的某个偏移量为 x 的地址开始; 2.APP程序的中断向量表相应的移动,移动的偏移量为 x; 默认条件下的起始地址 默认的条件下,图中 IROM1 的起始地址(Start)一般为 0x08000000,大小

    2024年02月03日
    浏览(34)
  • 基于STM32单片机BOOTLOADER通过串口升级程序IAP——APP方案

                            此方法前提是你得有一个EEPROM         我用的单片机是STM32F103ZET6 , 此单片机FLASH容量为512KB; 在此单片机里面FLASH的起始地址是0X8000000,BOOT作为引导加载程序一般都是从这个地址开始,单片机一上点默认会从这个地址开始运行,所以将自己

    2024年02月04日
    浏览(42)
  • STM32G473 固件升级IAP(BootLoader)CAN/USART。(详细步骤)

    本例程仅供参考(个人学习总结_有需要文中有的封装好的跳转函数可私信), 例程可举一反三完成FDCAN通信和USART通信。 目录 简介 1.APP程序配置步骤 APP 程序起始地址设置方法 中断向量表的偏移量设置方法 KEIL5生成bin文件步骤 2.IAP(BootLoader 程序)配置(HAL库,Cubemax) 2.1

    2024年02月03日
    浏览(33)
  • STM32 ICP、ISP、IAP、Bootloader、SWD、JTAG究竟是什么?它们之间有什么关系?

    从代码写入单片机的方式上去区分主要分为3种:ICP、ISP、IAP 一、 ICP(In Circuit Programing) :在电路编程,可通过CPU的Debug Access Port 烧录代码,比如ARM Cortex的Debug Interface主要是SWD(Serial Wire Debug)或JTAG(Joint Test Action Group); ICP 主要通过CPU的DAP(Debug Access Port) 烧录代码,下面以ARM Cor

    2024年02月04日
    浏览(33)
  • 国民技术N32G430开发笔记(9)- IAP升级 Bootloader的制作

    1、上节提到Flash的分区,0x8000000-0x8004000为Boot分区,我们的bootloader就烧录到此分区。 Bootloader很简单,新建一个普通的工程, 也不用初始化外部设备,开机后,直接跳转到 App分区所在的地址即可, 当然App的分区程序也要提前烧录进去, 否则也是跳不过去的。 代码 开机延时

    2024年02月02日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包