?? ucos ii v2.9 ?
字號:
break;
#endif
default:
OS_EXIT_CRITICAL();
*perr = OS_ERR_FLAG_WAIT_TYPE;
return ((OS_FLAGS)0);
}
pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; /* Point to next task waiting for event flag(s) */
}
OS_EXIT_CRITICAL();
if (sched == OS_TRUE) {
OS_Sched();
}
OS_ENTER_CRITICAL();
flags_cur = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
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.
*
* perr is a pointer to an error code returned to the called:
* OS_ERR_NONE The call was successfull
* OS_ERR_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 > 0u
OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp,
INT8U *perr)
{
OS_FLAGS flags;
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
if (perr == (INT8U *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
#if OS_ARG_CHK_EN > 0u
if (pgrp == (OS_FLAG_GRP *)0) { /* Validate 'pgrp' */
*perr = OS_ERR_FLAG_INVALID_PGRP;
return ((OS_FLAGS)0);
}
#endif
if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return ((OS_FLAGS)0);
}
OS_ENTER_CRITICAL();
flags = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
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,
INT32U timeout)
{
OS_FLAG_NODE *pnode_next;
INT8U y;
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;
}
}
/*$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 == 1u
OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; /* Only ONE event flag group! */
OSFlagFreeList->OSFlagType = OS_EVENT_TYPE_UNUSED;
OSFlagFreeList->OSFlagWaitList = (void *)0;
OSFlagFreeList->OSFlagFlags = (OS_FLAGS)0;
#if OS_FLAG_NAME_EN > 0u
OSFlagFreeList->OSFlagName = (INT8U *)"?";
#endif
#endif
#if OS_MAX_FLAGS >= 2u
INT16U ix;
INT16U ix_next;
OS_FLAG_GRP *pgrp1;
OS_FLAG_GRP *pgrp2;
OS_MemClr((INT8U *)&OSFlagTbl[0], sizeof(OSFlagTbl)); /* Clear the flag group table */
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];
#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 : OS_TRUE If the task has been placed in the ready list and thus needs scheduling
* OS_FALSE The task is still not ready to run and thus scheduling is not necessary
*
* 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 = 0u;
ptcb->OSTCBFlagsRdy = flags_rdy;
ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_FLAG;
ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
if (ptcb->OSTCBStat == OS_STAT_RDY) { /* Task now ready? */
OSRdyGrp |= ptcb->OSTCBBitY; /* Put task into ready list */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
sched = OS_TRUE;
} else {
sched = OS_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)
{
#if OS_TASK_DEL_EN > 0u
OS_TCB *ptcb;
#endif
OS_FLAG_GRP *pgrp;
OS_FLAG_NODE *pnode_prev;
OS_FLAG_NODE *pnode_next;
pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev;
pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */
pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp;
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 */
}
}
#if OS_TASK_DEL_EN > 0u
ptcb = (OS_TCB *)pnode->OSFlagNodeTCB;
ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;
#endif
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -