A task can exist in one of the following states:
When a task is actually executing it is said to be in the Running state. It is currently utilising the processor.
Ready tasks are those that are able to execute (they are not blocked or suspended) but are not currently executing because a different task of equal or higher priority is already in the Running state.
A task is said to be in the Blocked state if it is currently waiting for either a temporal or external event. For example, if a task calls vTaskDelay() it will block (be placed into the Blocked state) until the delay period has expired - a temporal event. Tasks can also block waiting for queue and semaphore events. Tasks in the Blocked state always have a 'timeout' period, after which the task will be unblocked. Blocked tasks are not available for scheduling.
Tasks in the Suspended state are also not available for scheduling. Tasks will only enter or exit the suspended state when explicitly commanded to do so through the vTaskSuspend() and xTaskResume() API calls respectively. A 'timeout' period cannot be specified.

Valid task state transitions
Low priority numbers denote low priority tasks, with the default idle priority defined by tskIDLE_PRIORITY as being zero.
The scheduler will ensure that a task in the ready or running state will always be given processor time in preference to tasks of a lower priority that are also in the ready state. In other words, the task given processing time will always be the highest priority task that is able to run.
void vATaskFunction( void *pvParameters )
{
for( ;; )
{
-- Task application code here. --
}
}
The type pdTASK_CODE is defined as a function that returns void and takes a void pointer as it's only parameter. All functions that implement a task should be
of this type. The parameter can be used to pass information of any type into the task - this is demonstrated by several of the
standard demo application tasks.
Task functions should never return so are typically implemented as a continuous loop. Again, see the RTOS demo application for numerous examples.
Tasks are created by calling xTaskCreate() and deleted by calling vTaskDelete().
The prototype for the function shown above can be written as:
void vATaskFunction( void *pvParameters );
Or,
portTASK_FUNCTION_PROTO( vATaskFunction, pvParameters );
Likewise the function above could
equally be written as:
portTASK_FUNCTION( vATaskFunction, pvParameters )
{
for( ;; )
{
-- Task application code here. --
}
}
The idle task is responsible for freeing memory allocated by the RTOS to tasks that have since been deleted. It is therefore important in applications that make use of the vTaskDelete() function to ensure the idle task is not starved of processing time. The activity visualisation utility can be used to check the microcontroller time allocated to the idle task.
The idle task has no other active functions so can legitimately be starved of microcontroller time under all other conditions.
It is possible for application tasks to share the idle task priority. (tskIDLE_PRIORITY).
There must always be at least one task that is ready to run. It is therefore imperative that the hook function does not call any API functions that might cause the task to block (vTaskDelay() for example. It is permissible for co-routines to block within the hook function).
This is a more flexible solution but has a higher RAM usage overhead.
To create an idle hook:
void vApplicationIdleHook( void );
Any and all data, files, source code, html content and documentation included in the FreeRTOS distribution or available on this site are the exclusive property of Richard Barry.
See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Richard Barry.