 Hello, in this part we will focus on free RTOS implementation of Mutexes. Mutex is binary semaphore that includes so-called priority inheritance mechanism, which will be described a bit later on. Binary semaphore is better choice for implementing synchronization between the tasks or between the tasks and interrupts, while Mutex is a better choice for implementing simple mutable exclusion. It can be useful to manage on access to short resources to be sure that we do not have any conflicts while accessing, for example, disk drive or a display by multiple tasks. When used for mutable exclusion, the Mutex acts like a token that can be used to guard a resource. When a task wishes to access the resource, it must first obtain so-called take, the token. When it has finished with the resource, it must give back the token, allowing other tasks to access the same resource. Important point here. Task, which took the Mutex, must give it back. Mutex cannot be returned to released by other OS component. In case of recursive Mutex, it should be given as many times as it was successfully taken, like counting semaphores, to release it for another tasks. Mutexes use the same access API functions as semaphores. The block time indicates the maximum number of ticks that a task should enter the blocked state when attempting to take the Mutex if the Mutex is not available immediately. Unlike binary semaphores, Mutexes employ priority inheritance. This means that if a higher priority task is blocked while attempting to obtain the Mutex token that is currently held by lower priority task than the priority of the task, holding the token is temporarily raised to that of the blocked task. It is managed, of course, by the scheduler. Thus, a task must not be deleted while it is controlling the Mutex. Otherwise, the Mutex resource will be locked out of all other tasks. The information about the Mutex hold by the task are stored within a task control block fields. This is why, while you enable the Mutex functionality with an operating system, please remember that the task control block size will be increased for each of the tasks immediately. Another difference versus binary semaphores is that Mutex management functions cannot be called from interrupts. Let's have a closer look at some terms related to semaphores and Mutexes. First one is priority inversion. This term describes the situation where a task with higher priority is waiting for a lower priority task to give a control of the operating system component, like give a semaphore or send data to the queue, and the low priority task is not able to execute. In such a case, it is important to set the priorities of the tasks carefully or use timeouts and monitor return values of the functions which are trying to get an access to the resource. Second term is priority inheritance. It is an answer to the previous problem. It is implemented within Mutexes. How does it work? It is temporarily rising the priority of the Mutex holder to that of the highest priority task that is attempting to obtain the same Mutex. The low priority task that holds the Mutex inherits the priority of the task waiting for the Mutex. The priority of the Mutex holder is reset automatically to its original value when it gives the Mutex back. We should remember that it is complicating system timing analysis, and it is not a good practice to rely on it for a correct system operations. Thus, it is better to set wisely priority levels to tasks and monitor OS titles underscore T type return values on all attempts to access the resources, like queues, semaphores or Mutexes. The third term effect we may face while working on queues, semaphores is a deadlock called deadly embrace. It occurs when two tasks cannot work because they are both waiting for resources held by each other. The best way to avoid the deadlock is to consider them at the design time and design the system to be sure that the deadlock cannot occur. Here again, we can use as well the finite timeouts within functions that which are accessing the resources and monitor return OS status underscore T values. In case we are using OS wait forever, we will be stuck within the code. In general, Mutexes works very similar to semaphores. We are using them usually to guard and access to shared resources like memory buffers or some communication interfaces to be sure that the only task has an access to them at the moment. Let's have a look how we can use the Mutex in practice. On this picture, we can see two tasks, task one and task two having the same priority. There is as well a shared resource, it can be for example memory buffer and a Mutex. Mutex gives us an access to this shared resource. Both tasks are requesting an access to the resource. First task to be executed is task one and within its code it takes a Mutex. It allows to this task execute the next instruction which could be right to shared memory which is the shared resource. Within this time task two is in blocked state and is waiting for the Mutex taken already by task one. After task one will do its job, so let's for example write something to the memory, it releases the Mutex that unblocks task two. Task two is taking the Mutex and is performing its operations on shared memory as well. After this, it must release the Mutex to make it available to other tasks. Important message here is that the Mutex must be released by the same task which took it. Let's have a look at a complete list of Mutex attributes. All of them are grouped with an OS Mutex ATTR underscore t structure defined within cmcs underscore OS 2.h file. Developer is specifying only the name of the Mutex, it is the only element to be specified within stm32cubemix and stm32cubede within Mutex creation process. The rest of the fields are filled automatically during Mutex creation with pointer to Mutex control block and its size on top. Now let's have a look at cmcs OS V2 API functions which are related to Mutexes. First of all, to start using Mutexes within our application, we need to enable them within freer2sconfig.h file. It is done by defining config useMutexes. Please remember that enabling Mutexes increases automatically task control block size of each task within our application. Mutex creation is very similar to other operating system components. At the beginning we need to specify attributes of it. The only attribute on developer shoulders is the name of the Mutex. Rest of them are filled automatically within Mutex creation function. To create a Mutex, we are using OS Mutex new function. It accepts only one argument which is the pointer to attribute structure. As a result value, we will have a handler to the Mutex. In case there is zero instead, it means that there was a problem during creation of the Mutex, most probably issues with a memory allocation. Wait for the Mutex release is done by OS Mutex acquire function. It accepts two arguments. First one is a handler to the Mutex and the second one is a maximum timeout. Our task will wait for it. Once the function is called, task is sent to block state waiting for the requested Mutex. In case Mutex is free, it is assigned to the task within its tcb so task control block dedicated fields and function returns with osok value which is zero. In this case Mutex is not accessible and the specified timeout elapses. The task is back from block state and function returns a negative value. In such a case Mutex is not assigned to the task so this is important to monitor the return value of this function. Detailed information about possible return values of os status underscore t which is return value of this os Mutex acquire you can find within cmc's underscore os API section within this session. Mutex release is done by os Mutex release function. Its only argument is a handler to the Mutex. This function returns as well os status underscore t value which informs us whether the operation was successful means zero or not any negative value. Let's have a quick view on available functions across different APIs. Mutexes are supported by all three APIs so 3R2OS, cmcOS version 1 and cmcOS in version 2. Important message here is a change in naming convention which has been introduced in cmcOS version 2. So instead of create there is a new instead of wait there is an acquire. Additionally we can see two new functions introduced in cmcOS version 2 concerning gothic information about the Mutex. Thank you for watching this video.