Cortex-M3 实时中断向量重映射
Cortex-M3 realtime interrupt vector remap
我将 GCC 4.9 (arm-none-eabi) 与 STM32 一起使用,并希望将中断 table 放入数组中,以便在我的代码需要时更改中断处理程序地址。
我阅读了现有的手册和文章并执行了以下操作:
我必须对齐数组,所以我更改了链接描述文件以在 RAM 中添加自定义部分并将其放置到 0x20001000 以便自动对齐它
.vectorsSection 0x20001000 :
{
KEEP(*(.vectorsSection))
} >RAM
声明放置 IVT 的数组,我在 header 和 .cc:
中将其声明为 extern
volatile word __attribute__((section (".vectorsSection"))) _vectors_[64] = {0};
检查数组地址是否正确:
arm-none-eabi-nm program.elf | grep _vectors_
20001000 d _ZL9_vectors_
现在要将 table 重新分配给 RAM。我写了这个函数
void (*new_code_entry)(void);
.......
static void remap_vector_table (void)
{
//VTOR is 0 on startup, so we change VTOR only once
if(SCB->VTOR)
return;
new_code_entry = (void (*)(void))((word)&_vectors_ + sizeof(word) + 1);//Skip SP and jump to Reset
memcpy((void*)_vectors_, (void*)SCB->VTOR, sizeof _vectors_);
SCB->VTOR = 0x1FFFFF80ul & (word)(&_vectors_); //Set VTOR offset
__DSB(); //Complete all memory requests
new_code_entry(); //Jump to new code
}
我从启动代码创建了枚举以便于访问数组。
最后一次跳转后,代码从头开始,VTOR 为 4096。
数组包含与启动代码中顺序相同的正确地址。
但是说到
__enable_irq();
__ISB();
它挂在第一个异常上,更具体地说,这是调用堆栈
5 <symbol is not available> 0x697b617a
4 <signal handler called>() 0xfffffff9
3 <symbol is not available> 0x200011f8
2 remap_vector_table() main.cc:31 0x08000cd4
1 main() main.cc:46 0x08000d32
200011f4: tickcounter+0 movs r0, r0
200011f6: tickcounter+2 movs r0, r0
200011f8: ; <UNDEFINED> instruction: 0xf0d3e321
tickcounter 来自 SysTick_Handler 肯定是第一个被调用的。
也许我应该用堆栈指针做点什么?
我不知道这里出了什么问题。
根本原因很简单:
根据手册第 29 位显示基本偏移量:RAM 或 FLASH。
SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos;
这解决了问题
- 更改 table 后无需重置 - 它会清除我的数组
我将 GCC 4.9 (arm-none-eabi) 与 STM32 一起使用,并希望将中断 table 放入数组中,以便在我的代码需要时更改中断处理程序地址。
我阅读了现有的手册和文章并执行了以下操作:
我必须对齐数组,所以我更改了链接描述文件以在 RAM 中添加自定义部分并将其放置到 0x20001000 以便自动对齐它
.vectorsSection 0x20001000 :
{
KEEP(*(.vectorsSection))
} >RAM
声明放置 IVT 的数组,我在 header 和 .cc:
中将其声明为 externvolatile word __attribute__((section (".vectorsSection"))) _vectors_[64] = {0};
检查数组地址是否正确:
arm-none-eabi-nm program.elf | grep _vectors_
20001000 d _ZL9_vectors_
现在要将 table 重新分配给 RAM。我写了这个函数
void (*new_code_entry)(void);
.......
static void remap_vector_table (void)
{
//VTOR is 0 on startup, so we change VTOR only once
if(SCB->VTOR)
return;
new_code_entry = (void (*)(void))((word)&_vectors_ + sizeof(word) + 1);//Skip SP and jump to Reset
memcpy((void*)_vectors_, (void*)SCB->VTOR, sizeof _vectors_);
SCB->VTOR = 0x1FFFFF80ul & (word)(&_vectors_); //Set VTOR offset
__DSB(); //Complete all memory requests
new_code_entry(); //Jump to new code
}
我从启动代码创建了枚举以便于访问数组。
最后一次跳转后,代码从头开始,VTOR 为 4096。
数组包含与启动代码中顺序相同的正确地址。
但是说到
__enable_irq();
__ISB();
它挂在第一个异常上,更具体地说,这是调用堆栈
5 <symbol is not available> 0x697b617a
4 <signal handler called>() 0xfffffff9
3 <symbol is not available> 0x200011f8
2 remap_vector_table() main.cc:31 0x08000cd4
1 main() main.cc:46 0x08000d32
200011f4: tickcounter+0 movs r0, r0
200011f6: tickcounter+2 movs r0, r0
200011f8: ; <UNDEFINED> instruction: 0xf0d3e321
tickcounter 来自 SysTick_Handler 肯定是第一个被调用的。 也许我应该用堆栈指针做点什么? 我不知道这里出了什么问题。
根本原因很简单:
根据手册第 29 位显示基本偏移量:RAM 或 FLASH。
SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos;
这解决了问题
- 更改 table 后无需重置 - 它会清除我的数组