stm32f103rct6 bootloader中断向量表
时间: 2025-05-25 17:07:18 浏览: 22
### STM32F103RCT6 Bootloader 中断向量表重定位配置
在 STM32F103RCT6 芯片中,当使用 Bootloader 功能时,中断向量表的重定位是一个重要的环节。这是因为 Bootloader 和应用程序通常位于不同的内存区域,而 Cortex-M3/M4 内核的硬件机制默认从固定的地址读取中断向量表。如果未正确配置中断向量表的偏移量,可能会导致中断无法正常工作。
#### 1. 默认中断向量表位置
STM32F103RCT6 的内部 FLASH 地址起始于 `0x08000000`,默认情况下,程序从该地址开始运行[^2]。Cortex-M3 内核会在复位后从 `0x08000004` 处获取初始堆栈指针,并从中断向量表中提取相应的中断处理函数地址[^3]。
#### 2. 中断向量表重定位原理
为了支持 Bootloader 和多个应用程序分区的功能,需要重新指定中断向量表的位置。这可以通过修改 SCB->VTOR 寄存器实现。SCB->VTOR 寄存器用于存储中断向量表的基地址,其低 9 位被保留,因此实际可设置的有效地址范围是以 0x200 字节对齐的[^1]。
#### 3. 实现中断向量表重定位的方法
以下是实现中断向量表重定位的具体方法:
##### a. 修改链接脚本
在开发环境中,需调整 linker script 文件以定义 Bootloader 和应用程序的空间分配。例如:
```ld
/* 定义 Bootloader 区域 */
BOOTLOADER_BASE = 0x08000000;
BOOTLOADER_SIZE = 0x2000;
/* 定义应用区域 */
APPLICATION_BASE = 0x08002000;
APPLICATION_SIZE = 0x1E000;
```
##### b. 编写初始化代码
在主程序中调用函数设置新的中断向量表地址。以下是一个典型的实现示例:
```c
#include "stm32f1xx.h"
/**
* @brief 设置中断向量表偏移地址
* @param baseaddr : 基址
* @param offset : 偏移量
* @retval 无
*/
void sys_nvic_set_vector_table(uint32_t baseaddr, uint32_t offset) {
/* 设置 NVIC 的向量表偏移寄存器, VTOR 低 9 位保留, 即 [8:0] 保留 */
SCB->VTOR = baseaddr | (offset & (uint32_t)0xFFFFFE00);
}
int main(void) {
// 假设应用程序从 0x08002000 开始
uint32_t application_base = 0x08002000;
// 设置中断向量表偏移
sys_nvic_set_vector_table(application_base, 0);
// 如果需要跳转到应用程序
typedef void (*application_reset_handler)(void);
application_reset_handler app_start = (application_reset_handler)(*((uint32_t*)(application_base + 4)));
__set_MSP(*(__IO uint32_t*)application_base); // 设置 MSP 初始值
app_start(); // 执行应用程序入口
}
```
此代码片段展示了如何通过 `sys_nvic_set_vector_table` 函数动态更改中断向量表的位置[^1]。
##### c. 注意事项
- **对齐要求**:VTOR 寄存器仅接受按 0x200 对齐的地址作为有效输入。
- **调试问题**:某些 IDE 或工具链可能不自动更新中断向量表,在这种情况下,手动调用 `NVIC_SetVectorTable` 可能是必要的[^5]。
- **兼容性测试**:确保不同版本的 HAL 库或 CMSIS 不会对 VTOR 寄存器的行为产生冲突。
---
### 示例场景分析
假设 Bootloader 存储在 `0x08000000 ~ 0x08001FFF`,应用程序存储在 `0x08002000 ~ 0x0801FFFF`。在这种布局下:
- 当设备启动时,默认从 `0x08000004` 获取复位向量并执行 Bootloader 初始化逻辑。
- 若检测到无需更新操作,则通过上述代码将控制权交给应用程序,并将其中断向量表设置为 `0x08002000`。
---
阅读全文
相关推荐


















