Electronic – Managing addresses of interrupt service routines and functions of the program in cortex M0

cortex-mcortex-m0interruptsprogramming

I am working with nordic nRF51422 uC with cortex M0 core and I have to store data in Non-Volatile Memory but to do that properly I need information where exactly code of the program is stored in flash.

The vector table is fixed at address 0x00000000 and it tells me the start of each interrupt service routine I have implemented but I struggle to find information what is the length of each ISR. It would be also useful to know where each function of the program starts and ends.

Summarizing, is there any easy way to spy how the code of program is mapped into flash? Is it compiler dependent? Can I set my own boundaries for each function? Are there any mechanisms that enable dynamically checking end address of the code while executing program on uC ?

Best Answer

The common approach is to make a const array that contains the appropriate values (initial SP, initial PC = adress of init code, addresses of the interrupt service routines) and use some compiler-dependant magic to force the linker to place this array at address 0.

An example in gcc (from my http://www.voti.nl/bmptk):

void (* const __vectors[ 8 ])(void) 
__attribute__ ((section(".vectors"))) = {
   (void (*)(void)) & __stack_end,  
   __startup,
   // interrupt verctors etc.
};

The __ attribute__ ((section(".vectors"))) marks this array as part of a section called "vectors". The matching linkerscript ensures that that section is placed first in the flash memory:

MEMORY
{
   rom (rx)     : org = ROM_START, len = ROM_SIZE
   ram (rwx)    : org = RAM_START, len = RAM_SIZE
   nul (rwx)    : org = 0x20000000, len = 0k
}
. . . 
SECTIONS
{
   .text :
   {

       . = ALIGN(4);
       KEEP(*(.vectors));
       . . .
       # other sections come here  (= the rest of your code)

In normal situations this is something that your tool vendor/builder/creator has done for you.