// Settings
TickType_t cs_wait = 250; // Time spent in critical section (ms)
TickType_t med_wait = 5000; // Time medium task spends working (ms)
// Globals
static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
//*****************************************************************************
// Tasks
// Task L (low priority)
void doTaskL(void *parameters) {
TickType_t timestamp;
// Do forever
while (1) {
// Take lock
Serial.println("Task L tentando o bloqueio...");
timestamp = xTaskGetTickCount() * portTICK_PERIOD_MS;
portENTER_CRITICAL(&spinlock);
// Say how long we spend waiting for a lock
Serial.print("Task L tem o bloqueio. Espere ");
Serial.print((xTaskGetTickCount() * portTICK_PERIOD_MS) - timestamp);
Serial.println(" ms esperando pelo bloqueio. Fazendo algum trabalho...");
// Hog the processor for a while doing nothing
timestamp = xTaskGetTickCount() * portTICK_PERIOD_MS;
while ( (xTaskGetTickCount() * portTICK_PERIOD_MS) - timestamp < cs_wait);
// Release lock
Serial.println("Task L liberando o bloqueio.");
portEXIT_CRITICAL(&spinlock);
// Go to sleep
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
// Task M (medium priority)
void doTaskM(void *parameters) {
TickType_t timestamp;
// Do forever
while (1) {
// Hog the processor for a while doing nothing
Serial.println("Task M fazendo algum trabalho...");
timestamp = xTaskGetTickCount() * portTICK_PERIOD_MS;
while ( (xTaskGetTickCount() * portTICK_PERIOD_MS) - timestamp < med_wait);
// Go to sleep
Serial.println("Task M feita!");
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
// Task H (high priority)
void doTaskH(void *parameters) {
TickType_t timestamp;
// Do forever
while (1) {
// Take lock
Serial.println("Task H tentando o bloqueio...");
timestamp = xTaskGetTickCount() * portTICK_PERIOD_MS;
portENTER_CRITICAL(&spinlock);
// Say how long we spend waiting for a lock
Serial.print("Task H tem o bloqueio. Espere ");
Serial.print((xTaskGetTickCount() * portTICK_PERIOD_MS) - timestamp);
Serial.println(" ms esperando pelo bloqueio. Fazendo algum trabalho...");
// Hog the processor for a while doing nothing
timestamp = xTaskGetTickCount() * portTICK_PERIOD_MS;
while ( (xTaskGetTickCount() * portTICK_PERIOD_MS) - timestamp < cs_wait);
// Release lock
Serial.println("Task H liberando o bloqueio.");
portEXIT_CRITICAL(&spinlock);
// Go to sleep
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 Critical Section---");
// The order of starting the tasks matters to force priority inversion
// Start Task L (low priority)
xTaskCreatePinnedToCore(doTaskL,
"Task L",
1024,
NULL,
1,
NULL,
1);
// Introduce a delay to force priority inversion
vTaskDelay(1 / portTICK_PERIOD_MS);
// Start Task H (high priority)
xTaskCreatePinnedToCore(doTaskH,
"Task H",
1024,
NULL,
3,
NULL,
1);
// Start Task M (medium priority)
xTaskCreatePinnedToCore(doTaskM,
"Task M",
1024,
NULL,
2,
NULL,
1);
// Delete "setup and loop" task
vTaskDelete(NULL);
}
void loop() {
// Execution should never get here
}