pendsv_handler, can heap or stack be too big, do my tasks have too many nested loops, others

jirvin32940 wrote on Sunday, March 26, 2017:

I am using FreeRTOS 7.3.0 on an Atmel ATSAME70 which is a Cortex-M7.

After merging lots of sample code together very quickly (read: sloppily), I find I am having some problems with tasks stopping for reasons not yet determined.

I am seeking clarification on the following:

  • My vTaskTickIncrement() function is not configured to run, but this does not seem to hurt me because I never delete a task and I am not using TaskDelay(). Is there any other reason I should configure this function to run?

  • At any given time I have 2 application tasks configured to run co-operatively (same priority). They each run through their logic and then call TaskYield(), which allows the other task to run, and when everything is working, they ping-ping back and forth as expected. Where does the context switch happen? I do not seem to have a PendSV_Handler() configured.

  • I have had problems with tasks not running, and then when I increase the stack sizes they start working again. I have one task configured for a stack depth of 2048 words, and another configured for a task depth of 8192 words. Does this seem excessive? I have lots of nested loops due to having written lots of XML parsing code.

  • The heap was originally configured for 0x5000 bytes and I now have it configured for 0x10000 bytes. Is that excessive for any reason?

  • Does FreeRTOS “prefer” to have more smaller tasks or fewer larger tasks? Is part of my problem that I have these 2 large tasks with all these nested loops?

  • heap_4.c is linked into my application.

Thanks for any insight you can provide. Best regards. -Julia

rtel wrote on Sunday, March 26, 2017:

I am using FreeRTOS 7.3.0 on an Atmel ATSAME70 which is a Cortex-M7.

FreeRTOS V7 is not strictly compatible with the Cortex-M7, you may find
it works, but it is technically out of spec. The Cortex-M4F port in
FreeRTOS V9 (and maybe earlier versions) was updated to also be in spec
for the Cortex-M7 parts. Also, if your Cortex-M7 has an r0p1 core then
you will need to use the special port specifically for that core version
as it contains workarounds for silicon errata. The r0p1 specific
Cortex-M7 port can be located in this directory:

https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1/

My vTaskTickIncrement() function is not configured to run, but this
does not seem to hurt me because I never delete a task and I am not
using TaskDelay(). Is there any other reason I should configure this
function to run?

vTaskTickIncrement() will be called automatically if you have installed
the FreeRTOS interrupt handlers, which you may have installed without
knowing it if you have copied code and configuration files from other
places.

vTaskTickIncrement() is needed if you make any blocking call (not just
vTaskDelay()), or ever read the time. It would be extremely rare to
write an application that required an RTOS without making any calls that
needed the tick count (which is maintained by vTaskTickIncrement()).

At any given time I have 2 application tasks configured to run
co-operatively (same priority). They each run through their logic
and then call TaskYield(), which allows the other task to run, and
when everything is working, they ping-ping back and forth as
expected. Where does the context switch happen? I do not seem to
have a PendSV_Handler() configured.

If the tasks are switching to each other then you do have the FreeRTOS
PendSV handler installed, you just might not realise how it got
installed. Maybe your FreeRTOSConfig.h file maps the standard names for
these functions to their FreeRTOS equivalents (FreeRTOS was ported to
these parts long before there was any standardisation on the naming) as
described in the ‘special note to Cortex-M users’ under the answer to
FAQ 1 on this page: http://www.freertos.org/FAQHelp.html

I have had problems with tasks not running, and then when I increase
the stack sizes they start working again. I have one task configured
for a stack depth of 2048 words, and another configured for a task
depth of 8192 words. Does this seem excessive? I have lots of nested
loops due to having written lots of XML parsing code.

Only you know how big the stacks for your tasks need to be. If you are
running XML parsing code then it is likely it is using a lot of stack,
especially if it is generic code that was not designed specifically to
minimise its stack usage to make it suitable for use on a microcontroller.

You can trap stack overflows
http://www.freertos.org/Stacks-and-stack-overflow-checking.html and
query a task’s stack high water mark
http://www.freertos.org/uxTaskGetStackHighWaterMark.html

The heap was originally configured for 0x5000 bytes and I now have
it configured for 0x10000 bytes. Is that excessive for any reason?

Only you know how much heap memory you can allocate to the heap, and how
much heap is needed. You can query how much heap is actually being used
(actually, in FreeRTOS V7 maybe you can’t).

Does FreeRTOS "prefer" to have more smaller tasks or fewer larger
tasks? Is part of my problem that I have these 2 large tasks with
all these nested loops?

FreeRTOS has no preference.