This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Memory related issue with MCU startup ( __libc_init_array )

Dear Community,

I am developing firmware for STM32l476VGT using Gnu Make Builder and "Ac6 STM32 MCU GCC" Toolchain. I encounter a memory related run time error during the startup (before main) of my controller. The error occurs during the execution of the LoopFillZeroBss section:

LoopFillZerobss:
	ldr	r3, = _ebss
	cmp	r2, r3
	bcc	FillZerobss

/* Call the clock system intitialization function.*/
    bl  SystemInit
/* Call static constructors */
    bl __libc_init_array
/* Call the application's entry point.*/
	bl	main

LoopForever:
    b LoopForever
    
.size	Reset_Handler, .-Reset_Handler

/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 *
 * @param  None
 * @retval : None
*/
    .section	.text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
	b	Infinite_Loop
	.size	Default_Handler, .-Default_Handler

After the execution of  bl __libc_init_array I end up in the Infinite_Loop of  the Default_Handler. It is worth noting, that this error can be influenced by the amount memory which is statically allocated. In my source code file there is an array

static uint8_t array[SIZE] = {0};

If SIZE is smaller than threshold1, I can enter main() without any problems. If SIZE is between threshold1 and threshold2 (with threshold1 < threshold2) then the behaviour is as described above. If SIZE exceeds threshold2, a linker error (section '.bss' will not fit in region 'RAM') is generated (as expected).

I have the following questions:

1. What exactly happens, when 'bl __libc_init_array' is executed?

2. How could the fail of this command possibly related to the memory usage?

Any thoughts or helpful sources on this topic would be greatly appreciated as well.

Kind regards

Oliver

Parents
  • Hey Oliver,

    without seeing the actual contents of your  compiled elf I can just guess that your 

    static uint8_t array[SIZE] = {0}

    overwrites parts of the __init_array section when the array is too big.

    __libc_init_array iterates through that section and calls the function pointers placed there to alloc memory for static C++ classes or functions marked with __attribute__((constructor)) if you're just using plain C. If you don't recall using that attribute: such functions might be part of linked libs.

    While this usually shouldn't happen, since __init_array should be placed in Flash, it might be that your linker script isn't set up right.

    But from your description of the problem without more info I'd say that's what's going on...

    Regards,
    Sebastian

Reply
  • Hey Oliver,

    without seeing the actual contents of your  compiled elf I can just guess that your 

    static uint8_t array[SIZE] = {0}

    overwrites parts of the __init_array section when the array is too big.

    __libc_init_array iterates through that section and calls the function pointers placed there to alloc memory for static C++ classes or functions marked with __attribute__((constructor)) if you're just using plain C. If you don't recall using that attribute: such functions might be part of linked libs.

    While this usually shouldn't happen, since __init_array should be placed in Flash, it might be that your linker script isn't set up right.

    But from your description of the problem without more info I'd say that's what's going on...

    Regards,
    Sebastian

Children