 Let's have a closer look on accounting semaphores, which are implemented within freeRTest. Counting semaphore can be seen as a queue of length greater than one. Users of semaphore, so tasks, interrupts are not interested in the data that is stored in the queue, but just whether the queue is empty or not. Before its usage, counting semaphore should be enabled within freeRTest config.h file by defining config.use.counting.semaphore. Counting semaphores are typically used for two purposes. The first one is counting events. An event handler can give a semaphore each time an event occurs by incrementing the semaphore count value. And the handler task will take a semaphore each time it processes an event and decrement the semaphore count value. In this case it is important to set the count value to 0 when the semaphore is created. The second purpose is resource management. The count value indicates the number of resources available. To obtain control of the resource, task must first obtain a semaphore and decrement the semaphore count value. When the count value within the semaphore reaches 0, means that there are no free resources left. So when the task finishes with the resource usage, it releases, it gives a semaphore back, incrementing the semaphore count value. In this case, it is important to set the count value to the maximum count value when the semaphore is created to inform the other components, the tasks, about the maximum number of available resources. Here is an example of counting semaphore usage. Let's assume that we have three tasks on the same priority and single counting semaphore with maximum value specified to 2. At the beginning, task 1 is giving a semaphore, then just after task 2 is giving the semaphore. After this, task 3 is taking semaphore two times in a row. When counting semaphores, we do not have control who will take the semaphore. Scheduler is selecting the task from the list of waiting ones based on the priority, higher priority first, and in case of equal priorities, the task which is waiting longer time is selected first. Let's have a look at CMC's OS V2 API dedicated to counting semaphores. To create a binary or counting semaphore, we need to fill partially its attribute structure, OS semaphore ATTR underscore T type. In fact, it is necessary to specify only the semaphore name. The rest of the fields are filled automatically during the semaphore creation, and those are the semaphore control block and its size and its start address. Then we can create the semaphore using OS semaphore new function. This is the same function which is used for binary semaphore creation. This function needs three arguments. The first one is a maximum number of tokens. In case of binary, it will be one. Then initial number of ready tokens. In case of counting semaphores, it can be either let the maximum value we would like to specify, in case the semaphore name will be used to guard the chart resources, or it will start from zero in case of other usage. Then the third argument is a pointer to the structure of attributes or null in case we would like to use the default values. This creation function will return the semaphore handler or zero in case of error. This error is usually related to memory allocation issues. To delete the semaphore, we should use OS semaphore delete function with semaphore handler as an only argument. This function returns OS status underscore t type, so zero means successful execution and any negative value means an error. Other functions for semaphores are common for binary and counting ones. To wait for semaphore, we should use OS semaphore acquire function with two arguments. Semaphore handler and the timeout in milliseconds, so how long we would like to wait for semaphore. If the semaphore is not available, the task will be sent to blocked state for a maximum timeout time. If, in the meantime, semaphore will become available, task will be unblocked and it will continue its operations. In such case return value will be zero, so it means OS okay, otherwise task will remain in blocked state for a complete timeout time and it will be unblocked at the end of it. And after this, the return value will be OS timeout error, so the negative value. For more details, you can refer to OS status underscore t description within cmcs underscore OS API section in this training. To release the semaphore, we should use OS semaphore release function with semaphore handler as an only argument. And this function returns as well OS status underscore t value, so zero means successful execution and any negative value means an error. Thank you for watching this video.