Loading...
 

STM32MP1 support available in SW4STM32

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world.
And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4; you can download a short video showcasing this on the ac6-tools website (registration required).

System Workbench for STM32


Locating data in a specific ROM section

Hi ST world,

I’d like to create some specific section in flash.
Can I find a reference documentation about the linker behavior somewhere ?

If not, here is what I did in my linker script:

Create a second const memory

/* Memories definition */
MEMORY
{
ROM_Code (rx) : ORIGIN = 0x8000000, LENGTH = 448K
ROM_Data (r) : ORIGIN = 0x8060000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}


/* Sections */
SECTIONS
{
..... AUTOMATICALLY SET SECTIONS

/* Specific const section*/
._const_data :
{
. = ALIGN(4);
*(._const_data) /* .text sections (code) */
*(._const_data*) /* .text* sections (code) */

. = ALIGN(4);
_e_cdata = .; /* define a global symbols at end of data */
} >ROM_Data
}

Is it the correct way to do this ?

My program links ok with this modified linker script, nevertheless, how can I explicitely set a variable to be in “_const_data” section from a C file? Should I use some pragmas ?

Thanks for your help,
Regards,

Sylvain


Hi,

thanks for your help, I read the web page and used your example but I can’t allocate the section where I’d like:

Here is what I did:

Linker script:


MEMORY
{
ROM_Code (rx) : ORIGIN = 0x8000000, LENGTH = 448K
ROM_Data (r) : ORIGIN = 0x8050000, LENGTH = 256K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}

/* Sections */
SECTIONS
{

....................

._const_data :
{
. = ALIGN(4);
*(.rodata)
*(.rodata*)
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
} >ROM_Data

}


Then in C code:

  1. define FL_SIZEOF_FLASH_SECTOR 127000 // 128 K
  2. define FL_NB_SECT_REQ_FOR_CONST_DATA 2



//! @brief const structure
typedef union _block_const_data_u
{
unsigned char bulkFL_SIZEOF_FLASH_SECTOR;

struct {
struct
{
unsigned char _number 20;
} infos;
} data;
} _block_const_data_t;

//! @brief block allocating all const structures
typedef struct _global_const_data_s
{
_block_const_data_t block2;

} _global_const_data_t;

volatile const _global_const_data_t s_const_data attribute ((section (“_const_data”))) =
{
.block0.data.infos._number = “12345678901234567890”,
.block1.data.infos._number = “12345678901234567890”
};


>>>> I expect the s_const_data structure to be allocated in .rodata of _const_data sections defined in linker script but I have the following error at link stage:

c:/utils/eclipse/eclipse-cpp-luna-sr1-win32/eclipse/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.1.0.201503101257/tools/compiler/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/bin/ld.exe: project.elf section `_const_data’ will not fit in region `RAM’
c:/utils/eclipse/eclipse-cpp-luna-sr1-win32/eclipse/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.1.0.201503101257/tools/compiler/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/bin/ld.exe: region `RAM’ overflowed by 130856 bytes

>>>> So obvisouly something is not correctly interpreted by gcc linker.


>>>> Map file excerpt:

._const_data
0x08050000 0x0
0x08050000 . = ALIGN (0x4)
*(.rodata)
*(.rodata*)
*(.text)
*(.text*)


>>> Nothing is allocated in the .text nor .rodata parts of the section _const_data

>>> And further in the map file, definititely unexpected interpretation:

_const_data 0x20000448 0x3e030 load address 0x0800d530
0x20000448 PROVIDE (startconst_data, .)
_const_data
0x20000448 0x3e030 ./src/Middlewares/gmx/mem/flash/flash_hal/flash_hal.o
0x20000448 s__const_data
0x2003e478 PROVIDE (stopconst_data, .)
0x2003e478 . = ALIGN (0x4)



>>> Any ideas about what’s wrong ?

Thanks,
Regards,
Sylvain


France

Hi Sylvain,

First in your C code, I don’t understand why you created your constant variable as “volatile const”; just creating it as “const” will place it in the “rodata” section that will go in flash automatically.

The “volatile const” idiom should be used for modeling read-only device registers, that you can’t write (so the const) but may change by themselves (so the volatile); this is obviously not what you want here, as you want this data to be really constant and placed in ROM.

Also when including code in a post, you should use the CODE plugin to format it correctly, and avoid the braces and quare braces to “disapear” from the output: use
{CODE()}your C code with [] and {}{CODE}
.


Anyway, in the fragment below, taken from your linker script:

._const_data :
{
    . = ALIGN(4);
    *(.rodata)
    *(.rodata*)
    *(.text) /* .text sections (code) */
    *(.text*) /* .text* sections (code) */
} >ROM_Data
  • You declare an output section, in your executable linker file, named ._const_data
  • This section will contain all .rodata, .rodata.xxx, .text and .text.xxx sections of your input files (at least if they were not already placed in a precedently defined output section)
  • You asked this output section to be placed in the ROM_data part of your flash


This does not work as you do not say where to place the ._const_data sections of your input files. The confusion you make here was between the names of sections as found in the input files and the names given to sections in the generated executable file.

The simplest to place some constant data in flash would be, if you don’t want to explicitly partition your flash array, to start from the standard linker script file and just add two lines reading

*(._const_data)         /* .rodata sections (constants, strings, etc.) */
    *(._const_data*)        /* .rodata* sections (constants, strings, etc.) */

in the .rodata output section; the only inconvenient is that your constant data will be interleaved with compiler-generated constant data.

However, any variable declared “const” at the global (or static) level of your source file is already, by default, placed in the .rodata section, so in fact this is even useless if you can accept your constant data to be interleaved with other constant data.

If that interleaving bothers you, add a full new output section by:

._const_data :
  {
    . = ALIGN(4);
    *(._const_data)         /* .rodata sections (constants, strings, etc.) */
    *(._const_data*)        /* .rodata* sections (constants, strings, etc.) */
  . = ALIGN(4);
  } >ROM

Then all your own constant data will be located together in memory.

Creating a specific ROM section is only needed if you want to control the amount of flash devoted to your own const data and to the generated code and litteral data.

Bernard


Hi Bernard,

I used volatile to force the compiler to take into account my variable.
Compiler will ignore my data as it’s not referenced. Volatile seemed to work well for this, but yes, it’s not usually used for const data...

thanks for your answer about the usage of const but maybe I was not accurate enough.

I agree, const is the common way to place data in flash memory.
But what I’m looking for is to fix the address of the const data I’m creating locating it in a given flash section.
This will be necessary to maintain my flash mapping during development time.
(e.g. you want to update an application using the bootloader and this new application keeps the const data belonging to the updated application)

So I need to force the address of my data and I’d like to set mapping through the linker script only (for C source code portability between all STM32 microprocessors)

Thanks for your help,
Regards,
Sylvain


France

Hi Sylvain,

So clearly you should use my last proposition above; let me know if you have any other problem.

Bernard


Hi Bernard,

many thanks !!
I could position my const data at expected address creating a dedicated memory space in linker script.

(e.g: ROM_Data (r) : ORIGIN = 0x8050000, LENGTH = 256K )

Thanks for your help,
Regards,
Sylvain