Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
# NOTES:
As the MBED simulator does not support the RTOS elements, we will need
to do this in platformIO and test on the boards.
We also need to make a change to the platformio.ini file to ake sure
the RTOS elements are incuded when compiling. If we add the line below, everything works.
~~~
build_flags = -D PIO_FRAMEWORK_MBED_RTOS_PRESENT
~~~
\clearpage
# Our first multithreaded program
In this example we will write code to blink 2 LEDS.
One LED will be contrlled by the Main Loop
The Second LED will have its own thread.
~~~c
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
//Create an empty thread object ready to attach a function
Thread thread;
//Function to deal with blinking the second LED
void led2_thread() {
//Loop forever
while (true) {
led2 = !led2;
wait(1);
}
}
//Main Program
int main() {
//Attach the function to the Thread then Start it
thread.start(led2_thread);
while (true) {
led1 = !led1;
wait(0.5);
}
}
~~~
Lets break that down a bit:
The ```led2_thread``` function is a seperate block of code that deals with blinking the second LED.
The ```main``` function (remeber this is also a thread) contains code the flash the first LED.
## What Happens when the code executes
- Main thread is created
- Spawns a second thread attached to the function
- Main thead is is **Running**
- Second thread is on **Ready**
Scheduler then allocates a time slice to each thread switiching
between the threads every *N* time slices. Note the code here is very
simple with only a few instructions per interation. It is likey that
the code will execute within one time slice.
Therefore:
- Main Thread executes code untill it hits the ```wait()``` statement
- Thread State changed to **waiting**
- Scheduler selects a thread from **ready** and moves it to **Running**
- Second thread runs till it hits the ``wait()`` statement
- Thread state is chaged to **waiting**.
As it is probable that both threads are now **waiting**. Therefore
there are no threads **ready**, and the system goes into low power
mode.
When the timer for either threads ```wait``` command is complete, the
thread is moved from **waiting** to **ready**, and can be selected by
the scheduler for execution
| Approx Time | | Thread 1 | Thread 2 | |
|-------------|------------------------|----------|----------|---|
| 0 | Start | Running | Ready | |
| 0 | Thread 1 hits Wait | Waiting | Ready | |
| 0 | Scheduler | Waiting | Running | |
| 0 | Thread 2 hits wait | Waiting | Waiting | |
| 0-0.5 | Time Passes | Waiting | Waiting | |
| 0.5 | Thread 1 Wait finished | Ready | Waiting | |
| 0.5 | Scheduler | Running | Waiting | |
| 0.5 | Thread 1 hits wait | Waiting | Waiting | |
| 1.0 | Thread 2 Wait finished | Waiting | Ready | |
| 1.0 | Thread 1 Wait finished | Ready | Ready | |
| 1.0 | Scheduler... | | | |
## Task
Modify the code to blink all 4 LEDS
\clearpage
# Revisiting the Interrupt
| Process | Arrives At | Execute Time |
|---------|------------|--------------|
| A | 1 | 1 |
| B | 2 | 5 |
| C | 3 | 3 |
Example
Here we want to add state to the Threads.
This is a basic form of message passing.
Here we add a global variable, **buttonstate** that can be upaded by
our Interrupt routine. Therefore we just use the Interrupt routine to
updat the state, avioding the problem of the routine takeing controll
f the main execution.
~~~c
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
//InterruptIn button(p12);
InterruptIn button(BUTTON1);
//Create an empty thread object ready to attach a function
Thread thread;
//And a Global Variable to hold state
int buttonState = 0;
//Function to deal with blinking the second LED
void led2_thread() {
while(true){
//for (int x=0; x<5; x++) {
if (buttonState){
for (int x=0;x<4;x++){
led2 = !led2;
wait(0.1);
}
buttonState = 0;
}
wait(0.1);
}
}
//Deal with Button Press
void handler(){
buttonState = !buttonState;
led3 = buttonState; //Debug with lights
}
//Main Program
int main() {
button.rise(&handler);
//Attach the function to the Thread then Start it
thread.start(led2_thread);
while (true) {
led1 = !led1;
wait(0.25);
//Debug with Light
led3=buttonState;
}
}
~~~
\clearpage
## Sending Signals to Threads
~~~c
#include "mbed.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
//InterruptIn button(p12);
InterruptIn button(BUTTON1);
//Create an empty thread object ready to attach a function
Thread thread;
//Function to deal with blinking the second LED
void led2_thread() {
while(true){
//Wait on the Signal to be sent: Note Automatically cleared
Thread::signal_wait(0x01);
for (int x=0;x<4;x++){
led2 = !led2;
wait(0.25);
}
}
}
//Deal with Button Press
void handler(){
led3 = !led3;
thread.signal_set(0x01); //Send the signal (id 0x01) to the Thread
}
//Main Program
int main() {
button.rise(&handler);
//Attach the function to the Thread then Start it
thread.start(led2_thread);
while (true) {
led1 = !led1;
wait(0.25);
}
}
~~~
## Threads and State Tasks
- Modify the Four threads example from before:
- Led1 Blinks Continuously
- On Button Press: Two things happen simultaneously
- Led2 Blinks 10 Times
- Led3 Blinks 20 Times
- After Led3 Finishes: LED4 Blinks 10 Times