Hello,
I have calibration values that I'd like to edit offline, therefore I'd like the labels to be first saved to flash, before being transferred to RAM.
For all of the values I define as "ExportedGlobal" with an initial value of "0", they are then being defined as bss, not data and not being stored in Flash.
The data type doesn't matter, boolean, unit8, single.
How can I easily ensure that labels are defined as data, not bss?
Solved! Go to Solution.
Hi @Sam_ECU
I am not sure what's the root cause becasue no any sample code from you. I would like to share my understanding and comments below.
1. If you initialize GlobalVar
with a non-zero value, it will be placed in the .data
section:
uint8_t GlobalVar = 1; // Initialize with a non-zero value
2. You can modify your linker script to force the variable into the .data
section. Here is an example of how you can do this:
uint8_t GlobalVar __attribute__((section(".my_data"))) = 0;
SECTIONS
{
.text :
{
*(.text*)
} > FLASH
.data :
{
*(.data*)
*(.my_data*) // Add your custom section here
} > RAM AT > FLASH
.bss :
{
*(.bss*)
*(COMMON)
} > RAM
}
3. If you prefer not to modify the linker script, you can initialize the variable in a custom initialization function that runs before main
:
uint8_t GlobalVar; void __attribute__((constructor)) initialize_global_var(void) {
GlobalVar = 0; // Initialize with a non-zero value if needed
}
// main.c
#include <stdint.h>
// Define GlobalVar in the .my_data section
uint8_t GlobalVar __attribute__((section(".my_data"))) = 0;
int main() {
// Your application code
while (1) {
// Do something
}
return 0;
}
SECTIONS
{
.text :
{
*(.text*)
} > FLASH
.data :
{
*(.data*)
*(.my_data*) // Add your custom section here
} > RAM AT > FLASH
.bss :
{
*(.bss*)
*(COMMON)
} > RAM
}
Hi,
what's your meaning of 'For all of the values I define as "ExportedGlobal" with an initial value of "0", they are then being defined as bss, not data and not being stored in Flash.' ? would you please check and give example to explain it.
https://mirzafahad.github.io/2021-05-08-text-data-bss/
Hello @Sam_Gao ,
Using the terminology from the example:
https://mirzafahad.github.io/2021-05-08-text-data-bss/
My GlobalVar is defined in my initial code as "0" and therefore has no initialisation value and lands in bss. Examples from my .map:
As they are being automatically defined as bss, I can't find them in flash and can't edit the .hex file offline to change a value, for example, from 0 to 1.
I'd like the ability to define, that unit8 GlobalVar that initially have the value "0" are defined as .data and not as .bss.
Hi @Sam_ECU
I am not sure what's the root cause becasue no any sample code from you. I would like to share my understanding and comments below.
1. If you initialize GlobalVar
with a non-zero value, it will be placed in the .data
section:
uint8_t GlobalVar = 1; // Initialize with a non-zero value
2. You can modify your linker script to force the variable into the .data
section. Here is an example of how you can do this:
uint8_t GlobalVar __attribute__((section(".my_data"))) = 0;
SECTIONS
{
.text :
{
*(.text*)
} > FLASH
.data :
{
*(.data*)
*(.my_data*) // Add your custom section here
} > RAM AT > FLASH
.bss :
{
*(.bss*)
*(COMMON)
} > RAM
}
3. If you prefer not to modify the linker script, you can initialize the variable in a custom initialization function that runs before main
:
uint8_t GlobalVar; void __attribute__((constructor)) initialize_global_var(void) {
GlobalVar = 0; // Initialize with a non-zero value if needed
}
// main.c
#include <stdint.h>
// Define GlobalVar in the .my_data section
uint8_t GlobalVar __attribute__((section(".my_data"))) = 0;
int main() {
// Your application code
while (1) {
// Do something
}
return 0;
}
SECTIONS
{
.text :
{
*(.text*)
} > FLASH
.data :
{
*(.data*)
*(.my_data*) // Add your custom section here
} > RAM AT > FLASH
.bss :
{
*(.bss*)
*(COMMON)
} > RAM
}
Hell @Sam_Gao
That worked great, but I don't have the correct values appearing at the ram addresses.
In model.c
When reviewing my .map file:
.my_data 0x200090dc 0x2 load address
.my_data 0x200090dc 0x2 Oiida.o
0x200090dc AirBoxTemp_Swi_RefVal_C
0x200090dd LED_Switch_C
Perfect, looks good. When I look at my hex file:
0x60061a90: 01 01 ff ff 00 00 -- -- -- -- -- -- -- -- -- --
Perfect, looks good (AirBoxTemp_Swi_RefVal_C and LED_Switch_C are both unit8 "0").
But when reviewing the Ram addresses:
0x200090dc AirBoxTemp_Swi_RefVal_C: 111
0x200090dd LED_Switch_C: 88
I looked through the startup_mimxrt1062.c, and it appears to be coping flash to ram as expected:
Attached my linker script.
What am I missing?
Hello @Sam_Gao
Any chance of further help?
Hi,
Would you please double check if '.my_data' initalzation has been done during boot? some comments as blow.
1. check functionSectionTableAddr
with trace log.
// startup_mimxrt1062.c
while (SectionTableAddr < &__data_section_table_end) {
LoadAddr = *SectionTableAddr++;
ExeAddr = *SectionTableAddr++;
SectionLen = *SectionTableAddr++;
data_init(LoadAddr, ExeAddr, SectionLen);
// Debug output
__asm volatile("bkpt #0"); // Breakpoint for debugging
printf("LoadAddr: 0x%08X, ExeAddr: 0x%08X, SectionLen: 0x%08X\n", LoadAddr, ExeAddr, SectionLen);
}
2. check __data_section_table, you can print it out.
3. check ld script with '.my_data' section.
SECTIONS
{
/* MAIN DATA SECTION */
.data : ALIGN(4)
{
FILL(0xff)
_data = . ;
PROVIDE(__start_data_RAM = .) ;
PROVIDE(__start_data_SRAM_DTC = .) ;
*(vtable)
*(.ramfunc*)
KEEP(*(CodeQuickAccess))
KEEP(*(DataQuickAccess))
*(RamFunction)
*(NonCacheable.init)
*(.data*)
*(.my_data*) /* Added custom section for .my_data */
. = ALIGN(4) ;
_edata = . ;
PROVIDE(__end_data_RAM = .) ;
PROVIDE(__end_data_SRAM_DTC = .) ;
} > SRAM_DTC AT>BOARD_FLASH
}