Source code Analysis of Ucos signal set

Source: Internet
Author: User

In the practical application, a task often needs to wait for multiple semaphores to take effect at the same time, or the task needs to determine the operation mode of the task according to the result of the combination of multiple semaphores, in order to realize the function of the multi-signal combination, Ucos realizes the special structure of the signal volume set.

The basis of the semaphore set is still the semaphore, which is like a plurality of semaphores consisting of a non-gate to form the execution of a logical result control task.

The signal volume in the implementation of the Ucos is divided into two parts, the first part is called the Flag group, which holds all signals in the signal concentration, the second is called the waiting list, each node in the list corresponds to a waiting task waiting for the semaphore set, the semaphore set according to the list to manage the waiting task

Unlike events such as Message Queuing message mailboxes, Ucos defines a semaphore set using a new structure called a flag group, which is structured as follows

typedef struct OS_FLAG_GRP {/* Event flag Group */

Int8u Osflagtype; /* semaphore set flag, must be Os_event_type_flag */

void *osflagwaitlist; /* Pointer to the first node of the task waiting group */

Os_flags Osflagflags; /* The length of the semaphore set */

#if os_flag_name_en > 0u

Int8u *osflagname;

#endif

} os_flag_grp;

The first few have comments, note osflagflags, which is a variable of type os_flags, in Osflagflags, a bit represents a semaphore, how much semaphore a flag group can hold depends on the length of the Os_flags, and Os_ The length definition of flags can make 8 bits of 16 bits 32 bits, as follows

#if Os_flags_nbits = = 8u

typedef int8u OS_FLAGS;

#endif

#if Os_flags_nbits = = 16u

typedef int16u OS_FLAGS;

#endif

#if Os_flags_nbits = = 32u

typedef INT32U OS_FLAGS;

#endif

Macros that determine their length are specified in the Os_cfg.h file, typically 16 bits, and are determined as needed

Osflagwaitlist points to a pointer to the list of tasks waiting for this semaphore set, and after the creation of a semaphore set is not directly connected to the task, then again, let's look at how the system manages the semaphore set

In fact, the management of the semaphore set is similar to the previous TCB ECB and QCB management, which is the form of the idle list, which has an array of flags in the system, as follows

Os_ext Os_flag_grp Osflagtbl[os_max_flags];

This variable indicates the size of the maximum number of flag groups The system contains, Os_max_flags is the macro defined in the Os_cfg.h file, and the user configures it as needed

You can see the following code when the flag group is initialized

for (ix = 0u; IX < (OS_MAX_FLAGS-1U); ix++) {/* Init. List of free EVENT FLAGS */

Ix_next = IX + 1u;

PGRP1 = &OSFlagTbl[ix];

PGRP2 = &OSFlagTbl[ix_next];

Pgrp1->osflagtype = os_event_type_unused;

Pgrp1->osflagwaitlist = (void *) Pgrp2;

#if os_flag_name_en > 0u

Pgrp1->osflagname = (int8u *) (void *) "?"; /* Unknown Name */

#endif

}

PGRP1 = &OSFlagTbl[ix];

Pgrp1->osflagtype = os_event_type_unused;

Pgrp1->osflagwaitlist = (void *) 0;

#if os_flag_name_en > 0u

Pgrp1->osflagname = (int8u *) (void *) "?"; /* Unknown Name */

#endif

Osflagfreelist = &OSFlagTbl[0];

It can be clearly seen that the management of the semaphore set is similar to TCBQCB, which is managed using a linked list, with a osflagfreelist pointing to a flag group as the table header of the free flag group at initialization time. Osflagwaitlist joins each flag group variable as a list when no flag group is created

Osflagwaitlist is defined as follows

Os_ext Os_flag_grp *osflagfreelist;

This is the organization of the flag group, so how to associate the flag group with the semaphore set, relying on the function of Os_flagblock, the prototype is as follows

static void Os_flagblock (Os_flag_grp *pgrp,

Os_flag_node *pnode,

Os_flags FLAGS,

Int8u Wait_type,

int32u Timeout)

The first parameter is the set of flags we generate, the second is a pnode variable, flags is the semaphore set data for the specified wait, the fourth is the wait type, and finally the Wait timeout event

Pick a simple first say, wait time without repeating, the front has been carefully analyzed, said the waiting type, the waiting type of the flag group is divided into eight, respectively, as follows

#define Os_flag_wait_clr_all 0u//signal all valid to continue to perform the task

#define Os_flag_wait_clr_and 0u//But signal valid identification is 0 valid

#define OS_FLAG_WAIT_CLR_ANY 1u//signal has one or more valid

#define OS_FLAG_WAIT_CLR_OR 1u//But signal valid identification is 0 valid

#define Os_flag_wait_set_all 2u//signal all valid to continue to perform the task

#define Os_flag_wait_set_and 2u//Signal valid identification is 1 valid

#define OS_FLAG_WAIT_SET_ANY 3u//signal has one or more valid

#define OS_FLAG_WAIT_SET_OR 3u//Signal valid identification is 1 valid

For example, if Osflagflags is 0b00000000 at this point, the task set to Os_flag_wait_clr_all is valid, and the signal set to Os_flag_wait_set_all is not valid because the signal bit is 0. All is 0, so valid, the signal bit is 1 when the time is valid, no bit is 1, so invalid.

There is also a os_flag_node element, which is defined as follows

typedef struct OS_FLAG_NODE {

void *osflagnodenext; /* point to the next node node */

void *osflagnodeprev; /* point to the previous node */

void *OSFLAGNODETCB; /* tcb*/pointing to the current task node

void *osflagnodeflaggrp;

Os_flags Osflagnodeflags;

Int8u Osflagnodewaittype; /* Current WAIT type */

} Os_flag_node;

The member Osflagnodeflaggrp is a pointer to the semaphore set Flag group, which is used when waiting for a member to be deleted in the task list or when adding a member.

The osflagnodeflags is equivalent to a filter that can filter out the semaphore required by the request task from the flag group, and the rest of the extraneous signals are screened out,

The interface for establishing the connection between the node and the flag group is Os_flagblock, and the core code is as follows

Ostcbcur->ostcbstat |= Os_stat_flag;

Ostcbcur->ostcbstatpend = OS_STAT_PEND_OK;

ostcbcur->ostcbdly = timeout; /* Store timeout in task s TCB */

#if os_task_del_en > 0u

Ostcbcur->ostcbflagnode = Pnode; /* TCB to link to node */

#endif

Pnode->osflagnodeflags = flags; /* Save The flags that we need to wait for */

Pnode->osflagnodewaittype = Wait_type; /* Save The type of wait we are doing */

PNODE->OSFLAGNODETCB = (void *) ostcbcur; /* Link to Task s TCB */

Pnode->osflagnodenext = pgrp->osflagwaitlist; /* ADD node at beginning of event flag wait list */

Pnode->osflagnodeprev = (void *) 0;

PNODE->OSFLAGNODEFLAGGRP = (void *) pgrp; /* Link to Event Flag Group */

Pnode_next = (Os_flag_node *) pgrp->osflagwaitlist;

if (Pnode_next! = (void *) 0) {/* is this, the first NODE to insert? */

Pnode_next->osflagnodeprev = Pnode; /* No, link in doubly linked list */

}

Pgrp->osflagwaitlist = (void *) Pnode;

y = ostcbcur->ostcby; /* Suspend current task until flag (s) received */

Osrdytbl[y] &= (Os_prio) ~ostcbcur->ostcbbitx;

if (osrdytbl[y] = = 0x00u) {

Osrdygrp &= (Os_prio) ~ostcbcur->ostcbbity;

As you can see, he will hang the task first and then

Pnode->osflagnodenext = pgrp->osflagwaitlist;

Put the task in the Wait task list and finally switch the head of the task list to the node we just inserted, as follows

Pgrp->osflagwaitlist = (void *) Pnode;

In this way, the task is associated with the semaphore set, in the scheduling we can say that should be in the postxxx inside the dispatch, see after the following code found

Sched = Os_false; /* Indicate that we don ' t need rescheduling */

Pnode = (Os_flag_node *) pgrp->osflagwaitlist;

while (Pnode! = (Os_flag_node *) 0) {

.........

Pnode = (Os_flag_node *) pnode->osflagnodenext;

}

if (sched = = os_true) {

Os_sched ();

}

In other words, when another task sends a semaphore set, a wait-list traversal will occur inside the semaphore set, the appropriate task can be scheduled, and then call Os_sched to dispatch, thus realizing the semaphore set

Speaking of which, basically the principle of the semaphore set is almost the same thing, now talk about using

Create a semaphore set

Osflagcreate, returns a pointer to the semaphore set created

Request Semaphore Set

Osflagpend

Send a signal to a semaphore set

Osflagpost

Querying the state of the semaphore set

Osflagquery

Delete a semaphore set

Osflagdel

Adding tasks to a semaphore set (this is important)

Os_flagblock, this function has a os_flag_node parameter, in the generation of this variable, only need to assign value waittype and flags two, the rest of the interface will be automatically assigned, do not need the user or to manually assign value, remember

Source code Analysis of Ucos signal set

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.