heap_3 problem on Kinetis

bowerymarc wrote on Saturday, March 15, 2014:

I just hit this issue and not sure the best way to deal with it….

I selected heap_3 (using system malloc), I’m using FreeRTOS 7.5.0 via Erich Steyger’s PE component.
Set up the system stack & heap with plenty of room for this,
What happens is I get a vApplicationMallocFailedHook when trying to create the first task.
It looks like what’s happening is the Kinetis EWL malloc (alloc.c) routine is set up to grow the heap into the stack,
so when it wants to grow it, it checks the stack pointer (SP register) to see if it’s collided and returns fail if so.
Since FreeRTOS uses the heap as the stack, it has just set SP to be basically at the top of the current heap, so of course
this test in malloc (well, actually in sbrk()) will fail.

Looking at alloc.c’s source, there’s a #define HEAP_GROWS 1 in there that could probably be set to zero so the heap is
fully allocated, but that means having the rebuild the system libraries, making that solution very non-portable…

I’m wondering what other ARM chip ports might have this same issue?

So what to do….? Perhaps, in the heap_3 wrapper, save and restore SP, and set it to something useful to detect actual collisions (in this case, SP_MAIN would probably be good) during the malloc call?

Thanks,
Marc

rtel wrote on Saturday, March 15, 2014:

From your description there doesn’t seem to be an easy option if you want all the allocated memory to come from the same heap. Changing the stack pointer for calls to malloc() would presumably work, but is somewhat fraught as you don’t know what the frame pointer is doing. I would suggest contacting Freescale support about this to see if they can provide a malloc() that has this functionality turned off.

If you don’t mind the task stacks coming from one memory allocator and all other calls to pvPortMalloc() coming from another memory allocator then you can define pvPortMallocAligned(). pvPortMallocAligned() is only ever used to allocate the task stack, and in most ports is just defined to pvPortMalloc(). To do that add something like the following to the bottom of FreeRTOSConfig.h.


#define #define pvPortMallocAligned( size, NotUsed ) myMalloc( size )

where myMalloc is a function provided by yourself, and NotUsed is a parameter that must be in the macro but can be ignored.

Actually, a third option is to pre-define your stacks as char arrays, then create your tasks using xTaskCreateRestricted() instead of xTaskCreate(). I think that should work (?).

Regards.

bowerymarc wrote on Saturday, March 15, 2014:

The thing is, it appears this isn’t limited to Kinetis – http://www.lpcware.com/content/faq/lpcxpresso/heap-checking-redlib for example.

So, to require anyone on two popular ARM platforms to rebuild their library doesn’t seem a good solution, when the problem stems from this fancy use of the SP.

When FreeRTOS switches tasks, it swaps out the SP for the next task; I wonder if similar code could be used to wrap malloc() in heap_3.c? Perhaps the current task’s stack extent could be put in SP, so that malloc could accurately detect a stack overflow for that task’s stack?

Using xTaskCreateRestricted() or multiple memory allocators with heap_3 won’t work because it’s not just the task creation malloc that fails, it’s any malloc, due to the way FreeRTOS sets the SP. It’s just that the first malloc that happens after FreeRTOS starts mucking with the SP is the first user task creation.

The only way around it is to not use heap_3.c and never call system malloc. Unfortunately, if you’re trying to use some C++, you have no choice but to use malloc(). So as soon as FreeRTOS starts to run, all malloc() calls will fail, unless you do a free() first and the next malloc() doesn’t need to grow the heap.

richard_damon wrote on Saturday, March 15, 2014:

My own opinion is an implementation that forces the checking of the stack pointer to the end of heap is not compatible with a multi-tasking system like FreeRTOS (as there is no long a “The Stack” to check against.

The article Marc links to points out several solutions, the best seem to be:

  1. You can alter your link map so that the heap starts above the stack. This disables the checks.
  2. You can override the stack checking function to get around the problem.

bowerymarc wrote on Saturday, March 15, 2014:

Actually FreeRTOS does the same kind of check to get it’s malloc failed check in heap 1,2, and 4. It’s just heap_3 that’s broken by not interfacing correctly with existing mallocs.

Unfortunately the EWL malloc implementation isn’t as flexible as LXPresso… the collision test would fail if you reversed the two.
Neither of the proposed solutions are workable here.
Clearly not many people use heap_3, because it won’t work as-is with any of the NXP or Kinetis ARMs, and possibly others, I haven’t looked.

On Mar 15, 2014, at 11:50 AMEDT, Richard Damon wrote:

My own opinion is an implementation that forces the checking of the stack pointer to the end of heap is not compatible with a multi-tasking system like FreeRTOS (as there is no long a “The Stack” to check against.

The article Marc links to points out several solutions, the best seem to be:

  1. You can alter your link map so that the heap starts above the stack. This disables the checks.
  2. You can override the stack checking function to get around the problem.

heap_3 problem on Kinetis

Sent from sourceforge.net because you indicated interest in SourceForge.net: Log In to SourceForge.net

To unsubscribe from further messages, please visit SourceForge.net: Log In to SourceForge.net

bowerymarc wrote on Saturday, March 15, 2014:

Upon further investigation, I realize that the problem is actually only with task creation. Once that happens, when you call malloc the SP will be OK.

So I came up with a solution which is to simply request all the heap memory and then free it, only on the first call to pvPortMalloc(). Heap is thus grown to it’s max - it only tests SP when it’s trying to grow the heap. Tested it, it works.

rtel wrote on Sunday, March 16, 2014:

Ah, good plan. Maybe we should add an FAQ to this effect for the next person that runs into the same issue.

Regards.

bowerymarc wrote on Sunday, March 16, 2014:

At least, I’d say. It’s a pretty abstruse issue.
Also I’d recommend to anyone doing ports to specifically test heap_3 to make sure it actually works before putting it out there.
Best,
Marc

On Mar 16, 2014, at 7:18 AMEDT, Real Time Engineers ltd. wrote:

Ah, good plan. Maybe we should add an FAQ to this effect for the next person that runs into the same issue.

Regards.

heap_3 problem on Kinetis

Sent from sourceforge.net because you indicated interest in SourceForge.net: Log In to SourceForge.net

To unsubscribe from further messages, please visit SourceForge.net: Log In to SourceForge.net

xz8987f wrote on Sunday, March 16, 2014:

I have looked into this issue, and in my view it is not related with task creation, and a more general problem. That malloc() performs a SP check which makes sense only if the SP is not inside the heap, but with FreeRTOS we have this case. I have published an article on this http://mcuoneclipse.com/2014/03/16/freertos-malloc-and-sp-check-with-gnu-tools/ plus the solution: to link a custom function to the application which has no such SP check.

Regards.

bowerymarc wrote on Friday, March 21, 2014:

I can’t be 100% sure looking at comments in the source, or the docs, whether calling vTaskDelay(0) in a higher priority task will allow lower priority tasks a chance to run?

For that matter, is there any difference in practice between vTaskDelay(0) and vTaskDelay(1)?

thanks,
Marc

bowerymarc wrote on Friday, March 21, 2014:

ugh please ignore, let me repost in a new thread - got tripped up by the email-to-group ‘algorithm’

On Mar 21, 2014, at 1:58 AMEDT, Marc Lindahl wrote:

I can’t be 100% sure looking at comments in the source, or the docs, whether calling vTaskDelay(0) in a higher priority task will allow lower priority tasks a chance to run?

For that matter, is there any difference in practice between vTaskDelay(0) and vTaskDelay(1)?

thanks,
Marc

heap_3 problem on Kinetis

Sent from sourceforge.net because you indicated interest in SourceForge.net: Log In to SourceForge.net

To unsubscribe from further messages, please visit SourceForge.net: Log In to SourceForge.net