Key Concept:
Sequential Programming
A sequential program explicitly waits in-line, for the expected events in various places in the execution path. This explicit waiting for events is implemented either by busy-polling or blocking on a time-delay, a semaphore or other such mechanism of a traditional Real-Time Operating System (RTOS).
Traditional Approach: Sequential Programming
Most embedded systems are traditionally programmed in a sequential manner, where the expected event sequences are hard-coded in the various blocking (or busy-polling) calls in the execution path.
An example of the basic sequential code is the traditional “Blink” implementation. This could be either a “superloop” or one of the treads in a RTOS-based design.
while (1) { /* "superloop" or a thread of an RTOS */
BSP_ledOn(); /* turn the LED on (computation) */
delay(1000); /* wait for 1000 ms (POLLING / BLOCKING) */
BSP_ledOff(); /* turn the LED off (computation) */
delay(1000); /* wait for 1000 ms (POLLING / BLOCKING) */
}
Sequential programs (“superloop” or threads of a traditional RTOS) work well for sequential problems, where the expected sequence of events can be hard-coded in the sequential manner.
What's Wrong with the Sequential Paradigm?
Trouble is that most real-life systems are not sequential, meaning that the system must handle many, equally valid event sequences. The fundamental problem is that while a sequential program is waiting for one kind of event (e.g., timeout event after a time delay) it is not doing anything else and is not responsive to other events (e.g., a button press). The hard-coded event sequences are simply not flexible enough for most real-life problems.