Skip to main content
BKain.2
Associate
March 17, 2023
Solved

How to place an ASC string in flash on STM32G474 controller when using CubeIDE with GCC compiler?

Hello,

I have an issue to place a ASCII string in flash when using CubeIDE and the GCC compiler:

#define APP_INFO_ADDR_2   ".ARM.__at_0x08000200"

const uint8_t my_text[] __attribute__((section (APP_INFO_ADDR_2))) = {"Hallo"};

when I compile this code (no opimization), I get no errors, but at the hex file at address 8000200 there is no "Hallo" string located.

0693W00000aJBt9QAG.jpg 

When I compile the same code with µVision and the Keil Compiler it works.

0693W00000aJBspQAG.jpgI also searched for this issue and the only working solution I found is, to define a separate section in the linker script and then place this string in this specific section.

But to change the linker script for this task is not my preferred way.

So the question for the community here is:

What do I need to change here to see also this ASCII string in the hex file, when using GCC and CubeIDE?

BR

This topic has been closed for replies.
Tesla DeLorean
Tesla DeLoreanBest answer
Guru
March 17, 2023

Cramming things at specific addresses tend to be very non-portable.

There are AT directives in GNU/GCC, don't remember exact syntax, see Point#1

You could expand tables/space after the vector table in startup.s to accommodate this.

Is this for patching calibration/serial information in production programming? The STM32 tend to have large flash sectors, and this early in the image you're apt to have to erase the critical structures if you need to rewrite or modify on-the-fly.

Best to park serial/calibration at the END of the available memory space, that way the checksum/integrity of the primary image isn't compromised by holes/differences in the middle of it.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..

5 replies

ST Technical Moderator
March 17, 2023

Hello BKain.2,

First, as you mentioned, it is possible to modify the linker file.

Since, you don't want to change it, you can try to use .rodata section to insert a constant read only string. Then, you should use it in your code. Otherwise, it will be deleted.

const char my_text[] __attribute__((section(".rodata"))) = "Hallo";

If this solves your problem, please mark my answer as "Best Answer" by clicking on the "Select as Best" button, this can be helpful for Community users to find this solution faster. 

Firas

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.Best regards,FBL
BKain.2
BKain.2Author
Associate
March 17, 2023

Hello Firas,

Thanks for your feedback. Unfortunately your proposal does not solve the problem.

This

__attribute__((section(".rodata"))) does not put the sting into any

flash place.

In the meantime I found an similar topic

here:

https://community.st.com/s/question/0D53W000014wt4KSAQ/placing-string-in-a-fixed-memory-address-on-flash

The main problem is, that the GCC compiler ignores this section ( ".ARM.__at_0x08000200") or your proposal:

(section(".rodata")

I found now a fix (workaround), that this section ( ".ARM.__at_0x08000200") is supported by both compiles,GCC and Keil.

The trick is to define in the GCC linker script a section with the same label name  .ARM.__at_0x08000200 like the KEIL compiler supports correctly.

1.) For GCC the linker skript must be changed in the following way:

/* Memories definition */

MEMORY

{

 CCMSRAM  (xrw)  : ORIGIN = 0x10000000,  LENGTH = 32K

 RAM  (xrw)  : ORIGIN = 0x20000000,  LENGTH = 128K

  /*FLASH  (rx)  : ORIGIN = 0x8000000,  LENGTH = 512K*/ 

 FLASH_INT  (rx) : ORIGIN = 0x08000000, LENGTH = 500

 EEPROM_0 (rx)  : ORIGIN = 0x08000200, LENGTH = 150

 FLASH  (rx)   : ORIGIN = 0x08000230, LENGTH = 510K

}

/* Sections */

SECTIONS

{

 /* The startup code into "FLASH" Rom type memory */

 .isr_vector :

 {

  . = ALIGN(4);

  KEEP(*(.isr_vector)) /* Startup code */

  . = ALIGN(4);

 } >FLASH_INT 

  /* prepare 1K from the FLASH as speudo EEPOM */

 /* .ARM.__at_0x08000200 :*/

 .ARM.__at_0x08000200 :

 {

  . = ALIGN(4);

  KEEP(*(.ARM.__at_0x08000200))

  . = ALIGN(4);

 } >EEPROM_0

  

 /* .flash_eeprom_0 :*/

 .flash_eeprom_0 :

 {

  . = ALIGN(4);

  KEEP(*(.flash_eeprom_0))

  . = ALIGN(4);

 } >EEPROM_0

.........

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
March 17, 2023

Cramming things at specific addresses tend to be very non-portable.

There are AT directives in GNU/GCC, don't remember exact syntax, see Point#1

You could expand tables/space after the vector table in startup.s to accommodate this.

Is this for patching calibration/serial information in production programming? The STM32 tend to have large flash sectors, and this early in the image you're apt to have to erase the critical structures if you need to rewrite or modify on-the-fly.

Best to park serial/calibration at the END of the available memory space, that way the checksum/integrity of the primary image isn't compromised by holes/differences in the middle of it.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Pavel A.
March 17, 2023

The mainstream GCC does not have __attribute__(("at")), or the mainstream GNU linker does not support it. This attribute is Keil specific.

​

IIRC the ​ GNU linker cannot even define a segment at absolute address that collides with any region in the MEMORY {} section.​

​

@BKain.2​ As Firas wrote, you need to make a reference to this data, else it will be removed as unused.