扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

GD32 IAP升级——boot和app相互切换

01/18 08:25
1173
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

1 Keil工程设置

1.1 修改ROM

GD32内部Flash是一整块连续的内存,但是因为要分成boot和app,因此我们的boot工程和app工程要分别设置代码存放的地址。

举个例子:我这里用的是GD32E50x,内存大小为512k,我把前面16k作为boot分区,后面的496k作为app分区。那么Keil的ROM的配置如下:

分区 起始地址 大小
boot 0x8000000 0x04000
app 0x8004000 0x7C000

keil配置如下图:boot工程配置:

在这里插入图片描述

app工程配置:

在这里插入图片描述

1.2 Keil烧录配置

如果需要使用Keil一键烧录的话,要先修改一下烧录的配置,具体根据自己boot和app的分区来设置。boot配置参考:

在这里插入图片描述

app配置参考:

在这里插入图片描述

2 代码编写

2.1 app跳转

从boot跳转到app的代码参考:

app_func application;uint32_t app_address;void jump_to_app(uint32_t app_load_addr){    if (((*(__IO uint32_t*)app_load_addr) & 0x2FFE0000U) == 0x20000000U)     {        app_address = *(__IO uint32_t*) (app_load_addr + 4U);        application = (app_func) app_address;        /* initialize user application's stack pointer */        __set_MSP(*(__IO uint32_t*) app_load_addr);        /* jump to user application */        application();    }}

完整用法示例:

#include "main.h"#define APP_LOADED_ADDR    0x08004000Uapp_func application;uint32_t app_address;void jump_to_app(uint32_t app_load_addr){    if (((*(__IO uint32_t*)app_load_addr) & 0x2FFE0000U) == 0x20000000U)     {        app_address = *(__IO uint32_t*) (app_load_addr + 4U);        application = (app_func) app_address;        /* initialize user application's stack pointer */        __set_MSP(*(__IO uint32_t*) app_load_addr);        /* jump to user application */        application();    }}int main(void){    systick_config();    jump_to_app(APP_LOADED_ADDR);    while(1)    {    }}

2.2 软件重启

在app运行期间,如果需要重新进入boot,可以通过软件重启实现,参考代码如下:

NVIC_SystemReset();

NVIC_SystemReset()函数原形如下:

/**  brief   System Reset  details Initiates a system reset request to reset the MCU. */__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void){  __DSB();                                                          /* Ensure all outstanding memory accesses included                                                                       buffered write are completed before reset */  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */  __DSB();                                                          /* Ensure completion of memory access */  for(;;)                                                           /* wait until reset */  {    __NOP();  }}

2.3 app中断向量表偏移

GD32的Flash存放了程序固件,默认从0x08000000开始启动,前面的部分是中断向量表,在做了boot和app的区分后,从0x08000000开始运行的是boot的中断向量,它在跳转到app以后就失效了,因此需要重新映射app的中断向量表。做法是在app的程序里面,修改中断向量表偏移,如下:

#define VECT_TAB_OFFSET  (uint32_t)0x4000            /* vector table base offset */

注:上述代码在system_gd32e50x.c里面定义,具体偏移多少取决于你app分区的起始地址,计算方法是:偏移 = app起始地址 - 0x08000000。

结束语

好了,关于GD32如何切换boot和app就讲到这里,有什么问题欢迎评论区留言。

相关推荐