Reconfigurable computing
Small Embedded Systems
Unit 6.3
Using Semaphores in an RTOS
Introduction
Problems are created by sharing of data between tasks whose interleaving on the processor is unpredictable
Language constructs that help ensure safety are:
Mutex
Identify critical section that only one task at a time can enter
Signalling semaphore
One task informs another of when it can proceed
Counting semaphore
Enable two tasks, one placing data in a queue and one removing it, to avoid overflow or
We will look at examples in FreeRTOS
FreeRTOS Mutex Example: setup()
Suppose two concurrent tasks use USART to print out to the console.
USART is a shared writable resource.
We want to enforce mutual exclusion
#include
#include
SemaphoreHandle_t myLock;
void setup() {
myLock = xSemaphoreCreateMutex();
Serial.begin(9600);
xTaskCreate(task1, “Task 1”, 128, NULL, 1, NULL);
xTaskCreate(task2, “Task 2”, 128, NULL, 1, NULL);
vTaskStartScheduler();
}
Declare the mutex globally
Create the mutex
Include the headers
FreeRTOS Mutex Example: Task 1
Suppose two concurrent tasks use USART to print out to the console.
USART is a shared writable resource.
We want to enforce mutual exclusion
void task1() {
while(1) {
if(xSemaphoreTake(myLock, 1000/portTICK_PERIOD_MS)) {
Serial.println(“Task 1 is running”);
xSemaphoreGive(myLock);
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
}
Name of the mutex
How long to wait before giving up
Critical section
FreeRTOS Mutex Example: Task 2
Suppose two concurrent tasks use USART to print out to the console.
USART is a shared writable resource.
We want to enforce mutual exclusion
void task2() {
while(1) {
if(xSemaphoreTake(myLock, 1000/portTICK_PERIOD_MS)) {
Serial.println(“Task 2 is running”);
xSemaphoreGive(myLock);
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
}
Critical section
FreeRTOS Signalling Example
Suppose we have two tasks: boss and worker
Worker will only do its task when boss issues request
Binary semaphore is used to tell worker when to start
#include
#include
SemaphoreHandle_t mySignal;
void setup() {
mySignal = xSemaphoreCreateBinary();
Serial.begin(9600);
xTaskCreate(boss, “Boss task”, 128, NULL, 1, NULL);
xTaskCreate(worker, “Worker task”, 128, NULL, 1, NULL);
vTaskStartScheduler();
}
Declare the semaphore
Create the Semaphore
Include the headers
FreeRTOS Signalling Example
Boss and worker share a semaphore
Worker task does Take() and blocks on semaphore until boss does Give()
void boss() {
while(1) {
Serial.println(“Boss is making a request”);
xSemaphoreGive(mySignal);
vTaskDelay(2000/portTICK_PERIOD_MS);
}
}
void worker() {
while(1) {
if(xSemaphoreTake(mySignal, 5000/portTICK_PERIOD_MS)) {
Serial.println(“Worker is fulfilling request”);
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
}
Give signal every 2 seconds
FreeRTOS Signalling Example
Boss and worker share a semaphore
Worker task does Take() and blocks on semaphore until boss does Give()
void boss() {
while(1) {
Serial.println(“Boss is making a request”);
xSemaphoreGive(mySignal);
vTaskDelay(2000/portTICK_PERIOD_MS);
}
}
void worker() {
while(1) {
if(xSemaphoreTake(mySignal, 5000/portTICK_PERIOD_MS)) {
Serial.println(“Worker is fulfilling request”);
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
}
Give signal every 2 seconds
FreeRTOS Queue Example
We have two tasks: producer and consumer
They cooperate through a queue (length 10 items)
Producer puts a data item onto queue
Consumer takes a items off the queue
#include
#include
QueueHandle_t myQueue;
void setup() {
myQueue = xQueueCreate(10, sizeof(int));
Serial.begin(9600);
xTaskCreate(producer, “Producer”, 128, NULL, 1, NULL);
xTaskCreate(consumer, “Consumer”, 128, NULL, 1, NULL);
vTaskStartScheduler();
}
void loop(void) {}
Declare the queue
Create the Queue
Include the headers
FreeRTOS Queue Example
Producer task
Runs every 2 seconds
If queue is full:
Blocks for 0.5 seconds to see if slot becomes available
If nothing available after 0.5 seconds, continue on without placing anything on the queue
void producer() {
int sentData=0;
while(1) {
Serial.print(“Producer is putting item into queue: “);
Serial.println(sentData);
if (xQueueSend(myQueue, &sentData, 500/portTICK_PERIOD_MS)) {
sentData++;
}
vTaskDelay(2000/portTICK_PERIOD_MS);
}
}
FreeRTOS Queue Example
Consumer task
Runs every 0.1 seconds
If queue is empty:
Blocks for 0.75 seconds to see if item becomes available
If nothing available after 0.75 seconds, continue on without taking anything off of the queue
void consumer() {
int receivedData;
while(1) {
xQueueReceive(myQueue, &receivedData, 750);
Serial.print(“Consumer is taking from queue: “);
Serial.println(receivedData);
vTaskDelay(100/portTICK_PERIOD_MS);
}
}
Summary
FreeRTOS examples for
Mutex
Signalling semaphore
/docProps/thumbnail.jpeg