📄 os_flag.c
字号:
if (flags_rdy == pnode->OSFlagNodeFlags) { if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) { /* Make task RTR, event(s) Rx'd */ sched = TRUE; /* When done we will reschedule */ } } break; case OS_FLAG_WAIT_SET_ANY: /* See if any flag set */ flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; if (flags_rdy != (OS_FLAGS)0) { if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) { /* Make task RTR, event(s) Rx'd */ sched = TRUE; /* When done we will reschedule */ } } break;#if OS_FLAG_WAIT_CLR_EN > 0 case OS_FLAG_WAIT_CLR_ALL: /* See if all req. flags are set for current node */ flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; if (flags_rdy == pnode->OSFlagNodeFlags) { if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) { /* Make task RTR, event(s) Rx'd */ sched = TRUE; /* When done we will reschedule */ } } break; case OS_FLAG_WAIT_CLR_ANY: /* See if any flag set */ flags_rdy = ~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; if (flags_rdy != (OS_FLAGS)0) { if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) { /* Make task RTR, event(s) Rx'd */ sched = TRUE; /* When done we will reschedule */ } } break;#endif } pnode = pnode->OSFlagNodeNext; /* Point to next task waiting for event flag(s) */ } OS_EXIT_CRITICAL(); if (sched == TRUE) { OS_Sched(); } OS_ENTER_CRITICAL(); flags_cur = pgrp->OSFlagFlags; OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (flags_cur);}/*$PAGE*//*********************************************************************************************************** QUERY EVENT FLAG ** Description: This function is used to check the value of the event flag group.** Arguments : pgrp is a pointer to the desired event flag group.** err is a pointer to an error code returned to the called:* OS_NO_ERR The call was successfull* OS_FLAG_INVALID_PGRP You passed a NULL pointer* OS_ERR_EVENT_TYPE You are not pointing to an event flag group** Returns : The current value of the event flag group.** Called From: Task or ISR**********************************************************************************************************/#if OS_FLAG_QUERY_EN > 0OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, INT8U *err){#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */ OS_CPU_SR cpu_sr;#endif OS_FLAGS flags;#if OS_ARG_CHK_EN > 0 if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */ *err = OS_FLAG_INVALID_PGRP; return ((OS_FLAGS)0); } if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */ *err = OS_ERR_EVENT_TYPE; return ((OS_FLAGS)0); }#endif OS_ENTER_CRITICAL(); flags = pgrp->OSFlagFlags; OS_EXIT_CRITICAL(); *err = OS_NO_ERR; return (flags); /* Return the current value of the event flags */}#endif/*$PAGE*//*********************************************************************************************************** SUSPEND TASK UNTIL EVENT FLAG(s) RECEIVED OR TIMEOUT OCCURS** Description: This function is internal to uC/OS-II and is used to put a task to sleep until the desired* event flag bit(s) are set.** Arguments : pgrp is a pointer to the desired event flag group.** pnode is a pointer to a structure which contains data about the task waiting for * event flag bit(s) to be set.** flags Is a bit pattern indicating which bit(s) (i.e. flags) you wish to check. * The bits you want are specified by setting the corresponding bits in * 'flags'. e.g. if your application wants to wait for bits 0 and 1 then * 'flags' would contain 0x03.** wait_type specifies whether you want ALL bits to be set/cleared or ANY of the bits * to be set/cleared.* You can specify the following argument:** OS_FLAG_WAIT_CLR_ALL You will check ALL bits in 'mask' to be clear (0)* OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'mask' to be clear (0)* OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'mask' to be set (1)* OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'mask' to be set (1)** timeout is the desired amount of time that the task will wait for the event flag * bit(s) to be set.** Returns : none** Called by : OSFlagPend() OS_FLAG.C** Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.**********************************************************************************************************/static void OS_FlagBlock (OS_FLAG_GRP *pgrp, OS_FLAG_NODE *pnode, OS_FLAGS flags, INT8U wait_type, INT16U timeout){ OS_FLAG_NODE *pnode_next; OSTCBCur->OSTCBStat |= OS_STAT_FLAG; OSTCBCur->OSTCBDly = timeout; /* Store timeout in task's TCB */#if OS_TASK_DEL_EN > 0 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 = 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; /* Suspend current task until flag(s) received */ if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { OSRdyGrp &= ~OSTCBCur->OSTCBBitY; }}/*$PAGE*//*********************************************************************************************************** INITIALIZE THE EVENT FLAG MODULE** Description: This function is called by uC/OS-II to initialize the event flag module. Your application* MUST NOT call this function. In other words, this function is internal to uC/OS-II.** Arguments : none** Returns : none** WARNING : You MUST NOT call this function from your code. This is an INTERNAL function to uC/OS-II.**********************************************************************************************************/void OS_FlagInit (void){#if OS_MAX_FLAGS == 1 OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; /* Only ONE event flag group! */ OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED; OSFlagFreeList->OSFlagWaitList = (void *)0;#endif#if OS_MAX_FLAGS >= 2 INT8U i; OS_FLAG_GRP *pgrp1; OS_FLAG_GRP *pgrp2; pgrp1 = &OSFlagTbl[0]; pgrp2 = &OSFlagTbl[1]; for (i = 0; i < (OS_MAX_FLAGS - 1); i++) { /* Init. list of free EVENT FLAGS */ pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED; pgrp1->OSFlagWaitList = (void *)pgrp2; pgrp1++; pgrp2++; } pgrp1->OSFlagWaitList = (void *)0; OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0];#endif }/*$PAGE*//*********************************************************************************************************** MAKE TASK READY-TO-RUN, EVENT(s) OCCURRED** Description: This function is internal to uC/OS-II and is used to make a task ready-to-run because the* desired event flag bits have been set.** Arguments : pnode is a pointer to a structure which contains data about the task waiting for * event flag bit(s) to be set.** flags_rdy contains the bit pattern of the event flags that cause the task to become* ready-to-run.** Returns : none** Called by : OSFlagsPost() OS_FLAG.C** Note(s) : 1) This function assumes that interrupts are disabled.* 2) This function is INTERNAL to uC/OS-II and your application should not call it.**********************************************************************************************************/static BOOLEAN OS_FlagTaskRdy (OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy){ OS_TCB *ptcb; BOOLEAN sched; ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; /* Point to TCB of waiting task */ ptcb->OSTCBDly = 0; ptcb->OSTCBFlagsRdy = flags_rdy; ptcb->OSTCBStat &= ~OS_STAT_FLAG; if (ptcb->OSTCBStat == OS_STAT_RDY) { /* Put task into ready list */ OSRdyGrp |= ptcb->OSTCBBitY; OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; sched = TRUE; } else { sched = FALSE; } OS_FlagUnlink(pnode); return (sched);}/*$PAGE*//*********************************************************************************************************** UNLINK EVENT FLAG NODE FROM WAITING LIST** Description: This function is internal to uC/OS-II and is used to unlink an event flag node from a* list of tasks waiting for the event flag.** Arguments : pnode is a pointer to a structure which contains data about the task waiting for * event flag bit(s) to be set.** Returns : none** Called by : OS_FlagTaskRdy() OS_FLAG.C* OSFlagPend() OS_FLAG.C* OSTaskDel() OS_TASK.C** Note(s) : 1) This function assumes that interrupts are disabled.* 2) This function is INTERNAL to uC/OS-II and your application should not call it.**********************************************************************************************************/void OS_FlagUnlink (OS_FLAG_NODE *pnode){ OS_TCB *ptcb; OS_FLAG_GRP *pgrp; OS_FLAG_NODE *pnode_prev; OS_FLAG_NODE *pnode_next; pnode_prev = pnode->OSFlagNodePrev; pnode_next = pnode->OSFlagNodeNext; if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */ pgrp = pnode->OSFlagNodeFlagGrp; /* Yes, Point to event flag group */ pgrp->OSFlagWaitList = (void *)pnode_next; /* Update list for new 1st node */ if (pnode_next != (OS_FLAG_NODE *)0) { pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0; /* Link new 1st node PREV to NULL */ } } else { /* No, A node somewhere in the list */ pnode_prev->OSFlagNodeNext = pnode_next; /* Link around the node to unlink */ if (pnode_next != (OS_FLAG_NODE *)0) { /* Was this the LAST node? */ pnode_next->OSFlagNodePrev = pnode_prev; /* No, Link around current node */ } } ptcb = (OS_TCB *)pnode->OSFlagNodeTCB;#if OS_TASK_DEL_EN > 0 ptcb->OSTCBFlagNode = (void *)0;#endif}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -