How to Ensure Atomic Access to Queue in ESP32 FreeRTOS Project?

Hey guys so while i was developing an ESP32 IoT project using FreeRTOS, I'm encountering intermittent data corruption when two tasks share a queue for sensor data (readSensorTask: Reads temperature, humidity, and pressure data from sensors (BME280) every 1 second and the processDataTask: Processes the sensor data and sends it to a cloud server (MQTT) every 10 seconds.) Despite using mutexes, I'm seeing the following error: Guru Meditation Error: Core 0 panic'ed (LoadProhibited) Error message: pc 0x400f36d6 ps 0x6000003f (crash log attached) I was trying to send sensor data to the queue using:
xQueueSend(sensorQueue, &sensorData, portMAX_DELAY);
xQueueSend(sensorQueue, &sensorData, portMAX_DELAY);
How can I ensure atomic access to the queue and prevent simultaneous writes?
Solution:
try this approach 1. Check Mutex Usage: Ensure you're correctly locking and unlocking the mutex when accessing the queue. ```c xSemaphoreTake(mutex, portMAX_DELAY);...
Jump to solution
5 Replies
32bitSaviour
32bitSaviour2mo ago
Hey @Daniel kalu. I think FreeRTOS stream buffers are more suited to your case. Their implementation is optimized and assumes a single writer task and single reader task. Keep in mind it is not safe to have multiple different reader or multiple different writers. It can safely pass data from one microcontroller core to another in a dual core CPU like yours. Check out xStreamBufferSend
Daniel kalu
Daniel kalu2mo ago
I will check it out 🙏 thanks
Solution
Joseph Ogbonna
Joseph Ogbonna2mo ago
try this approach 1. Check Mutex Usage: Ensure you're correctly locking and unlocking the mutex when accessing the queue.
xSemaphoreTake(mutex, portMAX_DELAY);
xQueueSend(sensorQueue, &sensorData, portMAX_DELAY);
xSemaphoreGive(mutex);

xSemaphoreTake(mutex, portMAX_DELAY);
xQueueSend(sensorQueue, &sensorData, portMAX_DELAY);
xSemaphoreGive(mutex);

2. Verify Queue Size: Make sure the queue is large enough for the data you're sending. 3. Check Return Values: Always check the return value of xQueueSend for errors:
if (xQueueSend(sensorQueue, &sensorData, portMAX_DELAY) != pdTRUE) {
// Handle error
}

if (xQueueSend(sensorQueue, &sensorData, portMAX_DELAY) != pdTRUE) {
// Handle error
}

4. Inspect Crash Log: Look at the crash log for details on where the error occurs. These steps should help you manage queue access and prevent data corruption.
techielew
techielew2mo ago
@Daniel kalu did this work for you?
Daniel kalu
Daniel kalu2mo ago
yes it worked after trying both approaches. Improving the mutex and queue handling helped stabilize the system, but I ultimately switched to using a FreeRTOS stream buffer since it’s a better fit for my single producer-consumer setup, and I haven't seen any data corruption or crashes since. Appreciate the help!
Want results from more Discord servers?
Add your server