Multitasking on the MSP430F5529 LaunchPad

What exactly is multitasking, scheduling, and context switching? This is a great question for those interested in understanding how operating systems work, even small real-time operating systems (RTOS). [Jeffrey] had the same question, so he built a multitasking scheduler for the MSP430F5529 LaunchPad.

These topics are some of the most difficult to wrap your head around in the embedded world. Choosing a project that helps you understand tough topics is a great way to learn, plus it can be very rewarding. In his post, [Jeffrey] goes over the basics of how all of these things work, and how they can be implemented on the MSP430. Overall, it is a great read and very informative. For more information on RTOS, check out a few sections in the FreeRTOS book. Be sure to see his code in action after the break.

[Jeffery] was nice enough to release all of his code as open source, so be sure to check out his repository on GitHub. “Feel free to use it and learn more. I have made the code self explanatory. Enjoy!”

Instead of a preemptive scheduler like this one, I would recommend a non-preemptive scheduler. It avoids a lot of the critical sections and race conditions, and is much easier to program for. In a non-preemptive scheduler, you don’t schedule in an interrupt handler, but by letting the foreground task call the scheduler function. This means that task switching never happens unexpectedly.

This is called cooperative multitasking. Lots of MCU OSes do this. Writing tasks for this is typically more sophisticated than for a thread-based system, although you only need one stack.

The problem with cooperative multitasking is that it is almost never capable of real-time scheduling. It can be real-time if the task duty is low and the tasks are very short. For any kind of protocol processing, though, it is usually insufficient.

The other two options are (1) use a thread-based, pre-emptive scheduler, (2) implement real-time drivers that run outsider the scheduler which activate cooperative tasks as needed. This is ultimately pre-emptive as well, although the real-time features are isolated in the drivers rather than in the kernel. Sometimes this is called an Exokernel. The “internet of things” OSes I’m aware of tend to use this architecture.

What you talk about is cooperative multitasking with threads. I don’t think this is a good idea unless you have really slow I/O. Otherwise the scheduler clock will need to be fast, and the scheduler will need to run really fast too — often not possible/practical on these MCUs. The exokernel approach is used often (certainly contiki, opentag, many proprietary MCU OSes), and it is similar in architecture to cooperative multithreading (i.e. non-preemptive tasking), except the I/O can be fast because it is managed in ISRs outside the scheduler.

No, there is no scheduler clock. The scheduler is only called by the active thread when it needs to wait for I/O or other events. It is in fact very lightweight. There is less scheduling than in a pre-emptive system. There are still ISRs for I/O. They do all the real-time processing, leave the data in a queue (or other), and wake up any task waiting for the I/O. I’m not sure why it is so confusing.

If he’s already using a timer, why not set up a second for accurate timekeeping? That way he doesn’t need to use busy loops (whose accuracy is skewed by interrupts and scheduling) as long as the task is schedules two for every blink.