iMXRT: "ExportedGlobal" being defined as bss, not data

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMXRT: "ExportedGlobal" being defined as bss, not data

Jump to solution
698 Views
Sam_ECU
Contributor V

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?

0 Kudos
Reply
1 Solution
636 Views
Sam_Gao
NXP Employee
NXP Employee

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
}

View solution in original post

0 Kudos
Reply
6 Replies
669 Views
Sam_Gao
NXP Employee
NXP Employee

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/

https://stackoverflow.com/questions/16557677/difference-between-data-section-and-the-bss-section-in-...

 

 

 

0 Kudos
Reply
659 Views
Sam_ECU
Contributor V

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:

Sam_ECU_0-1728973135717.png

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.

0 Kudos
Reply
637 Views
Sam_Gao
NXP Employee
NXP Employee

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
}
0 Kudos
Reply
608 Views
Sam_ECU
Contributor V

Hell  @Sam_Gao 

That worked great, but I don't have the correct values appearing at the ram addresses. 

In model.c

/* Storage class 'OiidaData' */
__attribute__((section(".my_data"))) uint8_T AirBoxTemp_Swi_RefVal_C = 0U;
__attribute__((section(".my_data"))) uint8_T LED_Switch_C = 0U;


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

Sam_ECU_0-1729251871457.png

I looked through the startup_mimxrt1062.c, and it appears to be coping flash to ram as expected:

__attribute__ ((section(".after_vectors.init_data")))
void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
    unsigned int *pulDest = (unsigned int*) start;
    unsigned int *pulSrc = (unsigned int*) romstart;
    unsigned int loop;
    for (loop = 0; loop < len; loop = loop + 4)
        *pulDest++ = *pulSrc++;
}



    // Copy the data sections from flash to SRAM.
    while (SectionTableAddr < &__data_section_table_end) {
        LoadAddr = *SectionTableAddr++;
        ExeAddr = *SectionTableAddr++;
        SectionLen = *SectionTableAddr++;
        data_init(LoadAddr, ExeAddr, SectionLen);
    }


Attached my linker script.

What am I missing?

0 Kudos
Reply
551 Views
Sam_ECU
Contributor V

Hello @Sam_Gao 

Any chance of further help?

0 Kudos
Reply
528 Views
Sam_Gao
NXP Employee
NXP Employee

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
}

 

0 Kudos
Reply