FreeeRTOS and newlib crashing, again…

Hi Folks – I’m working on a new project using ST32F4xx, and the STM-provided STMcubeIDE toolchain. STM’s wizard generates FreeRTOS-project-framework code that fails in many ways, primarily due to improper newlib and FreeRTOS integration. You may recall exactly the same set of issues with Freescale/NXP a couple years back. I’d be much obliged if you could check my (updated) analysis and solution: http://www.nadler.com/embedded/newlibAndFreeRTOS.html Thanks as always for your great OS and support, Best Regards, Dave PS: It would be great if you’d add my suggested heap_useNewlib.c to FreeRTOS!

FreeeRTOS and newlib crashing, again…

Thanks will look. Think I’m familiar with the file already. Won’t be able to reply fully just now – on cellphone.

FreeeRTOS and newlib crashing, again…

My code has an error in that it does not check for collision with the MSP stack used for ISRs. Can you tell me: 1. How should I reserve stack space for ISRs (to avoid heap growing into it), and 2. How does one check MSP stack area usage with FreeRTOS? Again this is for Cortex cores… Appreciate any suggestions, Thanks! Best Regards, Dave

FreeeRTOS and newlib crashing, again…

If it is a cortex-m then the stack allocated for use by main() is re-used as the interrupt stack. If that help.

FreeeRTOS and newlib crashing, again…

Hi Richard – What I want to do for the ISR stack (MSP): 1. Reserve a specific amount of space 2. Make sure heap does not overrun that stack 3. Report the amount of stack actually used I don’t see anything in FreeRTOS to do that – Am I missing something? Should I just invent something? Thanks! Best Regards, Dave

FreeeRTOS and newlib crashing, again…

I looked into the _sbrk implementation generated by the STM32Cube IDE and as you correctly pointed out, it has a bug where it tries to ensure that heap does not grow into the stack. The intention of the code there is to ensure that the heap does not grow into MSP and therefore the code should read MSP (instead of SP). The implementation should look like: ~~~ caddrt _sbrk(int incr) { extern char end asm(“end”); static char *heapend; char *prev_heap_end; char * stack_ptr;
if (heap_end == 0)
    heap_end = &end;

prev_heap_end = heap_end;
__asm volatile ( "MRS %0, msp" : "=r" (stack_ptr) );

if (heap_end + incr > stack_ptr)
{
    errno = ENOMEM;
    return (caddr_t) -1;
}

heap_end += incr;

return (caddr_t) prev_heap_end;
} ~~~ As you correctly mentioned in your article, two more changes are needed: 1. The default implementation of __malloclock and __mallocunlock from libcnano.a(liba-mlock.o) are no-op as can be verified using –wrap. The user therefore need to provide __malloclock and __mallocunlock. 2. The user also need to define configUSENEWLIBREENTRANT to 1 in their FreeRTOSConfig.h. After making these changes, if you use heap_3.c, pvPortMalloc will call malloc and will return heap space from the above. Thanks.

FreeeRTOS and newlib crashing, again…

One thing to be careful here. Often malloc will be called early, before FreeRTOS has started, and at that time the sp is the right register to use (and I am not sure if msp has been setup at all). In my experiance, configUSENEWLIBREENTRANT is not needed just to use malloc and free from newlib. malloc and free do not need thread local storage, and while the lock and unlock functions are passed pointers to the current reent structure, there is nothing that they really need from it. I suppose you could use this to make a version of malloc that kept track of which task created which memory blocks to allow you to figure out where a memory like came from. configUSENEWLIBREENTRANT is only needed to be a 1 if you are using certain ‘higher level’ functions out of the library that you want to have distinct storage for some internals. Likely the most common one would be the file system.

FreeeRTOS and newlib crashing, again…

Gaurav, checking against MSP won’t work, unless malloc is called within ISR. Hence the need to reserve a block for MSP stack and provide checking facility as detailed above. Thanks Richard, reentrant bits that I’ve seen cause trouble are sprintf with %f and strtok; hence configUSENEWLIBREENTRANT might be a better default especially as newlib context requirements have improved in 3.0 version (96 bytes per reentrancy structure/task). Richard Barry – There are hundreds if not thousands of FreeRTOS applications out there behaving badly (ie crashing sporadically) because of incorrect newlib-FreeRTOS applications by NXP/Freescale, STM, and probably others. I get lots of emails thanking me for the web page, and that’s a tiny fraction that actually figure it out and also bother to email me. It would be great to sort this in FreeRTOS and vendor distributions, and improve FreeRTOS’ reputation which is stained by the vendors… Any thoughts on the specific question I posted above regarding MSP stack? Thanks as always for your great work, Best Regards, Dave

FreeeRTOS and newlib crashing, again…

MSP is set as the first thing in the Reset Handler as this is the stack which is used to call main. ~~~ ResetHandler: ldr sp, =estack ~~~ It is therefore possible to call malloc from main and infect I tried using malloc from SystemInit which gets called even before main gets called and it does work. Dave, I am not reading the stack pointer but I am reading MSP explicitly and therefore it does not matter whether we are in the handler mode or user mode (i.e. ISR or FreeRTOS task). I have tested these changes myself and they are working. Do you have a scenario where it does not work? Thanks.

FreeeRTOS and newlib crashing, again…

Sorry Gaurav if I was not clear. The problem is: Ensure there is adequate stack space for ISRs. Do not allow heap to intrude on this space. What you have written does not address this problem. Again: What we want to do for the ISR stack (MSP): 1. Reserve a specific amount of space (top of heap – > _ estack) 2. Make sure heap does not overrun that stack 3. Report the amount of stack actually used I don’t see anything in FreeRTOS to do that – Am I missing something? Should I just invent something? Thanks! Best Regards, Dave

FreeeRTOS and newlib crashing, again…

I do not think we have anything specific for that as MSP stack is specified in your linker script. You can export a variable from your linker script and compare the heap space in _sbrk against that instead of comparing against MSP. Linker Script: ~~~ /* Boundary of stack */ _sstack = _estack – _Min_Stack_Size; ~~~ Sbrk: ~~~ caddrt _sbrk(int incr) { extern char end asm(“end”); extern char sstack asm(“sstack”); static char *heap_end; char *prev_heap_end; char * stack_boundary = &sstack;
if (heap_end == 0)
    heap_end = &end;

prev_heap_end = heap_end;

if (heap_end + incr > stack_boundary)
{
    errno = ENOMEM;
    return (caddr_t) -1;
}

heap_end += incr;

return (caddr_t) prev_heap_end;
} ~~~ The amount of stack space used can be figured from the difference of MSP and stack boundary. I was trying to point out that the implementation ST provides will work with the fix of reading MSP (this of course does not preserve space for MSP stack). Thanks.