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

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

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

跳至解决方案
946 次查看
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 项奖励
回复
1 解答
884 次查看
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 项奖励
回复
6 回复数
917 次查看
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 项奖励
回复
907 次查看
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 项奖励
回复
885 次查看
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 项奖励
回复
856 次查看
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 项奖励
回复
799 次查看
Sam_ECU
Contributor V

Hello @Sam_Gao 

Any chance of further help?

0 项奖励
回复
776 次查看
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 项奖励
回复