Skip to content

Commit

Permalink
Added 05 demo and 06 demo/solution
Browse files Browse the repository at this point in the history
  • Loading branch information
ShawnHymel committed Jan 21, 2021
1 parent 4447b3c commit 36a0c6f
Show file tree
Hide file tree
Showing 5 changed files with 380 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* FreeRTOS Queue Demo
*
* Send data to the serial terminal using a queue.
*
* Date: January 19, 2020
* Author: Shawn Hymel
* License: 0BSD
*/

// Use only core 1 for demo purposes
#if CONFIG_FREERTOS_UNICORE
static const BaseType_t app_cpu = 0;
#else
static const BaseType_t app_cpu = 1;
#endif

// Settings
static const uint8_t msg_queue_len = 5;

// Globals
static QueueHandle_t msg_queue;

//*****************************************************************************
// Tasks

// Task: wait for item on queue and print it
void printMessages(void *parameters) {

int item;

// Loop forever
while (1) {

// See if there's a message in the queue (do not block)
if (xQueueReceive(msg_queue, (void *)&item, 0) == pdTRUE) {
//Serial.println(item);
}
Serial.println(item);

// Wait before trying again
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}

//*****************************************************************************
// Main (runs as its own task with priority 1 on core 1)

void setup() {

// Configure Serial
Serial.begin(115200);

// Wait a moment to start (so we don't miss Serial output)
vTaskDelay(1000 / portTICK_PERIOD_MS);
Serial.println();
Serial.println("---FreeRTOS Queue Demo---");

// Create queue
msg_queue = xQueueCreate(msg_queue_len, sizeof(int));

// Start print task
xTaskCreatePinnedToCore(printMessages,
"Print Messages",
1024,
NULL,
1,
NULL,
app_cpu);
}

void loop() {

static int num = 0;

// Try to add item to queue for 10 ticks, fail if queue is full
if (xQueueSend(msg_queue, (void *)&num, 10) != pdTRUE) {
Serial.println("Queue full");
}
num++;

// Wait before trying again
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
static const uint8_t buf_len = 255; // Size of buffer to look for command
static const char command[] = "delay "; // Note the space!
static const int delay_queue_len = 5; // Size of delay_queue
static const int msg_queue_len = 3; // Size of msg_queue
static const int msg_queue_len = 5; // Size of msg_queue
static const uint8_t blink_max = 100; // Num times to blink before message

// Pins (change this if your Arduino board does not have LED_BUILTIN defined)
Expand Down Expand Up @@ -61,7 +61,7 @@ void doCLI(void *parameters) {
while (1) {

// See if there's a message in the queue (do not block)
if (xQueueReceive(msg_queue, &rcv_msg, 0) == pdTRUE) {
if (xQueueReceive(msg_queue, (void *)&rcv_msg, 0) == pdTRUE) {
Serial.print(rcv_msg.body);
Serial.println(rcv_msg.count);
}
Expand Down Expand Up @@ -122,8 +122,12 @@ void blinkLED(void *parameters) {
while (1) {

// See if there's a message in the queue (do not block)
if (xQueueReceive(delay_queue, &led_delay, 0) == pdTRUE) {
Serial.println("Message received");
if (xQueueReceive(delay_queue, (void *)&led_delay, 0) == pdTRUE) {

// Best practice: use only one task to manage serial comms
strcpy(msg.body, "Message received ");
msg.count = 1;
xQueueSend(msg_queue, (void *)&msg, 10);
}

// Blink
Expand All @@ -132,16 +136,14 @@ void blinkLED(void *parameters) {
digitalWrite(led_pin, LOW);
vTaskDelay(led_delay / portTICK_PERIOD_MS);

// If we've blinked 10 times, send a message to the other task
// If we've blinked 100 times, send a message to the other task
counter++;
if (counter >= blink_max) {

// Construct message and send
strcpy(msg.body, "Blinked: ");
msg.count = counter;
if (xQueueSend(msg_queue, (void *)&msg, 0) != pdTRUE) {
Serial.println("ERROR: Could not put item on message queue.");
}
xQueueSend(msg_queue, (void *)&msg, 10);

// Reset counter
counter = 0;
Expand Down
100 changes: 100 additions & 0 deletions 06-mutex/esp32-freertos-06-demo-mutex/esp32-freertos-06-demo-mutex.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* FreeRTOS Mutex Demo
*
* Increment a shared global variable with mutex protection.
*
* Date: January 20, 2021
* Author: Shawn Hymel
* License: 0BSD
*/

// You'll likely need this on vanilla FreeRTOS
//#include semphr.h

// Use only core 1 for demo purposes
#if CONFIG_FREERTOS_UNICORE
static const BaseType_t app_cpu = 0;
#else
static const BaseType_t app_cpu = 1;
#endif

// Globals
static int shared_var = 0;
static SemaphoreHandle_t mutex;

//*****************************************************************************
// Tasks

// Increment shared variable (the wrong way)
void incTask(void *parameters) {

int local_var;

// Loop forever
while (1) {

// Take mutex prior to critical section
if (xSemaphoreTake(mutex, 0) == pdTRUE) {

// Critical section (poor demonstration of "shared_var++")
local_var = shared_var;
local_var++;
vTaskDelay(random(100, 500) / portTICK_PERIOD_MS);
shared_var = local_var;

// Give mutex after critical section
xSemaphoreGive(mutex);

// Print out new shared variable
Serial.println(shared_var);

} else {
// Do something else
}
}
}

//*****************************************************************************
// Main (runs as its own task with priority 1 on core 1)

void setup() {

// Hack to kinda get randomness
randomSeed(analogRead(0));

// Configure Serial
Serial.begin(115200);

// Wait a moment to start (so we don't miss Serial output)
vTaskDelay(1000 / portTICK_PERIOD_MS);
Serial.println();
Serial.println("---FreeRTOS Race Condition Demo---");

// Create mutex before starting tasks
mutex = xSemaphoreCreateMutex();

// Start task 1
xTaskCreatePinnedToCore(incTask,
"Increment Task 1",
1024,
NULL,
1,
NULL,
app_cpu);

// Start task 2
xTaskCreatePinnedToCore(incTask,
"Increment Task 2",
1024,
NULL,
1,
NULL,
app_cpu);

// Delete "setup and loop" task
vTaskDelete(NULL);
}

void loop() {
// Execution should never get here
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* FreeRTOS Race Condition Demo
*
* Increment a shared global variable.
*
* Date: January 20, 2021
* Author: Shawn Hymel
* License: 0BSD
*/

// Use only core 1 for demo purposes
#if CONFIG_FREERTOS_UNICORE
static const BaseType_t app_cpu = 0;
#else
static const BaseType_t app_cpu = 1;
#endif

// Globals
static int shared_var = 0;

//*****************************************************************************
// Tasks

// Increment shared variable (the wrong way)
void incTask(void *parameters) {

int local_var;

// Loop forever
while (1) {

// Roundabout way to do "shared_var++" randomly and poorly
local_var = shared_var;
local_var++;
vTaskDelay(random(100, 500) / portTICK_PERIOD_MS);
shared_var = local_var;

// Print out new shared variable
Serial.println(shared_var);
}
}

//*****************************************************************************
// Main (runs as its own task with priority 1 on core 1)

void setup() {

// Hack to kinda get randomness
randomSeed(analogRead(0));

// Configure Serial
Serial.begin(115200);

// Wait a moment to start (so we don't miss Serial output)
vTaskDelay(1000 / portTICK_PERIOD_MS);
Serial.println();
Serial.println("---FreeRTOS Race Condition Demo---");

// Start task 1
xTaskCreatePinnedToCore(incTask,
"Increment Task 1",
1024,
NULL,
1,
NULL,
app_cpu);

// Start task 2
xTaskCreatePinnedToCore(incTask,
"Increment Task 2",
1024,
NULL,
1,
NULL,
app_cpu);

// Delete "setup and loop" task
vTaskDelete(NULL);
}

void loop() {
// Execution should never get here
}
Loading

0 comments on commit 36a0c6f

Please sign in to comment.