?? os_flag.c
字號:
switch (pnode->OSFlagNodeWaitType) /* 看當前節點是否設置了所有需要的位? */
{
case OS_FLAG_WAIT_SET_ALL:
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_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 = (OS_FLAG_NODE *)pnode->OSFlagNodeNext; /* 指向下一個等待事件標志的任務節點 */
}
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*/
/*
*********************************************************************************************************
* 查詢事件標志組的狀態
*
* 函數描述: 該函數用于查詢事件標志組的狀態
*
* 輸入參數 : pgrp 指向期望的事件標志組的指針
*
* err 指向出錯代碼:
* OS_NO_ERR 調用成功
* OS_FLAG_INVALID_PGRP 傳遞的是空指針
* OS_ERR_EVENT_TYPE 指向的類型不是事件標志組
*
* 返回值 : 當前的事件標志組值
*
* 從任務或ISR中調用
*********************************************************************************************************
*/
#if OS_FLAG_QUERY_EN > 0
OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_FLAGS flags;
#if OS_ARG_CHK_EN > 0
if (pgrp == (OS_FLAG_GRP *)0)
{ /* 無效的 'pgrp' */
*err = OS_FLAG_INVALID_PGRP;
return ((OS_FLAGS)0);
}
if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)
{ /* 無效的事件標志類型 */
*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); /* 返回當前的事件標志值 */
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 掛起任務一直到接收到事件標志或延時發生為止
*
* 函數描述: 該函數是 uC/OS-II的內部函數,它用于把一個任務置為睡眠態,直到期望的事件標志位置位為止。
*
* 輸入函數 : pgrp 指向期望的事件標志組的指針
*
* pnode 指向一個包含任務等待事件標志位置位的數據的結構指針。
*
* flags 顯示那一個位期望要檢測的位參數。
* 在'flags'中通過設定對應位來指定期望的位。例如,應用程序
* 期望等待位0和位1,那么,'flags'將包含0X03。
*
* wait_type 指定是否所有位或是任一位去置位或清除。
* 指定下列參數:
*
* OS_FLAG_WAIT_CLR_ALL 檢測'mask'中所有位清零 (0)
* OS_FLAG_WAIT_SET_ALL 檢測'mask'中所有位設置 (1)
* OS_FLAG_WAIT_CLR_ANY 檢測'mask'中任一位清零 (0)
* OS_FLAG_WAIT_SET_ANY 檢測'mask'中任一位設置 (1)
*
*
* timeout 任務等待事件標志位置位的延時時間。
*
* 返回值 : 無
*
* 調用函數 : OSFlagPend() OS_FLAG.C
*
* 注釋 : 該函數為內部函數,應用程序不該調用
*********************************************************************************************************
*/
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; /* 存儲任務 TCB 的延時數 */
#if OS_TASK_DEL_EN > 0
OSTCBCur->OSTCBFlagNode = pnode; /* 把節點鏈到TCB上 */
#endif
pnode->OSFlagNodeFlags = flags; /* 保存需要等待的標志 */
pnode->OSFlagNodeWaitType = wait_type; /* 保存等待的類型 */
pnode->OSFlagNodeTCB = (void *)OSTCBCur; /* 任務的 TCB 鏈接到節點上 */
pnode->OSFlagNodeNext = pgrp->OSFlagWaitList; /* 在事件標志等待列表的開頭添加節點 */
pnode->OSFlagNodePrev = (void *)0;
pnode->OSFlagNodeFlagGrp = (void *)pgrp; /* 鏈接事件標志組 */
pnode_next = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
if (pnode_next != (void *)0)
{ /* 這是要插入的第一個節點嗎? */
pnode_next->OSFlagNodePrev = pnode; /* 不, 鏈接雙鏈表 */
}
pgrp->OSFlagWaitList = (void *)pnode;
/* 掛起當前任務直到事件標志到 */
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0)
{
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* 初始化事件標志組
*
* 函數描述: 該函數由uC/OS-II 調用初始化事件標志模塊。換句話說,該函數是 uC/OS-II的內部函數。
*
* 輸入參數 : 無
*
* 返回值 : 無
*
* 警告 : 在應用程序中,不必調用該函數。這是 uC/OS-II的內部函數。
*********************************************************************************************************
*/
void OS_FlagInit (void)
{
#if OS_MAX_FLAGS == 1
OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0]; /* 只有一個事件標志組! */
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++)
{ /* 初始化空余事件標志 */
pgrp1->OSFlagType = OS_EVENT_TYPE_UNUSED;
pgrp1->OSFlagWaitList = (void *)pgrp2;
pgrp1++;
pgrp2++;
}
pgrp1->OSFlagWaitList = (void *)0;
OSFlagFreeList = (OS_FLAG_GRP *)&OSFlagTbl[0];
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* 使等待事件標志的任務進入就緒態
*
* 函數描述: 該函數是 uC/OS-II 的內部函數,并且因為期望的事件標志已置位,所以任務就緒待運行。
*
* 輸入參數 : pnode 指向包含等待事件標志位置位的任務的數據的指針。
*
* flags_rdy 包含引起任務就緒的位模式。
*
* 返回值 : none
*
* 由函數 OSFlagsPost() OS_FLAG.C調用
*
* 注釋 : 1) 該函數任務中斷已關閉
* 2) 該函數是 uC/OS-II的內部函數,應用程序不必調用。
*********************************************************************************************************
*/
static BOOLEAN OS_FlagTaskRdy (OS_FLAG_NODE *pnode, OS_FLAGS flags_rdy)
{
OS_TCB *ptcb;
BOOLEAN sched;
ptcb = (OS_TCB *)pnode->OSFlagNodeTCB; /* 指向等待任務的TCB */
ptcb->OSTCBDly = 0;
ptcb->OSTCBFlagsRdy = flags_rdy;
ptcb->OSTCBStat &= ~OS_STAT_FLAG;
if (ptcb->OSTCBStat == OS_STAT_RDY)
{ /* 把任務放到就緒列表中 */
OSRdyGrp |= ptcb->OSTCBBitY;
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
sched = TRUE;
}
else
{
sched = FALSE;
}
OS_FlagUnlink(pnode);
return (sched);
}
/*$PAGE*/
/*
*********************************************************************************************************
* 從等待列表中拆除事件標志節點
*
* 函數描述 : 該函數是 uC/OS-II 的內部函數,用于從等待事件標志任務列表中拆除事件標志節點。
*
* 輸入參數 : pnode 指向包含等待事件標志位置位的任務的數據的指針。
*
* 返回值 : none
*
* 由 : OS_FlagTaskRdy() OS_FLAG.C
* OSFlagPend() OS_FLAG.C
* OSTaskDel() OS_TASK.C 調用
*
* 注釋 : 1) 該函數任務中斷已關閉
* 2) 該函數是 uC/OS-II的內部函數,應用程序不必調用
*********************************************************************************************************
*/
void OS_FlagUnlink (OS_FLAG_NODE *pnode)
{
#if OS_TASK_DEL_EN > 0
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) /* 該節點是等待列表中的第一個節點嗎? */
{ /*是 */
pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp;
pgrp->OSFlagWaitList = (void *)pnode_next; /* 為新的第一個節點更新 */
if (pnode_next != (OS_FLAG_NODE *)0)
{
pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0; /* 鏈接新的第一個節點的前指針為空 */
}
}
else
{ /* 不是,在列表中其他位置 */
pnode_prev->OSFlagNodeNext = pnode_next; /* 搭接其他節點 */
if (pnode_next != (OS_FLAG_NODE *)0)
{ /* 是最后的節點嗎? */
pnode_next->OSFlagNodePrev = pnode_prev; /* 不是,搭接其他節點 */
}
}
#if OS_TASK_DEL_EN > 0
ptcb = (OS_TCB *)pnode->OSFlagNodeTCB;
ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;
#endif
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -