3 tasks and external functions

I have 3 tasks that access the same external function with a static value, one works the others come back 0.

Task1
{
...
setConfig(UartValue);
...
Config=getConfig();
... 
}
Task2
{
...
Config=getConfig();
... 
}
Task3
{
...
Config=getConfig();
... 
}

External code:

static uint8_t Config=FORMAT_NONE;
void setConfig(uint8_t format)
{ Config=format; }
uint8_t getConfig(void)
{ return Config;}

Task1 sets Config to FORMAT_2
Later Task2 calls getConfig(); and gets a 0
Later Task3 calls getConfig(); and gets a 0
Is this because each task has their own copy of the static Config?
How do I make static Config to only have 1 copy that they can all access?
Or am I not understanding the problem and could you explain to a newbie?

It’s likely a C language issue and not related to tasks / FreeRTOS.
You get a single instance of the static variable when defined in a single C file.
If the External code is in a header file and get’s included by multiple C files there will be an instance of the static variable per C file.
Try to comment out static and rebuild. You should get ‘multiple definition’ errors by the linker of that now global variable if this assumption is right.

The header only contains function names. The .c file contains the “static” and the function definitions. I put hard-coded buffers before and after the static Config. Every time getConfig() is called I display pieces of the before & after buffer and Config. The buffers do not change, but the other tasks see FORMAT_NONE. I’ll try a big value to indicate “FORMAT_INVALID” and assign that to Config as the initial value. If (FORMAT_INVALID == Config) setConfig(FORMAT_NONE); Maybe that will help it to decide that there is only 1 Config.

Strange… that should be ok.
static is static as defined by the C language. It’s not managed by FreeRTOS in any way.

Drat. I was hoping it was my ignorance of the inner workings of FreeRTOS. I’m finding all the occurrences of getConfig() and verifying that it comes in as INVALID and setting it to NONE. Hopefully the Task1 setConfig(2) works for all tasks.

Did your task one get a chance to run and set the value? You can put a breakpoint in after setting and examine the value.

Next, after setting, if you still get zero in task2 or 3, you can put a data breakpoint to see where Config gets changed.

Thanks.

I initialized static Config to INVALID (0x80). Looked OK first time through. Restarted the Uart feed. Task1 said setting 2 to 2. Good. Task2 was happy with finding 2. But Task3 says it is 128 and set it to NONE. Task3 looks like the culprit, but it never calls setConfig() until after it finds Config == INVALID and calls setConfig(NONE). Then all of the other tasks are happy to work with NONE. I guess my problem is in Task3 and I need to find out how it burns a new Config.
Thanks for the pointer.

Hmm … getting and setting the same static or global variable from multiple tasks might fail.
You’d need e.g. mutex protection when doing read-modify-writes of shared data or any other shared resource.

True. Theoretically Task1 with the “setConfig(UartValue);” should be the only one doing so. However, I needed to find out who was changing static Config back to its initial value while things are running. The UartValue comes from an external processor and a restart of that should have no effect on Config. Task1 works as expected and so does Task2. But how does Task3 screw Config up?

FreeRTOS is just C code that builds with the rest of your C code. It cannot change how the compiler or linker works. How ‘static’ works, or is supposed to work, is defined by the C standard. Which compiler are you using?

You could to set a breakpoint at setConfig and check pxCurrentTCB which task is currently running to get an idea…

Atmel Studios for the SAM E70.

I’ll check with pxCurrentTCB.

Sounds to me like task3 is doing the get before task1 does the set. What are you doing to prevent that?