STM32CubeIDE实现Bootloader

本文介绍了如何使用STM32CubeIDE开发Bootloader并实现从Bootloader跳转到APP程序。内容包括Bootloader中利用函数指针的三种跳转方案,设置Flash大小以防止擦除APP程序,以及在APP部分配置中断向量表偏移量和修改应用程序的Flash首地址和大小。
摘要由CSDN通过智能技术生成

一、简介

1.1、开发环境

STM32CubeIDE软件版本:V1.9.0。

单片机型号:STM32F103ZETx。

1.2、主要内容

使用STM32CubeIDE实现Bootloader跳转到APP程序。需分别建立Bootloader和APP两个工程。

二、Bootloader工程

Bootloader的CubeMX无需设置,直接生成程序。

2.1、Bootloader跳转程序

Bootloader跳转程序,主要是利用函数指针,让程序跳转到指定的应用程序地址。以下3种方案殊途同归,选择其一即可。

方案1:用typedef定义跳转函数指针的别名。


typedef void (*p_APP)(void);

/*
 * 功能:运行应用程程序
 * 输入:app_address:应用程序起始地址
 * 输出:
 * 备注: 
 */
void StartApplication(uint32_t app_address)
{
    p_APP application;
    uint32_t jump_address;

    if (((*(__IO uint32_t*)app_address) & 0x2FFE0000 ) == 0x20000000)
    {
        jump_address = *(__IO uint32_t*) (app_address + 4);
        application = (p_APP) jump_address;

      __set_MSP(*(__IO uint32_t*) app_address);

      application();
    }
}

方案2:直接定义函数指针。


/*
 * 功能:运行应用程程序
 * 输入:app_address:应用程序起始地址
 * 输出:
 * 备注: 
 */
void StartApplication(uint32_t app_address)
{
    void (*p_APP)(void);
    uint32_t jump_address;

    if (((*(__IO uint32_t*)app_address) & 0x2FFE0000 ) == 0x20000000)
    {
        jump_address = *(__IO uint32_t*) (app_address + 4);
        p_APP = (void(*)(void))jump_address;

        __set_MSP(*(__IO uint32_t*) app_address);

        (*p_APP)();
    }
}

方案3:跳转时,强制类型转换为函数指针。


/*
 * 功能:运行应用程程序
 * 输入:app_address:应用程序起始地址
 * 输出:
 * 备注: 
 */
void StartApplication(uint32_t app_address)
{
    uint32_t jump_address;

    if (((*(__IO uint32_t*)app_address) & 0x2FFE0000 ) == 0x20000000)
    {
        jump_address = *(__IO uint32_t*) (app_address + 4);

        __set_MSP(*(__IO uint32_t*) app_address);

        (*(void(*)(void))jump_address)();
    }
}

2.2、设置Flash大小

打开Bootloader工程下的文件STM32F103ZETX_FLASH.ld。

本文分配给Bootloader的程序空间为8K,因此将Flash的大小改为8K,具体如下:


/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 64K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 8K
}

注:用编译器烧录程序时,只会根据当前程序大小,以Flash页或扇区为最小单位,擦除需要用到的Flash页或扇区。因此只要Flash分区合理,用编译器烧写Bootloader程序时,也不会擦除已经烧录的APP程序。修改的目的,只是为了在Bootloader的程序大小超过8K后,编译时,软件会报错提醒。

2.3、跳转示例


#define ApplicationFlashAddress 0x08002000  //定义应用程序地址

int main(void)
{
    StartApplication(uint32_t app_address);
    while();
}

注:此处的应用程序地址,要和“3.2修改应用程序Flash首地址和大小”设置的APP程序Flash起始地址一致。

三、APP部分

APP根据需求,配置完CubeMX,再生成程序。

3.1、设置中断向量表偏移量

打开文件system_stm32f1xx.c。

找到如下位置:


#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */

主要修改内容:

(1)在语句“#if defined(USER_VECT_TAB_ADDRESS)”前面增加“#define USER_VECT_TAB_ADDRESS”;

(2)将“#define VECT_TAB_OFFSET 0x00000000U”改为“#define VECT_TAB_OFFSET 0x00002000”。

中断向量表偏移地址(0x00002000) = APP起始地址(0x08002000) - Flash起始地址(0x08000000)。

改后程序如下:


#define USER_VECT_TAB_ADDRESS                   //增加处1
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
     in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS   SRAM_BASE       /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00000000U     /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS   FLASH_BASE      /*!< Vector Table base address field.
                                                     This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET         0x00002000     //修改处1,0x00002000 = 应用程序地址 - 0x08000000
                                               /*!< Vector Table base offset field.
                                                     This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */

注:若找不到以上程序段,可全局搜索“VECT_TAB_OFFSET”。

3.2、修改应用程序Flash首地址和大小

打开APP工程下的文件STM32F103ZETX_FLASH.ld。

APP程序Flash起始地址(ORIGIN)改为0x08002000。注意与Bootloader设置的跳转地址一致。

APP程序Flash空间大小(LENGTH)改为32K。

具体如下:


/* Memories definition */
MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 64K
  FLASH    (rx)    : ORIGIN = 0x8002000,   LENGTH = 32K
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洪恒远

感君意气无所惜,一为歌行歌主客

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值