Cortex-M3实时中断向量重映射

Cortex-M3实时中断向量重映射,c,gcc,interrupt-handling,cortex-m3,linker-scripts,C,Gcc,Interrupt Handling,Cortex M3,Linker Scripts,我将GCC 4.9(arm none eabi)与STM32一起使用,并希望将中断表放入数组中,以便在代码中需要时更改中断处理程序地址。 我阅读了现有的手册和文章,并做了以下工作: 我必须对齐数组,所以我更改了链接器脚本,在RAM中添加自定义部分,并将其放置到0x2000000,以便自动对齐 .vectorsSection 0x20001000 : { KEEP(*(.vectorsSection)) } >RAM 声明要将IVT放入的数组,我在标

我将GCC 4.9(arm none eabi)与STM32一起使用,并希望将中断表放入数组中,以便在代码中需要时更改中断处理程序地址。
我阅读了现有的手册和文章,并做了以下工作:

我必须对齐数组,所以我更改了链接器脚本,在RAM中添加自定义部分,并将其放置到0x2000000,以便自动对齐

 .vectorsSection 0x20001000 :
  {    
    KEEP(*(.vectorsSection))       
  } >RAM
声明要将IVT放入的数组,我在标头中将其声明为extern,在.cc中:

volatile word __attribute__((section (".vectorsSection"))) _vectors_[64] = {0};
检查阵列是否位于正确的地址:

arm-none-eabi-nm program.elf | grep _vectors_
20001000 d _ZL9_vectors_
现在需要将表重新分配到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
}
为了方便访问阵列,我从启动代码创建了enum。
最后一次跳转后,代码从头开始,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
5 0x697b617a
4()0xFFFFF9
3 0x200011f8
2重新映射向量表()main.cc:31 0x08000cd4
1 main()main.cc:46 0x08000d32
200011f4:滴答计数器+0 movs r0,r0
200011f6:滴答计数器+2 MOV r0,r0
200011f8:;说明:0xf0d3e321
tickcounter来自SysTick_处理器,它肯定是第一个被调用的。 也许我应该用堆栈指针做些什么?
我不知道这里出了什么问题。

根本原因很简单:

  • 根据手动,位29显示基本偏移量:RAM或闪存


    SCB->VTOR |=1我从未“在需要时”更改过中断向量。我根据需要在中断中调度它。原因是我需要不时地更改处理程序。例如,有三个UART1中断处理程序,我需要在它们之间切换。这可能是代码设计不好的结果。可能,但VTOR寄存器存在,我只想知道当表在RAM中时如何以正确的方式处理它。表始终在RAM中。