📄 os_core.c
字号:
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
* CORE FUNCTIONS
*
* (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* File : OS_CORE.C
* By : Jean J. Labrosse
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE//防止一些文件加入到includes.h当中
#define OS_GLOBALS
#include "includes.h"
#endif
/*
*********************************************************************************************************
* MAPPING TABLE TO MAP BIT POSITION TO BIT MASK
*
* Note: Index into table is desired bit position, 0..7
* Indexed value corresponds to bit mask
*********************************************************************************************************
*/
/*
*********************************************************************************************************
映射位位置映射到位掩码的映射表
备注:表的索引是想得到的位的位置(0到7)
索引得到的值是位的掩码
*********************************************************************************************************
*/
INT8U const OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
/*
*********************************************************************************************************
* PRIORITY RESOLUTION TABLE
*
* Note: Index into table is bit pattern to resolve highest priority
* Indexed value corresponds to highest priority bit position (i.e. 0..7)
*********************************************************************************************************
*/
/*
**********************************************************************************************
优先级分辨表
备注:索引表是最高优先级的位模式
索引值对应于最高优先级的位位置(0到7)
***********************************************************************************************
*/
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 */
};//256个东东,干嘛呢?
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
//以下为初始化函数
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*/
/*
*********************************************************************************************************
* INITIALIZATION
*
* Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to
* creating any uC/OS-II object and, prior to calling OSStart().
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
/*
*********************************************************************************************************
初始化
功能:要先在调用 OSStart()后,再初始化uxosII内核,要先建立ucos任何一个任务
*********************************************************************************************************
*/
void OSInit (void)
{
#if OS_VERSION >= 204
OSInitHookBegin(); /* Call port specific initialization code */
//调用特定通信口初始化代码
#endif
OS_InitMisc(); /* Initialize miscellaneous variables */
//初始化多种变量
OS_InitRdyList(); /* Initialize the Ready List */
//初始化就绪链表
OS_InitTCBList(); /* Initialize the free list of OS_TCBs */
//初始化TCB空闲链表
OS_InitEventList(); /* Initialize the free list of OS_EVENTs */
//初始化事件空闲链表
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_FlagInit(); /* Initialize the event flag structures */
//初始化事件标志结构
#endif
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
OS_MemInit(); /* Initialize the memory manager */
//初始化存在管理
#endif
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
OS_QInit(); /* Initialize the message queue structures */
//初始化消息队列结构
#endif
OS_InitTaskIdle(); /* Create the Idle Task */
//建立空闲任务
#if OS_TASK_STAT_EN > 0
OS_InitTaskStat(); /* Create the Statistic Task */
//建立统计任务
#endif
#if OS_VERSION >= 204
OSInitHookEnd(); /* Call port specific init. code */
//调用专用通信口初始化代码
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* ENTER ISR
*
* Description: This function is used to notify uC/OS-II that you are about to service an interrupt
* service routine (ISR). This allows uC/OS-II to keep track of interrupt nesting and thus
* only perform rescheduling at the last nested ISR.
*
* Arguments : none
*
* Returns : none
*
* Notes : 1) This function should be called ith interrupts already disabled
* 2) Your ISR can directly increment OSIntNesting without calling this function because
* OSIntNesting has been declared 'global'.
* 3) You MUST still call OSIntExit() even though you increment OSIntNesting directly.
* 4) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
* end of the ISR.
* 5) You are allowed to nest interrupts up to 255 levels deep.
* 6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because
* OSIntEnter() is always called with interrupts disabled.
进入中断服务程序
描述:通知ucosII将进入中断服务程序,它允许ucos跟踪中断嵌套,所以只有
//在最后一层中断嵌套才重新安排。
参数:无
返回:无
注意:1、只有在关中断的时候才调用
2、因为中断嵌套定义为全局变量,所以在没有调用此函数的时候
也可以增加中断嵌套数
3、即使你增加了中断嵌套数,你也要调用OSIntExit()
4、你必须成对调用OSIntEnter() and OSIntExit(),即:每次在ISR开始时调用OSIntEnter()
你将在ISR结束时调用OSIntExit()
5、你可以嵌套255层深
6、因为每次调用时中断是关的,所以我去掉了OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL()
*********************************************************************************************************
*/
void OSIntEnter (void)
{
if (OSRunning == TRUE) {
if (OSIntNesting < 255) {
OSIntNesting++; /* Increment ISR nesting level */
}//增加中断嵌套数
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* EXIT ISR
*
* Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When
* the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether
* a new, high-priority task, is ready to run.
*
* Arguments : none
*
* Returns : none
*
* Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
* to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
* end of the ISR.
* 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
退出中断
描述:通知ucos你已经完成中断服务程序,当最后一层嵌套完成后,ucos将
重新调度看是否一个新的,高优先级任务将就绪。
参数:无
返回:无
备注:1、你必须成对调用OSIntEnter() and OSIntExit(),即:每次在ISR开始时调用OSIntEnter()
你将在ISR结束时调用OSIntExit()
2、当调度上锁的话,重新调度是不允许的。见OS_SchedLock()(就在下面)
*********************************************************************************************************
*/
void OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
if (OSRunning == TRUE) {//如果正在运行
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
//防止减到比0还小
OSIntNesting--;
}
if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ... */
OSIntExitY = OSUnMapTbl[OSRdyGrp]; /* ... and not locked. */
OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
//看到几遍了,就是不会算啊!哪交要算算
//终于明白了!!!!!!!!!!!!!!
if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
//如果当前任务不是最高优先级,将最高优先级放入最高优先级标志中。
OSCtxSwCtr++; /* Keep track of the number of ctx switches */
//跟踪任务转换次数
OSIntCtxSw(); /* Perform interrupt level ctx switch */
//执行中断水平任务切换???
}
}
OS_EXIT_CRITICAL();
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* PREVENT SCHEDULING
*
* Description: This function is used to prevent rescheduling to take place. This allows your application
* to prevent context switches until you are ready to permit context switching.
*
* Arguments : none
*
* Returns : none
*
* Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every
* call to OSSchedLock() you MUST have a call to OSSchedUnlock().
调度上锁函数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -