Real-Time Operating Systems (RTOS) have been extremely popular in recent years. Most engineers will select an RTOS very early on in the design cycle, sometimes even before requirements have been defined. One of the interesting things about RTOS is that for many MCU-based applications an RTOS is overkill.
The magic of an RTOS really comes into its own when the application requires task preemption (temporarily suspending a task to switch to a higher priority task and later resuming) and has hard real-time requirements. There are many instances where a much simpler, cooperative scheduler will fit the requirements just as easily.
A cooperative scheduler still allows tasks to be scheduled through the use of a background periodic timer that creates a system tick just like in an RTOS. The difference is that rather than having priorities and preemption, the cooperative scheduler only executes tasks that occur at a time periodic interval. If two tasks are due to run at the same time, the task higher up in the task list runs first followed by the second and so on. The cooperative scheduler allows for soft real-time behavior but through the use of interrupts and other mechanisms can also meet hard real-time needs as well.
One of the great advantages of using a cooperative scheduler is that they are fairly simple and straight forward compared to an RTOS. Debugging an RTOS can be extremely complicated and is usually very painful. A cooperative scheduler on the other hand has very few pieces and is much easier to debug. In fact, a cooperative scheduler can be designed and implemented in just a few easy steps. They also use very little flash and RAM. The cooperative scheduler that is presented in this example can be downloaded from http://bit.ly/1oh8sV5
Step 1 – Define the Scheduler Requirements
Before sitting down and writing any code it is a great idea to get an understanding of exactly what it is that is going to be written. This often means going to the project requirements document and understanding what is required. For a cooperative scheduler, there are a few basic requirements that should be kept in mind:
- The scheduler shall use a single interrupt driven timer to keep track of system time
- Scheduler shall be written so that it can be reused from one project to the next
- The scheduler shall be capable of scheduling periodic and background tasks
- The scheduler shall be easily configured through the use of a configuration table
Step 2 – Create the Software Architecture
When developing reusable software it is critical that a good software architecture be implemented. When it comes to a scheduler that will be used on more than one type of hardware, an architecture that is layered can be the difference between code that is reused forever and code that is thrown away after the first project. Creating an architecture that consists of a driver layer for hardware dependent code, an application layer for the guts of the scheduler and a configuration layer to configure the application works perfectly! An example of such an architecture can been see below in Figure 1.
Figure 1. Layered Architecture
To read more of this external content and to leave a comment, go to “Define the components of a task.“