📄 sem.c
字号:
#include <AT89X52.H>
#include "os_core.h"
#include "main.h"
#include "task_switch.h"
#include "sem.h"
#include "q.h"
#include "uart.h"
/////////////////信号量定义////////////////////////////////////////////////////
SemBlk Sem[MAX_SEM];
/////////////////////////////初始化信号量//////////////////////////////////////
void OSSemCreat(uint8 Index,uint8 Count) reentrant
{
if(Index<MAX_SEM) //存在该信号量
{
Sem[Index].OSTaskPendTbl=0; //等待信号量的任务列表
Sem[Index].OSEventCount=Count; //信号量
}
}
/////////////////////////任务等待信号量////////////////////////////////////////
uint8 OSTaskSemPend(uint8 Index,uint8 Timeout) reentrant
{
if(Index<MAX_SEM) //存在该信号量
{
if(Sem[Index].OSEventCount) //信号量有效
{
Sem[Index].OSEventCount -- ; //减一
}
else
{
Sem[Index].OSTaskPendTbl|=OSMapTbl[OS_Current_ID]; //加入信号的任务等待表
bb:
if(OSWait(K_TMO,Timeout)==TMO_EVENT) //超时
{
Sem[Index].OSTaskPendTbl &= ~OSMapTbl[OS_Current_ID]; //从等待表中去除
return SEM_TMO; //返时超时
}
if(Sem[Index].OSTaskPendTbl&OSMapTbl[OS_Current_ID]) //等待表中还有该任务
goto bb; //不是因为有信号而恢复
}
return SEM_OK; //信号量有效
}
return NOT_OK;
}
///////////////////////////////任务发送信号量///////////////////////////////////
void OSSemPost(uint8 Index) reentrant
{
uint8 i,tempPrio=255;
if(Index<MAX_SEM) //存在该信号量
{
for(i=0;i<TASK_NUM;i++) //查找优先级最高的任务
{
if(Sem[Index].OSTaskPendTbl&OSMapTbl[i]&&OS_TCB[i].Prio<tempPrio)
{
tempPrio=OS_TCB[i].Prio;
}
}
for(i=0;i<TASK_NUM;i++)
{
if(Sem[Index].OSTaskPendTbl&OSMapTbl[i]&&OS_TCB[i].Prio==tempPrio)
{
break;
}
}
if(i < TASK_NUM) //如果有任务需要
{
OS_ENTER_CRITICAL(); //进入临界区
Sem[Index].OSTaskPendTbl &= ~OSMapTbl[i]; //从等待表中去除
OS_EXIT_CRITICAL(); //退出临界区
OSSendSignal(i);
}
else //没有任务需要
{
Sem[Index].OSEventCount++; //使信号量加一
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -