NOTE: These pages have not yet been updated since the introduction of FreeRTOS V4.0.0. V4.0.0 introduces the concept of co-routines which would provide a different and novel solution to those presented here. The Tasks and Co-routines documentation provides further information.
Solution #2 makes full use of the RTOS. This results in a clean design, but one that can only be used on embedded computers with ample RAM and processing resource. Solution #3 attempts to reduce the RAM usage by changing the partitioning of functionality into tasks.

Solution #3 functions tasks and priorities
We have previously seen how the timing requirements of our hypothetical application can be split into three categories:
As before, a high priority task is created to service the critical control functionality.
Solution #3 groups the RS232, keyscan and LED functionality into a single medium priority task.
For reasons previously stated it is desirable for the embedded WEB server task to operate at a lower priority. Rather than creating a task specifically for the WEB server an idle task hook is implemented to add the WEB server functionality to the idle task. The WEB server must be written to ensure it never blocks!
The LED functionality is too simple to warrant it's own task if RAM is at a premium. For reasons of demonstration this example includes the LED functionality in the single medium priority task. It could of coarse be implemented in a number of ways (from a peripheral timer for example).
Tasks other than the idle task will block until an event indicates that processing is required. Events can either be external (such as a key being pressed), or internal (such as a timer expiring).
The grouping of functionality into the medium priority task has three important advantages over the infinite loop implementation presented in solution #1:
In addition, the functionality that has been grouped into a single task is taken from several tasks that previously shared the same priority anyway (barr the LED function). The frequency at which code at this priority executes will not alter whether in a single or multiple tasks.
The plant control task, as the highest priority task, is guaranteed to be allocated processing time whenever it requires. It will pre-empt the low and medium priority tasks if necessary. The idle task will execute whenever both application tasks are blocked. The idle task has the option of placing the processor into power save mode.
The scheduler is configured for preemptive operation. The kernel tick frequency should be set at the slowest value that provides the required time granularity.
![]() |
Creates only two application tasks so therefore uses much less RAM than solution #2. |
![]() |
Processor utilisation is automatically switched from task to task on a most urgent need basis. |
![]() |
Utilising the idle task effectively creates three application task priorities with the overhead of only two. |
![]() |
The design is still simple but the execution time of the functions within the medium priority task could introduce timing issues. The separation of the embedded WEB server task reduces this risk and in any case any such issues would not effect the plant control task. |
![]() |
Power consumption can be reduced if the idle task places the CPU into power save (sleep) mode, but may also be wasted as the tick interrupt will sometimes wake the CPU unnecessarily. |
![]() |
The RTOS functionality will use processing resources. The extent of this will depend on the chosen kernel tick frequency. |
![]() |
The design might not scale if the application grows too large. |
This can be a good solution for systems with limited RAM but it is still processor intensive. Spare capacity within the system should be checked to allow for future expansion.
This example is a partial implementation of the hypothetical application introduced previously. The FreeRTOS.org API is used.
The plant control task is identical to that described in solution #2.
This is simply a function that is called from the idle task and runs to completion.
The medium priority task can be represented by the following pseudo code.
#define DELAY_PERIOD 4
#define FLASH_RATE 1000
void MediumPriorityTask( void *pvParameters )
{
xQueueItem Data;
portTickType FlashTime;
InitialiseQueue();
FlashTime = xTaskGetTickCount();
for( ;; )
{
do
{
// A
if( xQueueReceive( xCommsQueue, &Data, DELAY_PERIOD ) )
{
ProcessRS232Characters( Data.Value );
}
// B
} while ( uxQueueMessagesWaiting( xCommsQueue ) );
// C
if( ScanKeypad() )
{
UpdateLCD();
}
// D
if( ( xTaskGetTickCount() - FlashTime ) >= FLASH_RATE )
{
FlashTime = xTaskGetTickCount();
UpdateLED();
}
}
// Should never get here.
return 0;
}
Referring to the labels within the code fragment above:
NEXT >>> Solution #4: Reducing the processor overhead
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.