103 lines
3.7 KiB
Arduino
103 lines
3.7 KiB
Arduino
/* Basic Multi Threading Arduino Example
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
Unless required by applicable law or agreed to in writing, this
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
*/
|
|
// Please read file README.md in the folder containing this example.
|
|
|
|
#define USE_MUTEX
|
|
int shared_variable = 0;
|
|
SemaphoreHandle_t shared_var_mutex = NULL;
|
|
|
|
// Define a task function
|
|
void Task(void *pvParameters);
|
|
|
|
// The setup function runs once when you press reset or power on the board.
|
|
void setup() {
|
|
// Initialize serial communication at 115200 bits per second:
|
|
Serial.begin(115200);
|
|
|
|
Serial.printf(" Task 0 | Task 1\n");
|
|
|
|
#ifdef USE_MUTEX
|
|
shared_var_mutex = xSemaphoreCreateMutex(); // Create the mutex
|
|
#endif
|
|
|
|
// Set up two tasks to run the same function independently.
|
|
static int task_number0 = 0;
|
|
xTaskCreate(
|
|
Task, "Task 0" // A name just for humans
|
|
,
|
|
2048 // The stack size
|
|
,
|
|
(void *)&task_number0 // Pass reference to a variable describing the task number
|
|
//, 5 // High priority
|
|
,
|
|
1 // priority
|
|
,
|
|
NULL // Task handle is not used here - simply pass NULL
|
|
);
|
|
|
|
static int task_number1 = 1;
|
|
xTaskCreate(
|
|
Task, "Task 1", 2048 // Stack size
|
|
,
|
|
(void *)&task_number1 // Pass reference to a variable describing the task number
|
|
,
|
|
1 // Low priority
|
|
,
|
|
NULL // Task handle is not used here - simply pass NULL
|
|
);
|
|
|
|
// Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
|
|
}
|
|
|
|
void loop() {}
|
|
|
|
/*--------------------------------------------------*/
|
|
/*---------------------- Tasks ---------------------*/
|
|
/*--------------------------------------------------*/
|
|
|
|
void Task(void *pvParameters) { // This is a task.
|
|
int task_num = *((int *)pvParameters);
|
|
Serial.printf("%s\n", task_num ? " Starting |" : " | Starting");
|
|
for (;;) { // A Task shall never return or exit.
|
|
#ifdef USE_MUTEX
|
|
if (shared_var_mutex != NULL) { // Sanity check if the mutex exists
|
|
// Try to take the mutex and wait indefinitely if needed
|
|
if (xSemaphoreTake(shared_var_mutex, portMAX_DELAY) == pdTRUE) {
|
|
// Mutex successfully taken
|
|
#endif
|
|
int new_value = random(1000);
|
|
|
|
char str0[35]; // Maximum possible length of the string
|
|
snprintf(str0, sizeof(str0), " %d <- %d |", shared_variable, new_value);
|
|
char str1[46]; // Maximum possible length of the string
|
|
snprintf(str1, sizeof(str1), " | %d <- %d", shared_variable, new_value);
|
|
Serial.printf("%s\n", task_num ? str0 : str1);
|
|
|
|
shared_variable = new_value;
|
|
delay(random(100)); // wait random time of max 100 ms - simulating some computation
|
|
|
|
snprintf(str0, sizeof(str0), " R: %d |", shared_variable);
|
|
snprintf(str1, sizeof(str1), " | R: %d", shared_variable);
|
|
Serial.printf("%s\n", task_num ? str0 : str1);
|
|
//Serial.printf("Task %d after write: reading %d\n", task_num, shared_variable);
|
|
|
|
if (shared_variable != new_value) {
|
|
Serial.printf("%s\n", task_num ? " Mismatch! |" : " | Mismatch!");
|
|
//Serial.printf("Task %d: detected race condition - the value changed!\n", task_num);
|
|
}
|
|
|
|
#ifdef USE_MUTEX
|
|
xSemaphoreGive(shared_var_mutex); // After accessing the shared resource give the mutex and allow other processes to access it
|
|
} else {
|
|
// We could not obtain the semaphore and can therefore not access the shared resource safely.
|
|
} // mutex take
|
|
} // sanity check
|
|
#endif
|
|
delay(10); // Allow other task to be scheduled
|
|
} // Infinite loop
|
|
}
|