Hi ,everyone,I'm using KL under KEIL environment.
I want to load function in flash while execute in ram.Though I can place the code in ram ,But I don't
know where it loads in flash,and that's important for me.
So can you tell me how to arrange the scatter file to load the function at a absolute address(or session)
and meanwhile place its execute address in ram?
Thanks!
Solved! Go to Solution.
sorry to disturb all of you.
It's my problem don't know much about scatter file.Now I tried as below,and succeed :
LR_IROM2 0x00007000 0X100
{
ER_RAM 0x20000000 0x00000100
{
Test.o
}
}
hi FU grace,
The following example show how to load code in flash to ram and run it.
/************************************************************************
* NAME: ftfl_command_inram
*
* DESCRIPTION: Launch the command. It must be in RAM.
************************************************************************/
void ftfl_command_inram(volatile unsigned char *ftfe_fstat)
{
*ftfe_fstat = MK_FTFL_FSTAT_CCIF_MASK;
while (!(*ftfe_fstat & MK_FTFL_FSTAT_CCIF_MASK))
{};
}
static void ftfl_command_32bit( unsigned char command, unsigned long *address, char *data )
{
char *pdata = data;
static void (*fnRAM_code)(volatile unsigned char *) = 0;
/* Adequate space for the small program */
#define PROG_SIZE (50)
if(!fnRAM_code)
{
int i = 0;
unsigned char *pCodeStart = (unsigned char *)ftfl_command_inram;
/* Make space for the routine on stack (this will have an even boundary) */
#if defined(__IAR_SYSTEMS_ICC__) || defined(__IASMARM__)
#pragma data_alignment=2
volatile static unsigned char ProgRamSpace[PROG_SIZE];
#else
volatile static unsigned char ProgRamSpace[PROG_SIZE] __attribute__ ((aligned (2)));
#endif
/* Thumb 2 address */
pCodeStart = (unsigned char *)(((unsigned int)pCodeStart) & ~0x1);
/* Copy program to SRAM */
while (i < PROG_SIZE)
{
ProgRamSpace[i] = pCodeStart[i];
i++;
}
/* Create a thumb 2 call */
fnRAM_code = (void(*)(volatile unsigned char *))(ProgRamSpace + 1);
}
DisableInterrupts;
/* The CCIF flag must read 1 to verify that any previous command has
* completed. If CCIF is zero, the previous command execution is still active, a new
* command write sequence cannot be started, and all writes to the FCCOB registers are
* ignored.
*/
while (!(MK_FTFL_FSTAT & MK_FTFL_FSTAT_CCIF_MASK))
{};
/* Ensure that the ACCERR and FPVIOL bits in the FSTAT register are cleared prior to
* starting the command write sequence.
*/
MK_FTFL_FSTAT = (MK_FTFL_FSTAT_ACCERR_MASK | MK_FTFL_FSTAT_FPVIOL_MASK);
/* The FCCOB register group uses a big endian addressing convention. */
/* Write a valid command to the FCCOB0 register. */
MK_FTFL_FCCOB0 = command;
/* Flash address.*/
MK_FTFL_FCCOB1 = (uint8)(((uint32)address) >> 16); /* Flash address [23:16] */
MK_FTFL_FCCOB2 = (uint8)(((uint32)address) >> 8); /* Flash address [15:8] */
MK_FTFL_FCCOB3 = (uint8)((uint32)address); /* Flash address [7:0] */
/* Data.*/
MK_FTFL_FCCOB4 = (uint8)(pdata[3]); /* Data Byte 0.*/
MK_FTFL_FCCOB5 = (uint8)(pdata[2]); /* Data Byte 1.*/
MK_FTFL_FCCOB6 = (uint8)(pdata[1]); /* Data Byte 2.*/
MK_FTFL_FCCOB7 = (uint8)(pdata[0]); /* Data Byte 3.*/
fnRAM_code(&MK_FTFL_FSTAT);
EnableInterrupts;
}
Hello,
In your example I could not understand why the last significant bit should be 0 ( pCodeStart = (unsigned char *)(((unsigned int)pCodeStart) & ~0x1). As I read the in cortex M processors for thump-2 instructions , the lsb bit for PC should be 1 ,right?? And then you use this instruction (void(*)(volatile unsigned char *))(ProgRamSpace + 1) to create thumb -2 call. Can you explain me the reason for this?
Thank you
Best regards
I would just like to add an 'application note' regarding this technique to get a 'small function' moved temporarily out to RAM. The ARM architecture, and compilers, require 32-bit constants, like 'fixed' peripheral addresses (MK_FTFL_FSTAT, etc) to be loaded from program-space at a 'relative' offset to the program counter. A compiler will place these numbers in program space at the end of an 'object' file, so 'following' the source code. This means two things: Firstly, that the 'routine' you are going to copy out to RAM MUST be at the 'end' of the associated source-file, AND that 'PROG_SIZE' must include not only the actual code, but ALSO these 'constants' off the end.
Hi,xiaodong,Thank you very much .You've really got what I want to do.And the answer maybe a solution.But it's a little too complex for me,I can understand what your function wants to do ,that's copy function from flash to ram and protect the FCCOB register.I guess it may be what the __main in KEIL completes which I don't know where its source code locates.
But I really want other more easy way to solve it,like using scatter file in KEIL to place the function in different load address and execute address.
Anyway,Thanks!
Please check below link about how to place function and data at dedicated address of Keil:
Linker User Guide: Placing functions and data at specific addresses
Wish it helps.
Best regards,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi,Ma hui.
I've solved the problem,it's ok to do like my fist reply for this question.My later hard fault problem occured because the code placed in that special
session has some illegal operation.
Thanks anyway!
hi,Ma hui.
actually I had seen the link about how to place at specific address ,and I tried both place function at flash or ram.
But now my question is a little different.Not only do I want to place my function in flash ,but the most important,I want to
execute it in RAM,so it's a difference between load address and execute address.My upper reply gives my tried solution,
I thought it works,but these days I tried another more complex file(not only simple test file) to do as the test,and find it works not
stable.That' s sometimes it works ,but more often it runs to hard Fault.
Can you give me more hints?Thanks very much!
sorry to disturb all of you.
It's my problem don't know much about scatter file.Now I tried as below,and succeed :
LR_IROM2 0x00007000 0X100
{
ER_RAM 0x20000000 0x00000100
{
Test.o
}
}