Skip to main content
Dave Nadler
Senior III
August 6, 2019
Solved

BUG: CubeMX FreeRTOS projects corrupt memory

  • August 6, 2019
  • 40 replies
  • 33909 views

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

This topic has been closed for replies.
Best answer by Dave Nadler

@Markus GIRDLAND​ - Its not just thread safety (as if that isn't bad enough).

malloc fails completely in a FreeRTOS task because STM provides an incorrect sbrk function.

There are at least a dozen posts on this forum about problems this has caused (though most don't realize why they're getting crashes, memory corruption, or sprintf float failures).

You're telling us you've been aware of these problems for a year and never bothered to fix them?

Yikes.

STM really needs to get this fixed.

40 replies

DerekR
Senior
February 10, 2020

Just wanted to provide an update for those who use System Workbench for STM32 (SW4STM32). Dave's patches work flawlessly without any modifications to the generated linker files using a very small FreeRTOS application. No more hard faults! I will update this post if I run into any issues.

DerekR
Senior
February 11, 2020

@Markus GIRDLAND​ I am currently using Dave Nadler's patches with no issue. Can you confirm when the STM32CubeIDE team will update it with "official" patches to support thread-safe operation with FreeRTOS? I am asking for future reference for myself and colleagues who may be using this IDE in the future.

Thanks,

Derek

Markus GIRDLAND
ST Employee
February 17, 2020

I can confirm that we are working on a way to make it thread safe by default but there are differing opinions on how it will be achieved. Not everyone is agreed that this is the way to do it so I believe there's some discussions about what solution is to be used.

Also, there's some team-synchronization needed as the generated code would need to be thread safe which is in the MX teams corner but there are still some things we are working on in the IDE team to speed things up.

GMG
Associate III
April 17, 2020

@Markus GIRDLAND​ follow the advice of @Dave Nadler​ and make a temporary patch! I wasted two days for your poor product! I created a project (STM32CubeIDE Version: 1.3.1 Build: 6291_20200406_0752) for STM32H7 (Lib version 1.7.0) with only RTOS and USB CDC and the USB doesn't work, no one line of my code only auto generated code and doesn't work! Incredible that you want to have a product that generate wrong code without advise users of that! Make a temporary path or remove the functionality, you and your team make people crazy! Also CubeIDE configurator have many many problems with freertos enabled, if you define a TIM7 for RTOS and you use other timers project will be corrupted and every time you change something you have to configure again timers! Also many other issues that I can't understand are happening. If many people have a problem and wast time with your tools many people are encouraged to choose a new brand for future projects. I hope in a very short patch for many bugs.

Regards

chaaalyy
Senior II
April 19, 2020

Not just in USB CDC ... Also with USB MSC there´s no chance... Meanwhile i believe, these "bugs" are built in intentionally to prevent "small" people from using expensive software for free. Behind the curtains and for big players (automotive and so on) of course there is support and of course there are ready to use solutions and fixes, already built in a stable version.

Dave Nadler
Senior III
April 18, 2020

@Markus GIRDLAND​ , @Camilo LEMOS​ - Please remove the following buggy post from ST:

https://community.st.com/s/question/0D50X0000CBmXufSQF/newlibmalloc-locking-mechanism-to-be-threadsafe

For heaven's sake don't post even more buggy code! Really Now!

How much do you want to infuriate customers??

chaaalyy
Senior II
April 18, 2020

Any news or updates about this ??

GMG
Associate III
April 21, 2020

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

Dave Nadler
Senior III
April 21, 2020

@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

GMG
Associate III
April 21, 2020

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
April 23, 2020

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
Visitor II
April 28, 2020

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
May 7, 2020

@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
May 13, 2020

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.

crackwitz
Associate II
May 13, 2020

look into _REENT_SMALL

GMock.1
Associate
May 13, 2020

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