cancel
Showing results for 
Search instead for 
Did you mean: 

Is STM32CubeIDE newlib with FreeRTOS now really thread safe?

msch
Associate III

I'm using STM32Cube IDE with FreeRTOS. The Errata for STM32CubeIDE 1.7.0 state "70505 Implemented a newlib-malloc solution that is thread safe by default."

Is newlib truly thread safe now? As far as I can tell, when building a project in STM32CubeIDE 1.8.0 with newlib-nano (3.3.0) no __malloc_lock()/unlock() is provided. There seem to be no calls to vTaskSuspendAll() nor to vPortEnterCritical() from inside newlib. So if newlib's malloc has been made thread safe, how? And the_ sbrk() provided in the file sysmem.c does not have any reentrancy protections.

Can someone from ST provide a definitive statement about this? And best, can you provide the source code that is used to build your version of newlib?

1 ACCEPTED SOLUTION

Accepted Solutions
mattias norlander
ST Employee

To elaborate on my first reply:

Newlib does not make any calls directly to vTaskSuspendAll() and vPortEnterCritical().

newlib is not written in mind to specifically support FreeRTOS.

We build newlib with the configure option --enable-newlib-retargetable-locking.

This makes sure that a number of functions inside newlib will contain calls to __retarget_lock_acquire() / __retarget_lock_release() / ... before executing critical sections.

Have a look here:

https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c

The ST thread-safe solution implements these hooks. We can imagine customers doing bare-metal apps, FreeRTOS apps or apps using any other RTOS... Regardless the user can implement their own acquire/release functions, or point to existing RTOS specific functions that already exist?!

The few patches we have for newlib vs the up-stream variant have nothing to do with thread-safety.

We build newlib with the following configure options:

CFLAGS_FOR_TARGET='-g -Os -ffunction-sections -fdata-sections -fno-unroll-loops -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -DSMALL_MEMORY'
 
/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/src/newlib/configure --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-none-eabi --prefix=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native --infodir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-newlib-io-long-long --enable-newlib-io-c99-formats --enable-newlib-reent-check-verify --enable-newlib-register-fini --enable-newlib-retargetable-locking --disable-newlib-supplied-syscalls --disable-nls
 
make -j8
 
make install

The newlib source code that we base our build on:

https://sourceware.org/git/?p=newlib-cygwin.git;a=tree;hb=2a3a03972b35377aef8d3d52d873ac3b8fcc512c

Our patches are attached as a diff. Enjoy!

View solution in original post

11 REPLIES 11
TDK
Guru

> Can someone from ST

Would be more interested in hearing from @Dave Nadler​, if he's looked at it.

There is a comically long post about it here (among many others):

https://community.st.com/s/question/0D50X0000BB1eL7SQJ/bug-cubemx-freertos-projects-corrupt-memory

Edit: seems there has been some discussion. See here:

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

If you feel a post has answered your question, please click "Accept as Solution".
msch
Associate III

I'm familiar with Dave Nadler's excellent work on this. I've also seen the ST post you reference. That was two years ago. The claimed production fix was documented a few months ago. I'd like to find out if it's truly fixed. I'd prefer to be using the standard released tools if they are working, for future compatibility.

msch
Associate III

Ok, I'm not sure why ST tech support seems to be unaware of it, but ST has an app note that addresses this:

https://www.st.com/resource/en/application_note/an5731-stm32cubemx-and-stm32cubeide-threadsafe-solution-stmicroelectronics.pdf

It looks like a good comprehensive solution, and I'm happy to report that it seems to be working fine for me.

I would suggest that ST update the MX User Guide to incorporate the information in the App Note. I do see that it is discussed in the IDE User Guide--I missed that before. But that discussion is not very helpful for an MX project--it just says that MX handles it for such projects.

mattias norlander
ST Employee

Hi,

Yes, the solution works. Is it optimal? Well depend on your use cases...

It is always possible to implement your own lock to fit specific needs.

The Newlib code can be shared. Drop me a PM if this is interesting.

I will ask internally for an MX doc update. Internal ticket reference#: 122409

mattias norlander
ST Employee

To elaborate on my first reply:

Newlib does not make any calls directly to vTaskSuspendAll() and vPortEnterCritical().

newlib is not written in mind to specifically support FreeRTOS.

We build newlib with the configure option --enable-newlib-retargetable-locking.

This makes sure that a number of functions inside newlib will contain calls to __retarget_lock_acquire() / __retarget_lock_release() / ... before executing critical sections.

Have a look here:

https://sourceware.org/git/?p=newlib-cygwin.git;a=blob_plain;f=newlib/libc/misc/lock.c

The ST thread-safe solution implements these hooks. We can imagine customers doing bare-metal apps, FreeRTOS apps or apps using any other RTOS... Regardless the user can implement their own acquire/release functions, or point to existing RTOS specific functions that already exist?!

The few patches we have for newlib vs the up-stream variant have nothing to do with thread-safety.

We build newlib with the following configure options:

CFLAGS_FOR_TARGET='-g -Os -ffunction-sections -fdata-sections -fno-unroll-loops -DPREFER_SIZE_OVER_SPEED -D__OPTIMIZE_SIZE__ -DSMALL_MEMORY'
 
/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/src/newlib/configure --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-none-eabi --prefix=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native --infodir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/build/gnu-tools-for-stm32_10.3-2021.10.20211105-1100/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-newlib-io-long-long --enable-newlib-io-c99-formats --enable-newlib-reent-check-verify --enable-newlib-register-fini --enable-newlib-retargetable-locking --disable-newlib-supplied-syscalls --disable-nls
 
make -j8
 
make install

The newlib source code that we base our build on:

https://sourceware.org/git/?p=newlib-cygwin.git;a=tree;hb=2a3a03972b35377aef8d3d52d873ac3b8fcc512c

Our patches are attached as a diff. Enjoy!

msch
Associate III

Thanks @mattias norlander​

Excellent information..

Pavel A.
Evangelist III

Thank you very much Mattias for the info.

Piranha
Chief II

Of course ST couldn't do it without breaking and messing up something...

https://community.st.com/t5/stm32cubemx-mcu/cubemx-generated-threadsafe-stm32-lock-h-potential-bug/td-p/77220

I created a FreeRTOS project for a NUCLEO-G474RE board with ThreadSafe support by way of an experiment. In StartDefaultTask I added a printf, expecting to verify the action of the locking. It blocks because the lock is null.

There appears to be some code/steps missing from the solution to initialise the lock