简体   繁体   中英

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.
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

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

Declare array to place IVT into, I declared it as extern in the header, and in .cc:

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. 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.
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. 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.

    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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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