cancel
Showing results for 
Search instead for 
Did you mean: 

How to relocate interrupt vector table in STM32L151RD?

dzikos
Associate II

Hello!

I have written a simple application that reads a byte on USART (in an interrupt) and then sends the same byte back (simple USART echo). I have no problem running this application on various STM32 devices as long as the firmware is programmed at the beginning of FLASH (0x80000000).

I have also managed to run the app from an offset in FLASH (e.g. 0x80001000) using GDB debugger in TrueStudio (I am setting SP and PC in debugger startup script). I am also writing appropriate offset to SCB->VTOR in SystemInit(). This works on STM32L011, STM32F411, but I can't make it work on STM32L151RD.

These are the steps that I am following:

1. Full chip erase.

2. Adjust FLASH region in linker script (ORIGIN = 0x8001000).

3. Set SCB->VTOR in SystemInit() to the same value as above (0x8001000).

4. Set PC and SP in debugger startup script.

5. Build, program and debug.

6. At the beginning of main() verify that SCB->VTOR has appropriate value (the one written to it in SystemInit).

7. Run.

8. Interrupt does not work.

Any idea why interrupts are not firing on STM32L151RD despite following the same procedure which works on other devices? Code optimisation is disabled.

If interrupt vector table is programmed in FLASH not only at my offset (0x80001000) but also at FLASH beginning (0x8000000), interrupt does work. It looks like STM32L151RD is looking for interrupt vector table at the beginning of FLASH despite the fact that SCB->VTOR points to 0x80001000.

Any help would be appreciated!

Bartosz

4 REPLIES 4

The processor ALWAYS boots from address ZERO, what's mapped there depends on the BOOTx pins, and is either the base of FLASH 0x08000000, RAM 0x20000000 or ROM 0x1FF?????

You can't make it boot in the middle of the field. You'll need some loader at the base of FLASH, and it can then dispatch control from there. Once booted you can change SCB->VTOR from zero, to the base of your executing image, which needs to be on a 512-byte boundary (depends on overall size of vectors as implemented in silicon, round to next power of two). 0x08001000 would be a valid location to set into SCB->VTOR, provided that the linker built for that address, and the absolute addresses in the Vector Table jived with that placement.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mpac1497958958E12
Associate

I had the same problem. Firmware started by the bootloader always used interrupts from bootloader despite its own ones (changed the VTOR register in firmware). The same code worked on F1 and F4 series, but it didn't on L1 series. Is there something different with implementation of the M3 core in L1 series?

Dear Avogadro Number,

this is not the problem I am dealing with.

I am aware of the fact that I will need a bootloader if I want to make it a stand-alone application. However, at the moment I am only trying to make it work inside a debugger session (and the debugger does allow me to run code from any memory location by setting PC and SP - and that works).

The problem that I am dealing with is that setting SCB->VTOR does not seem to affect where STM is looking for the interrupt table.

I'm hard pressed to see how even the most broken debugger could break the scb VTOR setting. Perhaps have two unique Hard Fault Handlers outputting different data, and fault intentionally. It's hard to mask them. Have it output to a UART so you can test without the debuggers entanglement in the issue.

Don't transfer control to the secondary image under interrupt/callback context.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..