 Let's have a closer look at binary semaphores implemented within 3R2s, using CMC's OS V2. Here we can see an illustration of binary semaphore usage. There are two tasks, task 1 and task 2 on equal priorities. The task 1 is releasing the semaphore while task 2 is waiting for it, being in a blocked state. As soon as task 1 releases the semaphore, task 2 is taking it, so in fact scheduler moves it from blocked to ready or run state. And then task 2 is continuing its operation still next call for semaphore. Please notice that there is no blocking mechanism for the task which is releasing the semaphore. So even the semaphore is already given released, we cannot wait and give the semaphore after it, it will be taken. It is a bit different than we could see it within queues, where both transmitter and receiver can be blocked by the queue. Let's have a look on semaphore parameters. Start within CMC's semaphore ATTR underscore T structure. We have to fill it partially within the semaphore creation, but at the time we are specifying only the name of the semaphore. The rest of the fields, which you can see now on the screen, are filled within the semaphore creation during the process. So it's quite invisible for us, but it's good to know what is stored over there and where to find the main information about the semaphore itself. So here, a part of the name, we can see the attribute bits, we can see the pointer to semaphore control block memory area, and we can see as well the semaphore control block size. So as you can see, there is no other component, I mean the memory component, because the semaphore is not storing anything on the stack apart of its control block. So it's much more simplified, but it's worth to know where is the pointer to this control block of the semaphore and size. The structure itself is defined within CMC's underscore OS2.h file, where you can find more details about this component. Let's have a closer look how the semaphore is created within CMC's OSv2. So to create the semaphore, like with the other components, we need to start from the setting the attributes for the semaphore. So filling the structure of OS semaphore attr underscore t type. In our case, we are specifying only the name. It is visible as well within stm32cubemix and qpiDE that the only component within binary semaphore creation is its name. Then we are creating the semaphore using the function ossemaphore new, and as a first argument, we are defining the maximum number of tokens, which would be held by the semaphore. For binary semaphore, we are specifying one. For the counting semaphore, which we will describe a bit later on, we should specify the maximum number of tokens, which would be available within the semaphore. Then the second argument is an initial counting. Usually it is zero, so the semaphore is not released, not available at the beginning. So zero is a good choice. And the third point is the pointer to the structure of the attributes for the semaphore. So, for example, with its name. And as a return a value of this function, we are receiving the handler to the semaphore, which can be used later on to, for example, deleting it once it is not needed anymore within the application to save some memory. So to delete the semaphore, we need to use the function ossemaphore delete as an argument. We need to specify the semaphore handler. And we should monitor as well the return status, whether it is zero, which means os okay. So the removal of the semaphore was successful. So those are the main two components to create and to delete the binary semaphore. Similar functions we will see within counting semaphores, because the only difference would be this maximum number of token, which is specified within the semaphore new function. Other functions for semaphores are common for binary and counting ones. To wait for semaphore, we should use ossemaphore acquire function with two arguments. Semaphore handler and timeout in milliseconds, telling the scheduler how long we would like to wait for the semaphore. Wait means being in a blocked state. If the semaphore is not available, the task is sent to blocked state for a maximum timeout time. If in the meantime semaphore became available, task is unblocked and can continue its operations. In such a case, return value is zero, which means os okay. It is one of the values of os status underscore t, type def, which has been described within CMC's os section on this training. Otherwise, in case the semaphore is not available, the task remains in a blocked state for complete timeout time and it's unblocked at the end. In this case, the return value is os timeout and it is a negative value. So it is quite easy to detect whether the semaphore has been taken or not. For more details, you can refer to os status underscore t description within CMC's underscore os section in this training. To release the semaphore, we should use ossemaphore release function with semaphore handler as an only argument. Both functions return os status underscore t type value. So means mean successful execution and any negative value means error. Thank you for watching this video.