📄 os_core.c
字号:
/*********************************************************************************************************
** Small RTOS(51)
** The Real-Time Kernel(For Keil c51)
**
** (c) Copyright 2002-2002, chenmingji
** All Rights Reserved
**
** V1.00
**
**
** 文件名: OS_CORE.C
** 创建人: 陈明计
** 日 期: 2002年6月20日
** 描 述: Small RTOS(51)与CPU无关的核心代码
**
**------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#define IN_OS_CORE
#include "config.h"
#if EN_OS_INT_ENTER > 0
unsigned char OSIntNesting;
#endif
unsigned char OSTaskID,OSNextTaskID;
unsigned char OSWaitTick[OS_MAX_TASKS-1];
#if OS_MAX_TASKS < 8
unsigned char OSTaskRuning = 0xff;
#else
unsigned int OSTaskRuning = 0xffff;
#endif
unsigned char const OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
void OSSched (void);
/*********************************************************************************************************
** 函数名称: OSIntSendSignal
** 功能描述: 中断中给指定任务发送信号,既使指定任务就绪
** 输 入: TaskId : 任务ID
** 输 出: 无
** 全局变量: OSTaskRuning
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2002年6月20日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void OSIntSendSignal (unsigned char TaskId)
{
OS_ENTER_CRITICAL();
#if OS_MAX_TASKS < 8
OSTaskRuning |= OSMapTbl[TaskId];
#else
if(TaskId<8)
{
((unsigned char *)(&OSTaskRuning))[LOW_BYTE] |= OSMapTbl[TaskId];
}
else
{
((unsigned char *)(&OSTaskRuning))[HIGH_BYTE] |= OSMapTbl[TaskId%8];
}
#endif
OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** 函数名称: OSSendSignal
** 功能描述: 任务中给指定任务发送信号,既使指定任务就绪
** 输 入: TaskId : 任务ID
** 输 出: 无
** 全局变量: OSTaskRuning
** 调用模块: OSSched
**
** 作 者: 陈明计
** 日 期: 2002年6月20日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void OSSendSignal (unsigned char TaskId)
{
OS_ENTER_CRITICAL();
#if OS_MAX_TASKS < 8
OSTaskRuning |= OSMapTbl[TaskId];
#else
if(TaskId<8)
{
((unsigned char *)(&OSTaskRuning))[LOW_BYTE] |= OSMapTbl[TaskId];
}
else
{
((unsigned char *)(&OSTaskRuning))[HIGH_BYTE] |= OSMapTbl[TaskId%8];
}
#endif
OSSched(); //开始任务切换
//OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
** 函数名称: OSClearSignal
** 功能描述: 清除指定任务信号,既使指定任务休眠
** 输 入: TaskId : 任务ID
** 输 出: 无
** 全局变量: OSTaskRuning
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2002年6月20日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void OSClearSignal (unsigned char TaskId)
{
#if OS_MAX_TASKS < 8
OSTaskRuning &= ~OSMapTbl[TaskId];
#else
if(TaskId<8)
{
((unsigned char *)(&OSTaskRuning))[LOW_BYTE] &= ~OSMapTbl[TaskId];
}
else
{
((unsigned char *)(&OSTaskRuning))[HIGH_BYTE] &= ~OSMapTbl[TaskId%8];
}
#endif
}
/*********************************************************************************************************
** 函数名称: OSIntExit
** 功能描述: 中断退出处理函数,在此进行中断后的任务切换
** 输 入: 无
** 输 出: 无
** 全局变量: OSIntNesting,OSNextTaskID
** 调用模块: OSIntCtxSw
**
** 作 者: 陈明计
** 日 期: 2002年6月20日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void OSIntExit (void)
{
unsigned char temp;
OS_ENTER_CRITICAL();
#if EN_OS_INT_ENTER >0
if (OSIntNesting > 0)
{
OSIntNesting--;
}
if (OSIntNesting == 0)
{
#endif
#if OS_MAX_TASKS < 9
temp = OSTaskRuning;
for(OSNextTaskID = 0;OSNextTaskID < OS_MAX_TASKS-1;OSNextTaskID++)
{
if((temp & 0x01) != 0) break;
temp = temp >> 1;
}
OSIntCtxSw();
#else
temp = OSTaskRuning % 256;
for(OSNextTaskID = 0;OSNextTaskID < 8;OSNextTaskID++)
{
if((temp & 0x01) != 0) goto TaskSw;
temp = temp >> 1;
}
temp = OSTaskRuning /256 ;
for(;OSNextTaskID < OS_MAX_TASKS-1;OSNextTaskID++)
{
if((temp & 0x01) != 0) break;
temp = temp >> 1;
}
TaskSw:
OSIntCtxSw();
#endif
//OS_EXIT_CRITICAL();
#if EN_OS_INT_ENTER >0
}
#endif
}
/*********************************************************************************************************
** 函数名称: OSSched
** 功能描述: 非中断的任务切换函数
** 输 入: 无
** 输 出: 无
** 全局变量: OSIntNesting,OSNextTaskID
** 调用模块: OS_TASK_SW
**
** 作 者: 陈明计
** 日 期: 2002年6月20日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void OSSched (void)
{
unsigned char temp;
#if EN_OS_INT_ENTER >0
if (OSIntNesting == 0)
{
#endif
#if OS_MAX_TASKS < 9
temp = OSTaskRuning;
for(OSNextTaskID = 0;OSNextTaskID < OS_MAX_TASKS-1;OSNextTaskID++)
{
if((temp & 0x01) != 0) break;
temp = temp >> 1;
}
OS_TASK_SW();
#else
temp = OSTaskRuning % 256;
for(OSNextTaskID = 0;OSNextTaskID < 8;OSNextTaskID++)
{
if((temp & 0x01) != 0) goto TaskSw;
temp = temp >> 1;
}
temp = OSTaskRuning /256 ;
for(;OSNextTaskID < OS_MAX_TASKS-1;OSNextTaskID++)
{
if((temp & 0x01) != 0) break;
temp = temp >> 1;
}
TaskSw:
OS_TASK_SW();
#endif
#if EN_OS_INT_ENTER >0
}
#endif
}
/*********************************************************************************************************
** 函数名称: OSTimeTick
** 功能描述: 系统时钟处理函数,处理各个任务的延时
** 输 入: 无
** 输 出: 无
** 全局变量: OSWaitTick
** 调用模块: OSIntSendSignal
**
** 作 者: 陈明计
** 日 期: 2002年6月20日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void OSTimeTick (void)
{
unsigned char i;
for(i = 0;i < OS_MAX_TASKS;i++)
{
if(OSWaitTick[i] !=0 )
{
OSWaitTick[i]--;
if(OSWaitTick[i] == 0)
{
OSIntSendSignal(i);
}
}
}
}
/*********************************************************************************************************
** 函数名称: OSWait
** 功能描述: 系统等待函数,任务调用此函数可以等待一定时间或信号
** 输 入: typ: 等待事件类型,目前可以取以下值,或是其中任意个值的按位或
** K_SIG: 等待信号
** K_TMO: 等待超时
** ticks : 等待超时时的系统嘀嗒数
** 输 出 : NOT_OK : 参数错误
** TMO_EVENT : 超时到
** SIG_EVENT : 有信号
** 全局变量: OSWaitTick
** 调用模块: OSIntSendSignal
**
** 作 者: 陈明计
** 日 期: 2002年6月20日
**-------------------------------------------------------------------------------------------------------
** 修 改:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
unsigned char OSWait (unsigned char typ, unsigned char ticks)
{
OSWaitTick[OSTaskID] = ticks;
switch(typ)
{
case K_SIG:
OS_ENTER_CRITICAL();
OSWaitTick[OSTaskID] = 0;
OSClearSignal(OSTaskID);
OSSched();
return SIG_EVENT;
case K_TMO:
while(OSWaitTick[OSTaskID]!=0)
{
OS_ENTER_CRITICAL();
OSClearSignal(OSTaskID);
OSSched();
}
return TMO_EVENT;
case (K_TMO | K_SIG):
if (OSWaitTick[OSTaskID] == 0) return TMO_EVENT;
OS_ENTER_CRITICAL();
OSClearSignal(OSTaskID);
OSSched();
if(OSWaitTick[OSTaskID] != 0)
{
OSWaitTick[OSTaskID] = 0;
return SIG_EVENT;
}
return TMO_EVENT;
default:
return NOT_OK;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -