1
votes

I'm working on a project that involves getting the CMSIS-RTOS packaging of FreeRTOS working on an STM32F051C6. I'm writing and debugging the code with VisualGDB inside of Visual Studio, and generating the project code using the STM32CubeMX tool provided by ST. The RTOS is running incredibly well and I'm all smiles, however, I added a queue and a memory pool to handle sending and receiving messages between tasks and the compiler complained that the .bss memory section that was compiled/generated would not fit in the memory section set out in the linker. This was resolved by decreasing the heap size in the FreeRTOS configuration header.

I'm a little unhappy about where this may take me when I want to make the project more complex (more tasks, queues etc) since I may start having to decrease the stack even further to allow the .bss section to fit.

So my question is - would a solution to this be to extend the .bss section into the .data section (the section above) to allow for more heap and uninitialized data in the .bss section? After some looking around and experimenting, I found that only about 1% (if not, less) of the .data section is actually being used, according to VisualGDB's Memory Explorer window at build time, and it seems crazy to have all that unused RAM.

In an attempt to do this myself, I had a thorough look through both the linker scripts and the startup code and I could not find where to define the start and end of the .bss. Is it possible to define these boundaries, how would I be able to do so if possible? If not possible, how does the linker know where these boundaries are on the target chip?

Below are what I think are the relevant sections in the linker script:

.data :
{
    . = ALIGN(4);
    _sidata = .;

    _sdata = _sidata;

    PROVIDE(__data_start__ = _sdata);
    *(.data)
    *(.data*)
    . = ALIGN(4);
    _edata = .;

    PROVIDE(__data_end__ = _edata);
} > SRAM

.bss :
{
    . = ALIGN(4);
    _sbss = .;

    PROVIDE(__bss_start__ = _sbss);
    *(.bss)
    *(.bss*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = .;

    PROVIDE(__bss_end__ = _ebss);
} > SRAM

PROVIDE(end = .);

...and the startup file:

extern void *_sidata, *_sdata, *_edata;
extern void *_sbss, *_ebss;

void __attribute__((naked, noreturn)) Reset_Handler()
{
    //Normally the CPU should will setup the based on the value from the first entry in the vector table.
    //If you encounter problems with accessing stack variables during initialization, ensure 
    //asm ("ldr sp, =_estack");

    void **pSource, **pDest;
    for (pSource = &_sidata, pDest = &_sdata; pDest != &_edata; pSource++, pDest++)
        *pDest = *pSource;

    for (pDest = &_sbss; pDest != &_ebss; pDest++)
        *pDest = 0;

    SystemInit();
    __libc_init_array();
    main();
    for (;;) ;
}
1
can you find the memory map file? there should be a .map file that tells you the memory allocation map of all sections in your binary directory.user3528438
Can't seem to find it, nor how to generate it. I'm using arm-eabi-g++ to linkWoodyWoodsta
Your linker can generate it.Martin James
-Map mapfile, Print to the file mapfile a link map--diagnostic information about where symbols are mapped by ld, and information on global common storage allocation.user3528438
How did you determine that only 1% of the .data section is being used? I'm skeptical of that claim. Usually the linker determines the size of the .data and .bss sections based on how much is required by the program.kkrambo

1 Answers

0
votes

I think you can not set size of .bss or .data section explicitly. It is only defined by your program. You can view how much memory each variable consumes from map-file.

Example:

.bss.xHeap     0x0000000020000690     0xa000 obj/heap_2.o

In my setup FreeRTOS configured with

#define configTOTAL_HEAP_SIZE           ( ( size_t ) ( 40 * 1024 ) )

and I see all this 40 KB in my map-file.

Linker knows how much memory your MCU has and tries to place all memory objects to it. If it doesn't fit you see an error.

You can not "extend" .bss into .data section because the former is occupied by uninitialized statically-allocated variables and the latter by initialized statically-allocated variables. If you can get rid of some of statically-allocated variables (e.g. globals) your .bss or/and .data section sizes will reduce. 8 KB of RAM is not very much.

Maybe you should look for ._user_heap_stack section (or similar name) in you linker script and optimize heap (don't confuse with FreeRTOS heap) and stack size values. E.g. if you use only FreeRTOS memory allocation then you can set heap size as 0 and this will allow more space for .bss section.

From my project:

_Min_Heap_Size = 0;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

._user_heap_stack :
{
  . = ALIGN(4);
  PROVIDE ( end = . );
  PROVIDE ( _end = . );
  . = . + _Min_Heap_Size;
  . = . + _Min_Stack_Size;
  . = ALIGN(4);
} >RAM