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.
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.