Permalink
Cannot retrieve contributors at this time
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?
KPIT_MBED_worksheet/Topic4/Worksheet1_RTOS.md
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
238 lines (178 sloc)
5.84 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 | |