📄 os_sem.c
字号:
/*********************************************************************************************************
** Small RTOS(51)
** The Real-Time Kernel(For Keil c51)
**
** (c) Copyright 2002-2002, chenmingji
** All Rights Reserved
**
** V1.10
**
**
**--------------当前版本信息----------------------------------------------------------------------------
** 文件名: OS_Q.C
** 创建人: 陈明计
** 日 期: 2002年9月1日
** 描 述: Small RTOS(51)信号量代码
**
**--------------历史版本信息----------------------------------------------------------------------------
** 无
**------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_OS_SEM
#include "config.h"
#if EN_OS_SEM > 0
#if OS_MAX_TASKS < 9
uint8 OS_SEM_MEM_SEL OsSemBuf[OS_MAX_SEMS*2];
#else
uint8 OS_SEM_MEM_SEL OsSemBuf[OS_MAX_SEMS*3];
#endif
/*********************************************************************************************************
** 函数名称: OSSemCreate
** 功能描述: 初始化消息队列
** 输 入: index:信号量索引
** data:信号量初始值
** 输 出: NOT_OK:没有这个信号量
** OS_SEM_OK:成功
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 OSSemCreate(uint8 index,uint8 Data)
{
OS_ENTER_CRITICAL();
if (index < OS_MAX_SEMS)
{
#if OS_MAX_TASKS < 9
OsSemBuf[2*index] = Data;
OsSemBuf[2*index+1] = 0;
#else
OsSemBuf[3*index] = Data;
OsSemBuf[3*index+1] = 0;
OsSemBuf[3*index+2] = 0;
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
OS_EXIT_CRITICAL();
return NOT_OK;
}
/*********************************************************************************************************
** 函数名称: OSSemPend
** 功能描述: 等待一个信号量
** 输 入: index:信号量索引
** Tick:等待时间
** 输 出: NOT_OK:参数错误
** OS_SEM_OK:得到信号量
** OS_SEM_TMO:超时到
** OS_SEM_NOT_OK:没有得到信号量
** 全局变量: 无
** 调用模块: OSRunningTaskID,OSClearSignal,OSSched,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_PENT > 0
uint8 OSSemPend(uint8 index, uint8 Tick)
{
#if EN_OS_SEM_CHK
if (index > OS_MAX_SEMS)
{
return 0;
}
#endif
OS_ENTER_CRITICAL();
OSWaitTick[OSRunningTaskID()] = Tick;
#if OS_MAX_TASKS < 9
while (OsSemBuf[index*2] == 0)
{
OsSemBuf[index*2+1] |= OSMapTbl[OSRunningTaskID()];
#else
while (OsSemBuf[index*3] == 0)
{
if (OSRunningTaskID() < 8)
{
OsSemBuf[index*3+1] |= OSMapTbl[OSRunningTaskID()];
}
else
{
OsSemBuf[index*3+2] |= OSMapTbl[OSRunningTaskID()&0x07];
}
#endif
#ifdef __C51__
SP++;
*((uint8 idata *)SP) = index;
#endif
OSClearSignal(OSRunningTaskID());
OSSched();
OS_ENTER_CRITICAL();
#ifdef __C51__
index = *((uint8 idata *)SP);
SP--;
#endif
if (OSWaitTick[OSRunningTaskID()] == 0)
{
break;
}
}
#if OS_MAX_TASKS < 9
if (OsSemBuf[index*2] > 0)
{
OsSemBuf[index*2]--;
#else
if (OsSemBuf[index*3] > 0)
{
OsSemBuf[index*2]--;
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
else
{
OS_EXIT_CRITICAL();
return OS_SEM_TMO;
}
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemAccept
** 功能描述: 无等待请求信号量
** 输 入: index:信号量索引
** 输 出: NOT_OK:参数错误
** OS_SEM_OK:得到信号量
** OS_SEM_TMO:超时到
** OS_SEM_NOT_OK:没有得到信号量
** 全局变量: 无
** 调用模块: OSClearSignal,OSSched,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_ACCEPT > 0
uint8 OSSemAccept(uint8 index)
{
#if EN_OS_SEM_CHK
if (index > OS_MAX_SEMS)
{
return 0;
}
#endif
OS_ENTER_CRITICAL();
#if OS_MAX_TASKS < 9
if (OsSemBuf[index*2] > 0)
{
OsSemBuf[index*2]--;
#else
if (OsSemBuf[index*3] > 0)
{
OsSemBuf[index*2]--;
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
else
{
#if OS_MAX_TASKS < 9
OsSemBuf[index*2+1] &= ~OSMapTbl[OSRunningTaskID()];
#else
if (i < 8)
{
OsSemBuf[index*3+1] &= ~OSMapTbl[OSRunningTaskID()];
}
else
{
OsSemBuf[index*3+2] &= ~OSMapTbl[OSRunningTaskID() & 0x07];
}
#endif
OS_EXIT_CRITICAL();
return OS_SEM_NOT_OK;
}
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemIntPost
** 功能描述: 中断中发送一个信号量
** 输 入: index:信号量索引
** 输 出: NOT_OK:参数错误
** OS_SEM_OK:发送成功
** 全局变量: 无
** 调用模块: OSIntSendSignal,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_INT_POST > 0 || EN_OS_SEM_POST > 0
uint8 OSSemIntPost(uint8 index)
{
uint8 temp,i;
#if EN_OS_SEM_CHK
if (index > OS_MAX_SEMS)
{
return NOT_OK;
}
#endif
OS_ENTER_CRITICAL();
#if OS_MAX_TASKS < 9
if (OsSemBuf[index*2] <255)
{
OsSemBuf[index*2]++;
}
temp = OsSemBuf[index*2+1];
for (i = 0; i < 8; i++)
{
if ((temp & 0x01) != 0)
{
break;
}
temp = temp >> 1;
}
if (i < 8)
{
OsSemBuf[index*2+1] &= ~OSMapTbl[i];
OSIntSendSignal(i);
}
#else
if (OsSemBuf[index*3] <255)
{
OsSemBuf[index*3]++;
}
temp = OsSemBuf[index*3+1];
for (i = 0; i < 8; i++)
{
if ((temp & 0x01) != 0)
{
break;
}
temp = temp >> 1;
}
if (i >= 8)
{
temp = temp = OsSemBuf[index*3+2];
for ( ; i < 16; i++)
{
if ((temp & 0x01) != 0)
{
break;
}
temp = temp >> 1;
}
}
if (i < 16)
{
if (i < 8)
{
OsSemBuf[index*3+1] &= ~OSMapTbl[i];
}
else
{
OsSemBuf[index*3+2] &= ~OSMapTbl[i & 0x07];
}
OSIntSendSignal(i);
}
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemPost
** 功能描述: 发送一个信号量
** 输 入: index:信号量索引
** 输 出: NOT_OK:参数错误
** OS_SEM_OK:发送成功
** 全局变量: 无
** 调用模块: OSSemIntPost,OSSched
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_POST > 0
uint8 OSSemPost(uint8 index)
{
if (OSSemIntPost(index) == OS_SEM_OK)
{
OSSched();
return OS_SEM_OK;
}
else
{
return NOT_OK;
}
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemQuery
** 功能描述: 查询信号量
** 输 入: index:信号量索引
** 输 出: 信号量的值
** 全局变量: 无
** 调用模块: OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陈明计
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_QUERY > 0
uint8 OSSemQuery(uint8 index)
{
uint8 temp;
if (index > OS_MAX_SEMS)
{
return 0;
}
OS_ENTER_CRITICAL();
#if OS_MAX_TASKS < 9
temp = OsSemBuf[2*index];
#else
temp = OsSemBuf[3*index];
#endif
OS_EXIT_CRITICAL();
return temp;
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -