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

📄 os_q.c

📁 SmallRTOSAVR.rar
💻 C
字号:
/*********************************************************************************************************
**                                        Small RTOS
**                                   The Real-Time Kernel
**                           (c) Copyright 2002-2003, chenmingji
**                                     All Rights Reserved
**                                         V1.50.0
**
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: OS_Q.C
**创   建   人: 陈明计
**最后修改日期: 2004年9月5日
**描        述: Small RTOS 消息队列处理代码
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 陈明计
** 版  本: V1.00
** 日 期: 2004年9月5日
** 描 述: 基本完成全新的Small RTOS核
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 版  本:
** 日 期:     
** 描 述:
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 焦进星
** 日 期: 2007年12月30日
** 描 述: 移植到AVR系列芯片,适用于atmega16/32等
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

#define  IN_OS_Q
#define  IN_OS
#include "..\APP\config.h"

#if OS_MAX_EVENTS > 0
/* 增加删除消息队列 */
#if EN_OS_Q > 0
/*********************************************************************************************************
** 函数名称: OSQCreate
** 功能描述: 初始化消息队列
** 输 入: Buf:为队列分配的存储空间地址
**         SizeOfBuf:为队列分配的存储空间大小
** 输 出: 事件指针,NULL为不成功
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/

        OS_EVENT * OSQCreate(void *Buf, uint8 SizeOfBuf)
{
    OS_EVENT *Rt=NULL;
    OS_Q *QPtr;
    
    if (Buf != NULL && SizeOfBuf >= (sizeof(OS_Q)))             /* 判断参数是否有效 */
    {
        OS_ENTER_CRITICAL();
        Rt = OSEventNew();
        if (Rt != NULL)
        {
            QPtr = (OS_Q *)Buf;
            Rt->OSEventType = OS_EVENT_Q;
            Rt->EventData.OSQPtr = QPtr;
                                                                /* 初始化结构体数据 */
            QPtr->MaxData = (SizeOfBuf - (uint32)(((OS_Q *)0)->Buf)) / 
                         sizeof(void *);                          /* 计算队列可以存储的数据数目 */
            QPtr->End = QPtr->Buf + QPtr->MaxData;              /* 计算数据缓冲的结束地址 */
            QPtr->Out = QPtr->Buf;
            QPtr->In = QPtr->Buf;
            QPtr->NData = 0;
        }
        OS_EXIT_CRITICAL();
    }
    return Rt;
}

/*********************************************************************************************************
** 函数名称: OSQPend
** 功能描述: 等待消息队列中的消息
** 输 入: pEvent:指向队列的指针
**         Tick:等待时间
**         err:用于返回状态
**             OS_NO_ERR:成功
**             OS_ERR_PEVENT_NULL:事件指针为空
**             OS_ERR_EVENT_TYPE:错误事件类型
**             OS_ERR_PEND_ISR:在IRS中等待事件
**             OS_EVENT_DEL:事件被删除
**             OS_TIMEOUT:超时
** 输 出: 消息,NULL为无消息
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: a
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_Q_PENT > 0

        void * OSQPend(OS_EVENT * pEvent, uint16 Tick, uint8 *err)
{
    OS_Q *QPtr;
    void *Rt;
    
    if (pEvent == NULL)
    {
        *err = OS_ERR_PEVENT_NULL;
        return NULL;
    }

    OS_ENTER_CRITICAL();
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列   */
    {
        *err = OS_ERR_EVENT_TYPE;
        Rt = NULL;
        goto Error;
    }

    QPtr = pEvent->EventData.OSQPtr;
    
    *err = OS_NO_ERR;
    if (QPtr->NData == 0)                       /* 队列是否为空 */
    {
        *err = OSEventWait(pEvent, Tick);
    }
    if (*err != OS_NO_ERR)
    {
        Rt = NULL;
        goto Error;
    }
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列    */
    {
        *err = OS_EVENT_DEL;                    /* 事件被删除           */
        Rt = NULL;
        goto Error;
    }
    if (QPtr->NData == 0)                        /* 队列是否为空 */
    {
        *err = OS_TIMEOUT;
        Rt = NULL;
        goto Error;
    }

    Rt = QPtr->Out[0];                          /* 消息出队     */
    QPtr->Out++;                                /* 调整出队指针 */
    if (QPtr->Out >= QPtr->End)
    {
        QPtr->Out = QPtr->Buf;
    }
    QPtr->NData--;                              /* 数据减少      */
    *err = OS_NO_ERR;

Error:
    OS_EXIT_CRITICAL();
    return Rt;
}
#endif

/*********************************************************************************************************
** 函数名称: OSQAccept
** 功能描述: 无等待从消息队列中取得消息
** 输 入: pEvent:指向队列的指针
** 输 出: 消息,NULL为无消息
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_Q_ACCEPT > 0
        void * OSQAccept(OS_EVENT * pEvent)
{
    OS_Q *QPtr;
    void *Rt;
    
    if (pEvent == NULL)
    {
        return NULL;
    }

    OS_ENTER_CRITICAL();
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列   */
    {
        Rt = NULL;
        goto Error;
    }

    QPtr = pEvent->EventData.OSQPtr;
        
    if (QPtr->NData == 0)                        /* 队列是否为空 */
    {
        Rt = NULL;
        goto Error;
    }

    Rt = QPtr->Out[0];                          /* 消息出队     */
    QPtr->Out++;                                /* 调整出队指针 */
    if (QPtr->Out >= QPtr->End)
    {
        QPtr->Out = QPtr->Buf;
    }
    QPtr->NData--;                              /* 数据减少      */

Error:
    OS_EXIT_CRITICAL();
    return Rt;
}
#endif


/*********************************************************************************************************
** 函数名称: OSQPost
** 功能描述: FIFO方式发送消息
** 输 入: pEvent:指向队列的指针
**         Msg:发送的消息
** 输 出: OS_NO_ERR:成功
**         OS_ERR_PEVENT_NULL:事件指针为空
**         OS_ERR_EVENT_TYPE:错误事件类型
**         OS_ERR_POST_NULL_PTR:发送消息指针为空
**         OS_Q_FULL:队列满
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_Q_POST > 0
        uint8 OSQPost(OS_EVENT * pEvent, void *Msg)
{
    OS_Q *QPtr;
    uint8 Rt;
    
    if (pEvent == NULL)
    {
        return OS_ERR_PEVENT_NULL;
    }
    
    if (Msg == NULL)
    {
        return OS_ERR_POST_NULL_PTR;
    }
    
    OS_ENTER_CRITICAL();
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列   */
    {
        Rt = OS_ERR_EVENT_TYPE;
        goto Error;
    }

    QPtr = pEvent->EventData.OSQPtr;
        
    if (QPtr->NData >= QPtr->MaxData)           /* 队列是否满 */
    {
        Rt = OS_Q_FULL;
        goto Error;
    }

    QPtr->In[0] = Msg;                          /* 数据入队    */
    QPtr->In++;                                 /* 调整入队指针*/
    if (QPtr->In >= QPtr->End)
    {
        QPtr->In = QPtr->Buf;
    }
    QPtr->NData++;                              /* 数据增加    */
    OSEventResume(pEvent);
    Rt = OS_NO_ERR;

Error:
    OS_EXIT_CRITICAL();
    return Rt;
}
#endif

/*********************************************************************************************************
** 函数名称: OSQPostFront
** 功能描述: 中LIFO方式发送消息
** 输 入: pEvent:指向队列的指针
**         Msg:发送的消息
** 输 出: OS_NO_ERR:成功
**         OS_ERR_PEVENT_NULL:事件指针为空
**         OS_ERR_EVENT_TYPE:错误事件类型
**         OS_ERR_POST_NULL_PTR:发送消息指针为空
**         OS_Q_FULL:队列满
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_Q_POST_FRONT > 0
        uint8 OSQPostFront(OS_EVENT * pEvent, void *Msg)
{
    OS_Q *QPtr;
    uint8 Rt;
    
    if (pEvent == NULL)
    {
        return OS_ERR_PEVENT_NULL;
    }

    if (Msg == NULL)
    {
        return OS_ERR_POST_NULL_PTR;
    }

    OS_ENTER_CRITICAL();
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列   */
    {
        Rt = OS_ERR_EVENT_TYPE;
        goto Error;
    }

    QPtr = pEvent->EventData.OSQPtr;
        
    if (QPtr->NData >= QPtr->MaxData)           /* 队列是否满 */
    {
        Rt = OS_Q_FULL;
        goto Error;
    }

    QPtr->Out--;                                /* 调整出队指针 */
    if (QPtr->Out < QPtr->Buf)
    {
        QPtr->Out = QPtr->End - 1;
    }
    QPtr->Out[0] = Msg;                         /* 数据入队     */
    QPtr->NData++;                              /* 数据增加    */
    OSEventResume(pEvent);
    Rt = OS_NO_ERR;

Error:
    OS_EXIT_CRITICAL();
    return Rt;
}
#endif

/*********************************************************************************************************
** 函数名称: OSQNMsgs
** 功能描述: 取得消息队列中消息数
** 输 入: pEvent:事件指针
** 输 出: 消息数
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_Q_NMsgs > 0
        uint16 OSQNMsgs(OS_EVENT * pEvent)
{
    OS_Q *QPtr;
    uint8 Rt;
    
    if (pEvent == NULL)
    {
        return 0;
    }

    OS_ENTER_CRITICAL();
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列   */
    {
        Rt = 0;
        goto Error;
    }

    QPtr = pEvent->EventData.OSQPtr;
    Rt = QPtr->NData;

Error:
    OS_EXIT_CRITICAL();
    return Rt;
}
#endif

/*********************************************************************************************************
** 函数名称: OSQSize
** 功能描述: 取得消息队列总容量
** 输 入: pEvent:事件指针
** 输 出: 消息总容量数
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_Q_SIZE > 0
        uint16 OSQSize(OS_EVENT * pEvent)
{
    OS_Q *QPtr;
    uint8 Rt;
    
    if (pEvent == NULL)
    {
        return 0;
    }

    OS_ENTER_CRITICAL();
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列   */
    {
        Rt = 0;
        goto Error;
    }

    QPtr = pEvent->EventData.OSQPtr;
    Rt = QPtr->MaxData;

Error:
    OS_EXIT_CRITICAL();
    return Rt;
}
#endif

/*********************************************************************************************************
** 函数名称: OSQFlush
** 功能描述: 清空队列
** 输 入: pEvent:事件指针
** 输 出: 无
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_Q_FLUSH > 0
        void OSQFlush (OS_EVENT * pEvent)
{
    OS_Q *QPtr;
    
    if (pEvent == NULL)
    {
        return;
    }

    OS_ENTER_CRITICAL();
    if (pEvent->OSEventType != OS_EVENT_Q)      /* 这个事件不是消息队列   */
    {
        goto Error;
    }

    QPtr = pEvent->EventData.OSQPtr;
    QPtr->Out = QPtr->Buf;
    QPtr->In = QPtr->Buf;
    QPtr->NData = 0;                            /* 数据数目为0 */

Error:
    OS_EXIT_CRITICAL();
    return;
}
#endif

#endif
#endif
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -