 Let's talk about events. It is called event groups within FreeRTOS API and event flags within CMC's OS version 2. It is not implemented within CMC's OS version 1. Event allow a task to wait for a combination of 1 or more events. Once an event occurs, it may unblock all the tasks that are waiting for it. Of course, if the tasks are not waiting for more than one event. As a result, unblocked task is moved from blocked to ready state. Events code is stored within event underscore groups.c file and event underscore groups.h file, which needs to be added to the code once we plan to use them. It requires some additional FreeRTOS components to be fully operational. We will describe it in next slides. Once you are generating code from stinferty to kubemix or kupide, those two files are added automatically once you generate even the simplest code based on FreeRTOS. It requires creation like most OS components. So to use events, we need to create and separate OS component like we're doing within semaphores or queues. And this object has its own control block to store its configuration and status. Events are supported within CMC's OS version 2 as event flags and within FreeRTOS API as event groups. What are the main advantages of events? It is allowing to reduce RAM usage by replacing various combinations of semaphores. It is simplifying the synchronization among the tasks by waiting for a combination of events. It allows to be read by multiple tasks, which are waiting for the information. It allows to use broadcasting mechanisms within operating system and it can be used within other tasks and interrupts. Event groups are using 16 or 32-bit long variables to store events. So each event means one bit set within this variable. This variable is defined within event underscore groups.c file as event bits underscore t and it can be 16-bit value without sign if config use 16-bit ticks is defined within FreeRTOS config.h file. It will be 32-bit long without sign otherwise. Most significant 8 bits within this variable are called scontrol bits and are defined as event bits control bytes. Those are blocked for the control data passed via event functions. The role of the control bits is the following. Event wait for all bits means that we are waiting for all of the bits from the specified mask. If it is cleared, event flags will be satisfied if any of the bit from the mask will be set. Event unblocked due to bit set mask it means that once it is set it means that the task waiting for event flags has been unblocked due to its required bit matching not due to timeout. And the last one event clear events on exit bits it means that all bits within the masks will be cleared on successful exit of this function. So once the bit flag mask will be set. Let's have a look at some differences among different APIs concerning group events. In FreeRTOS this mechanism is called event group in CMC's OS version 1 it is not implemented and in CMC's OS version 2 which we are describing within this session it is called event flags. And as in other CMC's OS functions there is no different function for thread and IRQ execution. It is checked within the function and proper FreeRTOS API call is done. We will focus on CMC's OS version 2 of this implementation. So let's have a closer look at event flags. Let's have a look at attributes of event flags specified within OS event flags ATR underscore T type. It is defined within CMC's underscore OS 2.h file. The only one we need to specify manually is the name of the event flag. The rest like attribute bits pointer to the control block memory area and control block size will be filled automatically after creation of the object. How we need to create the flags objects. So for this we've got a dedicated function OS event flags new which is requiring from us one argument which is the pointer to the structure with the attributes of the event flags object we would like to create. In fact we can specify only the name so in case we don't want to spend time for this we just put null within the pointer and in this case the default values would be set. The function is turning back the handler to event flags which can be used later on to pass the event flags or to wait for them within other functions. To delete event flags we need to use the function OS event flags delete. It is requiring one argument which is the handler to event flags objects and it returns the variable OS status underscore T. If it's zero means that the function has been executed correctly, if it's minus it is if there is let's say some other value lower than zero it means that there's some errors occurred during this process. To set bitmask we need to call OS event flags set function it requires two arguments a handler to event flag and 32-bit value with event bitmask to be set. Please remember that we mustn't use highest 8-bit of this mask as those are reserved for the control bits. Setting bits in an event group is not deterministic operation because there are known number of tasks that may be waiting for the bit or bits being set. FreeR2S doesn't allow non-deterministic operations to be performed in interrupts or from critical sections therefore X event group set bits from ISR sent a message to the timer task to have the set operation performed in the context of the timer task where a schedule lock is used to place a for a critical section. To use this we need to enable X event group set bits from ISR within include parameters at freeR2S configuration. This is why if you would like to use event groups and you would like to set some event groups within interrupts you need to enable as well the software timers. To clear a mask there is a dedicated function OS event flags clear which requires two arguments handler of the event flag object and bit mask to be cleared. Please remember to not use highest 8 bits. In both cases functions return 32-bit signed value. It contains event flags content after the operation or in case of an error its code. This code could be OS error parameter which is the bit mask when the bit mask is not in proper size so for example we were trying to use the highest 8 bits and the second error code could be OS error resource in case the resource was not available. Both components have a negative value by origin because those are coming from OS status underscore t and in this case both are casted to unsigned 32 bits. To wait for specific bit mask within selected event flags object we need to call OS event flags wait function. It cannot be run from interrupt as it is blocking function and we cannot block the interrupt. Arguments we need to pass to these functions are the following event flags handler bit mask which the task is waiting for and options. Those options could be OS flags wait all it is one in hexadecimal and it means that we need to wait for all specified bits within the bit mask. The second option which can be or with the previous one is OS flags no clear. This is a 2 hexadecimal and it means that event flags bits should be not cleared on exit of this function. The last our fourth argument for this function is a maximum timeout in milliseconds to wait for the event flags being set. Function is returning unsigned 32 bit value which contains either event flags value in case of successful execution or the error code casted from int 32 bits into unsigned int 32 bits value and it can be one of the values. OS error isr in case of calling this function from interrupt which is not allowed. OS parameter error parameter in case of taking into account most significant 8 bits which are reserved for the control bits. OS error timeout in case event flags bit mask is not set within given timeout and OS error resource in case it was not possible to access event flags object. An important component within event flags and software timers which would be described in separate section is so called RTOS agent task. Originally it was used to execute software timer callback functions now it is used to other components like event flags. Its priority is set within config timer task priority. Its tag size is set within config timer task stack depth and it is necessary to define config use timers and include x timer and function call within free RTOS config.h file to generate this function. What is important is to set properly the especially the priority of this agent task to allow execution among other tasks which are active in the system. Otherwise it may happen that it will be blocked so our event flags would be not serviced properly within the system. Below there is an example of additional configuration of free RTOS .h file in order to use event flags from interrupts because this RTOS agent which we discussed on the previous slide is used mainly to service the event flags from interrupts. So in our example we need to define config use timers to 1 it means that it's enabled then config timer task priority by default it is 2 so once you create an example please unify this value to the priorities used in your example. Then a config timer queue length is set to 10 it has more importance so within software timers one you can have multiple software timers and then you need some queue to store the commands sent by various timers. In case of event flags it is not that important so we can keep the default value and then config timer task stack depth it's 256 which is quite enough for this and then we need to enable the include x timer and function call to enable it we need to set it to 1. Above configuration is enabled and forced by default one we are using CMC's OS version 2 but we need to enable everything when using for example CMC's OS version 1. Important message once again is to update the RTOS agent task priority within config timer task priority value versus other tasks priorities in the system so there would be a possibility to execute it. Thank you for watching this video.