In the early days of embedded systems SW development, the developers were responsible of controlling all the processor states and configurations, as well as the application SW. Nowadays; there are Operating Systems that permits the performance of tasks either on parallel or on sequence permitting the developers to focus more in the ASW. Tasks are pieces of SW that run independently from each other’s and from the main operating systems. One example of task, is the main() function that runs everything in an old school embedded application. The main() is one task that can run from the very beginning of the power on of the embedded systems and don’t stop until it is power off.
As the tasks can run independently from each other, it is required a way to control and organize these tasks… Therefore, a schedule is used.
A schedule is a routine that handles the tasks process. It switches between groups of tasks depending of the configuration of the processor or if the current routine enters to a specific condition that triggers the switch between tasks.
The scheduler uses the idea of multitasking that in reality is that different groups of tasks take turns to execute themselves.
There are different configurations from the scheduler process, simple configuration as a time expiring set of tasks or to more complex (and more useful) tasks with priority.
Using the priority within tasks, the system has the ability to preempt a low tasks allowing a higher priority tasks run (in following articles, we will talk about Preemption). In essence, a preemption is the action to pause the execution of a tasks (save its registers to the stack, save the address of the PC, and so on) allowing the execution of a higher priority task, this also can be nested several times, but at the end of the higher priority tasks executions the lower priority task can recover its savings and continue with its execution.
The schedule might have background and foreground tasks. The background task runs only if there are no solitudes of foreground task to run, this is that the background task is the lowest priority, and can be used to save in nonvolatile memory or calculate more precise data that the one used currently.
There are different types of schedulers:
- Schedules with time execution, here the developer knows how long each job (set of tasks) will last and then assign a specific time (5ms, 10 ms, 1 s. …) that will run these tasks periodically.
- Schedules with resource calculation, here the operating system can ignore or postpone jobs when the resources to dispatch this task are no sufficient.
- Schedules with priority and deadline priorities, here it is calculated a primary priority deciding which is the highest priority task with the closest deadline, this is all with the cost of more computation overhead.