cancel
Showing results for 
Search instead for 
Did you mean: 

Using MX to locate IVT in RAM

RBack.1
Senior

I am using the STM32F746VET6 which was setup with STM32CubeMX project. In the code it creates I see there's a STM32F746VETX_RAM.ld linker file and a #define VECT_TAB_SRAM to locate the IVT in RAM, but I don't see in MX where I specify that I want the autogenerated code to behave that way. Am I just missing something?

The reason I want the IVT in RAM is that I want to reconfigure which ISR is used for a timer depending upon a setting set through the SPI port. Doing this by overwriting an IVT in Flash would be a problem for my bootloader which has a CRC over the entire Flash range.

12 REPLIES 12
Pavel A.
Evangelist III

AFAIK CubeMX does not have option to place the vectors in RAM. Add the code (and link script stuff) for this manually.

Thanks for this. I guess I'll stop looking and hopefully my changes don't get overwritten if I ever generate code from the MX project again.

Expect that you need some unused space in RAM, with suitable alignment, and then memcpy() the table into that RAM and change SCB->VTOR to point at it.

SystemInit() might be the place to do it, but it doesn't have to be.

You can dispense with the ST #define methodology too.

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

Thanks. I added the memcpy but my code still doesn't run. I'll dispense with the ST #define methodology and handle that part manually too.

What doesn't run? Your interrupts? All the interrupts?

The table will need to be on a 512-byte boundary, perhaps use 0x20000000, and then move up and shrink the space defined for that RAM in the Linker Script.

RAM based vector tables definitely work, but don't expect the data to magically appear there at startup. You should keep the regular table, copy it to the new location, and then you can modify the function pointers within the array.

Instrument your Hard Fault Handler so you can identify if anything goes sideways..

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

Well, at the moment the code builds but when I try to debug I get the message "(Read)Failed determine breakpoint type" and "Break at address "0x137cf8de" with no debug information available, or outside of program code."

I did reserve "IVT_RAM (xrw)      : ORIGIN = 0x20000200, LENGTH = 512" in the linker file and the map file shows the correct location. The first thing I do in main() is this:

    extern const unsigned char ivt_text_start;
    extern const unsigned char ivt_text_end;
    extern const unsigned char ivt_data;
    memcpy((void *)&ivt_text_start, (const void *)&ivt_data, (int) (&ivt_text_end - &ivt_text_start));

I'm obviously still doing something wrong, but I am still relying on the autogenerated startup_stm32f746vetx.s and system_stm32f7xx.c with USER_VECT_TAB_ADDRESS and VECT_TAB_SRAM defined and VECT_TAB_OFFSET defined as 0x00000200U.

It shouldn't be this hard..

Build as you would for a normal FLASH firmware

in main()

extern uint32_t *g_pfnVectors; // Original FLASH/ROM table

memcpy(0x20040000, (void *)&g_pfnVectors, 0x200); // Some arbitrary slack space for experiment

SCB->VTOR = 0x20040000;

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

That does allow me to run (after reverting system_stm32f7xx.c so that USER_VECT_TAB_ADDRESS and VECT_TAB_SRAM are not defined), but using the original FLASH linker file what's telling the linker not to place other variables at addresses 0x20040000 - 0x20040200?

What a bad looking code, shame on you! 😉

How about this:

// STM32F0 bootloader fragments
 
struct vectable_ {
    uint32_t Init_SP;
    void (*Reset_Handler)(void);
    void (*CoreExcHandler[14])(void);
    void (*IRQHandler[32])(void);
};
 
// these defs could be replaced by declarations with section attributes
#define RAM_VTBASE 0x20004000
#define ram_vectable (*(struct vectable_ *)RAM_VTBASE)
#define ROM_VTBASE 0x08004000
#define rom_vectable (*(struct vectable_ *)ROM_VTBASE)
 
int main(void)
{
    ...
    ram_vectable = rom_vectable;
    SCB->VTOR = (uint32_t)&ram_vectable;
    __set_MSP(ram_vectable.Init_SP);
   ram_vectable.Reset_Handler();
}