How can I protect global variable that both task and UART ISR perform read/write operations on this variable ?
Can I use mutex to protect this global variable ?
Mutexes can’t protect from stuff accessed by ISR. That needs a critical section, which you need to keep small. If the variable(s) can be updated/read “atomically”, then they might not need protection. If it is several variable with related values, you may need the critical section.
These are key design decisions, and need to be done carefully. Often, if you are careful in what you do in the ISR, you can eliminate most of these contentions. Normally the ISR should be doing “minimal” work, and then deferring the rest to a task. (Minimal gets by what can’t be deferred to a task and still meet timing requirements)
Also note that “mutual exclusion” between isrs and tasks is inherently asymmetric: As long as an isr executes, no task can execute, thus, no additional measures need to be taken on the isr’s side to ensure atomic access (it is implied), whereas a task’s only option to protect its shared resource is to explicitly prevent the competing isr from running altogether, even if the isr spends only a few cycles accessing the variable.
As has been discussed before, the critical section is the nuclear warhead of synchronization since claiming it effectively stalls the entire OS. So if you have an option to only “surgically” disabling the competing isr (eg on the device level), that is the preferred solution.
You do need to be careful about “surgical” disabling of interrupts, as the task that does this might get preempted by a higher priority task, and the “surgical” disabling made longer than first expected.
Full critical sections, prevent the preemption, so will always be the length expected, and if can be kept very short, work quite well. That is the key, the length must be well bounded and acceptably short (which is application dependent)
My normal guideline is just a couple of lines of code with no loops or function calls. (Breaking the guideline allowed if given due consideration of the actual timing)
Global variables are the evil; a global variable that can be updated in both, inside an ISR and in the secuential program flow, is even worst.
1.- You might find a way of avoiding the use of global variables.
2.- You might want to put off the variable updating action from the ISR to a task level. Then you can safely use mutexes or monitors.
3.- Look for some FreeRTOS mechanisms for sharing information: notifications, messages, queues (of length 1), etc.