I am looking at V9 with the aim of creating task pools for re-use in
RAM limited real time systems.
In my experience, and in the general case, RAM limited real time systems
rarely create and delete many tasks at run time. Rather they create all
the resources during initialisation, then those resources perform a
dedicated task and persist until the system is switched off.
Of course there are some application that fall outside of that
a) the request method creates (statically) a task but note that the
task handle is NOT unique to the executable code function as it is
essentially a pointer to the TCB, which is shared among a number of
potential code functions..
I’m not sure why that is an issue, but perhaps it is because you don’t
know if the task has changed between two subsequent reads of the task
handle – because the handle will be the same if the task is using the
same StaticTask_t object from your pool.
This has also been an issue for kernel aware IDE plug-ins. The issue
was solved by also giving each task a unique number. You will see the
uxTaskNumber variable is incremented each time a task is created or
deleted – it is incremented when a task is deleted so the kernel aware
debugger knows it has to re-read the task list. The variable is stored
inside the task’s TCB, but [by default] is not accessible – but could be
b) The TCB contains the link list elements for the task management so
the kernel must guarantee that all these items have been removed
from the kernel control lists before the TCB resource can be re-used.
This is achieved by the task delete function. I am not sure that this
can be checked externally in the application. If a task offers itself
for deletion it is not deleted immediately but placed on the pending
queue to be deleted next time the idle task is run.
In version 9 that is only the case if a task deletes itself. If one
task deletes another task then the deletion occurs immediately. In
either case, when the TCB is actually deleted (perhaps conceptually if
you are only using static memory allocation) then the portCLEANUP
macro will be executed. By default that is empty (I think) so you could
implement it in FreeRTOSConfig.h to return the TCB to the pool. Just be
careful to note that portCLEANUP
TCB() is called before the TCB is
access for the last time if dynamic memory allocation is used – but if
you are only using static memory allocation then that should be fine.