互斥信号量
1、互斥信号量的原理与创建
互斥信号量类型
typedef struct _tMutex
{
//事件控制块
tEvent event;
//已被锁定的次数
uint32_t lockedCount;
//拥有者
tTask * owner;
//拥有原始的优先级
uint32_t ownerOriginalPrio;
}
#初始化互斥信号量
void tMutexInit (tMutex * mutex)
{
tEventInit(&mutex->event, tEventTypeMutex);
mutex->lockedCount = 0;
mutex->owner = (tTask *)0;
mutex->ownerOriginalPrio = TINYOS_PRO_COUNT;
}
2、互斥信号量的等待与通知
2.1、等待信号量
uint32_t tMutexWait(tMutex * mutex,uint32_t waitTicks)
{
//1、进入临界保护区
uint32_t status = tTaskEnterCritical();
//2、如果没有锁定,则使用当前任务锁定
if(mutex->lockedCount <= 0)
{
//拥有者赋值为当前任务
mutex->owner = currentTask;
mutex->ownerOriginalPric = currentTask->prio;
mutex->lockedCount++;
//返回
return tErrorNoError;
}
else
{
//信号量已经被锁定
if(mutex->owner == currentTask)
{
//如果是信号量的拥有者再次被wait,简单增加计数
mutex->lockeCount++;
//退出临界区
tTaskExitCritical(status);
return tErrorNoError;
}
else
{
//如果是信号量拥有者之外的任务wait
//优先级继承方式处理
if (currentTask->prio < mutex->owner->prio)
{
tTask * owner = mutex->owner;
// 如果当前任务的优先级比拥有者优先级更高,则使用优先级继承
// 提升原拥有者的优先
if (owner->state == TINYOS_TASK_STATE_RDY)
{
// 任务处于就绪状态时,更改任务在就绪表中的位置
tTaskSchedUnRdy(owner);
owner->prio = currentTask->prio;
tTaskSchedRdy(owner);
}
else
{
// 其它状态,只需要修改优先级
owner->prio = currentTask->prio;
}
}
// 当前任务进入等待队列中
tEventWait(&mutex->event, currentTask, (void *)0, tEventTypeMutex, waitTicks);
tTaskExitCritical(status);
// 执行调度, 切换至其它任务
tTaskSched();
return currentTask->waitEventResult;
}
}
}
3、互斥信号量的删除与状态查询