Go Down

Topic: ESP32 and FreeRTOS and atomic updates (Read 122 times) previous topic - next topic

skyjumper

Hi All...

I'm playing with an ESP32 card, which is 32 bit and my understanding is that its Arduino lib port is based on FreeRTOS.

If I have a data structure full of floats, like this:

typedef struct {
  float var1;
  float var2;
  float var3;
} tRawData;


and I then have an instance of this type:

tRawData rawData;


When I update the members, since floats are 32 bits wide and the ESP32 is a 32 bit processor, is it correct that the updates to these members are atomic? I realize that updates to the entire data type may not be atomic, but am I at least guaranteed that the update of any individual member is atomic?

I ask of course because I want to populate this type in one thread (task) and consume the data in another thread.

Thanks very much...

Idahowalker

Going off this
Quote
Atomic operations in concurrent programming are program operations that run completely independently of any other processes.
. Your update task would be the only task or have the highest preemptive priority, for the moment, running on the assigned core. I would, also assign such a task to Core0. Hrrumph or is that Core1, I got it wrote down somewhere. Yup, I am correct, setup() and loop() are run on core1. So you'd run your task on core0.

If you are meaning that the ESP32 memory/register changes are done as a single 32 bit operation, then yes that is the case.

If you want to run freeRTOS on the ESP32 you'l need to include freeRTOS.
Code: [Select]
#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"

Idahowalker

Using queues is the way to pass info from one task to another or from core to core.

skyjumper

Using queues is the way to pass info from one task to another or from core to core.
Yes I could use queues, or also semaphores / mutexes, but if 32 bit variables are updated atomically in this 32 bit processor that is unnecessary. That's what I'm trying to figure out.

 

skyjumper

Going off this . Your update task would be the only task or have the highest preemptive priority, for the moment, running on the assigned core. I would, also assign such a task to Core0. Hrrumph or is that Core1, I got it wrote down somewhere. Yup, I am correct, setup() and loop() are run on core1. So you'd run your task on core0.
Okay I'll take a closer look at the xTaskCreate() function but I recall that I can assign a priority but not necessarily a core. It's good to know setup() and loop() run on core 1, thanks.

Quote
If you are meaning that the ESP32 memory/register changes are done as a single 32 bit operation, then yes that is the case.
Yes so I expect the compiler generated code moves the variable through the register.


Quote
If you want to run freeRTOS on the ESP32 you'l need to include freeRTOS.
Code: [Select]
#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "freertos/event_groups.h"

Interestingly, selecting the ESP32 in the Arduino dev environment, I was able to create tasks in my app, and run the samples, without including any of that. I don't know why.

Idahowalker

Code: [Select]
xTaskCreatePinnedToCore( fSendSerialToBrain, "fSendSerialToBrain", TaskStack20K, NULL, Priority3, &xHANDLE_SendSerialToBrain, TaskCore0 );

czu001

Yes 32 bit operations are atomic.  But.. protecting shared data between tasks is a different matter.

skyjumper

Yes 32 bit operations are atomic.  But.. protecting shared data between tasks is a different matter.
Right at this point if I have atomic reads and writes then I won't run the risk of reading a variable while it is half updated. Thats good enough for now.

Go Up