circuitcellar.com
Magazine Support   Digital Library   Products & Services   Suppliers Directory 
 
 





 

December 1998, Issue 101

A Minimalist Multitasking Executive


by Richard Man & Christina Willrich
A multitasking executive might seem like a nice enhancement, but the costs are prohibitive, right? Well, maybe they don’t have to be. With 畫xec, even simple embedded programs can be written as multiple tasks.

Start Task Function Scheduling and Timeslice Task Context Task Control Block Global Variables Memory Management API Assembly Functions Give it a Try Enhancements References, Sources & PDF

A typical embedded program reads data from input devices (ADC, keypad, serial port, etc.) and, after some processing, generates some output (LCD, pulses sent to drive motors, etc.).

One simple and crude method of going through this process is to have a control loop as the main function, looping through all the things needing to be done. Listing 1 shows you an example.

Control loop:
	check sensor 1
	check sensor 2
	compute pi to 347 digits
	contemplate and meditate
	activate death ray 1
	drive motor 
	goto control loop

Listing 1—This sample embedded program uses a control loop. Each time through the loop, several tasks are done in sequence.

The problem is that often you don’t want to perform all the steps every time the code goes through the loop. Also, each subroutine must temporarily return to the control loop after some period of time and be able to resume from where it leaves off the next time it’s called.

While this technique works for some programs, it’s usually more error prone and harder to use than using a multitasking executive. Listing 2 shows a program with a multitasking executive.

Task 1: check sensor 1
Task 2: check sensor 2
Task 3: compute pi to 347 digits 
Task 4: contemplate and meditate
Task 5: activate death ray 1
Task 6: drive motor

Listing 2—This program is the same as in Listing 1, but it is partitioned into separate tasks. The control loop is part of the multitasking executive.

Listing 2 looks similar to Listing 1, but the program is partitioned into independent tasks. The tasks don’t need to worry about returning control to a high-level function, and each task may run for a different amount of time before control transfers to another task. In some executives, a task may even stop running altogether and wait on some resource to become available before it is run again.

Since there’s only one CPU, in reality only one task is run at a time. What a multitasking executive does is to periodically take control of the CPU and allow other tasks to run.

So, how does a multitasking system work? In a cooperative multitasking system, each task voluntarily yields control to the system. In the world of PCs, the Mac OS (until OS X) is an example of a cooperative multitasking system and so is Windows 3.1 and below (except, strangely, for the DOS boxes under Windows 3.1).

In a preemptive multitasking system (e.g., Windows NT), the system interrupts a running task if other tasks must be run. A preemptive system is more powerful than a cooperative one because it’s easier to program and it enables tasks to run more fairly.

Under a preemptive system, priorities can be assigned to tasks so the scheduler will run higher priority tasks first. A high-priority task that is waiting for a resource may interrupt a lower priority task if the resource becomes available. The multitasking executive we describe here is the preemptive type.

Despite the benefits of a multitasking executive, it’s often not cost effective for most simple programs—or for people on a budget—to purchase a full-blown multitasking executive. Here, we show you a small multitasking executive, aptly named 畫xec (pronounced myoo-exec), written in ANSI C and some assembly routines. The supplied code is written for and tested on a Motorola ’HC11, but it should be easily ported to other microcontrollers of comparable power.

The code is quite small, in fact, compiling to only 700 bytes using the ImageCraft ICC11 ’HC11 C compiler. 畫xec is a preemptive multitasking system, but to keep the code small, its tasks all have the same priority level. So, you can enjoy the benefits of a multitasking executive without paying a lot in cost or resource consumption.

This article first gives a high-level description of 畫xec, including some of the design choices. Next, we describe the data structures, followed by API functions and assembly routines. Most porting efforts are only needed in modifying the assembly routines, so skip to that section if you’re interested in porting 畫xec to your favorite microcontrollers or compilers.

The last section gives a summary and ideas for enhancements. If you just want to use 畫xec, see the API descriptions for the interface functions.

Under 畫xec, a task runs for a period of time until a timer interrupt interrupts it, and the 畫xec control system chooses another task to run. This process repeats indefinitely—at least until the system crashes, or interrupts are (accidentally) disabled, or the embedded system runs out of battery juice.