Implementing Task Synchronization in RTOS for Sensor Data Processing and Display

@Middleware & OS Hey guys, am working on a code to implement a task in a complex real-time operating system (RTOS) that deals with two tasks, TaskA and TaskB. TaskA is responsible for receiving data from a sensor, processing it, and sending it to TaskB for further processing. TaskB should receive the data from TaskA, perform some calculations, and display the result on an LCD screen. The tasks need to synchronize their execution, ensuring that TaskA does not send data to TaskB before it is ready, and TaskB does not start processing until it receives the data from TaskA. How can I implement this RTOS mechanism
9 Replies
electro_coco
electro_coco7mo ago
Using event groups or semaphore or mutex
Nehal
Nehal7mo ago
Semaphore or mutex can be a good option but you can also create an enum for states (if task B is dependent on task A to get the data) . Let's say you create an enum with Task A, B and None. None means both tasks can acquire it. When you have the data in task A make the enum to A so that task B when checks the enum it gets task A and doesn't perform anything. After you are done with task A change the enum to task B so when task B checks it performs its operation and in the end change the state to again for Task A. In this way task B is dependent on task A. Also keep in mind use mutex to read and write the enum to avoid race conditions.
Marvee Amasi
Marvee Amasi7mo ago
Here is an example scenario;
#include <RTOS.h>

// Define task priorities
#define TASKA_PRIORITY 2
#define TASKB_PRIORITY 1

// Define task stack size
#define TASKA_STACK_SIZE 512
#define TASKB_STACK_SIZE 512

// Define global variables
volatile int dataReceived = 0; // Flag to indicate data is received
volatile int processedData = 0; // Variable to store the processed data

// Define task function prototypes
void TaskA(void* parameters);
void TaskB(void* parameters);

// Create task handles
TaskHandle_t taskAHandle;
TaskHandle_t taskBHandle;

void setup() {
// Initialize RTOS

// Create TaskA with higher priority
xTaskCreate(TaskA, "TaskA", TASKA_STACK_SIZE, NULL, TASKA_PRIORITY, &taskAHandle);

// Create TaskB with lower priority
xTaskCreate(TaskB, "TaskB", TASKB_STACK_SIZE, NULL, TASKB_PRIORITY, &taskBHandle);

// Start the scheduler
vTaskStartScheduler();
}

void loop() {
// Main loop is not used in RTOS-based systems
}

void TaskA(void* parameters) {
while(1) {
// Receive data from sensor
int sensorData = readSensorData();

// Process the data
int processedData = processSensorData(sensorData);

// Mark data as received
dataReceived = 1;

// Suspend task until TaskB finishes processing
vTaskSuspend(NULL);
}
}

void TaskB(void* parameters) {
while(1) {
// Wait until data is received
while (!dataReceived) {
vTaskDelay(pdMS_TO_TICKS(10));
}

// Process the data received from TaskA
int result = performCalculations(processedData);

// Display the result on LCD screen
displayResult(result);

// Clear the data received flag
dataReceived = 0;

// Resume TaskA to receive new data
vTaskResume(taskAHandle);

// Delay to allow TaskA to execute before resuming TaskB
vTaskDelay(pdMS_TO_TICKS(10));
}
}
#include <RTOS.h>

// Define task priorities
#define TASKA_PRIORITY 2
#define TASKB_PRIORITY 1

// Define task stack size
#define TASKA_STACK_SIZE 512
#define TASKB_STACK_SIZE 512

// Define global variables
volatile int dataReceived = 0; // Flag to indicate data is received
volatile int processedData = 0; // Variable to store the processed data

// Define task function prototypes
void TaskA(void* parameters);
void TaskB(void* parameters);

// Create task handles
TaskHandle_t taskAHandle;
TaskHandle_t taskBHandle;

void setup() {
// Initialize RTOS

// Create TaskA with higher priority
xTaskCreate(TaskA, "TaskA", TASKA_STACK_SIZE, NULL, TASKA_PRIORITY, &taskAHandle);

// Create TaskB with lower priority
xTaskCreate(TaskB, "TaskB", TASKB_STACK_SIZE, NULL, TASKB_PRIORITY, &taskBHandle);

// Start the scheduler
vTaskStartScheduler();
}

void loop() {
// Main loop is not used in RTOS-based systems
}

void TaskA(void* parameters) {
while(1) {
// Receive data from sensor
int sensorData = readSensorData();

// Process the data
int processedData = processSensorData(sensorData);

// Mark data as received
dataReceived = 1;

// Suspend task until TaskB finishes processing
vTaskSuspend(NULL);
}
}

void TaskB(void* parameters) {
while(1) {
// Wait until data is received
while (!dataReceived) {
vTaskDelay(pdMS_TO_TICKS(10));
}

// Process the data received from TaskA
int result = performCalculations(processedData);

// Display the result on LCD screen
displayResult(result);

// Clear the data received flag
dataReceived = 0;

// Resume TaskA to receive new data
vTaskResume(taskAHandle);

// Delay to allow TaskA to execute before resuming TaskB
vTaskDelay(pdMS_TO_TICKS(10));
}
}
Marvee Amasi
Marvee Amasi7mo ago
In the above code, we are using an RTOS to create TaskA and TaskB. TaskA is responsible for receiving data from a sensor, processing it, and marking it as received. TaskB waits until TaskA marks the data as received, then it processes the received data and displays the result on an LCD screen. To ensure synchronization between TaskA and TaskB, we are using a global flag dataReceived in TaskA. When TaskA receives the data, it sets the flag to 1, suspends its execution using vTaskSuspend(), and waits for TaskB to process the data. In TaskB, we have a loop that continuously checks the dataReceived flag. Once it becomes 1, TaskB processes the data, displays the result, clears the flag, and resumes TaskA using vTaskResume(). We also add a small delay using vTaskDelay() to allow TaskA some time to execute before TaskB resumes.
Nehal
Nehal7mo ago
Do you think, reading and writing the same variable "dataReceived" flag is correct? I know it's an example but still.
Marvee Amasi
Marvee Amasi7mo ago
@Nehal I get your concern , I just did it for basic understanding of task communication, the code is correct though , but it's not a safe approach for synchronization in RTOS environment
Enthernet Code
Enthernet Code7mo ago
Thanks, I would like a code structure example, can you please help with that
Enthernet Code
Enthernet Code7mo ago
Thanks, I can used this to practice
Want results from more Discord servers?
Add your server