FAQ 27860 lost?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FAQ 27860 lost?

1,642 Views
thomasdelfs
Contributor I

In old freescale forum there is a refence to a FAQ-27860 with information for

How to copy function from flash to ram

I'm not able to find these application.

 

regards

 

Thomas Delfs

Labels (1)
0 Kudos
Reply
7 Replies

1,441 Views
thomasdelfs
Contributor I

Thanks a lot.

I make a redesign of Code for a existing Project. There are some limitations. One is it has to programmed into external FLASH.

After relocating Code to RAM and activating the i-cache it's 3 times faster (and hopefully stable ;-) )

0 Kudos
Reply

1,441 Views
thomasdelfs
Contributor I

Do You now the reason for these problem? Cache and RAM are different memories isn't it? I'll check it for my Code, but at the moment the processor is running (MCF5282).

Thomas Delfs

0 Kudos
Reply

1,441 Views
TomE
Specialist II

> Do You now the reason for these problem? [sic] Cache and RAM are different memories isn't it?

Yes, That's the problem. Your copied code won't be in the right memory for the CPU to execute from. I thought the problem was obvious from my explanation. You should read up some more about what caches do and how they work.

These processors that have caches have separate code and data caches.. Copying code when the caches are enabled:

1 - CPU copy loop reads a word from the source address,

2 - A cache line of data is read into the data cache, CPU reads from there,

3 - CPU copy loop writes a word to the destination address,

4 - Usually a cache line is flushed to make room, and the data is written to the cache,

5 - Copy has finished, but the data is still in the data cache, not in the main memory,

6 - CPU calls the copied function and will either read:

6a - Stale data from the Instruction Cache (if it has called previous code from that address), or

6b - Instruction cache will read stale data from main memory, or

6c - You may have gotten lucky and other memory-using functions may have flushed the data and code caches "by accident".

The only clean way to do this is to:

1 - Perform the copy,

2 - Flush the Data Cache to push the code into main memory,

3 - Clear the Instruction Cache to get rid of any old copies.

Caches make these CPUs run faster. Think 10 to 20 times faster for the Instruction Cache. I was working on code on an MCF5235 which didn't have the data cache enabled, and was managing an Ethernet data transfer speed of 3.3 Mb/s. Enabling the data cache (with bursting) got it up to 6.5Mb/s, almost twice as fast. Rewriting the "memcpy()" and the UDP Checksum (both in assembly) eventually got it up to 9 Mb/s.

Handling the caches also makes "sample code" more complicated, so it is usually left out. Sample code is that, an example which is seldom usable "as-is".

Tom

0 Kudos
Reply

1,441 Views
TomE
Specialist II

There's one other thing to watch out for.

Surprisingly, neither AN4329 or FAQ-27860 mention this.

If you are copying code around on the any MCF Series 2, 3 or 4 chip (but not on MCF51), you have to watch out for the code and data caches. If the code is copied before the caches are enabled there's no problem. If the Data Cache is enabled for the destination memory in any mode other that "Write Through", then it needs to be flushed after the code has been copied. Likewise, the Instruction Cache needs to be invalidated after the copy, but normally only if the same destination RAM is being used for different functions. It would be a good idea to flush the cache even if it isn't necessary in case your "function copy" code is reused by someone else (or yourself) at some time in the future in a case where the cache flush is required.

Tom

0 Kudos
Reply

1,441 Views
miduo
NXP Employee
NXP Employee

Hi,

Yes, this post has been moved, sorry. I had retrieved it from our internal server. Please see below:

FAQ-27860

Problem: : With CodeWarrior's Coldfire implementation, how can I define a portion of the application's code so that it runs from RAM? This is useful to add Flash programming capability to an application.

Solution:

   There are two ways to have an application's code execute from RAM, which are decribed below.

Note the slight, but important differences between code that executes on a ColdFire V1 core, versus code the executes on ColdFire V2, V3, and V4 cores.

First method: Get the Startup code to automatically copy the code from ROM to RAM

=================================================================

Make the following changes to a CodeWarrior project created with the Project wizard:

1) Place the code to execute from RAM into a user-defined code section.

For a ColdFire V1 core, this is done as follows:

#pragma CODE_SEG __FAR_SEG CopyToRAM
unsigned int Fibonacci(unsigned int n) {
/*Code here*/
}
#pragma CODE_SEG DEFAULT

For a Coldfire V2, V3, or V4 core, do the following:

#pragma define_section CopyToRAM "CopyToRAM " far_code
__declspec (CopyToRAM) unsigned int Fibonacci(unsigned int n) {
/* Code here */
}

2) In the .lcf file, define a new section, .copyToRAM, which will hold the user-defined code section. This arrangement is easier to achieve when the user-defined section is allocated next to initialized data. Here are the linker commands:

.copyToRAM: AT(___DATA_ROM + SIZEOF(.data))
{
. = ALIGN (0x4);
__START_COPYTORAM = .;
*(CopyToRAM)
__END_COPYTORAM = .;
} >> userram

3) Increase the size of data to be copied from ROM to RAM to cover both the global data and the new section, .copyToRAM.
In case .copyToRAM is not placed next to the .data section, you may need to add an additional descriptor to the S_romp table, as shown below:

.romp : AT(_romp_at)
{
__S_romp = _romp_at;
WRITEW(___DATA_ROM); #ROM start address
WRITEW(___DATA_RAM); #RAM start address
WRITEW(SIZEOF(.data) + SIZEOF(.copyToRAM)); #size
WRITEW(0);
WRITEW(0);
WRITEW(0);
}

Second method: Copy the code to RAM only when needed
=============================================
Make the following changes to a CodeWarrior project created with the Project wizard.
1) Place the code that must execute from RAM into a user-defined code section.
For a ColdFire V1 core, proceeed as follows:

#pragma CODE_SEG __FAR_SEG CopyToRAM
unsigned int Fibonacci(unsigned int n) {
/*Code here*/
}
#pragma CODE_SEG DEFAULT

For a Coldfire V2, V3, or V4 core, do the following:

#pragma define_section CopyToRAM "CopyToRAM " far_code
__declspec (CopyToRAM) unsigned int Fibonacci(unsigned int n) {
/* Code here */
}

2) In the .lcf file, define a new section, .copyToRAM, where the user-defined code section goes. The linker commands are:

_ROMCodeToCopy = ___DATA_ROM + SIZEOF(.data);
.copyToRAM: AT(_ROMCodeToCopy) {
. = ALIGN (0x4);
__START_COPYTORAM = .;
*(CopyToRAM)
__END_COPYTORAM = .;
} >> userram

3) Create a new source file that implements a function that copies the code from ROM to RAM. The function is called CopyCode, whose source is in the file copycode.c. The function uses the symbols defined in the linker file to retrieve the source address, destination address, and size of the code block to be copied. Here is the code:

extern char far ROMCodeToCopy[], _START_CopiedToRAM[], _END_CopiedToRAM[];
extern unsigned long far SizeCodeToCopy[];
void CopyCode(void) {
char *src, *dest;
long size;
src = (char *)ROMCodeToCopy;
dest = (char *)_START_CopiedToRAM;
size = _END_CopiedToRAM - _START_CopiedToRAM;
if (dest != src)
while (size--)
*dest++ = *src++;
}

  

1,441 Views
TomE
Specialist II

It may not be lost, but it isn't on a public-side web server any more. I can't even find it on archive.org.

Fang Li might be able to help with this one.

This previous post might contain enough of a worked example to help you:

https://community.nxp.com/message/57126#comment-57126

Tom

0 Kudos
Reply

1,441 Views
thomasdelfs
Contributor I

These example will not work for my issue, but I've implemented the chapter

5.2 Placing Code and Data in RAM

from AN4329 and it works.

Thank You

0 Kudos
Reply