OS_FLAG.C(1)
本篇介紹OS_FLAG.C中的檢測事件標志組的標志狀態(tài)函數(shù)
OS_FLAGS ?OSFlagAccept (OS_FLAG_GRP ?*pgrp,OS_FLAGS flags,INT8U wait_type,INT8U *perr)檢測事件標志組的標志狀態(tài)函數(shù):
- 介紹一下wait_type:
在最后的代碼中也有相關介紹,為了更好理解,下面具體解釋一下:
?wait_type ? ? specifies whether you want ALL bits to be set/cleared or ANY of the bitsto be set/cleared.
* ? ? ? ? ? ? ? ? ? ? ? ? ? ?You can specify the following argument:
* ? ? ? ? ? ? ? ? ? ? ? ? ? ?OS_FLAG_WAIT_CLR_ALL ? You will check ALL bits in 'flags' to be clear (0)
* ? ? ? ? ? ? ? ? ? ? ? ? ? ?OS_FLAG_WAIT_CLR_ANY ? You will check ANY bit ?in 'flags' to be clear (0)
* ? ? ? ? ? ? ? ? ? ? ? ? ? ?OS_FLAG_WAIT_SET_ALL ? You will check ALL bits in 'flags' to be set ? (1)
* ? ? ? ? ? ? ? ? ? ? ? ? ? ?OS_FLAG_WAIT_SET_ANY ? You will check ANY bit ?in 'flags' to be set ? (1)
*--wait_type:定義等待事件標志位的方式.有以下四種參數(shù)選擇:
????OS_FLAG_WAIT_CLR_ALL:所有指定事件標志位清 (0);
? ??OS_FLAG_WAIT_CLR_ANY:任意指定事件標志位清 (0);
? ??OS_FLAG_WAIT_SET_ALL:所有指定事件標志位置 (1);
? ??OS_FLAG_WAIT_SET_ANY:任意指定事件標志位置 (1)。
將該參數(shù)加上一個常量OS_FLAG_CONSUME。例如,如果等待事件標志組中任意指定事件標志位置位,
并且在任意事件標志位置位后清除該位,則把參數(shù)wait_type設置為:OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME。
?所謂的消耗與否,就是事件組滿足條件后(獲得事件標志組后),事件標志組控制塊的對應事件標志是否清除,如果清除,就稱為消耗掉,如果不清除,就成為不消耗。
代碼中具體體現(xiàn)為:
result = (INT8U)(wait_type & OS_FLAG_CONSUME); /*將wiat_type與OS_FLAG_COUNSUME進行與,結果存放在result中*/if (result != (INT8U)0) /*判斷我們是否需要清除標志。*/{ wait_type &= ~OS_FLAG_CONSUME; /*不為0,消耗型,需要清除,wait_type保存其取反之后的值*/consume = OS_TRUE; /*"清除"事件標志位置1,需要對這個標志清0*/} else /*result為0,非消耗型。不需要清除*/{consume = OS_FALSE; /*"清除"事件標志位為0*/}將wiat_type與OS_FLAG_COUNSUME進行邏輯與運算,結果存放在result中。若是rusult為0,則說明wait_type是沒有加上OS_FLAG_CONSUME的,也就是非消耗類型的,否則就是消耗類型的。
- 該函數(shù)中第二個需要解釋的點:
以這個小片段為例,里面有一個與運算:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /*提取我們需要的位*/解釋一下我們是如何提取我們需要的位呢?這行語句為什么進行與運算?
| 0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 |
| 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
OSFlagFlags和flags都是8位。假定各自8位分別如上圖設置。當我們提取位的時候,就一一對應,進行邏輯與操作,并賦給flags_rdy:
| 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
如果是OS_FLAG_WAIT_SET_ANY等待類型,進行完與操作之后,
if (flags_rdy != (OS_FLAGS)0) /*看是否有任何設置為1的標志*/是將flags_rdy與0進行比較。然后執(zhí)行相關操作。
- 第三個需要提醒的點:
如果是消耗型的,在清除的時候,我們只清除了之前用到的位,并不是所有位都清除了。這點需要注意一下。
下面是該函數(shù)的源代碼:
/*$PAGE*/ /* ********************************************************************************************************* * CHECK THE STATUS OF FLAGS IN AN EVENT FLAG GROUP * 檢測事件標志組的標志狀態(tài) * Description: This function is called to check the status of a combination of bits to be set or cleared * in an event flag group. Your application can check for ANY bit to be set/cleared or ALL * bits to be set/cleared.This call does not block if the desired flags are not present. *描述:這個功能用來檢查位的組合狀態(tài),來確定事件標志組中的事件標志位是置位還是清0。你的應用程序可以檢查任意一位是置位還是清0,也可以檢查所有位是置位還是清0。 * 這個調用不會被阻塞如果需要的事件標志沒有產(chǎn)生。這點與于OSFlagPend()不同。 * Arguments : pgrp is a pointer to the desired event flag group. *參數(shù): --pgrp:指向事件標志組的指針 * 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. * --flags:指定需要檢查的事件標志位。為1則檢查對應位;為0則忽若對應位。flags是事件組合的標志,是位掩碼,表示事件要等待哪些位。如果應用程序等待任務組中事件標志中的0和2,掩碼為0x05。 * 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 'flags' to be clear (0) * OS_FLAG_WAIT_CLR_ANY You will check ANY bit in 'flags' to be clear (0) * OS_FLAG_WAIT_SET_ALL You will check ALL bits in 'flags' to be set (1) * OS_FLAG_WAIT_SET_ANY You will check ANY bit in 'flags' to be set (1) * --wait_type:定義等待事件標志位的方式.有以下四種參數(shù)選擇:OS_FLAG_WAIT_CLR_ALL:所有指定事件標志位清 (0);OS_FLAG_WAIT_CLR_ANY:任意指定事件標志位清 (0);OS_FLAG_WAIT_SET_ALL:所有指定事件標志位置 (1);OS_FLAG_WAIT_SET_ANY:任意指定事件標志位置 (1)。 * NOTE: Add OS_FLAG_CONSUME if you want the event flag to be 'consumed' by * the call. Example, to wait for any flag in a group AND then clear * the flags that are present, set 'wait_type' to: * OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME * 注釋:如果需要在得到期望的事件標志后,清除該事件標志,則可以在調用函數(shù)時,將該參數(shù)加上一個常量OS_FLAG_CONSUME。例如,如果等待事件標志組中任意指定事件標志位置位,并且在任意事件標志位置位后清除該位,則把參數(shù)wait_type設置為:OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME所謂的消耗與否,就是事件組滿足條件后,獲得事件標志組后。事件標志組控制塊的對應事件標志清除,即消耗掉。 * perr is a pointer to an error code and can be: * OS_ERR_NONE No error * OS_ERR_EVENT_TYPE You are not pointing to an event flag group * OS_ERR_FLAG_WAIT_TYPE You didn't specify a proper 'wait_type' argument. * OS_ERR_FLAG_INVALID_PGRP You passed a NULL pointer instead of the event flag * group handle. * OS_ERR_FLAG_NOT_RDY The desired flags you are waiting for are not * available. * --perr:是一個指向錯誤碼的指針,可以是一下幾種:OS_ERR_NONE:無錯誤OS_ERR_EVENT_TYPE:指針未指向事件標志組錯OS_ERR_FLAG_WAIT_TYPE:參數(shù)wait_type不是指定的四個方式之一。OS_ERR_FLAG_INVALID_PGRP:pgrp為空指針OS_ERR_FLAG_NOT_RDY:指定的事件標志沒有發(fā)生。 * Returns : The flags in the event flag group that made the task ready or, 0 if a timeout or an error * occurred. *返回值:返回事件標志組的事件標志。如果是超時或者有錯誤發(fā)生,返回0 * Called from: Task or ISR *調用:從任務或者中斷調用 * Note(s) : 1) IMPORTANT, the behavior of this function has changed from PREVIOUS versions. The * function NOW returns the flags that were ready INSTEAD of the current state of the * event flags.注釋:1)重點:該功能和之前版本的不同,現(xiàn)在版本的該功能返回的是就緒的標志,而不是當前事件的狀態(tài) ********************************************************************************************************* */#if OS_FLAG_ACCEPT_EN > 0u OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp,OS_FLAGS flags,INT8U wait_type,INT8U *perr) {OS_FLAGS flags_rdy; /*定義一個"準備完畢"含量值*/INT8U result; /*結果*/BOOLEAN consume; /*定義一個"清除"事件標志位(保存值)*/#if OS_CRITICAL_METHOD == 3u /*中斷被設置為類型3*/OS_CPU_SR cpu_sr = 0u;#endif#ifdef OS_SAFETY_CRITICAL /*如果定義了安全性中斷*/if (perr == (INT8U *)0) /*如果錯誤碼指針為空,調用安全中斷異常函數(shù)*/{OS_SAFETY_CRITICAL_EXCEPTION();}#endif#if OS_ARG_CHK_EN > 0u /*進行參數(shù)檢查*//*有效化pgrp指針*/if (pgrp == (OS_FLAG_GRP *)0) /*如果pgrp指針為空*/{ *perr = OS_ERR_FLAG_INVALID_PGRP; /*將錯誤碼指針設置為OS_ERR_FLAG_INVALID_PGRP*/return ((OS_FLAGS)0); /*返回0*/}#endifif (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) /*有效化事件控制塊類型 如果不是事件類型標志*/{ *perr = OS_ERR_EVENT_TYPE; /*將錯誤碼指針設置為OS_ERR_EVENT_TYPE*/return ((OS_FLAGS)0); /*返回0*/}result = (INT8U)(wait_type & OS_FLAG_CONSUME); /*將wiat_type與OS_FLAG_COUNSUME進行與,結果存放在result中*/if (result != (INT8U)0) /*判斷我們是否需要清除標志。*/{ wait_type &= ~OS_FLAG_CONSUME; /*不為0,需要清除,wait_type保存其取反之后的值*/consume = OS_TRUE; /*"清除"事件標志位置1,需要對這個標志清0*/} else /*result為0,不需要清除*/{consume = OS_FALSE; /*"清除"事件標志位為0*/}/*$PAGE*/*perr = OS_ERR_NONE; /*先將錯誤碼指針設置為無錯誤形式*/OS_ENTER_CRITICAL(); /*關中斷(進入中斷)*/switch (wait_type) /*判斷等待類型,根據(jù)類型不同,處理相應的代碼*/{case OS_FLAG_WAIT_SET_ALL: /*等待選擇的所有位都置1,即所有指定事件標志位清 (1)*/flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); /*提取我們需要的位*/if (flags_rdy == flags) /*必須匹配到我們需要的所有的位*/{ if (consume == OS_TRUE) /*如果是消耗型的*/{ pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /*將請求事件組中對應請求標志位的位清零,消耗了事件*/}}else /*沒有匹配到我們需要的所有的位,阻塞,等待事件標志組完成或者是超時*/{*perr = OS_ERR_FLAG_NOT_RDY;/*將錯誤碼設置為標志位位準備好類型*/}OS_EXIT_CRITICAL(); /*開中斷*/break;case OS_FLAG_WAIT_SET_ANY: /*如果等待類型為任意指定事件標志位清(1)*/flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags); if (flags_rdy != (OS_FLAGS)0) /*看是否有任何設置為1的標志*/{ if (consume == OS_TRUE) /*如果是消耗類型*/{ pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy; /*只清除我們需要的位*/}}else{*perr = OS_ERR_FLAG_NOT_RDY; /*將錯誤類型設置為OS_ERR_FLAG_NOT_RDY*/}OS_EXIT_CRITICAL(); /*開中斷*/break;#if OS_FLAG_WAIT_CLR_EN > 0u /*允許生成 Wait on Clear 事件標志代碼*/case OS_FLAG_WAIT_CLR_ALL: /* 等待類型為所有指定事件標志位清 (0); */flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /*只提取我們需要的位 */if (flags_rdy == flags) { if (consume == OS_TRUE) { pgrp->OSFlagFlags |= flags_rdy; }} else {*perr = OS_ERR_FLAG_NOT_RDY;}OS_EXIT_CRITICAL();break;case OS_FLAG_WAIT_CLR_ANY:flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags; /* Extract only the bits we want */if (flags_rdy != (OS_FLAGS)0) { /* See if any flag cleared */if (consume == OS_TRUE) { /* See if we need to consume the flags */pgrp->OSFlagFlags |= flags_rdy; /* Set ONLY the flags that we got */}} else {*perr = OS_ERR_FLAG_NOT_RDY;}OS_EXIT_CRITICAL();break; #endifdefault: /*默認情況下*/OS_EXIT_CRITICAL();/*開中斷(退出中斷)*/flags_rdy = (OS_FLAGS)0;/*將flags_rdy設置為0*/*perr = OS_ERR_FLAG_WAIT_TYPE;/*錯誤碼設置為OS_ERR_FLAG_WAIT_TYPE*/break;}return (flags_rdy);/*返回flags_rdy*/ } #endif大概流程圖為:
END
不足之處還望提醒,謝過~
總結
以上是生活随笔為你收集整理的OS_FLAG.C(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OS_CORE.C(总结)
- 下一篇: OS_FLAG.C(2)