 Hello, in this part I would like to demonstrate to you the difference between Mutex and Binary Semaphore. So within this part we will create a simple example with three tasks, one Mutex and one Binary Semaphore and we will check what is the difference between the behavior once we are using Mutex and the Binary Semaphore. Let's start with the creation of our components. So I'm starting with when STM32QPIDE, you can use as well QBMX, I start a new project, so file new STM32 project. My choice is STM32L476MG, which is located on the NucleoL476MG board which I'm using for this, within this training. The name of my project would be 10 underscore Mutex underscore SEM, so Mutex and Semaphore, I click finish. Okay, so from hardware point of view we would, we need only the debug interface of additional single wire viewer line, so a single wire output line, sorry. Still I'm selecting within debug the last option, to have those three lines SWD and SWO line. Time-based source I need to change from SysTick to Timer 6, it is used for HAL libraries to specify timeouts and delays, as SysTick is used by the operating system, we will change something different for HAL library. Then within middle-verse I'm selecting the 3R toys with interface CMCs version 2. Within 3R toys I'm checking whether Mutex is enabled, it's okay. Then I need to add three tasks, I would rename the default task by double-clicking on its name to task 1, I would specify the priority to normal, stack size 256 words and start task 1 as entry function. Then within the same tab, so task and queues I would add two more tasks, so task 2, the same priority, 256 words, start task 2 as entry function, I already made a mistake at the beginning, so it should be start task 1 and start task 1, and I would rename this. Okay, and we need the third one, ask 3, priority normal, 156 words, start task 3 as entry function. Okay, we will enable as well the Mutex like before, so Mutex is tab, Mutex is part, click add, I would use the default settings here, and I would need as well the semaphore, so I go to timers and semaphores tab, and within binary semaphores sections I click on add, and I would keep as well the default settings here. I can see that in the meantime I'm exceeding the specified heap size for the free R2S, so I need to extend it within config parameters from 3000 bytes to 4000, and now it is okay. Okay, so that's all for let's say cubemix part, let's see the configuration part, I can generate the code. Okay, my code is generated, main.c file is opened, if not you can find it within core source main.c, next point would be the modification of the source file to add necessary code. Okay, now we can continue with the code modification, so I opened main.c file, and within this main.c file if we scroll down we can see all the definitions of the handlers, so the task handlers, free tasks, then Mutex and binary semaphore, if I go below I can see as well the creation of the Mutex first, then binary semaphore and free tasks. So let's go to our code, we will start from task 2, as this task will continue quite similar operations like previous exercises, so in general task 2 and task 1 will share the same Mutex we just created, task 3 will continuously work without any say connection to this Mutex. So let me start from task 3 implementation, so first I would let's say send some sign of life, I'm using function task action in my implementation which you will see a bit later, I'm using ITM interface which is using single wire output pin which I selected during configuration of the debug interface at the beginning. I would like to send free over this interface, it will be visible within the console of instrumentation trace macrosal during debug session. After this I would like to keep this task active for 500 milliseconds, intentionally doing this using how delay instead of os delay due to the fact that os delay would let's say send my task to the blocked one, which I don't want to. I would like to have this task free as other tasks as long as possible with an either ready or run state. So this is a task free and let's say the implementations of both other tasks. Task 2 implementation would be the following. First I will try to collect the mutex, so os mutex acquire. This is my mutex and the timeout. For timeout I would use os wait forever, resummit control space forever, then once I will get the mutex I would like to send my sign of life. This is task 2 so it will be number 2 and I would release this mutex, control space and this mutex. After this I will keep this task busy for half a second. So again I would use how delay 500. And that's it. So similar code I would like to use within my task number 1 but there would be a big difference. This difference I will locate here and within my task 1 I will do the following modification. I would like to keep the execution like for task 2 for first 3 iterations and then I will decrease the priority of task 1 while I would still keep the mutex. I will do it to demonstrate that we've got a built-in mechanism within mutexes which would temporarily increase the priority of task 1 just to allow the release of the hold mutex. The next part of this exercise will replace mutex with the semaphore and would repeat the same example and you will see that semaphore will block our tasks. Task 1 and task 2 in the similar situation. So let me implement a local variable it will be 8 bit 1 idx equal to 0 and then here we will do 3 idx and here we will let's say set priority we need to change the priority of task 1 and the priority will be os priority low which is much lower than used one. After this I will just increase idx. So this is all code except of our task action. So task action this is my example of course you can use your own implementation using for example UART or if you have more LEDs you can turn on some particular LED. I got only one this is why I need to select something more sophisticated. So I'm using instrumentation trace macro cell for this. So ITM send chart to send single character and then I would send as well sign of new line just to be sure that all of the information coming from the tasks are located in separate lines. Okay I need to locate the prototype the good place for it is this one private function prototypes and that's it our code is ready I'm building it and soon I will start a debug session. I can see no errors no warning we can start the debug session. Okay my board is already connected I'm starting a debug session so I'm clicking this bug icon I would use this SWV ATM data console in case you do not see it you can select it using this quick access by pressing this SWV and you can select this line with the icon monitor here. Once done you can check whether it is properly configured so this zero stimulus port selected and please start trace after this we can play start display button let me pause and let's have a look what is happening I would try to display as well our code so at the beginning we can see that task three has been let's say selected by the scheduler then task two and task one then task three task two task one task three two one three two one okay so we can see one two three four four sequences like this you after let's say four occurrence of this sign of life from task one we are on this level on this on this line so the let's say priority of task one has been decreased to always priority low so as you can see below we cannot see any sign of life of this of this task anymore but please have a look that in this place if we execute function like this scheduler would immediately switch our task to another other task with higher priority so either task two or task one and in our case it was task three and in this case if it will be not let's say the mutex what we will check in a minute we will have the mutex hold within this task and not available anymore for task two but as mutexes have the let's say the priority inheritance mechanism scheduler increased temporarily the let's say the priority of this task to allow it let's say release of this of this mutex and then it it was let's say available for task two and from this moment we can see execution only for let's say task two and task three task two is let's say acquiring and then releasing the mutex while task task three is just executing the code so those two tasks task two and three are selected one by one by the scheduler so it is as expected in next exercise I would replace the mutex with the binary semaphore which just let's say created at the beginning and we will see the difference so let's let's pause for a while okay so let's come back to our code and let's focus on those two tasks task one and task two so instead of the mutex I would use let's say the semaphore functions os semaphore acquire and in our case it is this binary semaphore and I would use exactly the same so os wait forever argument okay I will comment out this mutex and after the operation I will release my semaphore os semaphore release and this is our semaphore okay and we need to comment this mutex operation and again the same the same here so I would just copy paste so first acquire of the mutex and then release sorry not not the mutex this time but the semaphore I would sorry just not to let's not to lose the code I'll copy those lines as well so we've got only semaphores semaphore I let me double check it's at the beginning not taken the zero we can build a code and track what is the difference so I'm building it to check whether everything is correct perfect we are ready to start a debug session before we will start our debug session we need to do one more modification in this particular example we will use semaphores bit different way than we have done it already in a binary section please have a look that both tasks task one and task two are waiting at the beginning for the semaphore and there is no other let's say component which would give it at the beginning so the best way here in this particular example is to set it up let's say the semaphore at the beginning two let's say to be to be ready to be taken and then the first task will take it and then after its action it will release it so let's let's try it once again so I'm building the application no errors no warning and I will now try to start a debug session so I press the back icon I switch to SWV ITM data console which is already configured state start tracing and start my application I can see let's say it's executing now I can pause it please have a look first for let's say times I've got all three tasks three to one three to one three to one three to one this is the fourth sequence so let's come back to the code this is this location of task one we are after this line and we are let's say decreasing the priority of task one and please have a look that this task is holding already the semaphore this time and it's lowering the priority so scheduler is removing this task from ready state to from run state to ready state and it will now select tasks to be executed from task two and task three task two in fact is waiting for the semaphore which is held by in the low priority task one so the only candidate to be executed is task three both tasks task two and task one are in a blocked state forever so as you can see there is a big difference between semaphores and mutexes mutexes are much more safer but what is really important here is that once you take the mutex you need to give it back so the task which let's say took the mutex it must be let's say the one which will let's say give it back okay so that's all for this section for this part thank you for watching this video