using newlib with FreeRTOS - comments please?

dnadler wrote on Tuesday, June 27, 2017:

Hi Guys - I’d appreciate any comments, especially if I’ve missed something or got something wrong…
Thanks!
Best Regards, Dave
http://www.nadler.com/embedded/draft1_newlibAndFreeRTOS.html

rtel wrote on Tuesday, June 27, 2017:

Is it worth noting that many of the FreeRTOS examples use
printf-stdarg.c to replace the printf/sprintf functions provided by a
library with a very small, but very basic, implementation? Although
very basic it is sufficient for a lot of small MCU designs.
Unfortunately there are several different versions floating about the
FreeRTOS distribution - the most complete and well exercised version
being found in the labs download as it is used by the TCP stack.

dnadler wrote on Tuesday, June 27, 2017:

I’m not sure I understand where one gets printf-stdarg.c - is the following correct?

To avoid using printf and dragging in some of the newlib components,
there are a number of cut-down printf implementations available.
One is printf-stdarg.c distributed in the FreeRTOS lab TCPIP example.

rtel wrote on Wednesday, June 28, 2017:

Yes.

There are copies in several of the FreeRTOS demo projects, and FreeRTOS
Labs demo projects - the most complete version being the copy in the
‘common’ area of the labs download.

richarddamon wrote on Wednesday, June 28, 2017:

One comment about using newlib with FreeRTOS, if youur goal is to try to replace the standard library that comes with your embedded implementation, (assuming it isn’t using newlib already) can be quite a bit of work and needs a good understanding of how everything works under the covers. II wouldn’t suggest it if you have uncertainties about what you need to do.

On the other hand, if your implementation is already using newlib, getting it to interface with FreeRTOS isn’t that bad, depending on the options used to build your vision of newlib. In many cases, it is just defining a couple of stubs that provide the needed syncronization operations.

dnadler wrote on Wednesday, June 28, 2017:

Thanks Richard. I’m trying to ensure that I’ve properly used newlib with FreeRTOS, starting from a toolchain with dysfunctional examples (unfortunate Freescale stuff). Your comments on my notes about this would be greatly appreciated! See:
http://www.nadler.com/embedded/draft1_newlibAndFreeRTOS.html
Thanks as always,
Best Regards, Dave

richarddamon wrote on Thursday, June 29, 2017:

Dave, personally, I think you are going after the problem backwards. Rather than trying to replace (partially) the newly memory allocation routines, I prefer to implement the RTOS hooks for newlib, so I don’t need to worry about code using the parts of the memory allocation routines you didn’t implement, like realloc and calloc.

dnadler wrote on Thursday, June 29, 2017:

Thanks for the suggestion Richard. I guess I could provide the hooks newlib requires (sbrk routed to FreeRTOS heap, malloc locs), but then I end up with two memory allocators and two pools (wsith associated RAM and flash costs). Always trade-offs… I should however remove the HCF routines I put in for testing so link fails if anything tries to use these routineswap but provide no impleation)…
Thanks again,
Best Regards, Dave

dnadler wrote on Friday, June 30, 2017:

Hi Richard - I took your suggestion and flipped it around, implementing heap_newlib to implent the FreeRTOS memory API. Now there’s only one memory subsystem and pool, and all newlib’s malloc-family are supported. Turns out sprintf even used realloc indirectly…
How does this look?
Thanks!
Best Regards, Dave
http://www.nadler.com/backups/20170629_heap_useNewlib.c

dnadler wrote on Friday, June 30, 2017:

Hi Richard - I took your suggestion and flipped it around, implementing heap_newlib to implent the FreeRTOS memory API. Now there’s only one memory subsystem and pool, and all newlib’s malloc-family are supported. Turns out sprintf even used realloc indirectly…
How does this look?
Thanks!
Best Regards, Dave
http://www.nadler.com/backups/20170629_heap_useNewlib.c

richarddamon wrote on Friday, June 30, 2017:

You don’t need two pools, as if you make malloc thread safe with the hooks, you just need to make the FreeRTOS heap functions call malloc/free directly (sort of like heap3.c, but without the exclusion primitives).

dnadler wrote on Friday, June 30, 2017:

Hi Richard - I already did just as you suggested. Can you have a look at the note above and the code? Perhaps it would be a useful addition to FreeRTOS?
Thanks as always,
Best Regards, Dave

richarddamon wrote on Friday, June 30, 2017:

It would be up to Richard Barry and the rest of the FreeRTOS team to decide if this should be incorperated into the main core of FreeRTOS (with an appropriate #define to enable).

A few comments:

  • The #ifdef 0 sections need to be removed to keep the code clean
  • The sbrk implementation should only be in the port layer for implementations that are broken. Many implementations of newlib have a perfectly fine sbrk and that should be left alone to avoid surprizes.
  • The waring on configUSE_NEWLIB_REENTRANT != 1 needs to go. The newlib malloc routines do not need it, and it adds significantly to the cost of a task. configUSE_NEWLIB_REENTRANT == 1 is only needed if you use one of the C library routines that are not reentrant in multiple threads.
  • I wouldn’t put your wrap malloc debug wrappers in the official distribution, but maybe in a demo.
  • pvPortMalloc() needs the null return trap that the existing implementations of pvPortMalloc have.

dnadler wrote on Friday, June 30, 2017:

Thanks Richard. Excellent points. Questions:

  1. I think custom sbrk is required both to implement vApplicationMallocFailedHook (I’ve done that now, thanks for catching that), and for an accurate xPortGetFreeHeapSize implentation. It is rather annoying… Yes?
  2. malloc debug wrappers will be stripped in any case by linker; best to leave in for documentation?
    Thanks!
    Best Regards, Dave

richarddamon wrote on Friday, June 30, 2017:

Triggering vApplicationMallocFailedHook in sbrk isn’t the defined behavior, as it is supposed to catch failed calls to pvPortMalloc(), not calls to malloc(). The key here is that it might be possible that there is code that currently calls malloc, and check and recovers from a failure, while it may be less possible to do so for things using pvPortMalloc(). Look at heap3.c as an example.

The issues with the debug wrappers is that their mere existance makes the assumption of gcc, which to my knowledge is NOT a requirement for newlib. My understanding of the FreeRTOS coding standards says that this sort of assumption is not allowed in any file out side of the portable tree (port specific code can have this sort of dependency, as in many cases it must, but the core files MUST be standard conformant C (with additional restrictions from other coding standards).

Note, that not all of the heap implementations define a xPortGertFreeHeapSize function, so its absense shouldn’t be considered fatal (and your example shows you can implement it with a newlib call), and sbrk doesn’t know the value anyway, A custom sbrk might be able to help with an implementation of xPortGetMinimumEverFreeHeapSize(). It might make sense to have a separete option to replace sbrk.

dnadler wrote on Saturday, July 01, 2017:

OK, hopefully I’vegot this wrapped up:
http://www.nadler.com/embedded/newlibAndFreeRTOS.html
Thanks again for the help!
Best Regards, Dave

@dnadler @richard-damon
Hey guys!
Are those changes described on dnadler web page are still needed?
It is now 3 year after the post and we have got FreeRTOS v10.
Can you comment on that?

You haven’t said what platform or compiler you are using.
Assuming its GCC (and newlib):
NXP currently ship the code I provided but may not have updated examples - check carefully.
ST is flailing about cluelessly and shipping crasheroo code - yes you need it.
Other platforms, not sure…
Hope that helps,
Best Regards, Dave

The issues aren’t anything that FreeRTOS can directly address, but a basic issue with the vender provided library.

One issue with providing an implementation of the newly support functions is that you really need to first check that your implementation of the library to see if it uses the __malloc_lock()/__malloc_unlock() or just adding the functions will give you a false sense of security (even if they use newlib, it depends on what options they used to compile it).

If a vendor packages support for FreeRTOS you would expect that they would have that kind of support, but they don’t always (sometime hardware providers aren’t the best at software).

Hello,

I have a question regarding the malloc_lock / unlock implementation. In your implementation Dave, there is a simple call to task suspend and resume…
I read another article (Link ) which say that the call of lock and unlock could be recursive… So that you need some kind of counting variable or something like that?!

Regards
Andy