OS_FLAG.C(2)
生活随笔
收集整理的這篇文章主要介紹了
OS_FLAG.C(2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本篇介紹OS_FLAG.C文件中的創建事件標志組函數*OSFlagCreate (OS_FLAGS ?flags,INT8U *perr)和刪除事件標志組函數?*OSFlagDel (OS_FLAG_GRP ?*pgrp,INT8U ?opt,INT8U ?*perr)。
OS_FLAG_GRP ?*OSFlagCreate (OS_FLAGS ?flags,INT8U ? ?*perr)創建事件標志組:
/*$PAGE*/ /* ********************************************************************************************************* * CREATE AN EVENT FLAG * 創建事件標志組 * Description: This function is called to create an event flag group. *描述:該函數是用來創建一個事件標志組。 * Arguments : flags Contains the initial value to store in the event flag group. *參數: --flags:事件標志組的事件標志初值 * perr is a pointer to an error code which will be returned to your application: * OS_ERR_NONE if the call was successful. * OS_ERR_CREATE_ISR if you attempted to create an Event Flag from an * ISR. * OS_ERR_FLAG_GRP_DEPLETED if there are no more event flag groups * --perr:指向錯誤碼的指針,該指針將會返回到你的應用程序中。OS_ERR_NONE:無錯誤類型,說明調用成功。OS_ERR_CREATE_ISR:從中斷中創建一個事件標志OS_ERR_FLAG_GRP_DEPLETED:如果系統中沒有剩余的空閑事件標志組,需要更改OS_CFG.H中的事件標志組數目配置 * Returns : A pointer to an event flag group or a NULL pointer if no more groups are available. *返回值:指向事件標志組的指針,如果沒有可以返回的可用指針,返回null。 * Called from: Task ONLY 只能被任務調用 ********************************************************************************************************* */OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags,INT8U *perr) {OS_FLAG_GRP *pgrp; /*指向事件標志組的指針*/ #if OS_CRITICAL_METHOD == 3u /*中斷類型被設置為3*/OS_CPU_SR cpu_sr = 0u; #endif#ifdef OS_SAFETY_CRITICAL /*如果定義了安全中斷*/if (perr == (INT8U *)0) /*如果錯誤碼為0*/{OS_SAFETY_CRITICAL_EXCEPTION(); /*調用安全中斷異常函數*/} #endif#ifdef OS_SAFETY_CRITICAL_IEC61508if (OSSafetyCriticalStartFlag == OS_TRUE) {OS_SAFETY_CRITICAL_EXCEPTION();} #endifif (OSIntNesting > 0u) /* 如果是從中斷函數調用 */{ *perr = OS_ERR_CREATE_ISR; /* 將錯誤碼指針設置為OS_ERR_CREATE_ISR,不能從中斷函數調用 */return ((OS_FLAG_GRP *)0); /*返回0*/}OS_ENTER_CRITICAL(); /*關中斷(進入中斷)*/pgrp = OSFlagFreeList; /*pgrp指向空閑事件標志列表,來得到一個空閑事件標志組*/ if (pgrp != (OS_FLAG_GRP *)0) /*有空閑的事件標志組*/{ OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList; /*分配后,調整系統空閑事件標志組鏈表指針*/pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; /* 將標志類型設置為事件標志類型*/pgrp->OSFlagFlags = flags; /* 事件標志初始化*/pgrp->OSFlagWaitList = (void *)0; /*等待任務鏈接表指針初始化為NULL*/#if OS_FLAG_NAME_EN > 0u /*如果標志有名字的話,將名字初始化為未命名*/pgrp->OSFlagName = (INT8U *)(void *)"?";#endifOS_EXIT_CRITICAL(); /*退出中斷*/*perr = OS_ERR_NONE; /*將錯誤類型設置為OS_ERR_NONE*/} else /*沒有空閑的事件標志組*/{OS_EXIT_CRITICAL(); /*退出中斷*/*perr = OS_ERR_FLAG_GRP_DEPLETED;/*將錯誤碼設置為OS_ERR_FLAG_GRP_DEPLETED*/}return (pgrp); /* Return pointer to event flag group */ }流程圖如下:
其中,上面的“進行相應處理”為:
這四個步驟對應代碼為:
OSFlagFreeList = (OS_FLAG_GRP *)OSFlagFreeList->OSFlagWaitList; /*分配后,調整系統空閑事件標志組鏈表指針*/pgrp->OSFlagType = OS_EVENT_TYPE_FLAG; /* 將標志類型設置為事件標志類型*/pgrp->OSFlagFlags = flags; /* 事件標志初始化*/pgrp->OSFlagWaitList = (void *)0; /*等待任務鏈接表指針初始化為NULL*/刪除事件標志組函數:???*OSFlagDel (OS_FLAG_GRP ?*pgrp,INT8U ?opt,INT8U ?*perr)
/*$PAGE*/ /* ********************************************************************************************************* * DELETE AN EVENT FLAG GROUP * 刪除事件標志組 * Description: This function deletes an event flag group and readies all tasks pending on the event flag * group. *描述:該功能刪除事件標志組并且將事件標志組中所有掛起的任務設為就緒 * Arguments : pgrp is a pointer to the desired event flag group. *參數: --pgrp:指向事件標志組的指針 * opt determines delete options as follows: * opt == OS_DEL_NO_PEND Deletes the event flag group ONLY if no task pending * opt == OS_DEL_ALWAYS Deletes the event flag group even if tasks are * waiting. In this case, all the tasks pending will be * readied. * --opt:刪除的方式可以有以下幾種選擇:OS_DEL_NO_PEND:只有當沒有任務掛起時才能刪除事件標志組OS_DEL_ALWAYS:即使任務處于等待狀態,也要刪除事件標志組。這種情況下所有掛起的任務將會處于就緒態。 * perr is a pointer to an error code that can contain one of the following values: * OS_ERR_NONE The call was successful and the event flag group was deleted * OS_ERR_DEL_ISR If you attempted to delete the event flag group from an ISR * OS_ERR_FLAG_INVALID_PGRP If 'pgrp' is a NULL pointer. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to an event flag group * OS_ERR_INVALID_OPT An invalid option was specified * OS_ERR_TASK_WAITING One or more tasks were waiting on the event flag * group. * --perr:指向錯誤碼的指針,該指針可以設置為以下值:OS_ERR_NONE:調用成功,事件標志組被刪除OS_ERR_DEL_ISR:嘗試從中斷中調用刪除函數OS_ERR_FLAG_INVALID_PGRP:如果pgrp為空指針OS_ERR_EVENT_TYPE:pgrp不是指向事件標志組的指針;OS_ERR_INVALID_OPT:opt參數不是指定的值;OS_ERR_TASK_WAITING:如果opt參數為OS_DEL_NO_PEND,那么此時有任務等待事件標志組 * Returns : pgrp upon error * (OS_EVENT *)0 if the event flag group was successfully deleted. *返回值:如果事件標志組被刪除,組則返回空指針;如果沒有刪除,則仍然返回指向該事件標志組的指針。后一種情況需要檢查出錯代碼,找出事件標志的失敗的原因。 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of * the event flag group MUST check the return code of OSFlagAccept() and OSFlagPend(). * 2) This call can potentially disable interrupts for a long time. The interrupt disable * time is directly proportional to the number of tasks waiting on the event flag group.注釋:1)該功能需要小心使用,期望事件標志組的任務一定要檢測OSFlagAccept()和OSFlagPend()兩個函數的返回碼。2)該函數有可能長時間關閉中斷,其時間長短決定于標志組的任務個數。 ********************************************************************************************************* */#if OS_FLAG_DEL_EN > 0u OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp,INT8U opt,INT8U *perr) {BOOLEAN tasks_waiting; /*有等待任務標志*/OS_FLAG_NODE *pnode; /*標志節點*/OS_FLAG_GRP *pgrp_return; /*返回指針*/ #if OS_CRITICAL_METHOD == 3u 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) /*有效化pgrp*/{ *perr = OS_ERR_FLAG_INVALID_PGRP;return (pgrp);} #endifif (OSIntNesting > 0u) /*看是否從中斷中調用的*/{ *perr = OS_ERR_DEL_ISR; return (pgrp);}if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG) /*有效化事件組類型*/{ *perr = OS_ERR_EVENT_TYPE;return (pgrp);}OS_ENTER_CRITICAL(); /*進入中斷*/if (pgrp->OSFlagWaitList != (void *)0) /*看任務正在等待事件標志是否為空*/{ tasks_waiting = OS_TRUE; /*有*/}else{tasks_waiting = OS_FALSE; /*無*/}switch (opt) /*選擇刪除的方式*/{case OS_DEL_NO_PEND: /*無任務掛起才刪除*/if (tasks_waiting == OS_FALSE) /*沒有任務正在等待*/{#if OS_FLAG_NAME_EN > 0upgrp->OSFlagName = (INT8U *)(void *)"?";/*名稱初始化*/#endifpgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;/*標志類型設置為未被使用*/pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /*將該事件標志組加入到事件標志組空閑鏈表中*/pgrp->OSFlagFlags = (OS_FLAGS)0; /*將標志位設為0*/OSFlagFreeList = pgrp; /*空閑列表指針指向新的(進行過刪除事件標志組函數)鏈表*/OS_EXIT_CRITICAL(); /*退出中斷*/*perr = OS_ERR_NONE; /*錯誤類型設置為無錯誤類型*/pgrp_return = (OS_FLAG_GRP *)0; /*事件標志組已經被刪除,因而返回為0*/} else /*有任務正在等待*/{OS_EXIT_CRITICAL();/*退出中斷*/*perr = OS_ERR_TASK_WAITING;/*將錯誤類型設置為OS_ERR_TASK_WAITING*/pgrp_return = pgrp; /*將pgrp賦給pgrp_return*/}break;case OS_DEL_ALWAYS: /*如果為無論有沒有掛起,都刪除*/pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList; /*指向等待事件組的節點鏈表*/while (pnode != (OS_FLAG_NODE *)0) /*遍歷該鏈表*/{ (void)OS_FlagTaskRdy(pnode, (OS_FLAGS)0); /*將該鏈表中的節點指向的任務轉為就緒狀態*/pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;}#if OS_FLAG_NAME_EN > 0u /*如果有名字,將名字初始化*/pgrp->OSFlagName = (INT8U *)(void *)"?";#endifpgrp->OSFlagType = OS_EVENT_TYPE_UNUSED; /*將標志類型設置為未使用類型*/pgrp->OSFlagWaitList = (void *)OSFlagFreeList;/* 將該組返回到空閑列表中*/pgrp->OSFlagFlags = (OS_FLAGS)0;OSFlagFreeList = pgrp;OS_EXIT_CRITICAL(); /*退出中斷*/if (tasks_waiting == OS_TRUE) { /*如果之前是有任務在等待事件標志組*/OS_Sched(); /*進行調度(執行最高優先級的任務)*/}*perr = OS_ERR_NONE; /*將錯誤類型設置為無錯誤類型*/pgrp_return = (OS_FLAG_GRP *)0; /* 事件標志組已經被刪除,返回空*/break;default: /*其他情況下*/OS_EXIT_CRITICAL(); /*退出中斷*/*perr = OS_ERR_INVALID_OPT; /*將錯誤碼設置為OS_ERR_INVALID_OPT*/pgrp_return = pgrp; /*將pgrp賦值給pgrp_return*/break;}return (pgrp_return); /*返回pgrp_return*/ } #endif刪除函數流程圖為:
其中,刪除操作為(針對OS_DEL_NO_PEND刪除類型):
如果刪除類型是OS_DEL_ALWAYS:則在上述操作步驟之前加一個:將等待事件組的節點鏈表中的節點指向的任務轉為就緒狀態。
對應的代碼段為:
#if OS_FLAG_NAME_EN > 0upgrp->OSFlagName = (INT8U *)(void *)"?";/*名稱初始化*/ #endif pgrp->OSFlagType = OS_EVENT_TYPE_UNUSED;/*標志類型設置為未被使用*/ pgrp->OSFlagWaitList = (void *)OSFlagFreeList; /*將該事件標志組加入到事件標志組空閑鏈表中*//*下圖<1>*/ pgrp->OSFlagFlags = (OS_FLAGS)0; /*將標志位設為0*/ OSFlagFreeList = pgrp; /*空閑列表指針指向新的(進行過刪除事件標志組函數)鏈表*//*下圖2*/可能直接理解有點困難,我們圖解一下:
上圖即從原始狀態經過程序之后的轉化狀態。<1><2>對應的代碼上面注釋也寫清楚了。
總結
以上是生活随笔為你收集整理的OS_FLAG.C(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OS_FLAG.C(1)
- 下一篇: OS_FLAG.C(3)