I'm working on a project using ESP32 with FreeRTOS where multiple tasks share and modify various types of global variables. My question is about the atomicity of read/write operations on naturally aligned variables in this environment.
Let’s say we have a shared variable that is accessed by two different tasks:
Code: Select all
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
// Naturally aligned global variable (aligned to its natural boundary)
volatile int16_t global_state = 0;
void task1(void *pvParameters) {
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
global_state = 1; // Write operation
}
}
void task2(void *pvParameters) {
while (1) {
if (global_state == 1) { // Read operation
printf("Task1 completed, executing Task2\n");
global_state = 0;
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
my questions are:
Which data types guarantee atomic reads and writes on the ESP32 platform?
Does the Xtensa LX6 architecture ensure atomic access for 16-bit, 32-bit, or 64-bit types when they are naturally aligned?
What about floating-point types like float (32-bit) or double (64-bit)?
I understand that synchronization primitives like mutexes or critical sections are the correct way to protect shared resources. But I'm specifically interested in understanding what the baseline behavior is at the hardware level on ESP32 — especially for variables that are properly aligned.
Any insights into:
Which types can be safely accessed without synchronization,
Architecture-specific guarantees,
Or official documentation from Espressif or Xtensa specs regarding atomicity of memory accesses
would be greatly appreciated.
Thank you in advance for your help!
Best regards