2023-03-17 02:15 AM
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.
When I compile the same code with µVision and the Keil Compiler it works.
I 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
Solved! Go to Solution.
2023-03-17 10:09 AM
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.
2023-03-17 08:16 AM
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.
2023-03-17 09:44 AM
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:
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
.........
2023-03-17 10:09 AM
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.
2023-03-17 01:04 PM
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.
2023-03-20 04:50 AM
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 ?