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

📄 os_event.c

📁 陈明计先生的RTOS,堪称经典
💻 C
字号:
/*********************************************************************************************************
**                                        Small RTOS
**                                   The Real-Time Kernel
**                           (c) Copyright 2002-2003, chenmingji
**                                     All Rights Reserved
**                                         V1.50.0
**
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: OS_EVENT.C
**创   建   人: 陈明计
**最后修改日期: 2004年9月5日
**描        述: Small RTOS 事件处理通用代码
**
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 陈明计
** 版  本: V1.00
** 日 期: 2004年9月5日
** 描 述: 基本完成全新的Small RTOS核
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 版  本:
** 日 期:
** 描 述:
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

#define  IN_OS_EVENT
#define  IN_OS
#include "config.h"

#if OS_MAX_EVENTS > 0

OS_EVENT            *OSEventFreeList;               /* 自由事件登记项 */
OS_EVENT            OSEventTbl[OS_MAX_EVENTS];      /* 事件登记项     */

/*********************************************************************************************************
** 函数名称: OSEventinit
** 功能描述: 初始化自由事件登记项
** 输 入: 无
** 输 出: OS_NO_ERR
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
    uint8 OSEventinit(void)
{
    uint32 i;
    
    OSEventFreeList = &(OSEventTbl[0]);
    for (i = 0; i < OS_MAX_EVENTS - 1; i++)
    {
        OSEventTbl[i].OSEventType = 0;
        OSEventTbl[i].WaitingTcb = NULL;
        OSEventTbl[i].EventData.EventNext = &(OSEventTbl[i + 1]);
        OSEventTbl[i].WaitingTcbEnd = NULL;
    }
    OSEventTbl[OS_MAX_EVENTS - 1].OSEventType = 0;
    OSEventTbl[OS_MAX_EVENTS - 1].WaitingTcb = NULL;
    OSEventTbl[OS_MAX_EVENTS - 1].EventData.EventNext = NULL;
    OSEventTbl[OS_MAX_EVENTS - 1].WaitingTcbEnd = NULL;
    return OS_NO_ERR;
}

/*********************************************************************************************************
** 函数名称: OSEventNew
** 功能描述: 创建事件
** 输 入: 无
** 输 出: 事件指针
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        OS_EVENT * OSEventNew (void)
{
    OS_EVENT * Rt;
    
    if (OSEventFreeList == NULL)
    {
        return NULL;
    }
    
    Rt = OSEventFreeList;
    OSEventFreeList = OSEventFreeList->EventData.EventNext;
    return Rt;
}

/*********************************************************************************************************
** 函数名称: OSEventResume
** 功能描述: 恢复等待此事件的任务
** 输 入: 无
** 输 出: OS_NO_ERR
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint8 OSEventResume(OS_EVENT *pEvent)
{
    OS_TCB *Tcb;

    Tcb = pEvent->WaitingTcb;                   /* 恢复处于等待链表的头的任务   */
    if (Tcb != NULL)
    {
        /* 从链表中删除它               */
        pEvent->WaitingTcb = Tcb->EventNext;
        Tcb->EventNext->EventPrev = NULL;
        Tcb->EventNext = NULL;
        /* 恢复任务                     */
        OS_TimeTickDel(Tcb);                    /* 从等待延时队列中删除 */
        _OS_TaskResume(Tcb);
        Tcb->OSTCBStat &= ~OS_STAT_EVENT;
        OSSched();                              /* 任务切换                     */
    }
    return OS_NO_ERR;
}

/*********************************************************************************************************
** 函数名称: OSEventFree
** 功能描述: 释放事件
** 输 入: pEvent:事件指针
** 输 出: OS_NO_ERR
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint8 OSEventFree (OS_EVENT *pEvent)
{
    uint8 Rt,OldPrio,NowPrio;
    OS_TCB *Tcb;

    /* 恢复初始值           */
    pEvent->OSEventType = 0;
    OldPrio = OSTCBCur->OSTCBPrio;
    NowPrio = OldPrio;
    pEvent->OSEventType = 0;
    /* 恢复所有等待的任务   */
    while (pEvent->WaitingTcb != NULL)
    {
        Tcb = pEvent->WaitingTcb;
        OSEventResume(pEvent);
        if (NowPrio < Tcb->OSTCBPrio)
        {
            NowPrio = Tcb->OSTCBPrio;
            /* 改变当前任务优先级确保被恢复的任务进入执行状态 */
            OSTaskChangePrio(OSTCBCur->OSTCBId, NowPrio);
        }
    }
    /* 恢复当前任务优先级   */
    OSTaskChangePrio(OSTCBCur->OSTCBId, OldPrio);
    /* 恢复初始值           */
    pEvent->WaitingTcbEnd = NULL;
    pEvent->EventData.EventNext = OSEventFreeList;
    OSEventFreeList = pEvent;               /* 加入空闲队列         */
    Rt = OS_NO_ERR;
    return Rt;
}


/*********************************************************************************************************
** 函数名称: OSEventWait
** 功能描述: 让当前任务等待事件
** 输 入: pEvent:事件指针
**         Tick:超时设置
** 输 出: OS_NO_ERR:成功
**         OS_ERR_PEND_ISR:在中断中等待事件
** 作 者: 陈明计
** 日 期: 2004年9月5日
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        uint8 OSEventWait (OS_EVENT *pEvent, uint8 Tick)
{
#if OS_EVENT_MODE == BASE_PRIO
    OS_TCB *pTcb;
    uint8 Prio;
#endif

    if (OSIntNesting != 0)
    {
        return OS_ERR_PEND_ISR;
    }

#if OS_EVENT_MODE == BASE_FIFO
    /* 基于FIFO */
    if (pEvent->WaitingTcb == NULL)
    {
        /* 如果无任务等待 */
        pEvent->WaitingTcb = OSTCBCur;
        OSTCBCur->EventPrev = NULL;
    }
    else
    {
        /*如果有任务等待 */
        OSTCBCur->EventPrev = pEvent->WaitingTcbEnd;
        pEvent->WaitingTcbEnd->EventNext = OSTCBCur;
    }
    OSTCBCur->EventNext = NULL;
#endif

#if OS_EVENT_MODE == BASE_PRIO
    /* 基于优先级 */
    Prio = OSTCBCur->OSTCBPrio;
    if ((pEvent->WaitingTcb) == NULL ||
        (pEvent->WaitingTcb->OSTCBPrio) > Prio)
    {
        /* 如果无任务等待或本任务比所有等待的任务的优先级都高 */
        pEvent->WaitingTcb = OSTCBCur;
        OSTCBCur->EventPrev = NULL;
        OSTCBCur->EventNext = pEvent->WaitingTcb;
    }
    else
    {
        pTcb = pEvent->WaitingTcbEnd;           /* 从链表最后往前查找 */
        if (pTcb->OSTCBPrio <= Prio)
        {
            /* 本任务比所有等待的任务的优先级都低 */
            OSTCBCur->TcbPrev = pEvent->WaitingTcbEnd;
            pEvent->WaitingTcbEnd->EventNext = OSTCBCur;
        }
        else
        {
            /* 查找合适位置 */
            while (1)
            {
                if (pTcb->OSTCBPrio <= Prio)
                {
                    break;
                }
                pTcb = pTcb->EventPrev;
            }
            /* 插入链表 */
            OSTCBCur->EventPrev = pTcb;
            OSTCBCur->EventNext = pTcb->EventNext;
            pTcb->EventNext = OSTCBCur;
            OSTCBCur->EventNext->EventPrev = OSTCBCur;
        }
    }
#endif
    OSTCBCur->OSTCBStat |= OS_STAT_EVENT;
    pEvent->WaitingTcbEnd = OSTCBCur;
    if (Tick > 0)
    {
        OS_TimeDly(Tick);                       /* 超时设置             */
    }
    else
    {
        _OS_TaskSuspend(OSTCBCur);              /* 从优先级链表中删除   */
    }
    OSSched();                                  /* 任务切换             */
    return OS_NO_ERR;
}
#endif

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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