?? os_flag.c
字號:
OS_EXIT_CRITICAL();
*err = OS_ERR_TASK_WAITING;
return (pgrp);
}
case OS_DEL_ALWAYS: /* 即使有等待的任務,也要刪除 */
pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
while (pnode != (OS_FLAG_NODE *)0)
{ /* 就緒所有等待標志的任務 */
OS_FlagTaskRdy(pnode, (OS_FLAGS)0);
pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
}
pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;
pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* 返回事件標志組到空余鏈表上 */
OSFlagFreeList = pgrp;
OS_EXIT_CRITICAL();
if (tasks_waiting == TRUE)
{ /* 如果在此之前任務等待,則調度 */
OS_Sched(); /* 尋找最高優先級就緒運行 */
}
*err = OS_NO_ERR;
return ((OS_FLAG_GRP *)0); /* 事件標志組被刪除 */
default:
OS_EXIT_CRITICAL();
*err = OS_ERR_INVALID_OPT;
return (pgrp);
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 等待一個事件標志組的事件標志位
*
* 函數描述: 該函數用于等待事件標志組中設定的組合位。應用程序可以等待任一位或所有位。
*
* 輸入參數 : pgrp 指向期望的事件標志組的指針
*
* 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)
*
* 注釋: 如果期望事件標志組通過調用清除則添加OS_FLAG_CONSUME 例如,等待事件標志組
* 中的任一標志置位后,清除位標志。設定 'wait_type' 為:
*
* OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME
*
* timeout 等待位組合的任務的延時選擇項。如果設為 0 ,任務將一直等到事件標志的到來。
*
* err 指向出錯代碼的指針:
* OS_NO_ERR 在延時時間內期望的位被設定。
* OS_ERR_PEND_ISR 從ISR中等待
* OS_FLAG_INVALID_PGRP 'pgrp' 是一個空指針。
* OS_ERR_EVENT_TYPE 沒有指向事件標志組
* OS_TIMEOUT 在延時時間內期望的位沒有被設定
* OS_FLAG_ERR_WAIT_TYPE 指定 'wait_type' 出錯
*
* 返回值 : 當任務重新運行時,在事件標志組中為新的標志狀態,或如果延時或出錯發生,則返回 0。
*
* 只有任務調用
*********************************************************************************************************
*/
OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_FLAG_NODE node;
OS_FLAGS flags_cur;
OS_FLAGS flags_rdy;
BOOLEAN consume;
if (OSIntNesting > 0)
{ /* 如果調用來自 ISR ... ... */
*err = OS_ERR_PEND_ISR; /* ... 從ISR中不能等待 */
return ((OS_FLAGS)0);
}
#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
if (wait_type & OS_FLAG_CONSUME)
{ /* 看是否需要清事件標志 */
wait_type &= ~OS_FLAG_CONSUME;
consume = TRUE;
}
else
{
consume = FALSE;
}
/*$PAGE*/
OS_ENTER_CRITICAL();
switch (wait_type)
{
case OS_FLAG_WAIT_SET_ALL: /* 看所有需要的標志位是否置1 */
flags_rdy = pgrp->OSFlagFlags & flags; /* 僅提取期望的標志位 */
if (flags_rdy == flags)
{ /* 必須匹配期望的所有標志位 */
if (consume == TRUE) /* 看是否需要清零標志位 */
{
pgrp->OSFlagFlags &= ~flags_rdy; /* 僅清除期望的標志位 */
}
flags_cur = pgrp->OSFlagFlags; /* 返回到標志組狀態 */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return (flags_cur);
}
else
{ /* 任務等待,直到事件發生或延時時間到 */
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
case OS_FLAG_WAIT_SET_ANY:
flags_rdy = pgrp->OSFlagFlags & flags; /* 僅提取期望的標志位 */
if (flags_rdy != (OS_FLAGS)0)
{ /* 看是否有標志置位? */
if (consume == TRUE)
{ /* 看是否需要清除標志? */
pgrp->OSFlagFlags &= ~flags_rdy; /* 只清除得到的標志位 */
}
flags_cur = pgrp->OSFlagFlags; /* 返回事件組狀態 */
OS_EXIT_CRITICAL(); /* 條件滿足返回調用函數 */
*err = OS_NO_ERR;
return (flags_cur);
}
else
{ /* 任務等待,直到事件發生或延時時間到 */
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
#if OS_FLAG_WAIT_CLR_EN > 0
case OS_FLAG_WAIT_CLR_ALL: /* 看所有需要的標志位是否清零 */
flags_rdy = ~pgrp->OSFlagFlags & flags; /* 僅提取期望的標志位 */
if (flags_rdy == flags)
{ /* 必須滿足期望的所有位 */
if (consume == TRUE)
{ /* 看是否需要清除標志? */
pgrp->OSFlagFlags |= flags_rdy; /* 設定期望的位 */
}
flags_cur = pgrp->OSFlagFlags; /* 返回事件組狀態 */
OS_EXIT_CRITICAL(); /* 條件滿足返回調用函數 */
*err = OS_NO_ERR;
return (flags_cur);
}
else
{ /* 任務等待,直到事件發生或延時時間到 */
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
case OS_FLAG_WAIT_CLR_ANY:
flags_rdy = ~pgrp->OSFlagFlags & flags; /* 僅提取期望的標志位 */
if (flags_rdy != (OS_FLAGS)0)
{ /* 看是否有其中一位清零? */
if (consume == TRUE)
{ /* 看是否需要清除標志? */
pgrp->OSFlagFlags |= flags_rdy; /* 設定期望的位 */
}
flags_cur = pgrp->OSFlagFlags; /* 返回事件組狀態 */
OS_EXIT_CRITICAL(); /* 條件滿足返回調用函數 */
*err = OS_NO_ERR;
return (flags_cur);
}
else
{ /* 任務等待,直到事件發生或延時時間到 */
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
#endif
default:
OS_EXIT_CRITICAL();
flags_cur = (OS_FLAGS)0;
*err = OS_FLAG_ERR_WAIT_TYPE;
return (flags_cur);
}
OS_Sched(); /* 尋找下一個 HPT 就緒運行 */
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBStat & OS_STAT_FLAG) /* 有延時嗎? */
{
OS_FlagUnlink(&node);
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* 是的 */
OS_EXIT_CRITICAL();
flags_cur = (OS_FLAGS)0;
*err = OS_TIMEOUT; /* 顯示延時等待 */
}
else
{
if (consume == TRUE)
{ /* 看是否需要清除標志? */
switch (wait_type)
{
case OS_FLAG_WAIT_SET_ALL:
case OS_FLAG_WAIT_SET_ANY: /* 僅清除得到的位 */
pgrp->OSFlagFlags &= ~OSTCBCur->OSTCBFlagsRdy;
break;
#if OS_FLAG_WAIT_CLR_EN > 0
case OS_FLAG_WAIT_CLR_ALL:
case OS_FLAG_WAIT_CLR_ANY: /* 僅設定得到的位 */
pgrp->OSFlagFlags |= OSTCBCur->OSTCBFlagsRdy;
break;
#endif
}
}
flags_cur = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*err = OS_NO_ERR; /* 事件發生 */
}
return (flags_cur);
}
/*$PAGE*/
/*
*********************************************************************************************************
* 發送事件標志位
*
* 函數描述: 該函數用于置位或清除事件標志組中的一些位。這些位由'位掩碼'指定設置或清除。
*
* 輸入參數 : pgrp 指向期望的事件標志組的指針
*
* flags 如果'opt'為OS_FLAG_SET,則在'flags'中設定的每一位在事件標志組中將設定對應的位。
* 例如,置高 0, 4和 5位,則設定'flags' 為:
*
* 0x31 (注意, 0位是等級最低位)
*
* 如果'opt'為OS_FLAG_CLR,則在'flags'中設定的每一位在事件標志組中將設定對應的位。
* 例如,置低 0, 4和 5位,則設定'flags' 為:
*
* 0x31 (注意, 0位是等級最低位)
*
* opt 標志選項:
* 置高 (OS_FLAG_SET)
* 置低 (OS_FLAG_CLR)
*
* err 指向出錯代碼:
* OS_NO_ERR 調用成功
* OS_FLAG_INVALID_PGRP 傳遞一個空指針
* OS_ERR_EVENT_TYPE 指向的類型不是事件標志組
* OS_FLAG_INVALID_OPT 無效選項
*
* 返回值 : 事件標志組設置的新值。
*
* 從任務或ISR中調用
*
* 警告 : 1) 該函數的執行時間取決于等待事件標志組任務的數量。
* 2) The amount of time interrupts are DISABLED depends on the number of tasks waiting on
* the event flag group.
*********************************************************************************************************
*/
OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err)
{
#if OS_CRITICAL_METHOD == 3 /* 為CPU狀態寄存器分配存儲變量 */
OS_CPU_SR cpu_sr;
#endif
OS_FLAG_NODE *pnode;
BOOLEAN sched;
OS_FLAGS flags_cur;
OS_FLAGS flags_rdy;
#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
/*$PAGE*/
OS_ENTER_CRITICAL();
switch (opt)
{
case OS_FLAG_CLR:
pgrp->OSFlagFlags &= ~flags; /* 在標志組中清除指定標志 */
break;
case OS_FLAG_SET:
pgrp->OSFlagFlags |= flags; /* 在標志組中置高指定標志 */
break;
default:
OS_EXIT_CRITICAL(); /* 無效選項 */
*err = OS_FLAG_INVALID_OPT;
return ((OS_FLAGS)0);
}
sched = FALSE; /* 不需要重調度 */
pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
while (pnode != (OS_FLAG_NODE *)0) /* 遍歷等待事件標志組的所有任務 */
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -