Tasks

For discussion of multitasking, we need to define a task. In its simplest form a task is any one thing to done by a controller. Think of an army with an overall mission to accomplish and many individual soldiers to carry it out. The overall mission, ”Drive out that dictator,” is the job, but the tasks might be, ”Drive this supply truck to the front lines,” or, ”Sit in this trench until ordered to advance.” For a controller, a task might be to wait for and process input from a keyboard or to keep a motor running at a set speed. A task can be as simple as a single routine having a few lines of code, or it can be an entire set of nested routines. Task divisions can be arbitrary as long as they relate to the functional parts of the overall job. Most important, tasks represent a way of thinking that logically divides the job and leads to the effective use of the microcontroller.

Priority

Should a task ‘move to the head of the line’ when other tasks have been waiting longer to run? Having different priorities in a system implies that some activities are more important or more urgent than others. We are used to degrees importance in the realm of politics and big business, and we expect to yield to fire trucks and ambulances because they have greater urgency. The same thing can be applied to individual tasks. Issuing a pulse to a stepper motor may be more urgent than the computing an average. Stepper pulses must come at regular times, whereas a computation can be done whenever time is available. The first-level processing of incoming readings is more important than subsequent processing if the new readings will be overwritten by the next readings if they aren’t processed and moved. In a realtime system the priority may be a measure of importance or urgency, or it can reflect the duration of a task–a very short task could run with higher priority because it will be over and done quickly, rather than any inherent degree of importance.

Preemption

Should a task not just move to the head of the line, but stop and replace the task that is currently running? If so, it has preempted the running task. The concept isn’t difficult but the implementation can be challenging because the preempted task could be in the middle of something that shouldn’t be interrupted and, at a minimum, the various registers must be saved so the preempted task can resume where it left off when it gets to run again.