NOTE: These pages have not 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:
Strict timing - the plant control
As before, a high priority task is created to service the critical control functionality.
Deadline only timing - the human interfaces
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!
Flexible timing - the LED
The LED functionality is too simple to warrant its 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 course 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).
Concept of Operation
The grouping of functionality into the medium priority task has three important advantages over the infinite loop
implementation presented in solution #1:
The use of a queue allows the medium priority task to block until an event causes data to be available - and then
immediately jump to the relevant function to handle the event. This prevents wasted processor cycles - in
contrast to the infinite
loop implementation whereby an event will only be processed once the loop cycles to the appropriate handler.
The use of the real time kernel removes the requirement to explicitly consider the scheduling of the time critical task
within the application source code.
The removal of the embedded web server function from the loop has made the execution time more predictable.
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
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
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 API is used.
This is simply a function that is called from the idle task and runs to completion.
The medium Priority Task
The medium priority task can be represented by the following pseudo code.
#define DELAY_PERIOD 4
#define FLASH_RATE 1000
void MediumPriorityTask( void *pvParameters )
FlashTime = xTaskGetTickCount();
for( ;; )
if( xQueueReceive( xCommsQueue, &Data, DELAY_PERIOD ) )
ProcessRS232Characters( Data.Value );
} while ( uxQueueMessagesWaiting( xCommsQueue ) );
if( ScanKeypad() )
if( ( xTaskGetTickCount() - FlashTime ) >= FLASH_RATE )
FlashTime = xTaskGetTickCount();
// Should never get here.
Referring to the labels within the code fragment above:
The task first blocks waiting for a communications event. The block time is relatively short.
The do-while loop executes until no data remains in the queue. This implementation would have to be
modified if data arrives too quickly for the queue to ever be completely empty.
Either the queue has been emptied of all data, or no data arrived within the specified blocking period.
The maximum time that can be spent blocked waiting for data is
short enough to ensure the keypad is scanned frequently enough to meet the specified timing constraints.
Check to see if it is time to flash the LED. There will be some jitter in the frequency at which this line
executes, but the LED timing requirements are flexible enough to be met by this implementation.