Arduino ESP32 FreeRTOS: Function to enclose shared variable assignment within critical section

andre_luis

Super Moderator
Staff member
Joined
Nov 7, 2006
Messages
9,646
Helped
1,191
Reputation
2,401
Reaction score
1,219
Trophy points
1,403
Location
Brazil
Activity points
55,955
Hi there,

I'm refactoring a program that deals with a lot of variables being asynchronously shared among different Tasks.
This is done enclosing them with spinlocks functions this way:

C++:
portENTER_CRITICAL(mux);
SharedVariable1 = value1;
// ...
SharedVariableN = valueN;
portEXIT_CRITICAL(mux);

So far so good, but there are a lot of those constructs spread in the code, most of them to protect a single assignment.

I was considering to create a function to do that, and this is the first thing that came to mind:

C++:
void ProtectedAssignStrVar ( const String origin,
                          String &destination,
                          portMUX_TYPE *mux )
{
    portENTER_CRITICAL(mux);
    destination = origin;
    portEXIT_CRITICAL(mux);
}
...which should be used this way:
C++:
String ValueOrigin = "Example";
String VariableDestinationShared;
ProtectedAssignStr( sharedOrigin,
                    sharedDestination,
                    muxSolenoid )
The problem here is that I fear this wont work because something tells me that the capture of the value in the function argument will take place before entering the safe section itself.

Ok, one could suggest to create a function containing all these global variables within, assigning their value upon a switch...case selector, but I would like to avoid creating more supporting structures that could make the program less intelligible.

So could you give your insights on this, if there is any other alternative ?
( maybe...by using funtion pointer, whatever )
 

Rather, a function pointer; I built this code, adapted from an example took elsewhere. It essentially allows calling some function, enclosed by portxxxxx_CRITICAL functions, where the function in the argument is a general assignment function allowing any value and destination variable.

I'm not sure if this will work (at least, compiled fine), seems promising; next step...define a strategy to debug if it really work ( e.g forcebly not exiting here and there ). Something still tells me that the issue of the ( shared variable ) argument being read before entering into the critical section persists.


Code C++ - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
typedef                 void ( *CallbackFunction )( void*, void* );
String origin = "Test";
String destination;
 
void ProtectedAssignCallback( CallbackFunction callbackArg,
                              void* destination,
                              void* value,
                              portMUX_TYPE *mux
                              )
    {
    portENTER_CRITICAL(mux);
    callbackArg(destination, value);
    portEXIT_CRITICAL(mux);
    }
void SharedVarAssignmentStr(void* destination, void* value) {
    String* destinationPtr  = static_cast<String*>(destination);
    String* valuePtr        = static_cast<String*>(value);
    *destinationPtr         = *valuePtr;
    }
ProtectedAssignCallback(  (CallbackFunction)SharedVarAssignmentStr,
                                    &destination,
                                    &originStr,
                                    &mux
                                    );

 

Cookies are required to use this site. You must accept them to continue using the site. Learn more…