...have some of my application code run from RAM?
I have an application executing out of FLASH memory however I need some of it to execute out of RAM. How can I do this?
Usually the easiest way to do this is to put the code you want to execute from RAM into the .fast section as on most targets the .fast section is placed into RAM using the default memory placement files. Using a FLASH configuration the .fast section will be loaded into FLASH and copied out of FLASH into RAM by the default startup code before entering the main function.
If you want to be less selective and want to put an entire section or indeed everything in RAM then you will need to modify the section placement file (usually flash_placement.xml for FLASH build configurations) and for each FLASH section you want to run in RAM:
- Create a section in a RAM segment that indicates where you want to the FLASH section to run.
- Modify the Section To Run In property of the FLASH section to be the name of the section in RAM you want the FLASH section to run in. Note that the order of the load sections in the FLASH segment must match the order of the run section in the RAM segment or you will get a cyclic memory section dependency error.
The crt0.s startup code will automatically copy the .data, .text, .fast, .ctors, .dtors and .rodata sections if it detects the load and run addresses are different. If you want any other sections to be copied into RAM on startup you will need to modify the crt0.s file to do this.
Note that we ship two example placement files:
- $(StudioDir)/targets/flash_run_all_from_ram_placment.xml - Everything runs from RAM
- $(StudioDir)/targets/flash_run_text_from_ram_placment.xml - The .text section (code) runs from RAM
If you are using the $(StudioDir)/targets/flash_placement.xml section placement file in your project you should be able to directly replace this with either of these files. To do this:
- Right click on the System Files folder in your project and select Add Existing File and select one of the two placement files.
- Right click on the file you've just added and select Properties
- Set the Configuration to RAM and set the Build Options > Exclude From Build property to Yes
- Right click on the existing flash_placement.xml file in the project explorer and select Remove.
- Rebuild your project.
If you aren't using $(StudioDir)/targets/flash_placement.xml, which maybe the case if you have multiple RAM and FLASH segments, you will need to modify your placement file as described above.
-
I did all this and I find my function correctly transferred to RAM (. fast).But the problem is that when I call the function from the main program in C, the jump address is wrong, and jump in flash where find a "BX PC" instruction that generates a hard fault.Why liker do non allocate the correct address to the calling function ?
-
Hi Paul,
I'm trying this out as well and having a very similar issue.
I try the absolute minimum RAM based function which is 'delay.c' from $(StudioDir)/samples directory of CrossWorks 2.2 on a Mac.
I snaffle the following code from delay.c into my main.c:
void delay(volatile unsigned int d) __attribute__((section(".fast")));
void
delay(volatile unsigned int d)
{
for (;d ;--d);
}And I find that if I comment out the protoytype line with the .fast attribute it works fine and with the prototype line enabled I get a hard fault on a 'bx pc' instruction (Thumb to ARM state change I think) which is in flash and is the second instruction after entry into the delay() function.
This is on a STM32F103VG target.
I'm using the default flash_placement.xml.
-
Symbol Browser says the .fast segment is at 2000003C-2000005f, so that seems unlikely.
I actually didn't have the NVIC initialized (i.e. no vector table) when I got the hard fault. When I initialize the NVIC the new behaviour at the same instruction is to branch to 4500e9d2. (The code is 0x4778 (i.e. bx pc) at 0x08001e40 followed by 0x46c0 at location 0x08001e42.)
The symbol browser doesn't show any segments loaded in that area and none of the registers contained anything like that value before the branch. The debugger halts immediately, as if it only executed one instruction, but no telling really.
I'm probably smoking something, but some ARM processors have issues with code alignment and switching between ARM and Thumb modes according to section 6.1.1 of this Google hit:
http://infocenter.arm.com/help/topic/com.arm.doc.uan0002a/UAN002A_1176-pan_use_of_blx.pdf
Much more likely its something I'm not familiar with in the tools, of course.
Please sign in to leave a comment.
Comments
5 comments