简体   繁体   English

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

[英]Cortex-M3 realtime interrupt vector remap

I use GCC 4.9 (arm-none-eabi) with STM32 and want to place an interrupt table into an array in order to change interrup handler adresses when it's needed in my code. 我将GCC 4.9(arm-none-eabi)与STM32结合使用,并希望将中断表放入数组中,以便在代码中需要时更改Interrup处理程序的地址。
I read existing manuals and articles and did the following: 我阅读了现有的手册和文章,并进行了以下操作:

I have to align the array, so I changed the linker script to add custom section in RAM and place it to 0x20001000 in order to automatically align it 我必须对齐数组,因此我更改了链接描述文件,以在RAM中添加自定义部分并将其放置到0x20001000,以便自动对齐它

 .vectorsSection 0x20001000 :
  {    
    KEEP(*(.vectorsSection))       
  } >RAM

Declare array to place IVT into, I declared it as extern in the header, and in .cc: 声明要放置IVT的数组,我在标头和.cc中将其声明为extern:

volatile word __attribute__((section (".vectorsSection"))) _vectors_[64] = {0};

Check that array is at the correct address: 检查数组是否在正确的地址:

arm-none-eabi-nm program.elf | grep _vectors_
20001000 d _ZL9_vectors_

Now it comes to reallocate the table to RAM. 现在是将表重新分配到RAM的时候了。 I wrote this function 我写了这个功能

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
}

I created enum from startup code in order to easy access the array. 我从启动代码创建了枚举,以便于访问数组。
After the final jump the code start from beginning and VTOR is 4096. 最后一次跳转后,代码从头开始,VTOR为4096。
Array contain correct addresses in the same order as in the startup code. 数组包含正确的地址,其顺序与启动代码中的顺序相同。
But when it comes to 但是当涉及到

__enable_irq();
__ISB();

It hangs on the first exception, to be more specific this is the callstack 它挂在第一个异常上,更具体地说,这是调用栈

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 is from SysTick_Handler that is surelly was called first. tickcounter来自肯定被首先调用的SysTick_Handler。 May be I should do something with stack pointer? 也许我应该对堆栈指针做些什么? I have no clue what is wrong here. 我不知道这是怎么了。

The root cause is quite simple: 根本原因很简单:

  1. According to manual bit 29 is shows the base offset: RAM or FLASH. 根据手册第29位显示了基本偏移量:RAM或FLASH。

    SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos; SCB-> VTOR | = 1 << SCB_VTOR_TBLBASE_Pos;

This fixed the issue 这解决了问题

  1. There is no need in reset after changing the table - it clears my array 更改表后无需重置-它清除了我的数组

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM