📄 os_mutex.c
字号:
/*
*******************************************************************************
*
* MicroROS
*
* Copyright (C) 2007 <amwox@163.com>
*
* Description : 互斥型信号量
*
* File : os_mutex.c
* Author : amwox
* Edition : V0.10
* History : 2007-11-18 created
* 2008-01-28 增加事件列表指针,并对处理方式作了相应的变化
*******************************************************************************
*/
#include "..\include\MicroROS.h"
#include "..\include\os_cpu.h"
#if MUTEX_EN > 0
/*
* Description :
* Arguments :
* Returns :
*/
void OS_MutexCreate(pMUTEX pMutex, BYTE priority)
{
pMutex->pLockMutex = NULL;
#if EVENT_BLOCK_COUNT > 0
pMutex->BlockCnt = 0;
#endif
pMutex->Priority = priority;
pMutex->LockPriority = priority;
}
/*
* Description : 申请一个互斥体
* Arguments :
* Returns :
*/
BYTE OS_MutexLock(pMUTEX pMutex,WORD timeout)
{
CPU_SREG cpu_sreg;
BYTE err = NO_ERROR;
OS_ENTER_CRITICAL();
pPID pTmp = os_kernel.pRunning;
if (pMutex->pLockMutex == NULL) { /*互斥体处于解锁状态*/
pMutex->pLockMutex = pTmp; /*锁定当前进程*/
pMutex->LockPriority = pTmp->Priority;
}
else {
pPID plock = pMutex->pLockMutex;
//检查:是否发生优先级反转
if (plock->Priority > pTmp->Priority) { /*互斥体已被一个低优先级的进程锁定*/ /*提升优先级*/
plock->Priority = pMutex->Priority; /*按优先级天花板协议提升*/
}
_AppendEvent(&pMutex->pLockMutex,pTmp);
pTmp->TimerCnt = timeout;
pTmp->State |= BV(PID_MUTEX); /*等待信号量状态*/
#if EVENT_BLOCK_COUNT > 0
pMutex->BlockCnt ++;
#endif
err = TIME_OUT;
while (pTmp->TimerCnt) {
OS_TaskSuspend(pTmp);
if (pTmp->TimerCnt != LIMITLESS) {
_QueueTimer(pTmp);
}
OS_EXIT_CRITICAL();
_Schedule();
OS_ENTER_CRITICAL();
if (pMutex->pLockMutex == pTmp) { /*已解锁*/
pMutex->LockPriority = pTmp->Priority;
break;
}
}
#if EVENT_BLOCK_COUNT > 0
pMutex->BlockCnt --;
#endif
_RemoveEvent(&pMutex->pLockMutex,pTmp);
pTmp->State &= ~BV(PID_MUTEX);
}
OS_EXIT_CRITICAL();
return err;
}
/*
* Description : 释放一个互斥体
* Arguments :
* Returns :
*/
void OS_MutexUnLock(pMUTEX pMutex)
{
if (pMutex->pLockMutex == NULL) {
return;
}
if (pMutex->pLockMutex != os_kernel.pRunning) { /*锁定的不是当前进程,原因TIMEOUT*/
return;
}
os_kernel.pRunning->Priority = pMutex->LockPriority; /*恢复优先级*/
pMutex->pLockMutex = pMutex->pLockMutex->pEventNext;
os_kernel.pRunning->pEventNext = NULL;
if (pMutex->pLockMutex != NULL) {
CPU_SREG cpu_sreg;
OS_ENTER_CRITICAL();
if (pMutex->pLockMutex->TimerCnt != LIMITLESS)
_RemoveTimer(pMutex->pLockMutex);
OS_TaskResume(pMutex->pLockMutex);
OS_EXIT_CRITICAL();
_Schedule();
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -