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





 

May 2006, Issue 190

Image Processing for Robots
Renesas M16C Platform Design Contest 2005


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.