XMC4500 linker script modifications

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Not applicable
Hallo everyone,


in my project with XMC4500 I have two realy big data Arrays. Each has 128*128 elements of data type int16. So in Total there are 128*128*2*2 = 65536 bytes = 64 kbytes to load into the controller.

It was obvious this doesn't fit into the SRAM. So both arrays must be loaded into (slow) flash. Since this data needs to be modificated I can't use the keyword "const" to put into flash.


Within my researches I found a document, that uses "__attribute__((section("MEMORY_REGION")))" behind the declaration to load this variable into MEMORY_REGION. To do so, MEMORY_REGION must be declared in the linker file, linker_script.ld, provided by DAVE 4.


And there is the problem:

I have no idea what to do here!


Till now I tried several things:
1. I wrote in the following in area "SECTIONS { ... }":

.MY_SECTION (NOLOAD) :
{
*(.MEMORY_REGION_1)
*(.MEMORY_REGION_2)

} > FLASH_1_cached



As I have two arrays to load, I need two MEMORY_REGIONs. I compiled. It worked (so I thought). Then I tried to use "FLASH_1_uncached" to test if there is a difference. Unexpectedly the "uncached"-version was faster than the "cached" version. So I wanted to knwo more. I read out the data I loaded into Flash and it was all wrong. I expect that some other data/code was linked into this memory space and has overwritten my data but I couldn't find any hind to that in the mapping file.

2. In addition to the first thing I tried I wrote the following in area "MEMORY { ... }":

MEMORY
{
FLASH_1_cached(RX) : ORIGIN = 0x08000000, LENGTH = 0x100000-0xFF00
FLASH_2_cached(RX) : ORIGIN = 0x0C000000+0x100000-0xFF00, LENGTH = 0xFF00
FLASH_1_uncached(RX) : ORIGIN = 0x0C000000, LENGTH = 0x100000
PSRAM_1(!RX) : ORIGIN = 0x10000000, LENGTH = 0x10000
DSRAM_1_system(!RX) : ORIGIN = 0x20000000, LENGTH = 0x10000
DSRAM_2_comm(!RX) : ORIGIN = 0x30000000, LENGTH = 0x8000
}



In my first attempt I found out both arrays nned a space of 0xFF00 bytes in the memory. So I reduced the excisting "FLASH_1_cached" by 0xFF00 and declared my own MEMORY_REGION and used it of course in the SECTION { ... } part.
After that I tried to to the same thing with the uncached memory part. Again for comparing purposes. And Again uncached access is faster than cached.
So this didn't change anything. Neither in speed nor in data quality, since I still read out wrong data. Some othe stuff must still be mapped over my arrays.



As I'm here I really need your help.
Long story short: How do I define large (none constant) data arrays in Flash ????
Maybe there is another (simpler) way to do so ?!? I'm open for all ideas and hints.


At the end I attached my current linker_script.ld.ld. I wrote my eddited things bold and saved it as *.rtf file. So you can see it better.
Maybe you find some realy bad errors ore something like that.


Best Regards

bqpd
0 Likes
3 Replies
User10215
Level 4
Level 4
First like received
Hi bqpd,

are you sure you know what you're doing? Flash can't be used the same way as RAM. First of all the sectors in the Flash only have 1000 write cycles (see page 68 of the datasheet v1.3).
This means you are limited in how often you can modify your data. RAM can be written almost indefinitely.
Then, in order to change on value in your array you first would have to erase a whole sector. Sectors are of sizes 16kB to 256kB which means you would have to erase a part of your array of at least 16kB in order
to change one value. Starting at page 8-7 of the reference manual v1.5 there is a table of how the flash is separated into sectors. At page 8-11 of the same reference manual you have a list of all
the commands you can use to program the flash. To sum up: you can only erase in sizes of sectors and program data in sizes of pages which are 256 bytes. I don't know if that is what you really want.

By the way the XMC4500 has 3 RAM areas. One spans from address 0x10000000 to 0x1000FFFF (so 64kB). The default RAM is also 64kB with the addresses 0x20000000 to 0x2000FFFF.
The third goes from 0x30000000 to 0x30007FFF which gives you a size of 32kB. Page 7-4 of the reference manual gives you that information. What I would do is to place one of the two big arrays in the
RAM starting from 0x30000000 and the other array in the second half of the RAM starting from 0x20000000.

Regards,
Niclas
0 Likes
User10215
Level 4
Level 4
First like received
And sorry, before you ask. I'm not that familiar with DAVE, so I don't know how to put variables to specific addresses in RAM. But I'm sure someone can give you that information. Good luck!

Greetings,
Niclas
0 Likes
Not applicable
Niclas wrote:
What I would do is to place one of the two big arrays in the RAM starting from 0x30000000 and the other array in the second half of the RAM starting from 0x20000000.



Hi Niclas,

thank you very much for the hint. I tried and it worked pretty good. I never changed any memory locations before so i realy wasn't sure what I was doing. Reading some data sheets might had helped I guess.


One last question:

The next step is to change the data in that way that the changes will be present after the next reset. As I can see I have to change the data pages in Flash, right? Or is there any other way to do so? I can get the memoyr adresses from themapping file. I can look for the page size in referenc manuall. And there are some LLD functions like (taken from xmc4_flash.c)

/*
* This API write the PFLASH page
*/
void XMC_FLASH_ProgramPage(uint32_t *address, const uint32_t *data);



This won't happen that often, so I'll stay far under 1000 write accesses.
0 Likes