FreeRTOS Fundamentals

Real-Time Scheduling

Real-time operating systems (RTOSes) achieve multitasking using these same principles - but their objectives are very different to those of general purpose (non real-time) systems. The different objective is reflected in the scheduling policy. Real-time embedded systems are designed to provide a timely response to real world events. Events occurring in the real world can have deadlines before which the real-time embedded system must respond and the RTOS scheduling policy must ensure these deadlines are met.

To achieve this objective using a small RTOS, such as FreeRTOS, the software engineer must assign a priority to each task. The scheduling policy of the RTOS is then to simply ensure that the highest priority task that is able to execute is the task given processing time. This may optionally include sharing processing time “fairly” between tasks of equal priority if there is more than one task at the same highest priority that are able to run (are not delaying and are not blocked).

This basic form of real-time scheduling isn’t magic - it can’t slow down or speed up time - the application writer must ensure their timing constraints are feasible to meet with their selected task prioritisation.

Example

A user must get visual feedback of each key press within a reasonable period - if the user cannot see that the key press has been accepted within this period the software product will at best be awkward to use (soft real-time). If the longest acceptable period was 100ms - any response between 0 and 100ms would be acceptable. This functionality could be implemented as an autonomous task with the following structure:

void vKeyHandlerTask( void *pvParameters )
{
    // Key handling is a continuous process and as such the task
    // is implemented using an infinite loop (as most real-time
    // tasks are).
    for( ;; )
    {
        [Block to wait for a key press event]
        [Process the key press]
    }
}

Now assume the real-time system is also performing a control function that relies on a digitally filtered input. The input must be sampled, filtered and the control cycle executed every 2ms. For correct operation of the filter the regularity of the sample must be accurate to 0.5ms. This functionality could be implemented as an autonomous task with the following structure:

void vControlTask( void *pvParameters )
{
    for( ;; )
    {
        [Delay waiting for 2ms since the start of the previous cycle]
        [Sample the input]
        [Filter the sampled input]
        [Perform control algorithm]
        [Output result]
    }
}

The software engineer must assign the control task the highest priority as:

  • The deadline for the control task is stricter than that of the key handling task.

  • The consequence of a missed deadline is greater for the control task than for the key handler task.

The diagram below demonstrates how these tasks would be scheduled by a real-time operating system. The RTOS has itself created a task - the idle task - which will execute only when there are no other tasks able to do so. The RTOS idle task is always in a state where it is able to execute.

Referring to the diagram above:

  • At the start neither of our two tasks are able to run - vControlTask is waiting for the correct time to start a new control cycle and vKeyHandlerTask is waiting for a key to be pressed. Processor time is given to the RTOS idle task.

  • At time t1, a key press occurs. vKeyHandlerTask is now able to execute - it has a higher priority than the RTOS idle task so is given processor time.

  • At time t2 vKeyHandlerTask has completed processing the key and updating the LCD. It cannot continue until another key has been pressed so suspends itself and the RTOS idle task is again resumed.

  • At time t3 a timer event indicates that it is time to perform the next control cycle. vControlTask can now execute and as the highest priority task is scheduled processor time immediately.

  • Between time t3 and t4, while vControlTask is still executing, a key press occurs. vKeyHandlerTask is now able to execute, but as it has a lower priority than vControlTask it is not scheduled any processor time.

  • At t4 vControlTask completes processing the control cycle and cannot restart until the next timer event - it suspends itself. vKeyHandlerTask is now the task with the highest priority that is able to run so is scheduled processor time in order to process the previous key press.

  • At t5 the key press has been processed, and vKeyHandlerTask suspends itself to wait for the next key event. Again neither of our tasks are able to execute and the RTOS idle task is scheduled processor time.

  • Between t5 and t6 a timer event is processed, but no further key presses occur.

  • The next key press occurs at time t6, but before vKeyHandlerTask has completed processing the key a timer event occurs. Now both tasks are able to execute. As vControlTask has the higher priority vKeyHandlerTask is suspended before it has completed processing the key, and vControlTask is scheduled processor time.

  • At t8 vControlTask completes processing the control cycle and suspends itself to wait for the next. vKeyHandlerTask is again the highest priority task that is able to run so is scheduled processor time so the key press processing can be completed.

Reference

1. freertos.org