📄 os_sem.c
字号:
/*********************************************************************************************************
** Small RTOS
** The Real-Time Kernel
** (c) Copyright 2002-2003, chenmingji
** All Rights Reserved
** V1.50.0
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: OS_sem.C
**创 建 人: 陈明计
**最后修改日期: 2004年9月5日
**描 述: Small RTOS信号量处理代码
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 陈明计
** 版 本: V1.00
** 日 期: 2004年9月5日
** 描 述: 基本完成全新的Small RTOS核
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 版 本:
** 日 期:
** 描 述:
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 焦进星
** 日 期: 2007年12月30日
** 描 述: 移植到AVR系列芯片,适用于atmega16/32等
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_OS_SEM
#define IN_OS
#include "..\APP\config.h"
#if OS_MAX_EVENTS > 0
#if EN_OS_SEM > 0
/*********************************************************************************************************
** 函数名称: OSSemCreate
** 功能描述: 初始信号量
** 输 入: data:信号量初始值
** 输 出: 事件指针
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
OS_EVENT * OSSemCreate(uint16 Data)
{
OS_EVENT * Rt;
OS_ENTER_CRITICAL();
Rt = OSEventNew();
if (Rt != NULL)
{
Rt->OSEventType = OS_EVENT_SEM;
Rt->EventData.Cnt = Data;
}
OS_EXIT_CRITICAL();
return Rt;
}
/*********************************************************************************************************
** 函数名称: OSSemPend
** 功能描述: 等待一个信号量
** 输 入: pEvent:事件指针
** Tick:等待时间
** 输 出: OS_NO_ERR:成功
** OS_ERR_PEVENT_NULL:事件指针为空
** OS_ERR_EVENT_TYPE:错误事件类型
** OS_ERR_PEND_ISR:在IRS中等待事件
** OS_EVENT_DEL:事件被删除
** OS_TIMEOUT:超时
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_PENT > 0
uint8 OSSemPend(OS_EVENT * pEvent, uint16 Tick)
{
uint8 Rt;
if (pEvent == NULL)
{
return OS_ERR_PEVENT_NULL;
}
OS_ENTER_CRITICAL();
if (pEvent->OSEventType != OS_EVENT_SEM) /* 这个事件不是信号量 */
{
Rt = OS_ERR_EVENT_TYPE;
goto Error;
}
if (pEvent->EventData.Cnt == 0) /* 无信号量 */
{
Rt = OSEventWait(pEvent, Tick);
if (Rt != OS_NO_ERR)
{
goto Error;
}
}
if (pEvent->OSEventType != OS_EVENT_SEM) /* 这个事件不是信号量 */
{
Rt = OS_EVENT_DEL; /* 事件被删除 */
goto Error;
}
if(pEvent->EventData.Cnt == 0) /* 无信号量 */
{
Rt = OS_TIMEOUT;
goto Error;
}
pEvent->EventData.Cnt--;
Rt = OS_NO_ERR;
Error:
OS_EXIT_CRITICAL();
return Rt;
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemAccept
** 功能描述: 无等待请求信号量
** 输 入: pEvent:事件指针
** 输 出: 信号量的值
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: a
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_ACCEPT > 0
uint16 OSSemAccept(OS_EVENT * pEvent)
{
uint8 Rt;
Rt = 0;
if (pEvent != NULL)
{
OS_ENTER_CRITICAL();
if (pEvent->OSEventType == OS_EVENT_SEM)
{
if (pEvent->EventData.Cnt != 0)
{
Rt = pEvent->EventData.Cnt;
pEvent->EventData.Cnt--;
}
}
OS_EXIT_CRITICAL();
}
return Rt;
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemPost
** 功能描述: 发送一个信号量
** 输 入: pEvent:事件指针
** 输 出: OS_NO_ERR:成功
** OS_ERR_PEVENT_NULL:事件指针为空
** OS_ERR_EVENT_TYPE:错误事件类型
** OS_SEM_OVF:信号量满
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_POST > 0
uint8 OSSemPost(OS_EVENT * pEvent)
{
uint8 Rt;
if (pEvent == NULL)
{
return OS_ERR_PEVENT_NULL;
}
OS_ENTER_CRITICAL();
if (pEvent->OSEventType != OS_EVENT_SEM)
{
Rt = OS_ERR_EVENT_TYPE;
}
else
{
if (pEvent->EventData.Cnt == (uint16)(-1)) /* 到达最大值 */
{
Rt = OS_SEM_OVF; /* 信号量满 */
}
else
{
pEvent->EventData.Cnt++;
OSEventResume(pEvent);
Rt = OS_NO_ERR;
}
}
OS_EXIT_CRITICAL();
return Rt;
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemQuery
** 功能描述: 查询信号量
** 输 入: pEvent:事件指针
** Cnt:用于输出信号量的值
** 输 出: OS_NO_ERR:成功
** OS_ERR_PEVENT_NULL:事件指针为空
** OS_ERR_EVENT_TYPE:错误事件类型
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_QUERY > 0
uint8 OSSemQuery(OS_EVENT * pEvent, uint16 *Cnt)
{
uint8 Rt;
if (pEvent == NULL)
{
return OS_ERR_PEVENT_NULL;
}
OS_ENTER_CRITICAL();
if (pEvent->OSEventType != OS_EVENT_SEM)
{
Rt = OS_ERR_EVENT_TYPE;
}
else
{
*Cnt = pEvent->EventData.Cnt;
Rt = OS_NO_ERR;
}
OS_EXIT_CRITICAL();
return Rt;
}
#endif
/*********************************************************************************************************
** 函数名称: OSSemDel
** 功能描述: 删除信号量
** 输 入: pEvent:事件指针
** 输 出: OS_NO_ERR:成功
** OS_ERR_PEVENT_NULL:事件指针为空
** OS_ERR_EVENT_TYPE:错误事件类型
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: a
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_DEL > 0
uint8 OSSemDel(OS_EVENT * pEvent)
{
uint8 Rt;
if (pEvent == NULL)
{
Rt = OS_ERR_PEVENT_NULL;
}
else
{
OS_ENTER_CRITICAL();
if (pEvent->OSEventType != OS_EVENT_SEM)
{
Rt = OS_ERR_EVENT_TYPE;
}
else
{
Rt = OSEventFree(pEvent);
}
OS_EXIT_CRITICAL();
}
return Rt;
}
#endif
#endif
#endif
/*********************************************************************************************************
** End Of File
********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -