In this blog post, we'll a bit about the multitasking code that allows the Alarm Clock to tell time, check if the alarm should sound, beep on and off, etc, all at the same time. The code is about 85% complete right now. We still need to make sure he alarm triggers properly and there are a bunch of UI indicators we want to add, like making the needles "flash" when the mode changes, but we wanted to share a little now with a mini-lesson about how the embedded code works. (You can also check out the code on Github here)
Small processors, like the one inside the Alarm Clock, only have one CPU, so they can't truly "multi-task", they're just taking turns using processor time to give the appearance of doing multiple things at once. There are different ways to achieve this, with increasing levels of complexity. The Clock falls somewhere in the middle on the list below.
Round Robbin Loop: all the tasks run over and over again, one at a time, to completion, in a main loop. If you're familiar with Arduino, the Arduino environment encourages this type of programming.
Round Robbin with Interrupts: The microcontroller is capable of pausing a program when an "interrupt" triggers and runs a special sub-program called an "interrupt service routine". Events like changing voltage on a pin, or an internal timer, might trigger those interrupts. The plain AWK-105 Clock has code written this way.
The AWK-105 Alarm still uses round robbin with interupts, but is a tad more complicated than the plain clock. A timer running between 2Hz and 10Hz (we're still tuning this) creates a series of "ticks" that wake up the CPU. The clock's tasks then check the time, decide if they're ready to execute, run to completion, and then the CPU goes back to sleep to wait for the next tick.
Schedulers and Operating Systems: The Clock doesn't require it, but the next level of complexity is to have a task queue, which maintains a running list of things to do. Then, for a truly sophisticated system, a full blown OS can prioritize tasks, will pause a task before it finishes running, and can implement all sorts of scheduling schemes to split time between tasks, too.