Hello everyone, I'm zhi.
I'm rather new to MCU programming, and I'm trying to copy a function over to RAM to execute so I can copy data to flash to run. I'm hoping to use it as a basis for a EEPROM emulator in RAM.
I followed TN228 ,and referenced the thread here : https://community.freescale.com/thread/50329
My code is as follows :
extern char __SEG_START_FLASH_ROUTINES[];
extern char __SEG_SIZE_FLASH_ROUTINES[];
/*****************************************************************************/
#pragma CODE_SEG __NEAR_SEG FLASH_ROUTINES
void func(void){
LCD_write(0x55);
return;
}
#pragma CODE_SEG DEFAULT
/**********************************************************************/
/* Copies Flash_Cmd() function into RAM, using steps documented in Tech
Note 228
Start_data refers to the begining of the flash block to be copied.
*/
#define Start_data __SEG_START_FLASH_ROUTINES
#define Size_data __SEG_SIZE_FLASH_ROUTINES
void CopyInRAM(void)
{
char *srcPtr, *dstPtr;
int count;
srcPtr = (char *)Start_data;
dstPtr = (char *)(void *__near)&func;
for (count = 0; count < (int)Size_data; count++) {
*dstPtr = *srcPtr;
dstPtr++;
srcPtr++;
}
}
I have adjusted the PRM to include room to accomodate the functions in ram, as below
SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
RAM = READ_WRITE 0x3000 TO 0x3EFF;
RAM_FUNCS = READ_ONLY 0xFE00 TO 0xFEFF
RELOCATE_TO 0x3F00;
FLASH_EEPROM = NO_INIT 0x4000 TO 0x47FF
ALIGN 2
FILL 0x00;
ROM_C000 = READ_ONLY 0xC000 TO 0xFDFF;
PAGE_38 = READ_ONLY 0x388000 TO 0x38BFFF;
PAGE_39 = READ_ONLY 0x398000 TO 0x39BFFF;
PAGE_3A = READ_ONLY 0x3A8000 TO 0x3ABFFF;
PAGE_3B = READ_ONLY 0x3B8000 TO 0x3BBFFF;
PAGE_3C = READ_ONLY 0x3C8000 TO 0x3CBFFF;
PAGE_3D = READ_ONLY 0x3D8000 TO 0x3D83FF;
PAGE_3D_B000 = READ_ONLY 0x3DB000 TO 0x3DBFFF;
END
PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */
_PRESTART,
STARTUP,
ROM_VAR,
STRINGS,
NON_BANKED,
DEFAULT_ROM,
COPY INTO ROM_C000;
FLASH_EEPROM INTO FLASH_EEPROM;
FLASH_ROUTINES INTO RAM_FUNCS;
DEFAULT_RAM INTO RAM;
END
It's more or less similar to the code posted in the thread above. The code compiles, and indeed is able to copy the function to RAM, but after calling the function and executing it, an RTS command jumps to a BGND at a reserved register.
What could be the problem?
I am using a Banked Model for memory and am using Processor Expert.
Any help is deeply appreciated.
Hi....
I have just finished doing something similar to what you are trying to do.
All your stuff seems OK, except that I haven't seen if the (flash) code has
been declared as PIC_CODE (position independent).
The compiler prefers to use PC-relative addressing, and - after you have
placed the code in RAM - the addresses will be all wrong.... Declaring it
as position independent forces it to use absolute addresses.
I was using a mc9s12c32 chip, but it applies even to S12X series chips.
Hope that it is useful,
Seb
I'm not sure what stuff you are talking about. If about allocating code directly to RAM, then why do you think it should be made position independent? Linker is told I want my function to be in RAM, say at 0x1000. And linker does all relocations for 0x1000. But codes don't end in S-records at 0x1000. Instead, they are treated as initializer for RAM object at 0x1000 and end in S-records at some existing flash addresses.
See attached demo that proves position independent compilation is not required. There's big function in RAM, which makes compiler using JMP with absulute addressing. No problems.
Hello
If you get an Illegal breakpoint at the end of the function then you have one of the following Problems>
1- The stack pointer is pointing to invalid memory
2- The content of the stack has been modified
3- The return PC is not pointing to a valid location.
I would suggest you to set a BP at the end of your RAM function and examine the content of the stack.
CrasyCat