Design Article
The basics of embedded multitasking on a PIC, part 3
Gamal Ali Labib
12/16/2007 8:10 AM EST
Part 1: The basics of embedded multitasking on a PIC--Introduction
Part 2: The basics of embedded multitasking on a PIC--Cooperative multitasking
In the last article, I presented a working project of four concurrent display tasks that shared embedded system resources and switched a PIC18F452 MCU equally and willingly among them. I called this kind of a system a cooperative multitasking. Shrinking the tasks' program into a single reentrant program was another accomplishment of that project that helps in fitting complex tasks into the limited size of embedded memory.
In this article, we'll look at the next level of sophistication with my second project as an example. Here, we force tasks to suspend their execution upon periodic system interrupts. We call such an embedded system preemptive. I built this project on macros and work areas used in the previous project. This project demonstrates how modularity and reusability of embedded designs can provide added-value to your projects.
Preemptive task scheduling
This project builds on the cooperative task scheduling project discussed in the previous article. I recommend reading this article first as it will help you understand the changes required to move from cooperative to preemptive multitasking to achieve the policy differences. Preemption does not rely on tasks giving up the PIC control to the scheduler as cooperation did. Instead, the scheduler uses internal or external interrupts to restore system control from user tasks. The project is composed of a group of assembler code and work areas declarations in Microchip's MPLAB IDE (Integrated Development Environment) shown in Figure 1.
Figure 1: Project files window.





TomSenior
12/19/2007 12:48 PM EST
The proofreading/editing for this article is poor.
The problem which Dr. Labib addresses, rotating text on a display, is appropriate for a microcontroller, and an 8-bit one is adequate. Interrupts and reentrancy are not needed, one only needs a pointer into the message, to set its beginning point, and a delay between transmissions of the message to the display. The PIC interrupt structure is very weak, as Dr. Labib says, and, indeed, the stack only saves the return address, and is fixed at only 31 of those. 31 is too many for just one task, and too few for any real multitasking. Almost by definition, tasks may be independent of each other, and what dependencies exist are a problem to be solved. The article's use of an example which repeats the same task four times, with varying data, solves the problem of independent multitasking by choosing a problem in which the tasks are not independent. Reentrant code, of which factorial number calculation is the standard example, can call itself or be called by different user tasks. Dr. Labib's example uses a scheduler via an interrupt to execute the same code repeatedly. This is not reentrancy. The PIC architecture is poorly suited for reentrancy, because of the stack weakness. The problem is unsuitable for reentrancy. I've done dual-task preemptive multiprocessing on a PIC, to integrate code from two programmers who split a project and developed in parallel. The problems were formidable, but the result was satisfactory. I split the stack and gave each of them half. Tasks alternated on the millisecond, and each user had the option to relinquish control if the task was completed early for that interval. It all worked, but I'd think a lot before I did it again. Two tasks was really the limit, because of the stack. The tasks were independent, but I had to be very careful, because of status saving and restoring. Conclusion: Avoid multitasking on an 8-bit PIC. The later 16-bit and 32-bit PIC units are a different story.
Sign in to Reply
umeet
12/21/2007 8:51 AM EST
I have been working in project where we deal with wireless communication application. We have used PIC18F4xxx with preemptive RTOS (made by us). RTOS has priority based preemptive scheduler, ipc, events and mutexes for synchronization and it really works as intended. There's about 5-8 independent tasks running and of course data memory is a bit of problem but nothing we couldn't handle. We cannot really use bigger MCU's and use of RTOS is almost compulsory to guarantee exact timings (we have achieved accuracy of 5us wakeup from timer event).
So at least with those larger 8-bit PIC's I do not see why one should avoid multitasking if task amount is small and application requires multitasking..
Sign in to Reply