This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Startup & data initialisation problems with gcc4.9.3 under eclipse environnement

Hi,

I'm working on nRF52822 device with gcc4.9.3 compiler under eclipse environnement (with gnuarm toolchain plugin).

I have some problems with data initialisation. To check what is wrong I made this simple example:

volatile uint32_t test_data=0x12345678;
volatile uint32_t test_bss = 0;

int main(void) {
	printf("test data %08X\n", (int)test_data);
	test_data = 0;

	printf("test bss %d\n", (int)test_bss);
	test_bss = 1;
}

On the first launch, the console shows:

test data 12345678
test bss 980  

Then I generate a reset to restart my test, the console shows:

test data 00000000
test bss 1

So

a) the "test_data" value is well initialized on the first time, but not on the following ones.

b) the "test_bss" value is never initialized.

Note, my linker options are -T "D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\nRF52_AA.ld" -Xlinker --gc-sections -Wl,-Map,"nRF52.map" --specs=rdimon.specs

I use rdimon library to have the SWO console.

If I try to debug the code, in the statup routine form "gcc_startup_nrf52.s" file, some values (addresses) are not correct.

Reset_Handler:
    ldr r1, =__etext					; <= value correspond to the end of text section
    ldr r2, =__data_start__				; <= value correspond to the start of the RAM (0x20000000)
    ldr r3, =__bss_start__				; !! value = 0x8000 doesn't correspond to the start of bss section !!
...

So the initialization of data is not done here. I guess that it's done inside crt0 routine.

Then to initialize the bss section I've compiled with -D__STARTUP_CLEAR_BSS to be sure the the following code will be added.

#ifdef __STARTUP_CLEAR_BSS
    ldr r1, =__bss_start__				; !! value still set to 0x8000
    ldr r2, =__bss_end__				; !! value = 0x8000 doesn't correspond to the end of bss section !!

    movs r0, 0

    subs r2, r1
    ble .L_loop3_done

.L_loop3:
    subs r2, #4
    str r0, [r1, r2]
    bgt .L_loop3
    
.L_loop3_done:
#endif /* __STARTUP_CLEAR_BSS */	

My linker script is like this

MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000
  RAM (rwx) :  ORIGIN = 0x20000000, LENGTH = 0x10000
}
...
    .bss :
    {
        . = ALIGN(4);
        __bss_start__ = .;
        *(.bss*)				# bss section content should be located between __bss_start__ and __bss_end__
        *(COMMON)
        . = ALIGN(4);
        __bss_end__ = .;
    } > RAM
...
  1. I don't know why bss_start and bss_end are not set to right values

  2. I don't know why crt routine doesn't initialize correctly the memory

Thanks for reply.

Regards, Thierry

  • what does the output map file say about the bss section? You should find, somewhere towards the end, it shows what's really an expanded version of the input with addresses on it, eg here's the top of one of mine

    .bss            0x20002180      0x844
                    0x20002180                __bss_start__ = .
     *(.bss .bss.* .gnu.linkonce.b.*)
     .bss._ZL11main_module
                    0x20002180       0xc8 _build/Intermediate/relay_module Custom/Nordic Debug/main.o
    

    is it really at 0x8000?

    What crt0.s are you linking?

    It would seem a huge fluke if the initialized data works only once, makes me wonder if the reset is actually going all the way back to the reset handler properly.

  • Hello,

    Thanks for your answer. The map file is correct, the sections are correctly fitted into the RAM. The real size 0x144 but not 0x8000.

    __bss_start__	= 0x200009c8
    __bss_end__		= 0x20000b0c
    

    But as you can see in the part of listing file the value aren't the right ones.

        ldr r3, =__bss_start__
         c04:	4b0b      	ldr	r3, [pc, #44]	; (c34 <Reset_Handler+0x34>)
    ...	
         c34:	00008000 	.word	0x00008000
    

    It's a very strange behaviour of linker. As I said one my first post, I use the rdimon spec. The crt0 is this one : armv7e-m/fpu/rdimon-crt0.o But If I don't want to use crt initialisation, the orignal startup should works.

    Thanks for reply, Thierry.

    Part of map file:
    ----------------------------------------------------------------------
    
    .text           0x00000000     0x6b38
     *(.isr_vector)
     .isr_vector    0x00000000      0x400 ./System/gcc_startup_nrf52.o
                    0x00000000                __isr_vector
     *(.text*)
     .text          0x00000400       0x5c d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7e-m/fpu/crtbegin.o
     .text          0x0000045c       0xe8 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu/rdimon-crt0.o
                    0x0000045c                _start
                    0x0000045c                _mainCRTStartup
    ...				
    
    .bss            0x200009c8      0x144
                    0x200009c8                . = ALIGN (0x4)
                    0x200009c8                __bss_start__ = .
     *(.bss*)
     .bss           0x200009c8       0x1c d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/armv7e-m/fpu/crtbegin.o
     .bss.m_clock_cb
                    0x200009e4       0x14 ./System/nRF52_Drivers/nrf_drv_clock.o
     .bss.test_bss  0x200009f8        0x4 ./Src/blinky/main_blinky.o
                    0x200009f8                test_bss
     .bss.test_tab_bss
                    0x200009fc       0x28 ./Src/blinky/main_blinky.o
                    0x200009fc                test_tab_bss
     .bss.__malloc_max_total_mem
                    0x20000a24        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-mallocr.o)
                    0x20000a24                __malloc_max_total_mem
     .bss.__malloc_max_sbrked_mem
                    0x20000a28        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-mallocr.o)
                    0x20000a28                __malloc_max_sbrked_mem
     .bss.__malloc_top_pad
                    0x20000a2c        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-mallocr.o)
                    0x20000a2c                __malloc_top_pad
     .bss.__malloc_current_mallinfo
                    0x20000a30       0x28 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-mallocr.o)
                    0x20000a30                __malloc_current_mallinfo
     .bss.monitor_stdout
                    0x20000a58        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\librdimon.a(rdimon-syscalls.o)
     .bss.heap_end.5994
                    0x20000a5c        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\librdimon.a(rdimon-syscalls.o)
     .bss.monitor_stdin
                    0x20000a60        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\librdimon.a(rdimon-syscalls.o)
     .bss.monitor_stderr
                    0x20000a64        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\librdimon.a(rdimon-syscalls.o)
     .bss.openfiles
                    0x20000a68       0xa0 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\librdimon.a(rdimon-syscalls.o)
     *(COMMON)
     COMMON         0x20000b08        0x4 d:/compilateurs/gnu tools arm embedded/4.9 2015q3/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-reent.o)
                    0x20000b08                errno
                    0x20000b0c                . = ALIGN (0x4)
                    0x20000b0c                __bss_end__ = .
    ----------------------------------------------------------------------				
    
    
    Part of listing output:
    ----------------------------------------------------------------------
    Sections:
    Idx Name          Size      VMA       LMA       File off  Algn  Flags
      0 .text         00006b38  00000000  00000000  00008000  2**3  CONTENTS, ALLOC, LOAD, READONLY, CODE
      1 .ARM.exidx    00000008  00006b38  00006b38  0000eb38  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA
      2 .data         000009c8  20000000  20000000  00010000  2**3  CONTENTS, ALLOC, LOAD, DATA
      3 .bss          00000144  200009c8  200009c8  000109c8  2**2  ALLOC
      4 .heap         00002000  20000b10  20000b10  000109c8  2**3  CONTENTS, READONLY
      5 .stack_dummy  00002000  20000b10  20000b10  000129c8  2**3  CONTENTS, READONLY
      6 .comment      00000070  00000000  00000000  000149c8  2**0  CONTENTS, READONLY
      7 .debug_aranges 000002a8  00000000  00000000  00014a38  2**3  CONTENTS, READONLY, DEBUGGING
      8 .debug_info   00002952  00000000  00000000  00014ce0  2**0  CONTENTS, READONLY, DEBUGGING
      9 .debug_abbrev 00000991  00000000  00000000  00017632  2**0  CONTENTS, READONLY, DEBUGGING
     10 .debug_line   0000214d  00000000  00000000  00017fc3  2**0  CONTENTS, READONLY, DEBUGGING
     11 .debug_frame  00001d84  00000000  00000000  0001a110  2**2  CONTENTS, READONLY, DEBUGGING
     12 .debug_str    00072be1  00000000  00000000  0001be94  2**0  CONTENTS, READONLY, DEBUGGING
     13 .debug_ranges 00000228  00000000  00000000  0008ea75  2**0  CONTENTS, READONLY, DEBUGGING
     14 .debug_macro  00015624  00000000  00000000  0008ec9d  2**0  CONTENTS, READONLY, DEBUGGING
     15 .ARM.attributes 00000030  00000000  00000000  000a42c1  2**0  CONTENTS, READONLY
     
     ...
     
      00000c00 <Reset_Handler>:
    Reset_Handler():
    D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\Debug_blinky/../System/gcc_startup_nrf52.asm:349
     *      __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ 
     *                    the user can add their own initialized data section before BSS section with the INTERT AFTER command. 
     *
     * All addresses must be aligned to 4 bytes boundary.
     */
        ldr r1, =__etext
         c00:	490a      	ldr	r1, [pc, #40]	; (c2c <Reset_Handler+0x2c>)
    D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\Debug_blinky/../System/gcc_startup_nrf52.asm:350
        ldr r2, =__data_start__
         c02:	4a0b      	ldr	r2, [pc, #44]	; (c30 <Reset_Handler+0x30>)
    D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\Debug_blinky/../System/gcc_startup_nrf52.asm:351
        ldr r3, =__bss_start__
         c04:	4b0b      	ldr	r3, [pc, #44]	; (c34 <Reset_Handler+0x34>)
    D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\Debug_blinky/../System/gcc_startup_nrf52.asm:353
    ...
    
        ldr r1, =__etext
         c2c:	00006b40 	.word	0x00006b40
    D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\Debug_blinky/../System/gcc_startup_nrf52.asm:350
        ldr r2, =__data_start__
         c30:	20000000 	.word	0x20000000
    D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\Debug_blinky/../System/gcc_startup_nrf52.asm:351
        ldr r3, =__bss_start__
         c34:	00008000 	.word	0x00008000
    D:\Eclipse\eclipse64-mars\workbench.arm\nRF52\Debug_blinky/../System/gcc_startup_nrf52.asm:376
    
     ----------------------------------------------------------------------
    
  • I don't understand how that is happening. Can you try compiling without the rdimon specs file to see if that makes a difference, if it does, we should look at what's in the specs file.

  • I try other version of gcc (4.9 2015q3, 4.9 2015q1, 4.8 2014q3) same results :( without --specs=rdimon.specs with and without --specs=nano.specs same results

        .text           0x00000000     0x8668
         *(.isr_vector)
         .isr_vector    0x00000000      0x400 ./System/gcc_startup_nrf52.o
                        0x00000000                __isr_vector
         *(.text*)
         .text          0x00000400        0x0 d:/compilateurs/gnu tools arm embedded/4.8 2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/armv7e-m/fpu/crti.o
         .text          0x00000400       0x54 d:/compilateurs/gnu tools arm embedded/4.8 2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/armv7e-m/fpu/crtbegin.o
         .text          0x00000454       0x74 d:/compilateurs/gnu tools arm embedded/4.8 2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7e-m/fpu/crt0.o
                        0x00000454                _start
                        0x00000454                _mainCRTStartup
        ...
        
        .bss            0x200008dc       0xac
                        0x200008dc                . = ALIGN (0x4)
                        0x200008dc                __bss_start__ = .
         *(.bss*)
         .bss           0x200008dc        0x0 d:/compilateurs/gnu tools arm embedded/4.8 2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/armv7e-m/fpu/crti.o
         .bss           0x200008dc       0x1c d:/compilateurs/gnu tools arm embedded/4.8 2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/armv7e-m/fpu/crtbegin.o
         .bss           0x200008f8        0x0 d:/compilateurs/gnu tools arm embedded/4.8 2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7e-m/fpu/crt0.o
         
         ...				
         
          *(COMMON)
         COMMON         0x20000984        0x4 d:/compilateurs/gnu tools arm embedded/4.8 2014q3/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7e-m/fpu\libg.a(lib_a-reent.o)
                        0x20000984                errno
                        0x20000988                . = ALIGN (0x4)
                        0x20000988                __bss_end__ = .
    
  • Hi,

    I've copied and updated for nRF52 MCU an old linker script from another project (STM32 MCU). With this linker script, bss and data sections are correct with and without --specs=rdimon.specs.

    The bad linker script I use is provided by nordic (nRF5_SDK_11.0.0_89a8197).

    It's composed by the files :

    the first is located in the example directory <sdk_location>\examples\peripheral\blinky\pca10040\blank\armgcc\blinky_gcc_nrf52.ld and the second is located in the directory <sdk_location>\components\toolchain\nrf5x_common.ld

    I've just made single file including this two files

    I don't know why it's doesn't work !!!

    Below is my linker script:

    /*
    *****************************************************************************
    ** thln linker script updated 21/04/2016 form STM32 project
    *****************************************************************************
    */
    /* GROUP(-lgcc -lc -lnosys) */
    GROUP(-lgcc -lc -lrdimon)
    
    /* Entry Point */
    ENTRY(Reset_Handler)
    
    
    /* Specify the memory areas */
    MEMORY
    {
      FLASH (rx)      : ORIGIN = 0x00000000, LENGTH = 512K
      RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 64K
    }
    
    /* Define output sections */
    SECTIONS
    {
    
      /* The program code and other data goes into FLASH */
      .text :
      {
            KEEP(*(.isr_vector))
    
    		
    		
        *(.text)           /* .text sections (code) */
        *(.text*)          /* .text* sections (code) */
        *(.glue_7)         /* glue arm to thumb code */
        *(.glue_7t)        /* glue thumb to arm code */
        *(.eh_frame)
    
        KEEP (*(.init))
        KEEP (*(.fini))
    
        . = ALIGN(4);
        _etext = .;        /* define a global symbols at end of code */
      } >FLASH
    
      /* Constant data goes into FLASH */
      .rodata :
      {
        . = ALIGN(4);
        *(.rodata)         /* .rodata sections (constants, strings, etc.) */
        *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
        . = ALIGN(4);
      } >FLASH
    
      .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
      .ARM : {
        __exidx_start = .;
        *(.ARM.exidx*)
        __exidx_end = .;
      } >FLASH
    
      .preinit_array     :
      {
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP (*(.preinit_array*))
        PROVIDE_HIDDEN (__preinit_array_end = .);
      } >FLASH
      .init_array :
      {
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array*))
        PROVIDE_HIDDEN (__init_array_end = .);
      } >FLASH
      .fini_array :
      {
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP (*(SORT(.fini_array.*)))
        KEEP (*(.fini_array*))
        PROVIDE_HIDDEN (__fini_array_end = .);
      } >FLASH
    
      /* used by the startup to initialize data */
      _sidata = LOADADDR(.data);
    
      	__etext = _sidata;
    	
      /* Initialized data sections goes into RAM, load LMA copy after code */
      .data : 
      {
        . = ALIGN(4);
        _sdata = .;        /* create a global symbol at data start */
    	__data_start__ = _sdata;
        *(.data)           /* .data sections */
        *(.data*)          /* .data* sections */
    
        . = ALIGN(4);
        _edata = .;        /* define a global symbol at data end */
      } >RAM AT> FLASH
    
      /* Uninitialized data section */
      . = ALIGN(4);
      .bss :
      {
        /* This is used by the startup in order to initialize the .bss secion */
        _sbss = .;         /* define a global symbol at bss start */
        __bss_start__ = _sbss;
        *(.bss)
        *(.bss*)
        *(COMMON)
    
        . = ALIGN(4);
        _ebss = .;         /* define a global symbol at bss end */
        __bss_end__ = _ebss;
    	
      } >RAM
    
      
        .heap (COPY):
        {
            __end__ = .;
            PROVIDE(end = .);
            *(.heap*)
            __HeapLimit = .;
        } > RAM
    
        /* .stack_dummy section doesn't contains any symbols. It is only
         * used for linker to calculate size of stack sections, and assign
         * values to stack symbols later */
        .stack_dummy (COPY):
        {
            *(.stack*)
        } > RAM
    
    	/* Highest address of the user mode stack */
        /* Set stack top to end of RAM, and stack limit move down by
         * size of stack_dummy section */
        __StackTop = ORIGIN(RAM) + LENGTH(RAM);
        __StackLimit = __StackTop - SIZEOF(.stack_dummy);
        PROVIDE(__stack = __StackTop);
        
        /* Check if data + heap + stack exceeds RAM limit */
        ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
    	
    
      /* Remove information from the standard libraries */
      /DISCARD/ :
      {
        libc.a ( * )
        libm.a ( * )
        libgcc.a ( * )
      }
    
      .ARM.attributes 0 : { *(.ARM.attributes) }
    }
    
Related