Topic : Custom flash section and __attribute__((section("name")))

Forum : ARM

Original Post
Post Information Post
September 10, 2010 - 5:47pm
Guest

Dear Sirs,

To able to place some compile-time constant data at a fixed Flash address i tried to use said attribute but this didn't work right out of the box.

The first thing i did was edit the STM32F103_128K_20K_DEF.ld ( I use a STM32F103RBT6 ) to include the STORAGE area:

MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
STORAGE (r) : ORIGIN = 0x8018000, LENGTH = 32K
..... more areas...
}

and used __attribute__((section("STORAGE"))) : I still couldn't place anything there, the compiler kept placing the data into RAM.

I therefore edited the sections_FLASH.ld linker script to include the following section:

.storage :
{
. = ALIGN(4);
*(.rodata)
} >STORAGE

Now adding __attribute__((section(".storage"))) works like i would expect.

I guess the only thing i want to know is if this is the correct way to do it and if not what the best way to do this is. :)

Replies
Post Information Post
+1
0
-1
September 13, 2010 - 9:45am
Raisonance Support Team

Hi,

I think you are confusing "sections" (.text, .data, .rodata, etc.) and "memory regions" (RAM, FLASH, etc.)

The compiler places data in sections. This is what you affect with the __attribute__(...).

Then the linker places sections content into memory regions. This is what you affect in the linker script.

With your workaround you place all constants in your special region, which is probably not what you intended.

The correct way to do it would be something like this:

/* declare a STORAGE_REGION memory region (in the linker script) */
MEMORY
{
  RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
  FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K-32K
  STORAGE_REGION (r) : ORIGIN = 0x8018000, LENGTH = 32K
..... more areas...
}

...

/* place data from storage_section section in STORAGE_REGION memory region (in the linker script)*/
    .storage_section :
    {
    . = ALIGN(4);
        *(.storage_section)
    } >STORAGE_REGION


/* Then use this syntax in the declaration of data to place in the new section/region (in the source code)*/
__attribute__((section(".storage_section"))) 

I hope it helps.

If it is not clear, I suggest you take a look at the source code and linker script of CircleOS, which are available in Ride folders, and which perform this manipulation for placing non-debuggable code at the end of the flash...

Best Regards,

Vincent

+1
0
-1
September 13, 2010 - 4:27pm
Guest

Thanks for that, so the only thing that needs to be altered is the *(.rodata) in the linker script? ( Which presumably instructs the linker to place *any* readonly stuff there?)

+1
0
-1
September 13, 2010 - 4:43pm
Raisonance Support Team

Hi,

You must also...

* make sure that the FLASH and STORAGE_REGION regions don't overlap (I added '-32K' to the FLASH size for that)

* use different names for the region and the section. (don't rely on case for that.)

* in the source code, the __attribute__(...) must reference the section, not the region.

* make sure the rodata is placed in flash as it was before you modified the script. (yes, what you wrote tells the linker to place _any_ readonly stuff in the STORAGE region)

See the linker doc and CircleOS for example if it is not clear.

Vincent

+1
0
-1
January 2, 2011 - 9:56pm
Guest

Pushing this thread, because I think, ist exactly this, what I need:
for I've the 32kB-limited version of rlink, I'll try to put tested code and constants like the FWLib and graphical tables outside the debuggable area. Is this possible for complete modules or only for single functions? I'm not very familiar with the linker files and I didn't found a quick solution in the documentation.

Regards
Kai

+1
0
-1
January 3, 2011 - 9:17am
Raisonance Support Team

Hi Kai,

Any compiler object emitted as a "segment" by the compiler can have an __attribute__(()). However, this applies only for a given function and *cannot* be applied to a whole module.

I hope this helps,

+1
0
-1
January 31, 2011 - 7:40pm
Guest

Hi Bruno,
I tried this and in the debugger it seemed to work. Curiously, if I try to use the progam "standalone", it can't find the definitions :/ , so the graphics are scratched. Is there a difference between those configurations?

Regards Kai

+1
0
-1
December 28, 2011 - 5:11pm
Guest

I am going to revive this topic. I am having extreme difficulty getting custom FLASH data sections initialized on the STM32E-EVAL kit I'm using (STM32F103ZGT6, with 1024KB FLASH in two banks).

I have tried using the CircleOS ld file as a template, and I also tried putting everything in Bank 1 (lower 512KB) in case something is not working with Bank 2. I want to know if this is something I'm doing wrong, or an error that RIDE is imposing.

I am using the starter kit R-Link, and I have very little code (the ZG kit was given to me). I have tried putting all code and flash data into the lower 64KB, but nothing I do can get my custom data tables to initialize into Flash. The addresses where there should be data are just FFFFF...

+1
0
-1
December 28, 2011 - 6:13pm
Guest

OK: update. As soon as I post for help, I always manage to find the answer.

The problem was that I needed to put KEEP() around my linker storage sections, like this:

.vl_ov : {
        . = ALIGN(4);
        KEEP(*(.vl_ov))
    } > FLASHOV

The data is initial values for a wear-leveling filesystem, so future read/writes to these areas of flash are not done using physical addresses directly. Therefore, the linker thought the data tables were unused and it ignored them.