Anything that is global or static will get referenced by all tasks.
That is, there is only one copy of the variable, so anything that reads
or manipulates the variable will be reading/manipulating the same
variable. In your case you used a semaphore to ensure the only one task
accesses the variables at a time, but you are not checking the return
value of the semaphore before you access the variable. To use a
semaphore you would need to check the ‘take’ function’s return value
then only access the variable if the return value indicated the ‘take’
was successful.
If you are just accessing variables like this then it would be much more
efficient to use a critical section than a semaphore. The critical
region would only be a few assembly instructions.