cancel
Showing results for 
Search instead for 
Did you mean: 

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

BKain.2
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions

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
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

5 REPLIES 5
FBL
ST Employee

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 Accept as Solution on the reply which solved your issue or answered your question.

BKain.2
Associate II

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

.........

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
Up vote any posts that you find helpful, it shows what's working..

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.

@Tesla DeLorean:

Thanks for your very helpful information.

The main idea is to save the name of the

FW version in ASCII on a defined placed in flash. So e.g. the factory has the

chance to open (or read out) the hex file and determine what FW version this

is.

We already noticed, that the same location the beginning between the different controller families (STM32G0 / STM32G4) can be risky, because the length of the vector tables varies.

This means at the beginning the offset must be away for the maximum length of the interrupt vector table the make sure not to crash.

There are pros and cons to place this FW information at: ".ARM.__at_0x08000200"

At this place it’s easy to find and should work for all the G4 family.

However, to place the FW information at the end of the flash would quire to place it individually for each G4 controller size.

What’s your thoughts ?