Skip to content

Commit 7162e7c

Browse files
committed
Added mutex semaphore example.
1 parent 9c5da7c commit 7162e7c

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include <Arduino_FreeRTOS.h>
2+
#include <semphr.h> // add the FreeRTOS functions for Semaphores (or Flags).
3+
4+
// Declare a mutex Semaphore Handle which we will use to manage the Serial Port.
5+
// It will be used to ensure only only one Task is accessing this resource at any time.
6+
SemaphoreHandle_t xSerialSemaphore;
7+
8+
// define two Tasks for DigitalRead & AnalogRead
9+
void TaskDigitalRead( void *pvParameters );
10+
void TaskAnalogRead( void *pvParameters );
11+
12+
// the setup function runs once when you press reset or power the board
13+
void setup() {
14+
15+
// initialize serial communication at 9600 bits per second:
16+
Serial.begin(9600);
17+
18+
// Semaphores are useful to stop a Task proceeding, where it should be paused to wait,
19+
// because it is sharing a resource, such as the Serial port.
20+
// Semaphores should only be used whilst the scheduler is running, but we can set it up here.
21+
if ( xSerialSemaphore == NULL ) // Check to confirm that the Serial Semaphore has not already been created.
22+
{
23+
xSerialSemaphore = xSemaphoreCreateMutex(); // Create a mutex semaphore we will use to manage the Serial Port
24+
if ( ( xSerialSemaphore ) != NULL )
25+
xSemaphoreGive( ( xSerialSemaphore ) ); // Make the Serial Port available for use, by "Giving" the Semaphore.
26+
}
27+
28+
// Now set up two Tasks to run independently.
29+
xTaskCreate(
30+
TaskDigitalRead
31+
, (const portCHAR *)"DigitalRead" // A name just for humans
32+
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
33+
, NULL
34+
, 2 // Priority, with 1 being the highest, and 4 being the lowest.
35+
, NULL );
36+
37+
xTaskCreate(
38+
TaskAnalogRead
39+
, (const portCHAR *) "AnalogRead"
40+
, 128 // Stack size
41+
, NULL
42+
, 1 // Priority
43+
, NULL );
44+
45+
// Now the Task scheduler, which takes over control of scheduling individual Tasks, is automatically started.
46+
}
47+
48+
void loop()
49+
{
50+
// Empty. Things are done in Tasks.
51+
}
52+
53+
/*--------------------------------------------------*/
54+
/*---------------------- Tasks ---------------------*/
55+
/*--------------------------------------------------*/
56+
57+
void TaskDigitalRead( void *pvParameters __attribute__((unused)) ) // This is a Task.
58+
{
59+
/*
60+
DigitalReadSerial
61+
Reads a digital input on pin 2, prints the result to the serial monitor
62+
63+
This example code is in the public domain.
64+
*/
65+
66+
// digital pin 2 has a pushbutton attached to it. Give it a name:
67+
uint8_t pushButton = 2;
68+
69+
// make the pushbutton's pin an input:
70+
pinMode(pushButton, INPUT);
71+
72+
for (;;) // A Task shall never return or exit.
73+
{
74+
// read the input pin:
75+
int buttonState = digitalRead(pushButton);
76+
77+
// See if we can obtain or "Take" the Serial Semaphore.
78+
// If the semaphore is not available, wait 5 ticks of the Scheduler to see if it becomes free.
79+
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
80+
{
81+
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
82+
// We want to have the Serial Port for us alone, as it takes some time to print,
83+
// so we don't want it getting stolen during the middle of a conversion.
84+
// print out the state of the button:
85+
Serial.println(buttonState);
86+
87+
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
88+
}
89+
90+
vTaskDelay(1); // one tick delay (15ms) in between reads for stability
91+
}
92+
}
93+
94+
void TaskAnalogRead( void *pvParameters __attribute__((unused)) ) // This is a Task.
95+
{
96+
97+
for (;;)
98+
{
99+
// read the input on analog pin 0:
100+
int sensorValue = analogRead(A0);
101+
102+
// See if we can obtain or "Take" the Serial Semaphore.
103+
// If the semaphore is not available, wait 5 ticks of the Scheduler to see if it becomes free.
104+
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
105+
{
106+
// We were able to obtain or "Take" the semaphore and can now access the shared resource.
107+
// We want to have the Serial Port for us alone, as it takes some time to print,
108+
// so we don't want it getting stolen during the middle of a conversion.
109+
// print out the value you read:
110+
Serial.println(sensorValue);
111+
112+
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
113+
}
114+
115+
vTaskDelay(1); // one tick delay (15ms) in between reads for stability
116+
}
117+
}

0 commit comments

Comments
 (0)