MPU port BSS segment initialization for FreeRTOS

jgreen wrote on Tuesday, November 29, 2016:

I’m working on creating a Cortex-M4 project using the MPU version of FreeRTOS. The target processor is the STM32F303RE.

To summarize the issue I’m having: global BSS data in FreeRTOS privileged areas is not being cleared to 0 on init.

I’m using a linker script based on FreeRTOS/Demo/CORTEX_MPU_Simulator_Keil_GCC/GCC_Specific/sections.ld but with the proper ROM and RAM areas for this MPU:
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K

The startup assembler file is the ST CMSIS startup file which comes with their standard peripheral library. Stepping through the Reset_Handler code, I see that it does a BSS init to zero for my application data. But this does not include variables in FreeRTOS privileged areas. This results in crashes when I start creating tasks, since structures like pxReadyTasksLists are essentially uninitialized.

My guess is that the startup assembler code needs to initialize a second BSS area and possibly also copy initialized data from ROM to RAM for another area for FreeRTOS. Or maybe there is something wrong with the linker map, where these areas should somehow be combined but still marked as privileged? Is there a startup assembler file I can look at for an MPU port? Any other ideas?

Best regards,

Element

jgreen wrote on Tuesday, November 29, 2016:

I have implemented a hack to get things to work for now, until I can fix this properly. In main() I have the following code:

extern uint32_t __privileged_data_start__[];
extern uint32_t __privileged_data_end__[];

int
main(void)
{
  // Hack to initialize privileged data areas to 0
  // FIXME - How does this usually happen with the FreeRTOS MPU port?
  memset (&__privileged_data_start__, 0, ((uint8_t *)(&__privileged_data_end__)) - ((uint8_t *)(&__privileged_data_start__)));

Would like to know how this SHOULD work.

Best regards,

Element

rtel wrote on Tuesday, November 29, 2016:

This is not really a FreeRTOS question.

The start up routine (the function that the reset handler calls) is
dependent on the linker script. It uses information from the linker
script, normally linker variables, to know the start and end address of
the RAM that needs to be cleared to 0, and the start and end address of
the data to copy and where to copy it to to initialise variables. If
you edit the linker script to add in new sections that need
initialisation then you also need to update the start up routine
accordingly.

jgreen wrote on Tuesday, November 29, 2016:

Seems pretty related to me. FreeRTOS MPU sets up specific regions of memory for different purposes. Knowing that it’s own BSS section is not initialized by run of the mill default startup code, is critical to getting the MPU port working on any platform. I did not see anything in the Keil simulator demo project showing this (perhaps it starts with a zeroed memory space by default), which seems to warrant at least some mention of this somewhere (which I could not find). The names of these sections and their purpose is defined by FreeRTOS. Regardless, as outlined in my other post, I’m just using memset() in main().