AnsweredAssumed Answered

Why do my interrupts stop working when I move the code 4 bytes?

Question asked by arnold_w on Jun 17, 2015
Latest reply on Jun 18, 2015 by arnold_w
I am working with the Discovery development board STM32F407 microcontroller and building using Eclipse/GNU. I have successfully created a small application can communicate with a PC via UART4 and it has free space for a bootloader:

MEMORY
{
  RAM (xrw)            : ORIGIN = 0x20000000, LENGTH = 128K
  CCMRAM (xrw)         : ORIGIN = 0x10000000, LENGTH = 64K
  STARTUP_VECTOR (rx)  : ORIGIN = 0x08000000, LENGTH = 1K
  BOOTLOADER (rx)      : ORIGIN = 0x08000400, LENGTH = 63K
  FLASH (rx)           : ORIGIN = 0x08010000, LENGTH = 960K
  FLASHB1 (rx)         : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  MEMORY_ARRAY (xrw)   : ORIGIN = 0x20002000, LENGTH = 32
}

In the area where the bootloader will reside, for now, I simply put a jump-to-the-application:

.startUpVector : ALIGN(4)
{
    KEEP(*(.startUpVector))
    *(.startUpVector .startUpVector.*)     
 
} >STARTUP_VECTOR
 
.jumpToApplication : ALIGN(4)
{
    KEEP(*(.jumpToApplication))
    *(.jumpToApplication .jumpToApplication.*)     
 
} >BOOTLOADER

#define JMP(addr) \
    __asm__("mov pc,%0" \
            : /*output*/ \
            : /*input*/ \
            "r" (addr) \
           );
 
 
__attribute__ ((section(".startUpVector"),used)) pHandler __startUpVector[] =
{
      (pHandler) &_estack,                      // The initial stack pointer
      (pHandler) 0x08000401,                    // The reset handler
};
 
 
void __attribute__ ((section(".jumpToApplication"),used)) __jumpToApplication(void)
{
    JMP(0x08010004);
}

In my main.c file I modify the Vector Table Offset Register appropriately and everything works like a charm:

SCB->VTOR = 0x08010000;

However, I would like to move my application 4 bytes:

MEMORY
{
  RAM (xrw)            : ORIGIN = 0x20000000, LENGTH = 128K
  CCMRAM (xrw)         : ORIGIN = 0x10000000, LENGTH = 64K
  STARTUP_VECTOR (rx)  : ORIGIN = 0x08000000, LENGTH = 1K
  BOOTLOADER (rx)      : ORIGIN = 0x08000400, LENGTH = 63K
  FLASH (rx)           : ORIGIN = 0x08010004, LENGTH = 983036
  FLASHB1 (rx)         : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB0 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB1 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB2 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  EXTMEMB3 (rx)        : ORIGIN = 0x00000000, LENGTH = 0
  MEMORY_ARRAY (xrw)   : ORIGIN = 0x20002000, LENGTH = 32
}

__attribute__ ((section(".startUpVector"),used)) pHandler __startUpVector[] =
{
      (pHandler) &_estack,                      // The initial stack pointer
      (pHandler) 0x08000401,                    // The reset handler
};
 
void __attribute__ ((section(".jumpToApplication"),used)) __jumpToApplication(void)
{
    JMP(0x08010008);
}

SCB->VTOR = 0x08010004;

When I do so, my interrupts stops working. Could someone please give me clue about what's wrong? And another question, what is the correct location to jump to from my bootloader, is it the first address in the interrupt table ("The initial stack pointer") or the 4th ("The reset handler")? It seems to work with both, but I suppose that's just luck.

Outcomes