GD32 IAP升级——boot和app相互切换
目录
- GD32 IAP升级——boot和app相互切换
- 1 Keil工程设置
- 1.1 修改ROM
- 1.2 Keil烧录配置
- 2 代码编写
- 2.1 app跳转
- 2.2 软件重启
- 2.3 app中断向量表偏移
- 结束语
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 0x08004000U
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();
}
}
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就讲到这里,有什么问题欢迎评论区留言。