views:

176

answers:

2

I'm trying to execute a function from RAM on a Cortex-M3 processor (STM32). The function erases the and rewrites the internal flash, so i definitely needs to be in RAM but how do I do that?

What I have tried is this: Copy the function to a byte array in RAM using memcpy (checking that it gets aligned correctly), setting a function pointer to point to the byte array an then calling the the function(pointer).

This works fine for maybe 10 instructions (I can follow the execution with the debugger) but then I get a buss error and the processor resets. The buss error occurs on the second pass through a loop so the code should be fine (as it works the first pass). I'm thinking that the faster RAM access mucks up the buss timing in some way...

Anyway is there a correct way to do this? How would a scatter file look like that places a function in RAM automatically (I'm using Keil uVision for Cortex-M3)?

Edit: More info: Toolchain: RealView MDK-ARM V 4.10 Compiler: Armcc v4.0.0.728 Assembler: Armasm v4.0.0.728 Linker: ArmLink v4.0.0.728 Processor: STM32F103ZE

The IMPRECISERR bit is set in the buss fault register when the reset happens.

A: 

Without knowing more about your situation I can only suggest a few general things... make sure you have a valid stack for that function (or avoid all stack operations in the function), that your interrupts are disabled, and that any vectors in the system vector table don't point to code that goes away when you erase flash. Lastly, make sure your function is linked to run at the address you put it... the code may not be relocatable and may jump to a spot in is old location.

Amardeep
+3  A: 

The crash upon loop iteration is probably because the function is branching to an absolute address and is not relative to the new function location in RAM. Would accessing the original code location at that point cause a bus error because of the flash erase operation?

I believe you can mark a function to be compiled and copied to RAM correctly with CARM by appending the __ram directive to the function definition. For instruction on how to do the same with the RealView compiler see the EXECUTING FUNCTIONS IN RAM technical support article:

µVision allows you to locate modules to specific memory areas that are entered in the dialog Project - Options - Target. To do so, right click on a source file (or file group) and open the dialog Options - Properties. Then select the memory regions under Memory Assignment.

There is an example in the folder ARMExamplesRAM_Function.

That should generate startup code to take care of copying the function to RAM and linking calls to that location correctly. Otherwise, if you need to dynamically copy arbitrary functions to RAM, then look into compiling position independent code (PIC) with RealView.

Judge Maygarden
Excellent answer!
c0m4
I've got the same problem except I'm not using RTX or any libraries so I don't include the compiler's code that automatically loads RAM functions into RAM.I'd like to have a load region or execution region in RAM where my code will actually be linked to but I need the JTAG programmer to load the code into another address (in flash).Ideally in the .sct file (I'm using Keil MDK) I'd have a section where I specify the storage and linkage address.But I haven't worked out how to do that yet.
Captain NedD
@Captain: You may want to consider opening a new question with your specifics. However, I believe the solution above applies in your situation as well.
Judge Maygarden