文章目录
最近使用了一款芯片是STM32F030F4(Cortex-M0内核),在编写把ootloader → pp 跳转代码时,发现它中断向量表的重映射方法与常见的F10x4(Cortex-M3内核)/F40x4(Cortex-M4内核)不同,遇到了新的现象,记录一下
结论:
Cortex-M0 没有 VTOR 寄存器,不能像 M3/M4 那样用 SCB->VTOR 改中断向量基址。想让放在非 0x08000000 的 App 正常跳转中断,一种做法是把 App 的向量表拷贝到 SRAM 起始(0x20000000),然后用 SYSCFG 的内存重映射把 SRAM 映射到 0x00000000,再开中断。这个动作可在 Boot 完成,也可在 App 代码中的初始化过程中完成
问题背景:为什么跳转后 HAL_Delay() 卡死?
为了测试bootloader的代码能否顺利跳转到app,写了最简单的一段测试代码如下:
while(1)
{
uartSendData((uint8_t *)“hello”,5);
HAL_Delay(200);
}
正常现象是串口每间隔200ms打印一句hello,但实际现象是:
- bootloader 能正确跳转到app
- 串口刚开始能输出一帧数据
- 之后整个程序卡死在 HAL_Delay() 里
原因分析:
- HAL_Delay() 依赖SysTick 中断来递增全局tick计数
- debug调试发现,SysTick_Handler 根本没有被调用
- Cortex-M0在响应中断时,会去地址0x00000000读取向量表入口
- 由于app的向量表实际位于Flash偏移区(如 0x08003000),如果没有做重映射,CPU 找不到 SysTick_Handler,于是 tick 不加 → HAL_Delay 永远等待
于是记起来要重定位向量表基地址(通过SCB->VTOR),但是在写代码过程中发现,STM32F030F4并没有SCB->VTOR这个寄存器
typedef struct
{
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
uint32_t RESERVED0;
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Res

最低0.47元/天 解锁文章
1937

被折叠的 条评论
为什么被折叠?



