内核解读
来源:互联网 发布:郑恺潮牌淘宝店 编辑:程序博客网 时间:2024/04/28 20:02
/*****************************************************************************************************
* uC/OS-II
* 实时操作系统
* 内核函数
*
* 文件: OS_CORE.C
* 建立: Jean J. Labrosse
* 修改: 千里冰封
* 功能: 操作系统核心代码
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE
#define OS_GLOBALS
#include "includes.h"
#endif
/*
********************************************************************************************
*
* 任务就绪表优先级别获取辅助常数数组,用查表的方法加速运算
*
********************************************************************************************
*/
INT8U const OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
/* 00000001 0x01 */
/* 00000010 0x02 */
/* 00000100 0x04 */
/* 00001000 0x08 */
/* 00010000 0x10 */
/* 00100000 0x20 */
/* 01000000 0x40 */
/* 10000000 0x80 */
/*******************************************************************************************
*/
INT8U const OSUnMapTbl[] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */
};
/*
********************************************************************************************
* 内部函数声明
********************************************************************************************
*/
static void OS_InitEventList(void); /*初始化空事件块链表 */
static void OS_InitMisc(void); /*操作系统运行前参数初始化*/
static void OS_InitRdyList(void); /*初始化任务就绪表 */
static void OS_InitTaskIdle(void); /*初始化空闲任务 */
static void OS_InitTaskStat(void); /*初始化统计任务 */
static void OS_InitTCBList(void); /*空任务控制快链表初始化 */
/*$PAGE*/
/*
********************************************************************************************
* 操作系统初始化函数void OSInit (void)
*
* 描述: 这个函数是操作系统运行前的初始化,必须在操作系统启动,创建任务
* 前被调用。
*
* 功能: 初始化操作系统参数
*
* 备注 :
* 1 OSInitHookBegin() 与OSInitHookEnd 在os_cpu_c.c中
* 2 创建统计任务OS_InitTaskIdle()
********************************************************************************************
*/
void OSInit (void)
{
#if OS_VERSION >= 204
OSInitHookBegin(); /* 调用钩子函数,用户代码 */
#endif
OS_InitMisc(); /* 基础参数初始化*/
OS_InitRdyList(); /* 初始化任务就绪表 */
OS_InitTCBList(); /* 初始化任务控制块*/
OS_InitEventList(); /* 初始化事情控制块 */
/****************************************根据条件编译***************************************/
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_FlagInit(); /* 事件标志组初始化*/
#endif
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
OS_MemInit(); /* 内存初始化 */
#endif
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
OS_QInit(); /* 消息队列初始化 */
#endif
OS_InitTaskIdle(); /* 创建空闲任务(无条件) */
#if OS_TASK_STAT_EN > 0
OS_InitTaskStat(); /* 创建统计任务 */
#endif
#if OS_VERSION >= 204
OSInitHookEnd(); /* 钩子函数 用户代码*/
#endif
}
/*$PAGE*/
/*
********************************************************************************************
* 中断进入函数 void OSIntEnter (void)
*
* 描述: uC/OS-II 操作系统下进入中断服务程序首先必须调用这个函数,它的作用
* 是通知操作系统已经进入中断,并且记录中断嵌套的次数。
*
* 功能: 将中断计数器OSIntNesting加1
*
* 返回:
*
* 备注 : 1 这个函数必须在中断禁止的情况下调用
* 2 OSIntNesting 必须是一个全局变量。
* 3 这个函数必须与中断退出函数OSIntExit()成对使用,有进入就必然有退出
* 4 也可以直接就操作OSIntNesting加1 而 不调用本函数,效果一样
* 5 退出时不可以直接将OSIntNesting加1 , 而必须调用OSIntExit()
* 6 中断嵌套最多允许255层
* 7 用OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL()来确保OSIntEnter () 与OSIntExit()在中断禁止
* 的环境下调用。
*
********************************************************************************************
*/
void OSIntEnter (void)
{
if (OSRunning == TRUE)
{
if (OSIntNesting < 255)
{
OSIntNesting++; /* 中断进入计数主要用于中断嵌套 OSIntNesting加1 */
}
}
}
/*$PAGE*/
/*
********************************************************************************************
* 中断退出函数 void OSIntExit (void)
*
* 描述: 这个函数是uC/OS-II 操作系统退出中断时调用的,当系统从最后一层中断
* 退出时调用本函数,通知操作系统,同时作一次任务调度,让任务就绪
* 表中就绪的最高优先级任务准备进入运行
* 功能 : OSIntNesting减1,同时让就绪的最高优先级的任务运行。
*
* 返回 :
*
* 备注 : 1 这个函数必须与中断退出函数OSIntEnter ()成对使用,有进入就必然有退出
* 2 退出时不可以直接将OSIntNesting加1 , 而必须调用OSIntExit()
* 3 用OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL()来确保OSIntEnter () 与OSIntExit()在中断禁止
* 的环境下调用。
* 4 OSIntCtxSw()在os_cpu_a.s中
********************************************************************************************
*/
void OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* 有些编译器可以得到处理器的状态字 */
OS_CPU_SR cpu_sr; /* OS_CPU_SR 这个宏就会在os_cpu.h中定义 */
#endif
if (OSRunning == TRUE) /*判断操作系统是否已经启动 */
{
OS_ENTER_CRITICAL(); /*代码临界段,不允许中断 */
if (OSIntNesting > 0)
{
OSIntNesting--; /*计数器减1 */
}
/*没有了其它中断且任务调度没有锁定*/
if ((OSIntNesting == 0) && (OSLockNesting == 0)) /*----中断退出进行任务调度的条件 */
{
/*获取最高优先级别的任务在任务就绪 */
/* ___表中的纵向位置 Y */
OSIntExitY = OSUnMapTbl[OSRdyGrp];
/*获取最高优先级别的任务的优先级别 */
OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
/*如果当前就绪任务中最高优先级别不等*/
/* ___于当前中断的任务优先级则任务切换*/
if (OSPrioHighRdy != OSPrioCur)
{ /*获取最高优先级别的任务控制块指针 */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++; /* 任务调度切换次数计数 */
OSIntCtxSw(); /* 进行中断级任务调度切换 */
}
}
OS_EXIT_CRITICAL(); /* 打开中断 */
}
}
/*$PAGE*/
/*
********************************************************************************************
* 任务调度锁定函数 void OSSchedLock (void)
*
* 描述: 锁定任务调度,锁定后任务将不做切换,一直执行一个任务直到
* 重新启动任务调度。
*
* 功能: 任务调度锁定 OSLockNesting加1
*
* 返回:
*
* 备注: 1 任何情况下OSSchedLock() and OSSchedUnlock() 必须成对使用
* 2 不要轻易的锁定任务调度,这样严重破坏了 uC/OS-II 的实时性违背了本意
* 3 当OSLockNesting >0时系统将禁止任务调度。
* 4 多次调用OSSchedLock() 需要同等次数OSSchedUnlock()调用才能解锁
********************************************************************************************
*/
#if OS_SCHED_LOCK_EN > 0
void OSSchedLock (void)
{
#if OS_CRITICAL_METHOD == 3 /* 有些编译器可以得到处理器的状态字 */
OS_CPU_SR cpu_sr; /* OS_CPU_SR 这个宏就会在os_cpu.h中定义 */
#endif
if (OSRunning == TRUE) /* 确认系统正在运行,若不在运行也无所谓锁定 */
{
OS_ENTER_CRITICAL(); /*代码临界段 */
if (OSLockNesting < 255) /* 最到允许锁定255次 */
{ /*禁止 OSLockNesting回到0 这里 255+1=0 */
OSLockNesting++; /* 任务调度锁定次数加1 */
}
OS_EXIT_CRITICAL();
}
}
#endif
/*$PAGE*/
/*
********************************************************************************************
* 解锁任务调度 void OSSchedUnlock (void)
*
* 描述: 开启任务调度.
*
* 功能: OSLockNesting-- 若OSLockNesting=0打开任务调度,引发任务调度
*
* 返回:
*
* 备注: 1 任何情况下OSSchedLock() and OSSchedUnlock() 必须成对使用
* 2 要明确的是调用了这个函数并不代表就真的打开了任务调度
* 只是将OSLockNesting减1,只有OSLockNesting=0才能打开任务调度,
* 任务调度锁定是可以嵌套的。
*
********************************************************************************************
*/
#if OS_SCHED_LOCK_EN > 0
void OSSchedUnlock (void)
{
#if OS_CRITICAL_METHOD == 3 /* 参见前面 */
OS_CPU_SR cpu_sr;
#endif
if (OSRunning == TRUE)
{ /* 确认操作系统正在运行 */
OS_ENTER_CRITICAL();
if (OSLockNesting > 0)
{ /* 确认任务调度已经被锁定*/
OSLockNesting--; /* 锁定次数减1 */
if ((OSLockNesting == 0) && (OSIntNesting == 0))
{ /* 没有中断,并且没有了锁定*/
OS_EXIT_CRITICAL();
OS_Sched(); /* 任务调度 */
/*这里引发了一次任务调度 */
}
else
{
OS_EXIT_CRITICAL();
}
}
else
{
OS_EXIT_CRITICAL();
}
}
}
#endif
/*$PAGE*/
/*
********************************************************************************************
* 启动操作系统void OSStart (void)
*
* 描述: 操作系统启动函数,启动操作系统之前必须调用OSInit()初始化,
* 并且建立了至少1个任务。
*
* 功能: 获取任务就绪表中最高优先级别的任务并运行
*
* 返回:
*
* 备注: 调用OSStartHighRdy()来运行就绪的最高优先级的任务
* 1 设置操作系统启动 OSRunning =1
* 2 调用钩子函数OSTaskSwHook
* 3 加载并运行操作系统的就绪最高优先级的任务
*
*********************************************************************************************************
*/
void OSStart (void)
{
INT8U y;
INT8U x;
if (OSRunning == FALSE) /*确保操作系统没有在运行*/
{
y = OSUnMapTbl[OSRdyGrp]; /* 获取任务就绪表中就绪的最高优先级 */
x = OSUnMapTbl[OSRdyTbl[y]];
OSPrioHighRdy = (INT8U)((y << 3) + x);
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* 指向就绪的最高优先级的任务控制块*/
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy();
/*这是的软中断函数 主要功能是告诉系统已经启动 OSRunning=1 同时装载任务*/
/*函数在os_cpu_c.c中,函数通过调用os_cpu.h 中的软中断_OSStartHighRdy(),
实际核心代码采用汇编语言编写在Os_cpu_a.s中 */
}
}
/*$PAGE*/
/*
********************************************************************************************
* 初始化统计任务 void OSStatInit (void)
*
* 描述: 这个函数的功能是计算没有其它任务运行的情况下 计算出1S内
* 统计任务运行的次数,为用户的应用程序计算用户任务CPU使用效率
* 做前提准备 。
*
* 功能: 获取1S 中计数的最大值在 OSIdleCtrMax (系统只有统计任务的情况下)
*
* 备注: 1 用户任务的CPU使用比例计算公式:
* OSIdleCtr
* CPU
- 内核解读
- Linux 内核解读入门
- Linux 内核解读入门
- Linux 内核解读入门
- Linux内核解读入门
- Linux 内核解读入门
- Linux内核解读入门
- linux 内核解读入门
- Linux内核解读入门
- Linux内核解读入门
- linux内核解读入门
- Linux内核解读入门
- Linux内核解读
- Linux内核解读入门
- Linux 内核解读入门
- linux内核解读网址
- Linux内核解读入门
- Linux内核解读入门
- 标准C++?(转自我的其它BLOG)
- 就续表之我见
- 急求解:汇编语言课程设计
- 内存管理
- 内核结构
- 内核解读
- 任务管理
- 任务控制块
- SQL Server中的触发器trigger
- 任务的五种状态(uc/os)
- 时钟中断技术
- SQL优化策略
- 事件控制块
- 新的开始还是新的结束