Best practices for exchanging variables between tasks

tomfrance
Posts: 12
Joined: Wed Mar 17, 2021 3:50 pm

Best practices for exchanging variables between tasks

Postby tomfrance » Thu Apr 01, 2021 7:54 am

Hello team!

I have a question concerning some best practices regarding data sharing between different tasks on the ESP32. My current (abstract) setup is described in the following and it works as expected, but I would highly appreciate your input regarding best practices, e.g., to avoid race conditions or undefined states when different tasks operate on the same data:

main.c:
- Declare global struct A with members B and C (again structs) and initialize them via corresponding macros:

Code: Select all

struct A {
struct B;
struct C;
};
INIT_B(A.B);
INIT_C(A.C);
- Setting up networking and event loop
- Starting webserver
- Setting the user_ctx of some httpd_uri_t variables, e.g.:

Code: Select all

uri_siteA.user_ctx = &(A.B);
uri_siteB.user_ctx = &(A.C);
- Start of FreeRTOS Tasks for SPI communication and pass pointer to struct A to xTaskCreate, such that the code in the task can access its members B, C for read and write operations.

webserver.h
- Declare httpd_uri_t Variables, set those that are also modified in main.c as "extern" (e.g., uri_siteA, uri_siteB).

webserver.c:
- Actual webserver code with corresponding GET and POST handlers
- Generate JSON from user_ctx, i.e., from A.B and serve upon GET request.
- Read received JSON and set values in A.C via provided user_ctx pointer upon POST request.

task.c:
- Init SPI bus and create while(1) loop that does the SPI transmission by filling receive and send buffers based on the the passed reference to struct A.

What do you think about this setup? Does it make sense to you? What can be done to avoid race conditions? Should I use something like binary semaphores or mutexes to ensure that only one task accesses struct A at the same time?

Best, Tom

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

Re: Best practices for exchanging variables between tasks

Postby ESP_Sprite » Fri Apr 02, 2021 1:51 am

Yeah, you're going to need mutexes there. The most important consideration is to look at what happens when a writer is halfway through writing (parts of) a struct, while a reader is reading from it. If that can cause an issue, you need some way to stop that from happening. As there doesn't seem to be much contention in your use case, mutexes probably are the easiest way to do it.

Who is online

Users browsing this forum: No registered users and 312 guests