MCU Bootload学习笔记分享
2025-09-30 来源:cnblogs

启动流程
CPU只会处理机器码,不同 CPU(如 ARM Cortex-M、x86、8051)支持的机器码格式不同。代码通过编译转为机器码的格式,存放在非易失性存储器中。存储器都有地址,可以存储多段数据,CPU通过设置的MSP的位置开始执行。
从固定地址读取初始栈指针和复位向量(CPU会自动加载这两个值)
Cortex-M内核规定
复位后CPU从Flash起始地址(如GD32的0x08000000)按顺序读取以下两个关键值:
主栈指针(MSP)初始值
地址:0x08000000(Flash起始地址)。
作用:CPU启动时自动加载到MSP寄存器,建立初始栈空间。
复位向量(Reset_Handler地址)
地址:0x08000004(即MSP地址 + 4)。
作用:CPU跳转到该地址执行Reset_Handler函数。
跳转本质:通过手动设置MSP和PC寄存器,将控制权移交到用户程序。
关键步骤:关闭中断 → 设置MSP → 重定向VTOR → 跳转Reset_Handler。
Reset_Handler作为第一个执行的函数,可以从文件startup_gd32f30x_hd.s看到先进行了硬件的初始化操作,才进入main函数执行

那如何通过bootload进行APP跳转呢?
关闭中断、设置MSP 、重定向VTOR(中断向量表)可有对应的寄存器或库函数继续设置。重点说说跳转到APP的Reset_Handler执行。
函数的本质:名字 = 地址
在单片机中,函数名就是它在Flash中的起始地址。例如:
void my_func() { /* 代码 */ }
编译后,my_func 可能存储在 0x08001000,那么 my_func 就代表 0x08001000。
那Reset_Handler也是同理,我们已知该函数的地址是固定的,只需在boot中调用APP的Reset_Handler,即可将程序跳转到APP执行。
这时我们就可以编写我们的boot跳转函数
#define MY_APP_ADDR 0x08010000 //定义APP起始地址
void jump_to_app(void)
{
typedef void (*app_func_t)(void);
u32 app_addr = MY_APP_ADDR;
u32 stk_addr = *((__IO uint32_t *)app_addr); // 从 MY_APP_ADDR + 0x0 读取 MSP
// 获取 Reset_Handler 地址(MY_APP_ADDR + 0x4)
app_func_t app_func = (app_func_t)(*((__IO uint32_t *)(app_addr + 4)));
/*
判断APP的MSP、Reset_Handler 地址是否合法。关闭中断等操作。
*/
__set_MSP(stk_addr);//设置修改主栈指针MSP
app_func();//执行APP的Reset_Handler
}
如何定义我们的MY_APP_ADDR ?可通过KIEL设置。
这是boot分配的rom,起始地址为0x08000000 大小为0x10000 也就是64k。

以下是APP的分配,APP起始地址的boot之后,从0x8010000开始,大小为0x30000。也就是192k。该芯片提供的ROM为256K,

通过以上的设置跳转,我们发现APP仍然无法正常使用。
在上述的关键步骤中,发现我们缺少了重定向VTOR。
在计算机体系结构中,VTOR(Vector Table Offset Register,向量表偏移寄存器) 是某些ARM架构处理器(如Cortex-M系列)中的一个特殊功能寄存器,用于重定位中断向量表在内存中的存储位置。
中断向量表是 Cortex-M 的“中断处理目录”,规定了 启动初始化、中断跳转的硬性规则,
中断向量表的位置
默认存储位置:
Cortex-M 内核复位时,默认从 0x00000000(或 Flash 起始地址,如 0x08000000)加载中断向量表。
Cortex-M3/M4/M7 支持通过 VTOR(Vector Table Offset Register) 动态修改向量表位置(如 0x08010000)。
Cortex-M0/M0+ 无 VTOR,向量表必须放在 0x00000000(通常由芯片厂商映射到 Flash)。
对齐要求:
向量表必须 256 字节对齐(地址低 8 位为 0),否则会触发硬件错误。
中断向量表与MSP的区别
| 对比项 | 中断向量表的位置 | MSP(主栈指针) |
|---|---|---|
| 存储内容 | 所有中断服务函数(ISR)的地址 | 仅占向量表的第一个条目(0x00) |
| 作用 | 告诉 CPU 中断时跳转到哪个函数 | 定义程序运行时的栈顶地址 |
| 修改方式 | 通过 VTOR 寄存器(Cortex-M3/M4/M7) | 直接修改 向量表[0] 或调用 __set_MSP() |
| 硬件依赖 | 所有 Cortex-M 均需向量表 | 所有 Cortex-M 均需 MSP 初始化 |
core_cm4.h
/** brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
__IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
__IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
__IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
__IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
__IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
__IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
__IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
__IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
__I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
__I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
__I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
__I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
__I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
uint32_t RESERVED0[5];
__IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
} SCB_Type;
#define SCB ((SCB_Type *) SCB_BASE )
/*!< SCB configuration struct */
system_gd32f30x.c
/*!
brief set the NVIC vector table base address
param[in] nvic_vict_tab: the RAM or FLASH base address
arg NVIC_VECTTAB_RAM: RAM base address
are NVIC_VECTTAB_FLASH: Flash base address
param[in] offset: Vector Table offset
param[out] none
retval none
*/
void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset)
{
SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK);
__DSB();
}
/*!
brief setup the microcontroller system, initialize the system
param[in] none
param[out] none
retval none
*/
void SystemInit (void)
{
/* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
/* reset the RCU clock configuration to the default reset state */
/* Set IRC8MEN bit */
RCU_CTL |= RCU_CTL_IRC8MEN;
while(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){
}
RCU_MODIFY(0x50);
RCU_CFG0 &= ~RCU_CFG0_SCS;
#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
/* reset HXTALEN, CKMEN and PLLEN bits */
RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
/* disable all interrupts */
RCU_INT = 0x009f0000U;
#elif defined(GD32F30X_CL)
/* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
RCU_CTL &= ~(RCU_CTL_PLLEN |RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
/* disable all interrupts */
RCU_INT = 0x00ff0000U;
#endif
/* reset HXTALBPS bit */
RCU_CTL &= ~(RCU_CTL_HXTALBPS);
/* Reset CFG0 and CFG1 registers */
RCU_CFG0 = 0x00000000U;
RCU_CFG1 = 0x00000000U;
/* configure the system clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */
system_clock_config();
/* add app addr */
nvic_vector_table_set(NVIC_VECTTAB_FLASH, RT_APP_OFFSET);
}
- 意法半导体中国本地造STM32微控制器启动规模量产
- 意法半导体发布Stellar P3E 汽车MCU内置AI加速
- 德州仪器 (TI) 扩展微控制器产品组合及软件生态系统,助力边缘 AI 在各种器件中落地
- 3D打印“狂飙”背后:兆易创新GD32 MCU多元方案驱动性能升级
- 基于恩智浦MCU的人形机器人灵巧手解决方案
- 国民技术发布N32H49x系列MCU:以澎湃性能与全链路可靠赋能工业控制、储能与光通信
- 英飞凌推出基于PSOC™ Control C3微控制器的ModusToolbox™电源套件
- 让AI为你优化代码,提升MCX MCU程序开发效率!攻略在此~
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 英飞凌强化车规级微控制器产品组合:符合ISO/SAE 21434标准、获中汽研认证
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策




