FreeRTOS Tutorial #7 -> Using MUTEX
There is no tutorial #6, and after no #5 we have #7 directly.
Mutex, which is short for Mutual Exclusion, does what’s it name indicates. It prevents several tasks from accessing a resource mutually. It ensures that at one time, only one task have access to the resource.
In this tutorial, we will see how to use mutex. And I will also explain the difference between a mutex and a binary semaphore. Also we will learn about priority inversion and priority inheritance.
- In the code above, I have created a mutex handler (SimpleMutex), two task handlers, and defined the task functions.
- Along with that, there is a function (Send_Uart), which will acquire the mutex first, waits for 2 seconds, sends the data to the UART, and releases the mutex.
Now, let’s write the Task Function
Above are the functions for two tasks. Both of them will make a call to the function, Send_Uart. Now we have to see, can the High Priority Task (HPT) preempt the Medium Priority Task (MPT) while the MPT holds the MUTEX.
We will write the following into the Main Function
We have created the MUTEX, along with two tasks with different priority. And at last, the scheduler will start.
Let’s see the output of the above program.
This was a very simple operation of mutex. And this is exactly what a binary semaphore does too. That’s why we will go a little more deep, and see what’s the difference between the two.
For this purpose, I will make some changes in the code again.
This time I have defined a handler for the binary semaphore also (BinSemaphore). Also all the three tasks are being used now.
let’s write the Task Function now
As you can see above, the HPT, and the LPT will call the function Send_Uart, so they will require the semaphore. But MPT will run independently without any need for the semaphore.
Let’s write the Main Function now
Both the mutex and semaphore were created along with three tasks of different priorities. And at last, the scheduler will start.
Let’s see the output of the above
You can see in the above pictures, the MPT can preempt the LPT, and therefore it delays the execution of the HPT also.
HPT even being the Highest priority Task, have to wait for the MPT to finish. This scenario is termed as PRIORITY INVERSION
Now let’s see how can we use mutex to avoid it.
I will just make a very small change in the code
In the Send_Uart function, instead of taking the semaphore, now we will take the mutex. The rest of the code will remain exactly as it is.
Let’s see the output now
- As shown above, when the LPT have the Mutex and HPT tries to preempt it, the priority of LPT rises to that of the HPT.
- This is called PRIORITY INHERITANCE as LPT inherits the priority of the highest priority task, that is waiting for the mutex. And in this case that is HPT.
- Now the MPT can not preempt LPT, because the priority of LPT is HIGHER than MPT and the execution goes as planned.