事件标志组的等待与通知
生活随笔
收集整理的這篇文章主要介紹了
事件标志组的等待与通知
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 事件標志組的等待與通知
- 1.1 設計需求
- 1.2 設計實現
1 事件標志組的等待與通知
1.1 設計需求
當事件標志位發生時:
- 沒有任務等待,設置相應的事件標志。
- 有任務等待時,喚醒等待任務。
1.2 設計實現
等待事件標志:
無查詢等待事件標志:
通知事件發生:
tFlagGroup.h:
/*************************************** Copyright (c)****************************************************** ** File name : tFlagGroup.h ** Latest modified Date : 2016-06-01 ** Latest Version : 0.1 ** Descriptions : tinyOS的事件標志實現 ** **-------------------------------------------------------------------------------------------------------- ** Created by : 01課堂 lishutong ** Created date : 2016-06-01 ** Version : 1.0 ** Descriptions : The original version ** **-------------------------------------------------------------------------------------------------------- ** Copyright : 版權所有,禁止用于商業用途 ** Author Blog : http://ilishutong.com **********************************************************************************************************/ #ifndef TFLAGGROUP_H #define TFLAGGROUP_H#include "tConfig.h" #include "tEvent.h"typedef struct _tFlagGroup {// 事件控制塊tEvent event;// 當前事件標志uint32_t flags; }tFlagGroup;#define TFLAGGROUP_CLEAR (0x0 << 0) #define TFLAGGROUP_SET (0x1 << 0) #define TFLAGGROUP_ANY (0x0 << 1) #define TFLAGGROUP_ALL (0x1 << 1)#define TFLAGGROUP_SET_ALL (TFLAGGROUP_SET | TFLAGGROUP_ALL) #define TFLAGGROUP_SET_ANY (TFLAGGROUP_SET | TFLAGGROUP_ANY) #define TFLAGGROUP_CLEAR_ALL (TFLAGGROUP_CLEAR | TFLAGGROUP_ALL) #define TFLAGGROUP_CLEAR_ANY (TFLAGGROUP_CLEAR | TFLAGGROUP_ANY)#define TFLAGGROUP_CONSUME (0x1 << 7)/********************************************************************************************************** ** Function name : tFlagGroupInit ** Descriptions : 初始化事件標志組 ** parameters : flagGroup 等待初始化的事件標志組 ** parameters : flags 初始的事件標志 ** Returned value : 無 ***********************************************************************************************************/ void tFlagGroupInit (tFlagGroup * flagGroup, uint32_t flags);/********************************************************************************************************** ** Function name : tFlagGroupWait ** Descriptions : 等待事件標志組中特定的標志 ** parameters : flagGroup 等待的事件標志組 ** parameters : waitType 等待的事件類型 ** parameters : requstFlag 請求的事件標志 ** parameters : resultFlag 等待標志結果 ** parameters : waitTicks 當等待的標志沒有滿足條件時,等待的ticks數,為0時表示永遠等待 ** Returned value : 等待結果,tErrorResourceUnavaliable.tErrorNoError,tErrorTimeout ***********************************************************************************************************/ uint32_t tFlagGroupWait (tFlagGroup * flagGroup, uint32_t waitType, uint32_t requestFlag,uint32_t * resultFlag, uint32_t waitTicks);/********************************************************************************************************** ** Function name : tFlagGroupWaitGet ** Descriptions : 獲取事件標志組中特定的標志 ** parameters : flagGroup 獲取的事件標志組 ** parameters : waitType 獲取的事件類型 ** parameters : requstFlag 請求的事件標志 ** parameters : resultFlag 等待標志結果 ** Returned value : 獲取結果,tErrorResourceUnavaliable.tErrorNoError ***********************************************************************************************************/ uint32_t tFlagGroupNoWaitGet (tFlagGroup * flagGroup, uint32_t waitType, uint32_t requstFlag, uint32_t * requestFlag);/********************************************************************************************************** ** Function name : tSemNotify ** Descriptions : 通知信號量可用,喚醒等待隊列中的一個任務,或者將計數+1 ** parameters : sem 操作的信號量 ** Returned value : 無 ***********************************************************************************************************/ void tFlagGroupNotify (tFlagGroup * flagGroup, uint8_t isSet, uint32_t flags);#endif /* TFLAGGROUP_H */tFlagGroup.c:
/*************************************** Copyright (c)****************************************************** ** File name : tFlagGroup.c ** Latest modified Date : 2016-06-01 ** Latest Version : 0.1 ** Descriptions : tinyOS的事件標志實現 ** **-------------------------------------------------------------------------------------------------------- ** Created by : 01課堂 lishutong ** Created date : 2016-06-01 ** Version : 1.0 ** Descriptions : The original version ** **-------------------------------------------------------------------------------------------------------- ** Copyright : 版權所有,禁止用于商業用途 ** Author Blog : http://ilishutong.com **********************************************************************************************************/ #include "tFlagGroup.h" #include "tinyOS.h"/********************************************************************************************************** ** Function name : tFlagGroupInit ** Descriptions : 初始化事件標志組 ** parameters : flagGroup 等待初始化的事件標志組 ** parameters : flags 初始的事件標志 ** Returned value : 無 ***********************************************************************************************************/ void tFlagGroupInit (tFlagGroup * flagGroup, uint32_t flags) {tEventInit(&flagGroup->event, tEventTypeFlagGroup);flagGroup->flags = flags; }/********************************************************************************************************** ** Function name : tFlagGroupCheckAndConsume ** Descriptions : 輔助函數。檢查并消耗掉事件標志 ** parameters : flagGroup 等待初始化的事件標志組 ** parameters : type 事件標志檢查類型 ** parameters : flags 待檢查事件標志存儲地址和檢查結果存儲位置 ** Returned value : tErrorNoError 事件匹配;tErrorResourceUnavaliable 事件未匹配 ***********************************************************************************************************/ static uint32_t tFlagGroupCheckAndConsume (tFlagGroup * flagGroup, uint32_t type, uint32_t * flags) {uint32_t srcFlags = *flags;uint32_t isSet = type & TFLAGGROUP_SET;uint32_t isAll = type & TFLAGGROUP_ALL;uint32_t isConsume = type & TFLAGGROUP_CONSUME;// 有哪些類型的標志位出現// flagGroup->flags & flags:計算出哪些位為1// ~flagGroup->flags & flags:計算出哪位為0uint32_t calcFlag = isSet ? (flagGroup->flags & srcFlags) : (~flagGroup->flags & srcFlags);// 所有標志位出現, 或者做任意標志位出現,滿足條件if (((isAll != 0) && (calcFlag == srcFlags)) || ((isAll == 0) && (calcFlag != 0))){// 是否消耗掉標志位if (isConsume){if (isSet){// 清除為1的標志位,變成0flagGroup->flags &= ~srcFlags;}else {// 清除為0的標志位,變成1flagGroup->flags |= srcFlags;}}*flags = calcFlag;return tErrorNoError;}*flags = calcFlag;return tErrorResourceUnavaliable; }/********************************************************************************************************** ** Function name : tFlagGroupWait ** Descriptions : 等待事件標志組中特定的標志 ** parameters : flagGroup 等待的事件標志組 ** parameters : waitType 等待的事件類型 ** parameters : requstFlag 請求的事件標志 ** parameters : resultFlag 等待標志結果 ** parameters : waitTicks 當等待的標志沒有滿足條件時,等待的ticks數,為0時表示永遠等待 ** Returned value : 等待結果,tErrorResourceUnavaliable.tErrorNoError,tErrorTimeout ***********************************************************************************************************/ uint32_t tFlagGroupWait (tFlagGroup * flagGroup, uint32_t waitType, uint32_t requestFlag,uint32_t * resultFlag, uint32_t waitTicks) {uint32_t result;uint32_t flags = requestFlag;uint32_t status = tTaskEnterCritical();result = tFlagGroupCheckAndConsume(flagGroup, waitType, &flags);if (result != tErrorNoError){// 如果事件標志不滿足條件,則插入到等待隊列中currentTask->waitFlagsType = waitType;currentTask->eventFlags = requestFlag;tEventWait(&flagGroup->event, currentTask, (void *)0, tEventTypeFlagGroup, waitTicks);tTaskExitCritical(status);// 再執行一次事件調度,以便于切換到其它任務tTaskSched();*resultFlag = currentTask->eventFlags;result = currentTask->waitEventResult;}else{*resultFlag = flags;tTaskExitCritical(status);}return result; }/********************************************************************************************************** ** Function name : tFlagGroupNoWaitGet ** Descriptions : 獲取事件標志組中特定的標志 ** parameters : flagGroup 獲取的事件標志組 ** parameters : waitType 獲取的事件類型 ** parameters : requstFlag 請求的事件標志 ** parameters : resultFlag 等待標志結果 ** Returned value : 獲取結果,tErrorResourceUnavaliable.tErrorNoError ***********************************************************************************************************/ uint32_t tFlagGroupNoWaitGet (tFlagGroup * flagGroup, uint32_t waitType, uint32_t requestFlag, uint32_t * resultFlag) {uint32_t flags = requestFlag;uint32_t status = tTaskEnterCritical();uint32_t result = tFlagGroupCheckAndConsume(flagGroup, waitType, &flags);tTaskExitCritical(status);*resultFlag = flags;return status; }/********************************************************************************************************** ** Function name : tFlagGroupNotify ** Descriptions : 通知事件標志組中的任務有新的標志發生 ** parameters : flagGroup 事件標志組 ** parameters : isSet 是否是設置事件標志 ** parameters : flags 產生的事件標志 ***********************************************************************************************************/ void tFlagGroupNotify (tFlagGroup * flagGroup, uint8_t isSet, uint32_t flags) {tList *waitList;tNode * node;tNode * nextNode;uint8_t sched = 0;uint32_t status = tTaskEnterCritical();if (isSet) {flagGroup->flags |= flags; // 置1事件} else {flagGroup->flags &= ~flags; // 清0事件}// 遍歷所有的等待任務, 獲取滿足條件的任務,加入到待移除列表中waitList = &flagGroup->event.waitList;for (node = waitList->headNode.nextNode; node != &(waitList->headNode); node = nextNode) {uint32_t result;tTask *task = tNodeParent(node, tTask, linkNode);uint32_t flags = task->eventFlags;nextNode = node->nextNode;// 檢查標志result = tFlagGroupCheckAndConsume(flagGroup, task->waitFlagsType, &flags);if (result == tErrorNoError) {// 喚醒任務task->eventFlags = flags;tEventWakeUpTask(&flagGroup->event, task, (void *)0, tErrorNoError);sched = 1;}}// 如果有任務就緒,則執行一次調度if (sched){tTaskSched();}tTaskExitCritical(status); }參考資料:
總結
以上是生活随笔為你收集整理的事件标志组的等待与通知的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win8蓝屏后怎么重启电脑 突然蓝屏怎么
- 下一篇: u盘文件夹为文件怎么打开方式 怎样打开U