7、事件标志位

事件标志组的实现

  1. 事件标志组的原理与创建
  2. 事件标志组的等待与通知
  3. 事件标志组的删除与状态查询

1、事件标志组的原理与创建

typedef struct _tFlagGroup
{
    // 事件控制块
tEvent event;

// 当前事件标志
uint32_t flags;
}tFlagGroup;


void tFlagGroupInit (tFlagGroup * flagGroup, uint32_t flags)
{
    tEventInit(&flagGroup->event, tEventTypeFlagGroup);
    flagGroup->flags = flags;
}

2、事件标志组的等待与通知

###任务二中首先调用tFlagGroupWait
tFlagGroupWait(&flagGroup1, TFLAGGROUP_CLEAR_ALL, 0x4, &resultFlags, 10);
##函数原型:
/**********************************************************************************************************
** 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;
}
#检查并消耗掉事件标志:
    result = tFlagGroupCheckAndConsume(flagGroup, waitType, &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:计算出哪位为0
    uint32_t calcFlag = isSet ? (flagGroup->flags & srcFlags) : (~flagGroup->flags & srcFlags);

    // 所有标志位出现, 或者做任意标志位出现,满足条件
    if (((isAll != 0) && (calcFlag == srcFlags)) || ((isAll == 0) && (calcFlag != 0)))
    {
        // 是否消耗掉标志位
        if (isConsume)
        {
            if (isSet)
            {
                // 清除为1的标志位,变成0
                flagGroup->flags &= ~srcFlags;
            }
            else 
            {
                // 清除为0的标志位,变成1
                flagGroup->flags |= srcFlags;
            }
        }
        *flags = calcFlag;
        return tErrorNoError;
    }

    *flags = calcFlag;
    return tErrorResourceUnavaliable;
}
#任务1中:通知事件标志组中的任务有新的标志发生
    tFlagGroupNotify(&flagGroup1, 0, 0x6);
#原型:

3、事件标志组的删除与状态查询

/**********************************************************************************************************
** 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);
}
#获取事件标志组中特定的标志
/**********************************************************************************************************
** 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;
}

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/79257297
今日推荐