📄 os_event.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 + -