Tics Realtime -----


 
Home Services Products Tutorials Contact Us
- - - - -

When does it Make Sense to use a Real-time Kernel?

Not all real-time systems gain from using a real-time kernel. Consider a real-time system comprised of three motors and three switches. The switches have two positions, ON and OFF. The switches must be scanned at about 10 times per second, and the motors turned on or off as appropriate. A possible solution is shown below.
void main(void)
{
	int i;
	for (;;) {
		for (i= 0; i < 3; i++ ) {
			if (switchChanged(i)) changeMotor(i);
		}
	}
}
Note that the code above does not incorporate any timing to insure that each switch is scanned at least 10 times per second. However, on even basic processors, the code will scan much faster than 10 times per second, and since a faster scan rate will do no harm, the above code is presented as an adequate solution.

Adding Complications

Assume now that the motor switches must be polled at a fairly accurate rate of 10 times per second. This can be handled by modifying the code as follows:
	for (;;) {
		if (OneTenthSecondIsUp) {
			for (i= 0; i < 3; i++ ) {
				if (switchChanged(i)) changeMotor(i);
			}
			OneTenthSecondIsUp = 0;
		}
	}
The global OneTenthSecondIsUp is set to 1 by the timer interrupt service routine every 100 milliseconds.

As a further complication, assume now that a pressure gage must be checked every 50 milliseconds and a valve opened if the pressure is greater than 100 psi. Once opened, the valve must be closed after the pressure drops below 90 psi. This is done by adding the following to the loop.
	if (FiftyMsIsUp) {
		switch (valveState) {
			case CLOSED:
				if (pressure() > 100) {
					openValve(); 
					valveState = OPEN;
				}
				break;
			case OPEN:
				if (pressure() < 90) {
					closeValve();
					 valveState = CLOSED;
				}
		}
		FiftyMsIsUp = 0;
	}
The global FiftyMsIsUp is set to 1 by the timer interrupt service routine every fifty milliseconds.

At this point the for(;;) loop is becoming quite large, and should be re-written as follows.
	for (;;) {
		checkMotorSwitches();
		checkPressure();
	}
As more "tasks" are added to the system, they would be coded as C functions and a call to the function added to the loop as has been done above. An inherent problem with this approach is that as function calls are added to the loop, the "round trip" time through the loop increases, and at some point, the timing requirement that the switches be scanned 10 times per second may not be met.

As a final complication, assume that the system is connected to a network and that incoming datagrams must be processed. This could be handled by adding yet another function call to the loop.
	for (;;) {
		checkMotorSwitches();
		checkPressure();
		checkDatagrams();
	}
If the function checkDataGrams is not called at a sufficient rate, datagrams can be lost. In order to avoid this, a queue must be created so that when the interrupt service routine for incoming datagrams is entered, the datagram is placed into a queue for processing by the function checkDatagrams.

Remarks

The technique outlined above is referred to as a cyclical or round robin kernel/executive. It is adequate for a number of applications, and for some, it is the only choice. For example, consider an 8051 microcontroller application with no external memory. In this type of environment there is simply not enough RAM memory to accommodate a preemptive multi-tasking kernel that requires a private stack for each task. The cyclical executive is small, compact, and easy to use and understand. On the negative side, there are no priorities, busy waiting is employed, and more responsibility (e.g. timer management) is put on the programmer.

Real-time Kernel Solution

The example above has three main requirements:
  1. Concurreny (the 3 separate tasks to be performed)
  2. Timing (sampling switches and pressure)
  3. Message queuing (queuing of incoming datagrams)
These requirements are some of the features that a typical real-time kernel offers. The kernel provides concurrency by allowing the creation of independent tasks; timing is provided by a timer management system; and message queuing is built into the kernel's message system. Using a real-time kernel, the above example could be implemented by coding each of the functions checkMotorSwitches, checkPressure, checkDatagrams as independent tasks.
void checkMotorSwitches(void)
{
	while (TRUE) {
		pause(100L);
		for (i = 0; i < 3; i++) {
			if (switchChanged(i)) changeMotor(i);
		}
	}
}

void checkPressure(void)
{
	while (TRUE) {
		pause(50L);
		if (pressure() > 100) {
			closeValve();
			while (TRUE) {
				pause(50L);
				if (pressure < 90) {
					openValve();
					break;
				}
			}
		}
	}
}

void checkDatagrams(void)
{
	typeMsg * msg;

	while (TRUE) {
		msg = waitMsg(DATA_GRAM);
		processDataGram(msg);
		freeMsg(msg);
	}
}
pause, waitMsg, and freeMsg are Tics system calls. Each of the above C functions are started in main (not shown) by making Tics system calls. The tasks checkMotorSwitches and checkPressure wake up periodically and check conditions. The task checkDatagrams only wakes up when a message is sent to it, since waitMsg suspends the task until a message arrives. The message is sent to checkDatagrams by the receive datagram interrupt service routine. Note the following:
  1. Busy waiting is eliminated.
  2. Timer management is no longer a concern of the programmer.
  3. checkPressure does not have to retain a state variable.
  4. Queue development and management is no longer a concern of the programmer.
Note also that a typical kernel allows for priorities. So, for example, if the checkPressure task sample rate of 50 milliseconds is critical, the task could be run at a higher priority, meaning that if the 50 millisecond timer expires while another task is running, that task would be preempted, to run checkPressure.

Concluding Remarks

Any real-time system can be coded without a kernel, however, even simple systems can benefit from one. For some applications, timer management alone may be reason enough to use a kernel. Much can be written on this subject, and if there is enough interest, a more complete article may be written in the future.


We welcome comments. Let us know what subjects you would like written up. Send comments to Mike@TicsRealtime.com

Copyright © 2000, Tics Realtime