The whole truth about RTOS. Article # 17. Event flag groups: introduction and basic services

 
3r3-31. The whole truth about RTOS. Article # 17. Event flag groups: introduction and basic services 3r38080.  
3r38080.  
Groups of event flags have already been mentioned earlier in a previous article (# 5). In the Nucleus SE, they look like signals, but are more flexible. They provide a low-cost and flexible way to transfer simple messages between tasks. 3r38080.  
3r38080.  
3r38080.  
3r3141. Using event flags
3r38080.  
In Nucleus SE, event flags are defined at the build stage. The maximum number of event flag groups in an application is 16. If event flag groups are not defined, then code related to data structures and service calls for event flag groups will not be included in the application. 3r38080.  
3r38080.  
A group of event flags is a set of eight bit flags, access to which is regulated in such a way that several tasks can be safely used by one flag. One task can set or clear any combination of event flags. Another task can read a group of flags at any time, and can also wait for a certain sequence of flags (by polling or with suspension). 3r38080.  
3r38080.  
3r3141. Setting up groups of event flags 3r3142. 3r38080.  
3r33352. The number of groups of event flags
3r38080.  
As with most Nucleus SE objects, the setting of groups of event flags is given by the directives 3r-33682. #define [/b] in 3r3682. nuse_config.h [/b] . The main parameter is NUSE_EVENT_GROUP_NUMBER which determines how many groups of event flags will be defined in the application. By default, this parameter is set to 0 (that is, groups of event flags are not used) and can have any value up to 16. An incorrect value will result in a compilation error, which will be generated by checking in 3r38282. nuse_config_check.h [/b] (it turns on 3r33682. nuse_config.c [/b] , which means it compiles with this module), as a result, the directive 3r336822 will work. #error [/b] . The choice of a non-zero value serves as the main activator of groups of event flags. This parameter is used when defining data structures and their size depends on its value (for more details, see the following articles). In addition, a non-zero value activates the API settings. 3r38080.  
3r38080.  
3r33352. Activate API calls
3r38080.  
Each API function (service call) in Nucleus SE is activated by the directive 3r-33682. #define [/b] in 3r3682. nuse_config.h [/b] . For groups of event flags, these include: 3r3680.  
3r3600. NUSE_EVENT_GROUP_SET
 
NUSE_EVENT_GROUP_RETRIEVE
 
NUSE_EVENT_GROUP_INFORMATION
 
NUSE_EVENT_GROUP_COUNT
 
3r38080.  
By default, they are assigned the value FALSE thus disabling every service call and blocking the inclusion of the code that implements them. To set up groups of event flags, you need to select the necessary API calls and set the appropriate directives to 3r33682. TRUE [/b] . 3r38080.  
3r38080.  
The following is an excerpt from the default nuse_config.h file. 3r38080.  
3r3599. 3r3600. #define NUSE_EVENT_GROUP_NUMBER 0 /* Number of event groups
in the system - 0-16 * /
#define NUSE_EVENT_GROUP_SET FALSE /* Service call enabler * /
#define NUSE_EVENT_GROUP_RETRIEVE FALSE /* Service call enabler * /
#define NUSE_EVENT_GROUP_INFORMATION FALSE /* Service call enabler * /
#define NUSE_EVENT_GROUP_COUNT FALSE /* Service call enabler * /

3r38080.  
An activated API function if there are no event flag groups in the application will result in a compilation error (except 3r3-33682. NUSE_Event_Group_Count () [/b] , Which is always allowed). If your code uses an API call that has not been activated, a build error will occur because the implementation code was not included in the application. 3r38080.  
3r38080.  
3r3141. Service calls for event flags
3r38080.  
Nucleus RTOS supports seven service calls that provide the following functionality: 3r-33680.  
• Set event flags. The Nucleus SE is implemented in the function 3r33682. NUSE_Event_Group_Set () [/b] . 3r38080.  
• Read event flags. The Nucleus SE is implemented in 3r33682. NUSE_Event_Group_Retrieve () [/b] . 3r38080.  
• Providing information on a specific group of event flags. The Nucleus SE is implemented in 3r33682. NUSE_Event_Group_Information () [/b] . 3r38080.  
• Return the number of currently configured event flag groups in the application. The Nucleus SE is implemented in 3r33682. NUSE_Event_Group_Count () [/b] . 3r38080.  
• Add a new group of event flags to the application. Nucleus SE is not implemented. 3r38080.  
• Remove a group of event flags from the application. Nucleus SE is not implemented. 3r38080.  
• Return pointers to all groups of event flags in the application. Nucleus SE is not implemented. 3r38080.  
3r38080.  
The implementation of each of these service calls is detailed below. 3r38080.  
3r38080.  
It is worth noting that there is no reset function in either the Nucleus RTOS or the Nucleus SE. This is intentional. The reset function implies the predominance of a special state of flags. For groups of event flags, the only “special” state is the zeroing of all flags, which can be performed using 3r368282. NUSE_Event_Group_Set () [/b] . 3r38080.  
3r38080.  
3r3141. Service calls for setting and reading groups of event flags 3r3142. 3r38080.  
The fundamental operations that can be performed on a group of event flags are setting the value of one or more flags, as well as reading the current values ​​of the flags. Nucleus RTOS and Nucleus SE provide four basic API calls for these operations. 3r38080.  
3r38080.  
Since event flags are bits, they are best rendered as binary numbers. Since standard C does not historically support the representation of binary constants (octal and hexadecimal only), Nucleus SE has a useful 3r38282 header file. nuse_binary.h [/b] which contains the characters 3r38282. #define [/b] 3r38282. b01010101 [/b] for all 256 8-bit values. 3r38080.  
3r38080.  
3r33352. Setting event flags
3r38080.  
The Nucleus RTOS API service call for setting flags is very flexible and allows you to set and clear flag values ​​using operations And and 3r38282. OR [/b] . Nucleus SE provides similar functionality, but pausing tasks is optional. 3r38080.  
3r38080.  
3r38282. 3r3-3549. Call to set flags in the Nucleus RTOS 3r33550. [/b] 3r38080.  
Service Call Prototype:
 
3r38282. STATUS NU_Set_Events (NU_EVENT_GROUP * group, UNSIGNED event_flags, OPTION operation); [/b] 3r38080.  
3r38080.  
Parameters: 3r3680.  
3r38282. group [/b] - pointer to the user-provided control unit for the group of event flags; 3r38080.  
3r38282. event_flags [/b] - the value of the bit mask of the group of flags; 3r38080.  
3r38282. operation 3r3683. - operation performed, 3r38282. NU_OR [/b] (to set flags) or NU_AND (to clear flags). 3r38080.  
3r38080.  
Return value:
 
3r38282. NU_SUCCESS [/b] - the call was successfully completed; 3r38080.  
3r38282. NU_INVALID_GROUP [/b] - incorrect pointer to the group of event flags; 3r38080.  
3r38282. NU_INVALID_OPERATION [/b] - the specified operation is different from 3r38282. NU_OR [/b] and 3r38282. NU_AND [/b] . 3r38080.  
3r38080.  
3r38282. 3r3-3549. Call to set flags in the Nucleus SE [/i] [/b] 3r38080.  
This API call supports the core Nucleus RTOS API. 3r38080.  
3r38080.  
Service Call Prototype:
 
3r38282. STATUS NUSE_Event_Group_Set (NUSE_EVENT_GROUP group, U8 event_flags, OPTION operation); [/b] 3r38080.  
3r38080.  
Parameters: 3r3680.  
3r38282. group [/b] - the index (ID) of the group of events whose flags are set /cleared; 3r38080.  
3r38282. event_flags [/b] - the value of the bit maxi group of flags; 3r38080.  
3r38282. operation 3r3683. - operation performed, 3r38282. NUSE_OR [/b] (to set flags) or NUSE_AND (to clear flags). 3r38080.  
3r38080.  
Return value:
 
3r38282. NUSE_SUCCESS [/b] - the call was successfully completed; 3r38080.  
3r38282. NUSE_INVALID_GROUP [/b] - incorrect index of the group of event flags; 3r38080.  
3r38282. NUSE_INVALID_OPERATION [/b] - the specified operation is different from 3r38282. NUSE_OR [/b] and 3r38282. NUSE_AND [/b] . 3r38080.  
3r38080.  
3r38282. 3r3-3549. Implementing setting event flags in the Nucleus SE [/i] [/b] 3r38080.  
The initial code of the API function is NUSE_Event_Group_Set () is common (after checking the parameters), regardless of whether support for call blocking API (task suspension) is activated or not. The logic is pretty simple:
 
3r3599. 3r3600. NUSE_CS_Enter ();
if (operation == NUSE_OR)
{
NUSE_Event_Group_Data[group]| = event_flags;
}
else /* NUSE_AND * /
{
NUSE_Event_Group_Data[group]& = event_flags;
}
3r38080.  
Bit mask event_flags superimposed (using operation 3r38282. And [/b] or 3r3-33682. OR [/b] ) on the value of the selected group of event flags. 3r38080.  
3r38080.  
The remaining code is enabled only when the task lock is activated: 3r33680.  
3r3599. 3r3600. #if NUSE_BLOCKING_ENABLE
while (NUSE_Event_Group_Blocking_Count[group]! = 0)
{
U8 index; /* check whether any tasks are blocked * /
/* on this event group * /
for (3) 3r3326. (3r3696.) = NUSE_SUCCESS;
NUSE_Task_Status[index]= NUSE_READY;
break;
}
}
NUSE_Event_Group_Blocking_Count[group]-;
}
#if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER
NUSE_Reschedule (NUSE_NO_TASK);
# endif
#endif
NUSE_CS_Exit ();
return NUSE_SUCCESS; 3r3646. 3r3647.
 
If any tasks are suspended (for reading) from this group of flags, they are resumed. When they are given the opportunity to continue execution (it depends on the scheduler), they can determine whether the conditions for their resumption are satisfied or not (see reading the event flags). 3r38080.  
3r38080.  
3r33352. Reading event flags
3r38080.  
Nucleus RTOS API read calls are very flexible and allow you to suspend tasks indefinitely or with a specific timeout if the operation cannot be performed immediately (for example, if you try to read a certain sequence of event flags that do not represent the current state). Nucleus SE provides the same functions, only task suspension is optional, and timeout is not implemented. 3r38080.  
3r38080.  
3r38282. 3r3-3549. A call to read flags in the Nucleus RTOS 3r33550. [/b] 3r38080.  
Service Call Prototype:
 
3r38282. STATUS NU_Retrieve_Events (NU_EVENT_GROUP * group, UNSIGNED requested_events, OPTION operation, UNSIGNED * retrieved_events, UNSIGNED suspend); [/b] 3r38080.  
3r38080.  
Parameters: 3r3680.  
3r38282. group [/b] - pointer to the user-provided control unit for the group of event flags; 3r38080.  
3r38282. requested_events [/b] - bitmask defining readable flags; 3r38080.  
3r38282. operation 3r3683. - Four operations are available: 3r38282. NU_AND [/b] , 3r38282. NU_AND_CONSUME [/b] , 3r38282. NU_OR [/b] and 3r38282. NU_OR_CONSUME [/b] . Operations 3r3682. NU_AND [/b] and 3r38282. NU_AND_CONSUME [/b] indicates that all requested flags are required. Operations 3r3682. NU_OR [/b] and 3r38282. NU_OR_CONSUME [/b] indicate that one or more of the requested flags is sufficient. Parameter 3r38282. CONSUME [/b] automatically clears existing flags after a successful request; 3r38080.  
3r38282. retrieved_events [/b] - pointer to the repository for the values ​​of the read event flags; 3r38080.  
3r38282. suspend [/b] - specification for pausing tasks; may be 3r38282. NU_NO_SUSPEND [/b] or NU_SUSPEND , or timeout value in system t cyclesAymer (1 to ?29?96?293). 3r38080.  
3r38080.  
Return value:
 
3r38282. NU_SUCCESS [/b] - the call was successfully completed; 3r38080.  
3r38282. NU_NOT_PRESENT [/b] - the specified operation did not return events (not a single event in the case of NU_OR and not all events in the case of NU_AND); 3r38080.  
3r38282. NU_INVALID_GROUP [/b] - incorrect pointer to the group of event flags; 3r38080.  
3r38282. NU_INVALID_OPERATION [/b] - the specified operation was incorrect; 3r38080.  
3r38282. NU_INVALID_POINTER [/b] - null pointer to the storage of event flags (NULL); 3r38080.  
3r38282. NU_INVALID_SUSPEND [/b] - an attempt to suspend a non-task related thread; 3r38080.  
3r38282. NU_TIMEOUT [/b] - the required combination of event flags was not established even after the specified timeout; 3r38080.  
3r38282. NU_GROUP_DELETED [/b] - a group of event flags was deleted, while the task was suspended. 3r38080.  
3r38080.  
3r38282. 3r3-3549. Challenge for reading flags in the Nucleus SE [/i] [/b] 3r38080.  
This API call supports the core Nucleus RTOS API. 3r38080.  
3r38080.  
Service Call Prototype:
 
3r38282. STATUS NUSE_Event_Group_Retrieve (NUSE_EVENT_GROUP group, U8 requested_events, OPTION operation, U8 * retrieved_events, U8 suspend); [/b] 3r38080.  
3r38080.  
Parameters: 3r3680.  
3r38282. group [/b] - index (ID) of the readable group of event flags; 3r38080.  
3r38282. requested_events [/b] - bitmask defining readable flags; 3r38080.  
3r38282. operation 3r3683. - specification indicating the number of flags required: 3r33682. NUSE OR [/b] (some flags) or 3r3r8282. NUSE AND [/b] (all flags); 3r38080.  
3r38282. retrieved_events [/b] - a pointer to the repository for the actual values ​​of the event flags read (at operation 3r3-33682. NUSE_AND [/b] This will be the same as transmitted in parameter 3r38282. Requested_events 3r3683.); 3r38080.  
3r38282. suspend [/b] - specification for pausing the task, can take the values ​​3r368282. NUSE_NO_SUSPEND [/b] or NUSE_SUSPEND . 3r38080.  
3r38080.  
Return value:
 
3r38282. NUSE_SUCCESS [/b] - the call was successfully completed; 3r38080.  
3r38282. NUSE_NOT_PRESENT [/b] - the specified operation did not return events (not a single event in the case of 3r368282. NUSE_OR [/b] And not all events in the case of 3r336822. NUSE_AND [/b] ); 3r38080.  
3r38282. NUSE_INVALID_GROUP [/b] - incorrect index of the group of event flags; 3r38080.  
3r38282. NUSE_INVALID_OPERATION [/b] - the specified operation is different from 3r38282. NUSE_OR [/b] or NUSE_AND ; 3r38080.  
3r38282. NUSE_INVALID_POINTER [/b] - null pointer to the storage of the read event flags (3r368282. NULL [/b] ); 3r38080.  
3r38282. NUSE_INVALID_SUSPEND [/b] - an attempt to pause from a thread not associated with the task or with support for blocking API calls disabled. 3r38080.  
3r38080.  
3r38282. 3r3-3549. Implementing the reading of event flags in the Nucleus SE [/i] [/b] 3r38080.  
A variant of the API function code NUSE_Event_Group_Retrieve () (after checking the parameters) is selected during conditional compilation, depending on whether the API support for blocking (suspending) tasks is activated or not. Consider these two options separately. 3r38080.  
3r38080.  
If the lock is disabled, the full code for this API call will look like this:
 
3r3599. 3r3600. temp_events = NUSE_Event_Group_Data[group]& requested_events;
if (operation == NUSE_OR)
{
if (temp_events! = 0)
{
return_value = NUSE_SUCCESS;
}
else
{
return_value = NUSE_NOT_PRESENT;
}
}
else /* operation == NUSE_AND * /
{
if (temp_events == requested_events)
{
return_value = NUSE_SUCCESS;
}
else
{
return_value = NUSE_NOT_PRESENT;
}
}

3r38080.  
The required event flags are selected from the specified group of event flags. The value is compared with the required events, given the operation 3r368282. AND /OR [/b] , as well as the return result and the immediate values ​​of the requested flags. 3r38080.  
3r38080.  
If task lock is activated, the code becomes more complicated: 3r38080.  
3r3599. 3r3600. do
{
temp_events = NUSE_Event_Group_Data[group]& requested_events;
if (operation == NUSE_OR)
{
if (temp_events! = 0)
{
return_value = NUSE_SUCCESS;
}
else
{
return_value = NUSE_NOT_PRESENT;
}
}
else /* operation == NUSE_AND * /
{
if (temp_events == requested_events)
{
return_value = NUSE_SUCCESS;
}
else
{
return_value = NUSE_NOT_PRESENT;
}
}
if (return_value == NUSE_SUCCESS)
{
suspend = NUSE_NO_SUSPEND;
}
else
{
if (suspend == NUSE_SUSPEND) /* block task * /
{
NUSE_Event_Group_Blocking_Count[group]++;
NUSE_Suspend_Task (NUSE_Task_Active, (group 4) |
NUSE_EVENT_SUSPEND);
return_value =
NUSE_Task_Blocking_Return[NUSE_Task_Active];
if (return_value! = NUSE_SUCCESS)
{
suspend = NUSE_NO_SUSPEND;
}
}
}
} while (suspend == NUSE_SUSPEND);

3r38080.  
The code is placed in cycle 3r38282. do while [/b] which works until parameter 3r38282. suspend [/b] has a value of 3r38282. NUSE_SUSPEND [/b] . 3r38080.  
3r38080.  
The requested event flags are read in the same way as when calling without blocking. If the read is not successful, and parameter 3r33682. suspend [/b] has a value of 3r38282. NUSE_NO_SUSPEND [/b] , API call is assigned the value 3r33682. NUSE_NOT_PRESENT [/b] . If the parameter 3r38282. suspend [/b] 3r38282 has been assigned. NUSE_SUSPEND [/b] , the task is suspended. On return (when the task resumes), if the return value is 3r-33682. NUSE_SUCCESS [/b] , indicating that the task was resumed because the flags of the events in this group were set or cleared, the cycle starts from the beginning, the flags are read and checked. Since there is no API function for resetting groups of event flags, this is the only reason for resuming the task, but the verification process is 3r368282. NUSE_Task_Blocking_Return[] [/b] has been left in the system for locking control compatibility with other types of objects. 3r38080.  
3r38080.  
The next article will describe additional API calls related to groups of event flags, as well as their data structures. 3r38080.  
3r38080.  
3r38282. About the Author: [/b] Colin Walls has been working in the electronics industry for over thirty years, devoting much of his time to embedded software. He is now the firmware engineer for Mentor Embedded (a division of Mentor Graphics). Colin Walls often speaks at conferences and seminars, author of numerous technical articles and two books on embedded software. Lives in the UK. Professional 3r3684. Colin's blog
, e-mail: [email protected] 3r3693.
! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () (); 3r3690.
3r3693.
+ 0 -

Comments 2

Offline
James Lee
James Lee 1 November 2018 15:27
You have written very informative article about RTOS. I have just read it and got complete information about the topic.I will visit this website to read more similar articles.
rubber grass mats

Add comment