⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_sem.c

📁 可以在单片机中运行的操作系统
💻 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 + -