Greetings to all readers, shortly ago I read, that the execution of binary code stored in the first section of the ram of an STM32F407xx is possible although the Cortex-M4F has an harvard architecture (http://www.arm.com/files/downloads/Developing_Advanced_Signal_Processing_Software_on_the_Cortex-M4_Processor.pdf) . Well, so far I began to introduce myself in the settings of the linker of the launchpad-gcc-toolchain until a single question start to circle around in my head: Does it really make sense to execute code from ram, if I just want to increase the speed of execution, for example for calculating an FFT? If you want to program a bootloader I would agree, that it might be advantageous, but thats not the application I'm focusing. Thanks, Lauren
executing in RAM is maybe a good idea for two reasons: + some JTAG (like JLINK) has small licences with no debug support in flash + flash can be written only 100.000 times. While developing it is nessecary to flash very often. So execution in RAM would be good for flash
ST Microelectronics promotes the STM32F4 series with: "Based on CoreMark benchmark, the performance achieved thanks to the ART accelerator is equivalent to 0 wait state program execution from Flash memory at a CPU frequency up to 168 MHz." (Source: DM00037051.pdf/Datasheet, ART section). A "branche cache" is mentioned so zero wait-states (from the cache) should be possible for non-linear code execution to a certain level. It might be a good idea to ask in the forum at st.com but since only very small modifications are needed to place selected functions in Flash or in RAM, profiling both options should not be that difficult. Please post your results.
> although the Cortex-M4F has an harvard architecture If you look at the block diagram of the Cortex-M family, you will see that this is not a classic Harvard architecture. It is about as much Harvard as pretty much every Intel CPU since the Pentium is, which means that data and code have different buses for performance reasons only (think separate D-Cache/I-Cache in almost every desktop CPU today). Really, people should stop calling it Harvard architecture, because while technically correct, for all practical purposes it isn't. Also, it only applies to the Cortex-M core itself, not to the MCU as a whole (most of which usually have a hierarchical von-Neumann architecture). As for the original questions, I agree with what Martin Thomas wrote. Note also that external RAM tends to be much slower than Flash on these MCUs. On a side note: > flash can be written only 100.000 times. Shouldn't that be "10.000"? Some flash MCUs even guarantee just 1.000 write cycles. 100.000 is more typical for EEPROMs.
Thank you for answering! Currently I try to set up an example to get a running linker-script: In main.c intiates a gpio-port and catches the MC a loop:
1 | while(1) |
2 | {
|
3 | delay(); |
4 | toggle_io(); |
5 | }
|
The function "toggle_io" is in an different file for the code which should be executed from a ram-location. In my example the function just toggles the gpio-port. My problem is the linker-script. Normaly the script looks like this (in CooCox):
1 | OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") |
2 | SEARCH_DIR(.) |
3 | INCLUDE "memory.ld" |
4 | |
5 | /* Section Definitions */ |
6 | SECTIONS |
7 | { |
8 | |
9 | .text : |
10 | { |
11 | KEEP(*(.isr_vector .isr_vector.*)) |
12 | *(.text .text.* .gnu.linkonce.t.*) |
13 | *(.glue_7t) *(.glue_7) |
14 | *(.rodata .rodata* .gnu.linkonce.r.*) |
15 | } > rom */ |
16 | |
17 | |
18 | |
19 | .ARM.extab : |
20 | { ... |
21 | |
22 | ... |
23 | ... |
24 | } |
In my first attemp I divided the .text section in two part (without any further changes) and inserted my .boot-section between the isr-vectors and the user-code-section . Currently I havn't implemented a loader-function, I only wanted to see, if the MC jumps to a ram-location. It didn't! The toggle-fuction was executed from a flash-location, so the programm was able to run. I assume, that the toggle-function is linked a second time in the second part of the .text-section, so I tried to link the other .o-files manually. After that I got an elf-file with 32KB large .text-section, that is even not able to init the gpio-port. Now I'm confused... Whats wrong with this code?
1 | SECTIONS |
2 | { |
3 | .text : |
4 | { |
5 | KEEP(*(.isr_vector .isr_vector.*)) /* keep interrupt vector at default position */ |
6 | } >rom |
7 | |
8 | .boot : /* create boot-section between isr-vectors and user code*/ |
9 | AT (0x20000000) /* relocate to ram begin */ |
10 | { |
11 | _sram_code = . ; /* save start adress of code */ |
12 | ..\obj\boot.o *(.text); /* link code to ram-position*/ |
13 | _eram_code = . ; /* save end adress of code*/ |
14 | } > rom |
15 | |
16 | /* first try */ |
17 | /* .text : |
18 | { |
19 | *(.text .text.* .gnu.linkonce.t.*) |
20 | *(.glue_7t) *(.glue_7) |
21 | *(.rodata .rodata* .gnu.linkonce.r.*) |
22 | } > rom */ |
23 | /* end first try*/ |
24 | |
25 | /* second try: */ |
26 | .text : |
27 | { |
28 | ..\obj\main.o *(.text); |
29 | ..\obj\stm32f4xx_gpio.o *(.text); |
30 | ..\obj\startup_stm32f4xx.o *(.text); |
31 | ..\obj\stm32f4xx_rcc.o *(.text); |
32 | ..\obj\system_stm32f4xx.o *(.text); |
33 | |
34 | *(.glue_7t) *(.glue_7) |
35 | *(.rodata .rodata* .gnu.linkonce.r.*) |
36 | } > rom |
37 | /* end second try*/ |
38 | |
39 | .ARM.extab : |
40 | {... |
41 | ... |
The deeper I go, the less I understand... I tried to read out a simple unsigned long int variable:
1 | ... |
2 | .text : |
3 | { |
4 | KEEP(*(.isr_vector .isr_vector.*)) |
5 | *(.text .text.* .gnu.linkonce.t.*) |
6 | *(.glue_7t) *(.glue_7) |
7 | *(.rodata .rodata* .gnu.linkonce.r.*) |
8 | } > rom |
9 | |
10 | _stfunc = 0x00000100; /* just for reading out */ |
11 | ... |
In my main.c I declared "extern unsigned long _stfunc" an read it out. The result is not what I assigned to it in the linker-script. If I rename it in the script, I got (the expected) error-message. Are these linker-settings some kind of vodoo ???
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
Log in with Google account
No account? Register here.