cancel
Showing results for 
Search instead for 
Did you mean: 

BUG: CubeMX FreeRTOS projects corrupt memory

Typical user symptom: sprintf with floating point doesn't work or crashes.

I've provided a complete explanation and required fixes here:

http://www.nadler.com/embedded/newlibAndFreeRTOS.html

To illustrate the crash in minimal test application, I've provided this example project ready to run for a Nucleo 429:

http://www.nadler.com/embedded/20190804_STM_malloc-Kaboom_demo.zip

Set breakpoints at:

sysmem.c: on the line with errno = ENOMEM;

main.c, in default task, on line kaboomP1 = malloc(16);

Enjoy the fireworks.

Comments on (one of) the problems are provided in sysmem.c

The fixes are explained in the web page linked above, and illustrated in this corrected minimal project:

http://www.nadler.com/embedded/20191115_malloc-Kaboom_fixed.zip

It would be great if STM could:

- confirm they understand this set of bugs

- fix them in a prompt release of ST32cubeIDE/CubeMX/etc.

OK, we can dream, right?

Thanks,

Best Regards, Dave

85 REPLIES 85
GMG
Associate III

After many hours spent to solve FREERTOS and USB issues, I have made a GIT with my experience and some tips to survive...

https://github.com/gmgunderground/STM32-RTOS-USB-HowToFix/blob/master/README.md

Fell free to everyone to contribute

@GMG​  - You may want to update your notes with this workflow:

http://www.nadler.com/backups/20200111_draft2_STM_Cube_Issues_and_Workflow.html

Also, can you clarify about _sbrk? I provide an implementation in heap_useNewlib....

Hope that helps,

Best Regards, Dave

Yes I know ​_sbrk in your lib, but if you use the default heap_4.c the _sbrk in sysmem.c is never called (check with breakpoint) so I think that code is no more used, seam to be dead code (in the project there aren't other _sbrk) but I can't find documentation about that

Kazimierz Król
Associate III

Hi, after some time of searching why my printf(%f) code behaves weirdly, I found the Dave's page about Newlib issues, and this fixed my problems. It's a shame ST doesn't fix this ASAP, and keeps the buggy solutions in newer versions (without even placing warnings in the code that would come up during compilation, so the users would know what's going on).

My issue was that printf(%f) sometimes worked, and sometimes showed dumb things, like:

float step = 0.1;

printf("%4.2f", step);

was printing: st.ep (yes, the NAME of the variable instead of its value :D)

But it worked fine if and only if the first call to malloc was from the main function before the FreeRTOS scheduler start.

Using heap_useNewlib.c from Dave's site solved my problem. I use TrueStudio 9.3.0, that provides Newlib 2.5.0, and Dave's code works fine with it, despite the warning that it's for 3.0.0 only.

In the newest CubeMX (5.6.1) there are even options to help implementing that:

  • USE_NEWLIB_REENTRANT, which sets the variable for FreeRTOS,
  • Use FW pack heap file - which enables/disables generation of heap_4.c.

Too bad the first one is disabled by default. Any reason for this?

Even more too bad, that such critical problem is still not solved several months after reporting.

DFedo.1
Associate II

This is honestly ridicilous, everybody in embedded community laughing on this and will start to depart from vendor, who need 7 month to fix printf in their RTOS.

I just wasted several hours, to realise your environment unable to implement even such basic function. I'm afraid now to use your Cube and IDE at all, how many blocker bugs remains there?

It is beyond my understanding that you cannot even offer a new heap option that works properly and still are "discussing".

ST, wake up.

GMock.1
Associate II

@Dave Nadler​ Thanks for the fix that ST should have provided long ago. With CubeMX 5.5.0/SystemWorkbench and STM32L071 (Cortex M0+), I found that two additional steps are needed for successful compilation:

  1. comment out _sbrk() in generated syscalls.c, so the implementation in heap_useNewlib.c is used instead.
  2. add missing M0-specific macro: #define xPortIsInsideInterrupt()  (((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk ) == 0)? pdFALSE : pdTRUE)

Wouldn't mind if someone could review/confirm.

GMock.1
Associate II

If I am not mistaken, setting "configUSE_NEWLIB_REENTRANT == 1" pulls in a "struc _reent" into each "tskTCB", thereby increasing the memory needed for each task by (in my case) a whopping 1064 bytes!

I am afraid this makes this approach totally unusable on a MCU with just a few kB of RAM.

look into _REENT_SMALL

Thanks, that brings it down to 240 Bytes for "struc _reent".

Yes, configUSE_NEWLIB_REENTRANT == 1 chews up lots of memory, depending on how newlib is built.

Perfectly OK to disable this option - as long as you're SURE you're not using RTL functions that use the reentrant structure in multiple tasks.

Hope that helps,

Best Regards, Dave