'MCU crashes when "declaring" vector table in SRAM
I have a new standard c++ project on an imx rt 1024 (an nxp chip), in which I try to move my vector table to SRAM. It fails, depending on a change I apply in the linker script.
The project is a new project from scratch created by MCUxpresso. I am not looking for answers MCUxpresso related, or c/c++/startup code related. I only want to properly understand the consequences of my changed linker script I show below.
The part that works
My starting point is a small program on my evk board, using a simple FreeRTOS task to blink a led. This works fine, when I put my vector table in flash.
linker script:
/* Not relevant for this question, other than showing there is something
written to flash before my vector table, harmless I think, but didn't want to leave
out of this question
*/
.boot_hdr : ALIGN(4)
{
__boot_hdr_start__ = ABSOLUTE(.) ;
KEEP(*(.boot_hdr.conf))
. = 0x1000 ;
KEEP(*(.boot_hdr.ivt))
. = 0x1020 ;
KEEP(*(.boot_hdr.boot_data))
. = 0x1030 ;
KEEP(*(.boot_hdr.dcd_data))
__boot_hdr_end__ = ABSOLUTE(.) ;
. = 0x2000 ;
} >PROGRAM_FLASH
/*
Here I write my vector table to flash
*/
.vector : ALIGN(4)
{
__vector_table_flash_start__ = ADDR(.vector) ;
__vector_table_itc_start__ = LOADADDR(.vector) ;
KEEP(*(.isr_vector))
__vector_table_flash_end__ = ABSOLUTE(.) ;
. = ALIGN(4) ;
} >PROGRAM_FLASH
Disassembled code for vector table
Disassembled code of reset handler
Note: 0x600022e5 corresponds to 0x600022e4, this has something to do with arm .thumb. I don't exactly know how that works tbh.
When I run this app, it runs fine. If I set a breakpoint in the ResetHandler it breaks and I can step through the startup code and jump to main. When I let the program run, my led will blink every second.
The part which fails
I changed my linker script to put my vector table in SRAM as follows
.vector : ALIGN(4)
{
__vector_table_flash_start__ = ADDR(.vector) ;
__vector_table_itc_start__ = LOADADDR(.vector) ;
KEEP(*(.isr_vector))
__vector_table_flash_end__ = ABSOLUTE(.) ;
. = ALIGN(4) ;
} >SRAM_ITC AT>PROGRAM_FLASH
For reference, the memory section:
MEMORY
{
PROGRAM_FLASH (rx) : ORIGIN = 0x60000000, LENGTH = 0x400000
SRAM_DTC (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
SRAM_ITC (rwx) : ORIGIN = 0x0, LENGTH = 0x10000
SRAM_OC (rwx) : ORIGIN = 0x20200000, LENGTH = 0x20000
}
ENTRY(ResetISR)
When I upload, my program doesn't even reach the reset vector. It goes straight into the woods, and crashes somewhere outside program code.
The questions
What EXACTLY happens when I adjust my linker script with >SRAM_ITC AT>PROGRAM_FLASH
?
I am pretty sure the produced elf file still contains the entire vector table starting from address 0x60002000. The >SRAM_ITC only tells the linker where certain parts of memory will end up AFTER the startup code copied all parts to their final ram location. Right? So how on earth can the initial jump to 0x60002004 (the address which holds the location of the reset handler) fail? The nxp bootloader always expects the reset vector on that location. I didn't change that. I only told the linker that the memory on that location will finally end up in SRAM. What am I misunderstanding here?
Maybe a stupid question: If I am completely wrong with my above assumptions, is there a way to see this from disassembly? I think objdump only shows the final addresses, but my debug probe will only write to flash as far as I know. So after uploading my code to my target, I still assume that stuff got written to flash, and after reset the built in bootloader will jump to 0x60002004 and set the PC to the address located at 0x60002000. Where can I see the actual blob of bytes which is programmed to flash memory?
Solution 1:[1]
Copying the vector table to sram from my custom bootloader solved the problem. That way the "on chip bootloader" from nxp can jump to my custom bootloader.
Before I just to my app from my custom bootloader, I copy the vector table to sram and set SCB->VTOR
to the start of sram vector table.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | bas |