Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

To enable µC/OS-II event flags services, you must set the configuration constants in OS_CFG.H. Specifically, table 9.1 shows which services are compiled based on the value of configuration constants found in OS_CFG.H. You should note that NONE of the event flag services are enabled when OS_FLAG_EN is set to 0. To enable the feature (i.e. service), simply set the configuration constant to 1. You will notice that OSFlagCreate(), OSFlagPend() and OSFlagPost() cannot be individually disabled like the other services because they are always needed when you enable µC/OS-II event flag management.

Table 9.1 Event Flag configuration constants in OS_CFG.H.

µC/OS-II Event Flag ServiceEnabled when set to 1 in OS_CFG.H

OSFlagAccept()

OS_FLAG_ACCEPT_EN

OSFlagCreate()

 

OSFlagDel()

OS_FLAG_DEL_EN

OSFlagPend()

 

OSFlagPost()

 

OSFlagQuery()

OS_FLAG_QUERY_EN

Figure 9.1 shows a flow diagram to illustrate the relationship between tasks, ISRs, and a event flags. Note that the symbology used to represent an event flag group is a series of 8 bits even though the event flag group can contain 8, 16 or 32 bits (see OS_FLAGS in OS_CFG.H). The hourglass represents a timeout that can be specified with the OSFlagPend() call.

As you can see from Figure 9.1, a task or an ISR can call OSFlagAccept(), OSFlagPost() or OSFlagQuery(). However, only tasks are allowed to call OSFlagCreate(), OSFlagDel() or OSFlagPend().

Figure 9.1, µC/OS-II Event Flag services.

Event Flag Internals

A µC/OS-II's event flag group consist of three elements as shown in the OS_FLAG_GRP structure below.

You should note that the wait list for event flags is different than the other wait lists in µC/OS-II. With event flags, the wait list is accomplished through a doubly linked list as shown in figure 9.2. Three data structures are involved. OS_FLAG_GRP (mentioned above), OS_TCB which is the task control block and OS_FLAG_NODE which is used to keep track of which bits the task is waiting for and what type of wait (AND or OR). As you can see, there are a lot of pointers involved.Figure 9.2, Relationship between Event Flag Group, Event Flag Nodes and TCBs.

An OS_FLAG_NODE is created when a task desires to wait on bits of an event flag group and the node is ‘destroyed’ when the event(s) occur. In other words, a node is created by OSFlagPend() as we will see shortly. Before we discuss this, let’s look at the OS_FLAG_NODE data structure.

You should note that AND and ALL means the same thing and either one can be used. I prefer to use OS_FLAG_WAIT_???_ALL because it’s more obvious but you are certainly welcomed to use OS_FLAG_WAIT_???_AND. Similarly, OR or ANY means the same thing and either one can be used. Again, I prefer to use OS_FLAG_WAIT_???_ANY because it’s more obvious but again, you can use OS_FLAG_WAIT_???_OR. The other thing to notice is that you can wait for either bits to be SET or CLEARED.

...

The code to create an event flag group is shown in listing 9.3.

Figure 9.3 Event Flag group just before OSFlagCreate() returns.

Deleting an Event Flag Group, OSFlagDel()

...

As mentioned above, if the desired bits and conditions of a PEND call are not satisfied the calling task is suspended until either the event or a timeout occurs. The task is suspended by OS_FlagBlock() (see Listing 9.6) which adds the calling task to the wait list of the event flag group. The process is shown in Figure 9.4.

Figure 9.4, Adding the current task to the wait list of the Event Flag Group.

Setting or Clearing event(s) in an Event Flag Group, OSFlagPost()

...

The unlinking of the OS_FLAG_NODE is performed by the function OS_FlagUnlink() as shown in listing 9.9. Figure 9.5 shows the four possible locations of an OS_FLAG_NODE which needs to be removed from the event flag wait list. This is a classical doubly linked list removal problem except that there are also other pointers to adjust.

Figure 9.5, Removing an OS_FLAG_NODE from the wait list.

Figures 9.6 through 9.9 shows the before and after for each case mentioned. The number in parenthesis corresponds to the number in parenthesis of listing 9.9. You will notice that OS_FlagUnlink() updates at most three pointers. Because the node being removed exist on the stack of the task that is being readied (it was allocated by OSFlagPend()), that node will automatically disappear! As far as the task that pended on the event flag is concerned, it doesn’t even know about the OS_FLAG_NODE.Figure 9.6, Removing an OS_FLAG_NODE from the wait list, Case A.Figure 9.7, Removing an OS_FLAG_NODE from the wait list, Case B.

Figure 9.8, Removing an OS_FLAG_NODE from the wait list, Case C.

Figure 9.9, Removing an OS_FLAG_NODE from the wait list, Case D.

Looking for event(s) of an Event Flag Group, OSFlagAccept()

...