1 Description
A typical design model for a microcontroller-based embedded application is to factor the
application functionality into multiple tasks. These tasks are run cooperatively in a
super loop (while(1) loop) in the main function.
Each application task performs a small portion of its functionality and allows the control to move to the other tasks. These tasks will use hardware features (for example, reading or writing to peripherals, such as I2C, USART, SPI) to implement portions of the work. For the application to work correctly, the peripheral drivers used by these tasks need to be implemented in a non-blocking manner.
The user need to consider the following application, implemented using the cooperative multitasking model.
Problem Statement: The application reads the current room temperature from a temperature sensor. The temperature reading is displayed on a serial console periodically every second. Further, the application writes the temperature readings to the EEPROM. When a character is entered on the console, the last five written temperature values are read from the EEPROM and displayed on the console.
The application is divided into two tasks, the Sensor task and the EEPROM task, and each
running their own state machines. The Sensor task and the EEPROM tasks are called from
the SYS_Tasks routine which is run in a while(1)
loop. The user triggers the read of the last five stored values in the EEPROM by a user
input (keypress on the keyboard) through an Asynchronous USART read complete event.
The above state machine based (non-RTOS) application design can be implemented using the Asynchronous mode of the MPLAB Harmony v3 drivers.
The cooperative multitasking application design model works well in many situations, but has limitations and faces implementation challenges when the application being designed is large and feature rich constituting multiple sub tasks. This design model faces implementation challenges when an existing application is scaled or extended as the tasks rely on each other regularly giving up the CPU. Also, there are specific situations when a task cannot give up the CPU to other tasks due to its inherent blocking implementation. For example, the file system style read and write functions block and do not return until the entire transfer has completed. In such situations, the application designer can use a Real Time Operating System to perform multitasking and simultaneously allow the use of blocking driver function calls.
