6.2 Partitioning Into Tasks
The overall goal of the example application is to blink an LED, handle button pushes and display the time on an OLED screen. Revisit the way of thinking described in section “Thinking like an RTOS developer”. Accordingly, the different jobs are partitioned into individual tasks.
When thinking about what the application should do, it seems useful to have one task that is responsible for the LED blinking every 250 ms. The handling of the buttons pushed should also be an individual task. There is also a need for some sort of clock handling and a way to write to the OLED without causing any conflict because of simultaneous writing.
The example uses seven tasks, two queues, a mutex, a stream buffer and a message buffer. The section “Implementation” will go into detail on how these tasks are implemented. Below is a short description of each task and the communication methods they use.
Status LED Task
Blinks the LED0 on the ATmega4809 Xplained Pro every 250 ms. Uses no communication.
Keyboard Task
Detects if the state of one of the keys (buttons) changes, that is, if a
button is pushed or released. Sends the updated key state to a queue called
key_queue
.
Main Task
Receives the updated key states through the key_queue
, and
creates a string to be printed on the OLED screen. Before writing, the task asks for a
mutex protecting the screen called oled_semaphore
. The task also sends
info about pushed buttons to led_queue
.
LED Task
Receives information about the latest button events through
led_queue
and sets the state of the LEDs accordingly.
Clock Task
Increments the time every second and writes to the OLED screen after taking
the oled_semaphore
. Can also set a new time if requested.
Terminal Transmit Task
Receives information on a message buffer called
terminal_tx_buffer
, and then puts this to the USART TX buffer.
Terminal Receive Task
Receives information through a stream buffer called
terminal_rx_buffer
and can, based on the received message, request
the clock task to set a new time.