Linking to SRAM instead of flash?
Moderator: RoccoMarco
Linking to SRAM instead of flash?
How do I change the build of an STM32F4 target so that GDB/st-util will load it into SRAM instead of erasing and programming flash?
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Linking to SRAM instead of flash?
I never did that but you should change all the "> flash" in "> ram".
Giovanni
Giovanni
Re: Linking to SRAM instead of flash?
I have just tried to run rom RAM in the STM32F4 Discovery and it works.
Off course that only works form GDB (Open OCD in my case).
Here's my procedure:
Change the liker file
-------------------------
I have created a file STM32F407xG_RAM.ld from STM32F407xG.ld
This file is on (CHIBIOS)\os\ports\GCC\ARMCMx\STM32F4xx\ld
The ROM has to be reallocated to RAM. I have used 64k of RAM as flash
and the 58k rest as RAM.
You can use any partition as long as total RAM is 112k
This is my example:
MEMORY
{
/*flash : org = 0x08000000, len = 1M
ram : org = 0x20000000, len = 112k */
flash : org = 0x20000000, len = 64k
ram : org = 0x20010000, len = 48k
ethram : org = 0x2001C000, len = 16k
ccmram : org = 0x10000000, len = 64k
}
The rest of the linker file stays the same.
In the Makefile the line that references the linker script must be changed:
LDSCRIPT= $(PORTLD)/STM32F407xG_RAM.ld
Set boot pins
----------------
If you don't want to remap the Vector table, the STM32F4 Discovery must
have BOOT0 and BOOT1(PB2) set to "1".
Those pins are set to "0" in the board using 510 Ohm resistors.
The ideal solution is desolder them, but shorting those pins to 3V works
and only increases a little the board current comsumption.
The board must be rebooted in order for the changes to operate.
Set the Debug Configuration
----------------------------------
I use a quite standard Debug configuration.
Changes are mainly in the Startup tab:
Reset and delay (seconds): 3
Initialization commands:
set remotetimeout 20
monitor reset init
monitor sleep 200
monitor halt 2000
monitor sleep 200
Load image: Use proyect binary bin/ch.elf
Load symbols: Use proyect binary bin/ch.elf
Set Breakpoint at: main
Run commands:
jump ResetHandler
It's possible that a simpler configuration works also.
I have now a blinking project by my side running from RAM.
Best regards
Vicente
Off course that only works form GDB (Open OCD in my case).
Here's my procedure:
Change the liker file
-------------------------
I have created a file STM32F407xG_RAM.ld from STM32F407xG.ld
This file is on (CHIBIOS)\os\ports\GCC\ARMCMx\STM32F4xx\ld
The ROM has to be reallocated to RAM. I have used 64k of RAM as flash
and the 58k rest as RAM.
You can use any partition as long as total RAM is 112k
This is my example:
MEMORY
{
/*flash : org = 0x08000000, len = 1M
ram : org = 0x20000000, len = 112k */
flash : org = 0x20000000, len = 64k
ram : org = 0x20010000, len = 48k
ethram : org = 0x2001C000, len = 16k
ccmram : org = 0x10000000, len = 64k
}
The rest of the linker file stays the same.
In the Makefile the line that references the linker script must be changed:
LDSCRIPT= $(PORTLD)/STM32F407xG_RAM.ld
Set boot pins
----------------
If you don't want to remap the Vector table, the STM32F4 Discovery must
have BOOT0 and BOOT1(PB2) set to "1".
Those pins are set to "0" in the board using 510 Ohm resistors.
The ideal solution is desolder them, but shorting those pins to 3V works
and only increases a little the board current comsumption.
The board must be rebooted in order for the changes to operate.
Set the Debug Configuration
----------------------------------
I use a quite standard Debug configuration.
Changes are mainly in the Startup tab:
Reset and delay (seconds): 3
Initialization commands:
set remotetimeout 20
monitor reset init
monitor sleep 200
monitor halt 2000
monitor sleep 200
Load image: Use proyect binary bin/ch.elf
Load symbols: Use proyect binary bin/ch.elf
Set Breakpoint at: main
Run commands:
jump ResetHandler
It's possible that a simpler configuration works also.
I have now a blinking project by my side running from RAM.
Best regards
Vicente
Re: Linking to SRAM instead of flash?
This is a follow-up of my last message.
I include it here to help whoever wants to run ChibiOS/RT from RAM as it is somewhat tricky.
It turns out that running from RAM is quite more complex that I thought.
My first try worked fine but it was a question of luck.
Starting the program with "jump ResetHandler" don't always work. This is due to the fact that the Main Stack Pointer (MSP) is obtained from the Vector table by hardware at start-up. Using "jump ResetHandler" don't enable to test BOOT0 and BOOT1 and reload the MSP when the program starts.
Using "reset init" do the proper operations and, as BOOT0=BOOT1="1" aliases the RAM range 0x2000000 to 0x00000000 the vector table is correctly loaded and the MSP is initializated correctly.
So far so, good.
The problem is trying to run from RAM without needing to use the BOOT0 and BOOT1 leaving them at "0" as is the default mode in the STM32F4 Discovery board.
I supposed that setting the CORTEX_VTOR_INIT value to 0x20000000 would remap the Vector table at start-up and this is in fact the case as this is done in _port_init in the file chcore_v7m.c.
But regardless of that I obtained Unhandled Exceptions.
Those exceptios turned out to be Undefined Instruction expections that were generated in _port_irq_epilogue inside the same chcore_v7m.c file.
I finally traced that to a incorrect MSP value. Thanks goodness to the on chip debugger!!
This is due to the fact that the basic MCU initialization in crt0.c initializas the PSP but not the MSP as the MSP is loaded by hardware upon start-up using the vector table.
The remap used with CORTEX_VTOR_INIT don't help here because it is done after the initialization in crt0.c.
I observed the initialization code in crt0.c for PSP:
/* Process Stack initialization, it is allocated starting from the
symbol __process_stack_end__ and its lower limit is the symbol
__process_stack_base__.*/
asm volatile ("cpsid i");
psp = SYMVAL(__process_stack_end__);
asm volatile ("msr PSP, %0" : : "r" (psp));
And added in crt0.c an equivalent code for MSP:
/* Main Stack initialization, it is allocated starting from the
symbol __main_stack_end__ and its lower limit is the symbol
__main_stack_base__.*/
asm volatile ("cpsid i");
msp = SYMVAL(__main_stack_end__);
asm volatile ("msr MSP, %0" : : "r" (msp));
With that change I can now reliablily run code from RAM in the STM32F4 Discovery board.
That could be interesting because I use the board for students lab work and I don't want to run out of flash cycles.
Best regards
Vicenet Jiménez
I include it here to help whoever wants to run ChibiOS/RT from RAM as it is somewhat tricky.
It turns out that running from RAM is quite more complex that I thought.
My first try worked fine but it was a question of luck.
Starting the program with "jump ResetHandler" don't always work. This is due to the fact that the Main Stack Pointer (MSP) is obtained from the Vector table by hardware at start-up. Using "jump ResetHandler" don't enable to test BOOT0 and BOOT1 and reload the MSP when the program starts.
Using "reset init" do the proper operations and, as BOOT0=BOOT1="1" aliases the RAM range 0x2000000 to 0x00000000 the vector table is correctly loaded and the MSP is initializated correctly.
So far so, good.
The problem is trying to run from RAM without needing to use the BOOT0 and BOOT1 leaving them at "0" as is the default mode in the STM32F4 Discovery board.
I supposed that setting the CORTEX_VTOR_INIT value to 0x20000000 would remap the Vector table at start-up and this is in fact the case as this is done in _port_init in the file chcore_v7m.c.
But regardless of that I obtained Unhandled Exceptions.
Those exceptios turned out to be Undefined Instruction expections that were generated in _port_irq_epilogue inside the same chcore_v7m.c file.
I finally traced that to a incorrect MSP value. Thanks goodness to the on chip debugger!!
This is due to the fact that the basic MCU initialization in crt0.c initializas the PSP but not the MSP as the MSP is loaded by hardware upon start-up using the vector table.
The remap used with CORTEX_VTOR_INIT don't help here because it is done after the initialization in crt0.c.
I observed the initialization code in crt0.c for PSP:
/* Process Stack initialization, it is allocated starting from the
symbol __process_stack_end__ and its lower limit is the symbol
__process_stack_base__.*/
asm volatile ("cpsid i");
psp = SYMVAL(__process_stack_end__);
asm volatile ("msr PSP, %0" : : "r" (psp));
And added in crt0.c an equivalent code for MSP:
/* Main Stack initialization, it is allocated starting from the
symbol __main_stack_end__ and its lower limit is the symbol
__main_stack_base__.*/
asm volatile ("cpsid i");
msp = SYMVAL(__main_stack_end__);
asm volatile ("msr MSP, %0" : : "r" (msp));
With that change I can now reliablily run code from RAM in the STM32F4 Discovery board.
That could be interesting because I use the board for students lab work and I don't want to run out of flash cycles.
Best regards
Vicenet Jiménez