cancel
Showing results for 
Search instead for 
Did you mean: 

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

arnold_w
Senior
Posted on June 17, 2015 at 17:31

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 theVector 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.
4 REPLIES 4
Posted on June 17, 2015 at 17:47

Yeah, I really don't think you've grasped the vector table thing at all well. Might I recommend the review of the Cortex-M4 TRM, and one of Joseph Yiu's books?

SCB->VTOR = 0x08010004;

The vector TABLE needs to reside on a 512-byte aligned boundary. Processor isn't using an ADD, but rather using the high-order bits and replacing the low-order bits with the index it wants.

The Second Entry, the 32-bit word at +4, is the address of the routine that performs the ResetHandler function, it in turn should initialize the system [SystemInit()], the C memory arena, and transfer control to your main() function.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 17, 2015 at 17:47

SCB->VTOR = 0x08010004;

Read PM0214

, ch.4.4.4 VTOR JW
arnold_w
Senior
Posted on June 18, 2015 at 11:23

Thanks for your post.

arnold_w
Senior
Posted on June 18, 2015 at 11:25

Thanks. For a while now I've had a feeling I am lacking some documentation and it was exactly the document you referred to.