?? os_sem.c
字號:
/*********************************************************************************************************
** Small RTOS(51)
** The Real-Time Kernel(For Keil c51)
**
** (c) Copyright 2002-2003, chenmingji
** All Rights Reserved
**
** V1.12.0
**
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名: OS_Q.C
**創(chuàng) 建 人: 陳明計
**最后修改日期: 2002年12月2日
**描 述: Small RTOS(51)信號量代碼
**
**--------------歷史版本信息----------------------------------------------------------------------------
** 創(chuàng)建人: 陳明計
** 版 本: V1.10
** 日 期: 2002年9月1日
** 描 述: 原始版本
**
**------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 版 本: V1.10.5
** 日 期: 2002年10月26日
** 描 述: 更正筆誤和統(tǒng)一格式
** 更正檢查信號量的錯誤,改善OSSemIntPost()的執(zhí)行性能,更正
** OSSemAccept()在信號量無效時的Bug,減少OSSemQuery()對中斷延遲
** 的影響,更正OSSemPend()在超時時的Bug
**------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 版 本: V1.11.0
** 日 期: 2002年12月2日
** 描 述: 根據(jù)新版本需求更改開、關(guān)中斷代碼,增加注釋
**
**------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 版 本: V1.12.0
** 日 期: 2002年12月30日
** 描 述: 根據(jù)新版本需求更改部分代碼
**
**--------------當(dāng)前版本修訂----------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_OS_SEM
#include "config.h"
/* 分配信號量存儲空間 */
#if EN_OS_SEM > 0
#if OS_MAX_TASKS < 9
uint8 OS_SEM_MEM_SEL OsSemBuf[OS_MAX_SEMS * 2];
#else
uint8 OS_SEM_MEM_SEL OsSemBuf[OS_MAX_SEMS * 3];
#endif
/*********************************************************************************************************
** 函數(shù)名稱: OSSemCreate
** 功能描述: 初始化消息隊列
** 輸 入: Index:信號量索引
** data:信號量初始值
** 輸 出: NOT_OK:沒有這個信號量
** OS_SEM_OK:成功
** 全局變量: 無
** 調(diào)用模塊: 無
**
** 作 者: 陳明計
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8 OSSemCreate(uint8 Index,uint8 Data)
{
OS_ENTER_CRITICAL();
if (Index < OS_MAX_SEMS )
{
#if OS_MAX_TASKS < 9
OsSemBuf[2 * Index] = Data; /* 計數(shù)器置初值 */
OsSemBuf[2 * Index + 1] = 0; /* 清空等待隊列 */
#else
OsSemBuf[3 * Index] = Data; /* 計數(shù)器置初值 */
/* 清空等待隊列 */
OsSemBuf[3 * Index + 1] = 0;
OsSemBuf[3 * Index + 2] = 0;
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
OS_EXIT_CRITICAL();
return NOT_OK;
}
/*********************************************************************************************************
** 函數(shù)名稱: OSSemPend
** 功能描述: 等待一個信號量
** 輸 入: Index:信號量索引
** Tick:等待時間
** 輸 出: NOT_OK:參數(shù)錯誤
** OS_SEM_OK:得到信號量
** OS_SEM_TMO:超時到
** OS_SEM_NOT_OK:沒有得到信號量
** 全局變量: 無
** 調(diào)用模塊: OSRunningTaskID,OSClearSignal,OSSched,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陳明計
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年10月20日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年10月26日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年12月2日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年12月30日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_PENT > 0
uint8 OSSemPend(uint8 Index, uint8 Tick)
{
#if EN_OS_SEM_CHK > 0
if (Index >= OS_MAX_SEMS)
{
return 0;
}
#endif
OS_ENTER_CRITICAL();
OSWaitTick[OSRunningTaskID()] = Tick; /* 設(shè)置超時時間 */
/* 可以優(yōu)化寄存器的使用 */
/* 把任務(wù)加入等待任務(wù)隊列 */
#if OS_MAX_TASKS < 9
OsSemBuf[Index * 2 + 1] |= OSMapTbl[OSRunningTaskID()];
#else
if (OSRunningTaskID() < 8)
{
OsSemBuf[Index * 3 + 1] |= OSMapTbl[OSRunningTaskID()];
}
else
{
OsSemBuf[Index * 3 + 2] |= OSMapTbl[OSRunningTaskID() & 0x07];
}
#endif
/* 信號量是否有效 */
#if OS_MAX_TASKS < 9
while (OsSemBuf[Index * 2] == 0)
{
#else
while (OsSemBuf[Index * 3] == 0)
{
#endif
/* 使用堆棧是為了使函數(shù)具有重入性 */
#ifdef __C51__
SP++;
*((uint8 data *)SP) = Index;
#endif
/* 信號量無效 */
OSClearSignal(OSRunningTaskID()); /* 任務(wù)進(jìn)入等待狀態(tài) */
OSSched(); /* 運行下一個任務(wù) */
#ifdef __C51__
Index = *((uint8 data *)SP);
SP--;
#endif
/* 任務(wù)再次運行,如果超時到,退出循環(huán) */
if (OSWaitTick[OSRunningTaskID()] == 0)
{
break;
}
}
/* 將任務(wù)從等待隊列中清除(可以刪除) */
#if OS_MAX_TASKS < 9
OsSemBuf[Index * 2 + 1] &= ~OSMapTbl[OSRunningTaskID()];
#else
if (OSRunningTaskID() < 8)
{
OsSemBuf[Index * 3 + 1] &= ~OSMapTbl[OSRunningTaskID()];
}
else
{
OsSemBuf[Index * 3 + 2] &= ~OSMapTbl[OSRunningTaskID() & 0x07];
}
#endif
/* 判斷信號量是否有效。有效,信號量計數(shù)器減一 */
#if OS_MAX_TASKS < 9
if (OsSemBuf[Index * 2] > 0)
{
OsSemBuf[Index * 2]--;
#else
if (OsSemBuf[Index * 3] > 0)
{
OsSemBuf[Index * 3]--;
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
else
{
/* 無信號返回信號無效 */
OS_EXIT_CRITICAL();
return OS_SEM_TMO;
}
}
#endif
/*********************************************************************************************************
** 函數(shù)名稱: OSSemAccept
** 功能描述: 無等待請求信號量
** 輸 入: Index:信號量索引
** 輸 出: NOT_OK:參數(shù)錯誤
** OS_SEM_OK:得到信號量
** OS_SEM_TMO:超時到
** OS_SEM_NOT_OK:沒有得到信號量
** 全局變量: 無
** 調(diào)用模塊: OSClearSignal,OSSched,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陳明計
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年10月20日
***-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年10月26日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_ACCEPT > 0
uint8 OSSemAccept(uint8 Index)
{
#if EN_OS_SEM_CHK > 0
if (Index >= OS_MAX_SEMS)
{
return 0;
}
#endif
OS_ENTER_CRITICAL();
/* 判斷信號量是否有效。有效,信號量計數(shù)器減一 */
#if OS_MAX_TASKS < 9
if (OsSemBuf[Index * 2] > 0)
{
OsSemBuf[Index * 2]--;
#else
if (OsSemBuf[Index * 3] > 0)
{
OsSemBuf[Index * 3]--;
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
else
{
/* 無信號返回信號無效 */
OS_EXIT_CRITICAL();
return OS_SEM_NOT_OK;
}
}
#endif
/*********************************************************************************************************
** 函數(shù)名稱: OSSemIntPost
** 功能描述: 中斷中發(fā)送一個信號量
** 輸 入: Index:信號量索引
** 輸 出: NOT_OK:參數(shù)錯誤
** OS_SEM_OK:發(fā)送成功
** 全局變量: 無
** 調(diào)用模塊: OSIntSendSignal,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陳明計
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年10月26日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年12月30日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_INT_POST > 0 || EN_OS_SEM_POST > 0
uint8 OSSemIntPost(uint8 Index)
{
uint8 temp,i;
#if EN_OS_SEM_CHK > 0
if (Index >= OS_MAX_SEMS)
{
return NOT_OK;
}
#endif
OS_ENTER_CRITICAL();
#if OS_MAX_TASKS < 9
/* 信號量計數(shù)器加一 */
if (OsSemBuf[Index * 2] <255)
{
OsSemBuf[Index * 2]++;
}
/* 察看信號量的等待任務(wù)隊列 */
temp = OsSemBuf[Index * 2 + 1];
for (i = 0; i < OS_MAX_TASKS; i++)
{
if ((temp & 0x01) != 0)
{
break;
}
temp = temp >> 1;
}
/* 有任務(wù)等待信號,使其中優(yōu)先級最高的進(jìn)入就緒狀態(tài),并將其從等待隊列中清除 */
if (i < OS_MAX_TASKS)
{
OsSemBuf[Index * 2 + 1] &= ~OSMapTbl[i];
OSIntSendSignal(i);
}
#else
/* 信號量計數(shù)器加一 */
if (OsSemBuf[Index * 3] <255)
{
OsSemBuf[Index * 3]++;
}
temp = OsSemBuf[Index * 3 + 1];
for (i = 0; i < 8; i++)
{
if ((temp & 0x01) != 0)
{
break;
}
temp = temp >> 1;
}
if (i >= 8)
{
temp = OsSemBuf[Index * 3 + 2];
for ( ; i < OS_MAX_TASKS; i++)
{
if ((temp & 0x01) != 0)
{
break;
}
temp = temp >> 1;
}
}
/* 有任務(wù)等待信號,使其中優(yōu)先級最高的進(jìn)入就緒狀態(tài),并將其從等待隊列中清除 */
if (i < OS_MAX_TASKS)
{
if (i < 8)
{
OsSemBuf[Index * 3 + 1] &= ~OSMapTbl[i];
}
else
{
OsSemBuf[Index * 3 + 2] &= ~OSMapTbl[i & 0x07];
}
OSIntSendSignal(i);
}
#endif
OS_EXIT_CRITICAL();
return OS_SEM_OK;
}
#endif
/*********************************************************************************************************
** 函數(shù)名稱: OSSemPost
** 功能描述: 發(fā)送一個信號量
** 輸 入: Index:信號量索引
** 輸 出: NOT_OK:參數(shù)錯誤
** OS_SEM_OK:發(fā)送成功
** 全局變量: 無
** 調(diào)用模塊: OSSemIntPost,OSSched
**
** 作 者: 陳明計
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_POST > 0
uint8 OSSemPost(uint8 Index)
{
if (OSSemIntPost(Index) == OS_SEM_OK)
{
OSSched();
return OS_SEM_OK;
}
else
{
return NOT_OK;
}
}
#endif
/*********************************************************************************************************
** 函數(shù)名稱: OSSemQuery
** 功能描述: 查詢信號量
** 輸 入: Index:信號量索引
** 輸 出: 信號量的值
** 全局變量: 無
** 調(diào)用模塊: OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
**
** 作 者: 陳明計
** 日 期: 2002年9月1日
**-------------------------------------------------------------------------------------------------------
** 修改人: 陳明計
** 日 期: 2002年10月26日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#if EN_OS_SEM_QUERY > 0
uint8 OSSemQuery(uint8 Index)
{
if (Index >= OS_MAX_SEMS)
{
return 0;
}
#if OS_MAX_TASKS < 9
return OsSemBuf[2*Index];
#else
return OsSemBuf[3*Index];
#endif
}
#endif
#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -