Out of curiosity what would happen if the relocation in the example at the top took place right at the very beginning, before any serial communications?
I'm not clear whether the table is being copied from its current location or from the original location in ROM. If ROM then assuming the serial handler initalized some interrupt handlers (with vectors in RAM) wouldn't they get nuked at that point?
<</quote>>
Hi Oliver
My understanding is that the MBED SDK copies the vector table from a hard-coded location during startup (for the F401RE this is 0x8000 0000) . This means that if your bootloader is in this default location (e.g. the code that runs at startup), the vector table that will be vector table for your bootloader, causing havoc, because now your interrupts are handled by the code in the bootloader.
In the example I posted, it would not matter when the relocation code is executed, because the MBED online compiler doesn't have the option to offset to code to a different address and thus the vectors in the linker file are still pointing to the default location. As you know, the vector table is just a sequential list of memory addresses at the beginning of the binary. e.g.
1. Timer interrupt - Goto 0x080030e
2. UART interrupt - Goto 0x08003ba
...
Those memory addresses for each interrupt handler in the vector table are hard coded by the linker. So you can see if you decide to program your main application at a different location without telling the linker about it, the interrupt handler that get's called will be in a memory space where your code isn't residing, most likely an arbitrary location in your bootloader code.
Here is an example of ".ld" file you can give the linker to tell it that you intent on using a different location to write your binary to:
/* Linker script to configure memory regions. */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 464K
RAM (rwx) : ORIGIN = 0x20000194, LENGTH = 96k - 0x194
}
This will cause the interrupt table in the binary to be offset from the origin given.
It's very important to remember that the interrupt handler vectors are determined during linking and not during runtime. I.e. Your binary actually contains a vector table that says for instance, a UART interrupt will cause the controller to jump to address 0x0800 03ba for instance.
BUT... this isn't enough
Like I mentioned, the MBED platform copies the vector table from a hard-coded location (0x0800 0000 for the F401RE) at startup. So if you move your application elsewhere, you will have to ensure the vector table is copied from the correct location.
The code in a nutshell in the post I made 29 March, takes the vector table from the location where you offset programmed your binary, and copies it into RAM. Strictly speaking, you can place your vector table anywhere in RAM, but I re-used the default memory location. The reason you can use any location is because the register SCB->VTOR stands for Vector Table Offset Register and simply points the microcontroller to where to read interrupt handler addresses from.
STM32F401 Problems when relocating vector table on mbed project
Can someone please check if I've got the wrong idea: https://developer.mbed.org/users/riaancillie/code/F401RE_VectorTableRelocation_Issues/
The short story: I'm working on a bootloader and main application project and my mbed main application has issues with the vector table. In the example provided I've removed the bootloader from my testing and identified that just relocating the vector table on an mbed project already causes a crash/freeze and I have no idea why. This is the output on the serial port:
As you can see, it froze midway during a printf.
The longer story: I'm working on a proof-of-concept project that involves a main application and a bootloader. So far I've adapted ST application note AN3965 (In-Application Programming) to work as a decent bootloader which checks an SD card for an updated binary and writes the binary to flash. It works pretty good. I'm using Keil uVision 5 by the way and my bootloader is 17kb so I decided to offset my main application to 0x08008000.
My main application started as an mbed project in the online compiler and has progressed well due to the good amount of libraries for external components (LCD, USB MSD etc). To offset my main application to 0x08008000 I exported my mbed project and loaded it up in uVision. I set the linker to offset 0x08008000 and since there is no system_stm32f4xx.c file to edit I can't set the #define VECT_TAB_OFFSET, so I called NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000)
With the application being loaded by the bootloader, I can see it starting and then just stopping completely. The printf statement that goes the Serial on the computer stops halfway. After struggling for days I noticed if I call disable_irqs() in my bootloader before jumping to the main application, my application works fine, except obviously there are no interrupts breaking some of the hardware like the USB MSD. If I try enabling the IRQs again in the main application I get the same crash/hang.
Figuring the problem must be related the vector table and its offset, I've been trying for days now to determine what exactly is going wrong. When I modify the blinky example (which includes a systick_handler) that comes with the Nucleo's pack in uVision to be used as a main application (i.e. flash offset to the same address and vector table offset set) it works fine with the interrupts enabled.
Here's where it gets interesting. If I take my mbed main application, set its flash offset to the default 0x08000000 and make VECT_TAB_OFFSET 0x0 again and program that on the Nucleo everything works fine. I then tried copying the vector table and setting SCB-> VTOR to the new array, it also breaks. I can remap the blinky uVision example's vector table anywhere I want, but getting an mbed project to work properly in a bootloader environment has been keeping me busy for days now.
I've only been using Nucleo for two weeks after spending most of my adult life working with Arduinos so likely I've made some elementary mistake somewhere. Please let me know if you need for information.