May
2006, Issue 190
Image
Processing for Robots
Renesas
M16C Platform Design Contest 2005
by
Jens
Altenburg
RTOS
SOFTWARE STRUCTURE
Designing
a simple software structure for the robot platform can
be a real challenge. There is a lot of information about
this subject on the Internet, but most of it deals with
only a few fixed tasks like object avoidance.
The
M30624 microcontroller is powerful enough to run a multitasking
real-time operating system (RTOS). In most cases, however,
beginners have problems understanding the system and
they implement their own functions. In addition, every
multitasking system has to cooperate with the debugging
ROM monitor on the microcontroller.
So,
let’s define what you need. Some functions are based
on real-time requirements. Others are non-critical tasks
that can run in a multitasking environment. The easiest
thing to do is design interrupt-based cooperative multitasking
software. Every software module must be divided into
fast-running short code snippets. Every module will
start in a fixed time slice.
A
simple solution for such a mechanism would be a function
pointer list (in the sample code system.c: const CallBackFunc
TimerA0[]). But a critical problem can arise. Every
task has to be divided into short subsequences. The
sum of the run-times of all code snippets must be shorter
than the timer cycle time. Sometimes it can be really
hard to program software modules in this way. The most
important feature of such a solution is the excellent
timing behavior (if everything works correctly).
Your
work will be simplified if you don’t have to look at
the task switch between several software modules. Figure
3 is a timing diagram of such a system. A number of
independent tasks run with low priority. Every task
has its own memory space (variables, stack, etc.). The
scheduler controls the context switch. Higher-priority
interrupts are reserved for special events.
|

(Click
here to enlarge)
|
Figure
3—The multitasking kernel is extended by some higher-priority
functions. The scheduler must be the lowest-priority
interrupt. Normal tasks run in time slices without
different priorities. Real-time functions, like
the wheel PID controller, need interrupt functions. |
ImageCraft’s
µexec multitasking system is easy to use. I used it
as a preemptive multitasking system for the UniRoP.
Originally
designed for an 8-bit controller, porting is not a problem
because most of the code is written in C. Because the
context switch runs during the interrupt, assembler
code is needed. Four assembler functions must be programmed:
UEXC_Resume(), UEXC_StartTimer(), UEXC_SaveregsAndResched(),
and UEXC_StartNewTask(). These functions are in the
system.c file posted on the Circuit Cellar FTP site.
Up
to this point, porting the code is clear and understandable.
But remember that during the context switch, the scheduler
builds an interrupt stack frame and returns with the
reit command (see Listing 1, p.
30). If the scheduler is interrupted by a higher-priority
interrupt, a new interrupt stack frame exists. As a
result, the interrupt function runs and returns to the
scheduler. This isn’t a problem.
The
debugging monitor and the KD30 software needs one of
the M30624’s UARTs for communication purposes. The monitor,
which activates periodically, handles communication.
To minimize the timing overhead, incoming command sequences
interrupt the M30624 application software. The global
interrupt immediately reenables after receiving commands,
but the monitor isn’t finished at the same time. If
the scheduler starts a context switch in any of the
monitor functions at this point, the software system
crashes. The application and monitor work independently,
but the scheduler doesn’t know it. The monitor and µexec
can’t cooperate without major changes to the software.
The
solution is simple. The scheduler checks the interrupted
function’s ROM space before the context switch. In other
words, the monitor isn’t scheduled.
The
monitor runs in a higher ROM address area than the application.
In Listing 1, the CMP.W command decides whether the
monitor or the application has been interrupted. As
a result, the µexec runs independently from the monitor.
It works well.