?? os_q.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 + -