?? 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核
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 版 本:
** 日 期:
** 描 述:
**
**--------------當前版本修訂------------------------------------------------------------------------------
** 修改人: 焦進星
** 日 期: 2007年12月30日
** 描 述: 移植到AVR系列芯片,適用于atmega16/32等
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_OS_EVENT
#define IN_OS
#include "..\APP\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;
if (Tcb->EventNext != NULL)
{
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;
/* 恢復初始值 */
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 + -