ESP32 Task

Suded Emmanuel
Posts: 3
Joined: Fri Apr 29, 2022 4:37 am

ESP32 Task

Postby Suded Emmanuel » Fri Apr 29, 2022 4:50 am

I have a task on ESP32
I need to see an updated variable
The task is running in parallel with main.src
My variable is declared in .h file that is included in main.src using a structure, the variable is float and dynamically change by the software, how can I keep track of the variable and see its updated values in the task, there is an endless loop running in the task to keep comparing the float variable in an IF statement
im using platformio under visual basic code
Can you please help?this will be appreciated
Regards,
Suded

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 Task

Postby ESP_Sprite » Fri Apr 29, 2022 5:57 am

You can make the variable volatile, but this generally is a hack... you'll run into other problems (watchdog timeouts) if you do this. Better to make use of e.g. a semaphore and block on that.

Suded Emmanuel
Posts: 3
Joined: Fri Apr 29, 2022 4:37 am

Re: ESP32 Task

Postby Suded Emmanuel » Fri Apr 29, 2022 8:05 am

I want to keep track of a variable that is declared in a typedef struct, I have instance of that variable, this done in aheader .h file that im including in main.src, all is comppiling ok but i cant use the right value of the variable
The variable is used elsewhere in the software and dynamically changing
Can you please advise a solution? do you need snippet of the code?
Regards,
Suded

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 Task

Postby ESP_Sprite » Fri Apr 29, 2022 11:58 am

Yes. Use a semaphore. 'Give' the semaphore when the value has changed and the task needs to be active. https://www.freertos.org/a00113.html

mikemoy
Posts: 626
Joined: Fri Jan 12, 2018 9:10 pm

Re: ESP32 Task

Postby mikemoy » Fri Apr 29, 2022 1:58 pm

ESP_Sprite wrote:
Fri Apr 29, 2022 5:57 am
You can make the variable volatile, but this generally is a hack... you'll run into other problems (watchdog timeouts) if you do this. Better to make use of e.g. a semaphore and block on that.
I am really interested in your thoughts on this point. For many years I have been using volatile variables, so if i've been lucky all this time I would like to learn more on the why behind it. I am really curious how a volatile variable would have any effect on the watchdog timing out.

Thanks

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 Task

Postby ESP_Sprite » Sat Apr 30, 2022 7:49 am

This article is Linux-based, but it more-or-less makes the point that needs to be made. The thing is: either you poll the volatile variable in a loop:

Code: Select all

volatile int i=0;
..
while (!i) ;
in which case there's the likelihood of a loop that spins for ever triggering the task watchdog, which you generally do not want in a RTOS environment. Alternatively, you use some function to wait a bit or block or whatnot:

Code: Select all

volatile int i=0;
...
while (!i) vTaskDelay(100);
which is loads better as the RTOS gets a chance to do other things, but in which case the blocking function functions as a compiler barrier (think: the compiler doesn't know if the vTaskDelay somehow could change i and as such forces the code to re-read it from memory) and the volatile is unnecessary.

In any case, while the second option is leaps and bounds better than the first one, I'd say both of the options are lazy. You're effectively trying to re-implement a semaphore, but without the help of the RTOS you're just wasting cycles. Better to do it right and use an *actual* semaphore (or other multithreading implement) so the RTOS doesn't have to bother with your task until it's actually supposed to go active.

mikemoy
Posts: 626
Joined: Fri Jan 12, 2018 9:10 pm

Re: ESP32 Task

Postby mikemoy » Sat Apr 30, 2022 1:55 pm

ESP_Sprite wrote:
Sat Apr 30, 2022 7:49 am
This article is Linux-based, but it more-or-less makes the point that needs to be made. The thing is: either you poll the volatile variable in a loop:

Code: Select all

volatile int i=0;
..
while (!i) ;
in which case there's the likelihood of a loop that spins for ever triggering the task watchdog, which you generally do not want in a RTOS environment. Alternatively, you use some function to wait a bit or block or whatnot:

Code: Select all

volatile int i=0;
...
while (!i) vTaskDelay(100);
which is loads better as the RTOS gets a chance to do other things, but in which case the blocking function functions as a compiler barrier (think: the compiler doesn't know if the vTaskDelay somehow could change i and as such forces the code to re-read it from memory) and the volatile is unnecessary.

In any case, while the second option is leaps and bounds better than the first one, I'd say both of the options are lazy. You're effectively trying to re-implement a semaphore, but without the help of the RTOS you're just wasting cycles. Better to do it right and use an *actual* semaphore (or other multithreading implement) so the RTOS doesn't have to bother with your task until it's actually supposed to go active.


Thanks for explaining what you meant. The word lazy is what threw me in thinking you should not use volatile at all.
For instance you have two threads. One thread is handling the LCD screen & user inputs. The other thread is reading a A/D converter via SPI, and updating a volatile variable on what was read so the LCD task can use that variable to throw it up on the LCD.
In your example to use a volatile variable to be used as a signal event....ya that would not be a "lazy" way of doing it.

I agree that its not the best approach to use a variable in the way you shown. I thought

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32 Task

Postby ESP_Sprite » Sun May 01, 2022 1:16 am

mikemoy wrote:
Sat Apr 30, 2022 1:55 pm
Thanks for explaining what you meant. The word lazy is what threw me in thinking you should not use volatile at all.
For instance you have two threads. One thread is handling the LCD screen & user inputs. The other thread is reading a A/D converter via SPI, and updating a volatile variable on what was read so the LCD task can use that variable to throw it up on the LCD.
In your example to use a volatile variable to be used as a signal event....ya that would not be a "lazy" way of doing it.

I agree that its not the best approach to use a variable in the way you shown. I thought
Note that the concept of checking a variable in a loop to check if some event happened is 'lazy but OK'. However, using volatile generally is not. Note in your example, you would not have to use a volatile, as the LCD task presumably calls other functions in between checking that variable. Those functions function as compiler barriers, forcing the compiler to read the actual value of the variable instead. In other words: no volatile needed to force that.

What you would want there is an *atomic* variable (if the value is 32 bits or less) or muxes around setting/reading the value (if the value is stored in e.g. a struct) to stop the reader task from reading a 'half-written' variable. (Given the architecture of ESP32 chips is simple, ints and other 32-bit values are atomic by nature, so you can get away by simply using one of those. Do note that technically that is not portable as other architectures may not be atomic on that level.) Given that you use atomics (either explicitly or not caring about portability and making sure the variable is something the ESP can handle atomically) or proper muxing, and you're not running the loop simply to check if the sensor value has changed and nothing else, there's nothing wrong with this technique.

Who is online

Users browsing this forum: arunbm123 and 92 guests