 SEMIFORCE. Next group of operating system components are SEMIFORCE. SEMIFORCE are used to synchronize tasks with each other and with other events like interrupts. Waiting for SEMIFORCE is equal to wait procedure when the task is in a blocked state and it's not taken into the consideration by the scheduler till the SEMIFORCE, which is requested by the task, is released. SEMIFORCE should be created before usage, like we have seen already, within kills and tasks. In freeer-to-less implementation, SEMIFORCE are based on Q-mechanism. In fact, those SEMIFORCE are kills with length 1 and data size 0. There are following types of SEMIFORCE within freeer-to-less implementation. The most popular one are binary SEMIFORCE, which are based on simple on-off mechanism. Then we've got a counting SEMIFORCE, which counts multiple GIF and multiple take events. Then we've got a special type of the SEMIFORCE, which would be described separately. Those are Mutexes, Mutual Exclusion type SEMIFORCE, and we've got as well Recursive SEMIFORCE, which are implemented within CMC's OS as Mutexes as well. To turn on the SEMIFORCE, we need to give it from the function from other task or interrupt subroutine, and turn off SEMIFORCE means that we are taking the SEMIFORCE, which can be done from the other task. Let's focus on two most popular types of the SEMIFORCE, so binary and counting. On the left side, on the screen, we can see an illustration of a binary SEMIFORCE and its cooperation with other components of the operating system. So let's take an example that we've got Task A and interrupt IORQ1, which can give us the SEMIFORCE, which can release the SEMIFORCE, and we've got two tasks, Task C and Task D, which are waiting for the SEMIFORCE. So they are waiting, being in a blocked state. So in the second picture on the left side, we can see in the situation that Task A is giving the SEMIFORCE. So within CMC's OSV2 there is a dedicated function to it OS SEMIFORCE, release. After this operation, the SEMIFORCE is available. One of the tasks which are waiting for this SEMIFORCE, so either C or D, can take it. Only one can take it, because it is a binary SEMIFORCE, so once the SEMIFORCE is given, it can be taken once as well. So on the third picture, we can see the situation the Task C is taking the SEMIFORCE. There is a dedicated function OS SEMIFORCE Acquire within CMC's OSV2, and after taking this SEMIFORCE, this task is taken as well from blocked state into the ready state. We can see as well that Task D is still blocked waiting for the SEMIFORCE, because as I told you, the binary SEMIFORCE can be taken only once. So in case we've got multiple tasks waiting for the binary SEMIFORCE, the scheduler is sorting them according to the priority, and the highest priority task is selected to take the active SEMIFORCE, which is waiting for. In case we've got two tasks with the same priority, the SEMIFORCE will be taken by the task, which is waiting longer time for the SEMIFORCE. On the right side of the screen, we can see the situation, we can see the illustration of how the counting SEMIFORCE are working. So in this case is the similar situation, so Task A and interrupt IRQ1 can possibly give us the SEMIFORCE, and they both are giving the SEMIFORCE at the same time, or more or less the same time. We can see that there is an internal number within the SEMIFORCE, it's increased to 2. By the way, we are specifying this maximum number within the counting SEMIFORCE during its creation. So how many time it can be given and then taken by the other tasks. So in this case, we've got two components, Task A and IRQ1, which can give us the SEMIFORCE, and they are doing it. So the SEMIFORCE on the second picture on the right side can be taken two times. So in this case, it's ideal situation for both tasks, which are waiting for it, so Task D and Task C, and we can see on the third and fourth picture that first Task D is acquiring the SEMIFORCE, so we can see that the counter of the SEMIFORCE is decreased by one, and then on the fourth picture we can see that Task D is acquiring the remaining SEMIFORCE from this binary SEMIFORCE, and then the counter is zero, so it cannot be taken anymore till it will be released or given by Task A or IRQ1. So this is the difference between the binary and counting SEMIFORCE, and in the next section of this training we will focus separately on binary SEMIFORCE and we'll perform some hands-on exercise, and then we will illustrate how we should work with counting SEMIFORCE as well. Before we will go into details with SEMIFORCE, Binary and Counting, let me highlight the differences which are available across the different APIs. Here on the table we can see CMC's OS API in version 1, then in the middle CMC's OS API in version 2, which we are currently using within this session, and original 3-year OS API on the right side of the table. It is important to mention because there are, let's say, huge differences between CMC's OS API in version 1 and version 2. Especially on a creation, process creation of the SEMIFORCE, so SEMIFORCE Create has been replaced with OS SEMIFORCE New, and OS SEMIFORCE Wait has been replaced with OS SEMIFORCE Acquire. It is important as if by mistake we will select a different function, we are able to because within our project which is generated by CubeMix or Cube IDE, we've got availability to use both of the APIs. So CMC's OS V1 and CMC's OS V2. So please be careful once you are selecting the functions which we are using during your development to select the proper one. It is extremely important, especially within the SEMIFORCE and the QS, where the differences are quite big and are as well important due to the return values which are different, especially within the QS APIs. Thank you for watching this video.