GD32单片机IAP升级教程实现Bootloader与应用程序跳转
1 Keil工程设置
在基于GD32系列MCU的嵌入式开发项目中,内部Flash通常被视作一个连续的逻辑存储空间。为了实现Bootloader(引导加载程序)与主应用程序(App)的物理隔离与独立运行,必须在Keil MDK开发环境中为两者分别配置专属的代码存储地址与空间大小。
1.1 修改ROM地址
我们以GD32E50x系列(Flash容量为512KB)为例进行说明。假设规划将前16KB(0x4000字节)分配给Bootloader,剩余496KB(0x7C000字节)分配给应用程序,则具体的内存地址划分如下表所示:
| 分区 | 起始地址 | 大小 |
|---|---|---|
| boot | 0x8000000 | 0x04000 |
| app | 0x8004000 | 0x7C000 |
地址规划完成后,需要在Keil的“Options for Target”对话框中进行具体配置。
Bootloader工程的ROM地址设置参考:

应用程序工程的ROM地址设置参考:

1.2 Keil烧录配置
若希望直接使用Keil集成环境的一键下载(Load)功能将程序烧录至指定分区,还需同步配置调试器(如J-Link、ULINK)的烧录选项,使其擦写范围与预设的Boot和App分区严格对应。
Bootloader工程的下载算法与地址范围配置参考:

应用程序工程的下载算法与地址范围配置参考:

2 代码编写
完成工程的基础配置后,实现Bootloader与App之间可靠切换的核心逻辑需要通过代码来完成,主要包括跳转函数、软件复位及中断向量表重映射。
2.1 从Boot跳转到App
Bootloader在执行完系统初始化、固件校验或更新等任务后,需要将CPU的控制权移交给应用程序。其核心跳转函数实现如下:
typedef void (*app_func)(void);
app_func application;
uint32_t app_address;
void jump_to_app(uint32_t app_load_addr)
{
// 校验目标地址内容是否为合法的栈顶指针(应位于RAM地址空间)
if (((*(__IO uint32_t*)app_load_addr) & 0x2FFE0000U) == 0x20000000U)
{
// 获取应用程序的复位中断服务程序(Reset_Handler)地址
app_address = *(__IO uint32_t*) (app_load_addr + 4U);
application = (app_func) app_address;
// 将应用程序的栈顶指针加载到主栈指针(MSP)
__set_MSP(*(__IO uint32_t*) app_load_addr);
// 执行跳转,进入应用程序
application();
}
}
在实际的Bootloader工程主函数中,调用方式如下:
#include "main.h"
#define APP_LOADED_ADDR 0x08004000U // 应用程序的起始地址
// ... (jump_to_app函数定义同上)
int main(void)
{
// 系统时钟、外设等初始化
systick_config();
// 执行跳转,启动应用程序
jump_to_app(APP_LOADED_ADDR);
while(1)
{
// 正常情况下,Bootloader执行流不应到达此处
}
}
2.2 软件重启
当应用程序在运行过程中需要主动返回Bootloader模式(例如,响应升级指令或发生严重错误),可以通过触发一次软件系统复位来实现。最简洁的方法是调用CMSIS标准库提供的函数:
NVIC_SystemReset();
该函数内部会向ARM Cortex-M内核的“应用程序中断与复位控制寄存器”(AIRCR)发起复位请求,其典型实现逻辑如下:
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
{
__DSB(); // 数据同步屏障,确保所有内存操作在复位前完成
// 写入AIRCR寄存器,请求系统复位
SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)
| (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk)
| SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); // 再次确保写操作完成
for(;;) // 等待复位生效
{
__NOP();
}
}
2.3 App中断向量表偏移
这是一个至关重要的步骤。GD32的Flash起始地址(0x08000000)默认存放着中断向量表。芯片上电启动后,内核会从该地址读取向量表。
当Bootloader跳转到App后,如果未做处理,CPU在响应中断时仍会去0x08000000地址查找向量表,而这部分现在是Bootloader的向量表,将导致程序跑飞。因此,应用程序必须在初始化阶段,重新设置向量表偏移寄存器(VTOR),将其指向自己的中断向量表所在位置。
具体做法是在App工程的系统初始化文件(如`system_gd32e50x.c`)中定义偏移量并设置VTOR:
#define VECT_TAB_OFFSET (uint32_t)0x4000 // 中断向量表基地址偏移量
偏移量的计算公式为:应用程序起始地址 - Flash基地址(0x08000000)。例如,App起始于0x08004000,则偏移量即为0x4000。此操作确保了所有中断都能正确跳转到App的中断服务程序。
结束语
本文详细阐述了在GD32微控制器平台上实现Bootloader与应用程序分离部署与相互跳转的全流程,涵盖了Keil MDK工程配置、关键跳转代码编写、软件复位机制以及中断向量表重定位等核心内容。掌握这些步骤,能够帮助你构建支持固件升级(IAP)的可靠嵌入式系统。如果在具体实现中遇到任何问题,欢迎进一步交流探讨。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
GD32单片机IAP升级教程实现Bootloader与应用程序跳转
在GD32嵌入式开发中,实现IAP升级需将内部Flash分区,分别为Bootloader和应用程序分配独立地址。Keil工程需相应配置ROM起始地址与大小。代码层面,Bootloader通过检查栈指针合法性并设置主栈指针后跳转至App入口地址;应用程序可通过软件复位请求返回Bootloader,并需重设中断向量表偏移量以匹配其存储位置。
腾讯吐司App三分钟教你零基础开发应用
你是否也曾有过这样的瞬间——脑海中闪过一个绝佳的App创意,却因为不懂编程,只能眼睁睁看着灵感消散? 最近,腾讯悄然上线了一款名为“吐司”的产品,似乎正是为了解决这个问题而来。 它的定位非常直白:“应用生成及灵感共创平台”。说得更通俗些,就是你动动嘴描述,AI来帮你写代码、做界面,最后打包成一个可安
出海产品运营必备Lucius高效协作指南
对于许多出海团队而言,下面这个场景恐怕并不陌生。 凌晨两点,东八区一片寂静。产品的Discord社区里,一条新消息弹了出来: “Anyone here? Been trying for an hour, the export keeps failing Is this product even m
智能体时代的高效办公方法与实用指南
最开始以为,只是一次,不会怎么样 现在,已经回不去了。 还记得第一次让Agent处理合同时,心里想着“就试这一次”。然后是邮件,接着是各种材料,再到活动复盘。如今,一小时处理几十份文档,手都不会抖一下。过去一天的工作量,现在只能算热身,处理总量翻了十倍还觉得不够。最可怕的是,已经完全不记得从前
AI内容创作方法论三年实战经验分享
上周在公司内部做了一场分享,在白板前边画边讲,聊了将近两个小时。主题是关于内容创作的方法论,以及在AI时代,我们该如何做好内容。这些思考源于过去几年的实战踩坑,从零做到近百万粉丝,经历了无数爆款与扑街稿件的洗礼。既然这些经验对团队有用,或许对行业里的其他同行也能有些参考价值。于是决定整理出来,与大家
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

