📄 os_core.c
字号:
* 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.
*********************************************************************************************************
*/
void OSIntEnter (void)
{
if (OSRunning == OS_TRUE) { /* 系统已启动 */
if (OSIntNesting < 255u) { /* 未达到中断嵌套的上限 */
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())
*********************************************************************************************************
*/
void OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register 用于储存CPU状态寄存器 */
OS_CPU_SR cpu_sr = 0;
#endif
/* 系统已启动 */
if (OSRunning == OS_TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping 中断中 */
OSIntNesting--; /* 中断嵌套的层次减一 */
}
if (OSIntNesting == 0) { /* Reschedule only if all ISRs complete ... 完全退出中断 */
if (OSLockNesting == 0) { /* ... and not locked. 并调度器没上锁,则任务调度 */
OS_SchedNew();
if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy 避免多余的任务切换 */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* 获取最高级就绪任务任务控制块指针 */
#if OS_TASK_PROFILE_EN > 0
OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task 该任务被调度次数加一 */
#endif
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().
*********************************************************************************************************
*/
#if OS_SCHED_LOCK_EN > 0
void OSSchedLock (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register 用于储存CPU状态寄存器 */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSRunning == OS_TRUE) { /* Make sure multitasking is running 系统已启动 */
OS_ENTER_CRITICAL();
if (OSIntNesting == 0) { /* Can't call from an ISR 不在中断中 */
if (OSLockNesting < 255u) { /* Prevent OSLockNesting from wrapping back to 0 未达到调度器上锁层次的上限 */
OSLockNesting++; /* Increment lock nesting level 调度器上锁层次加一 */
}
}
OS_EXIT_CRITICAL();
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* ENABLE SCHEDULING
*
* Description: This function is used to re-allow rescheduling.
*
* 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().
*********************************************************************************************************
*/
#if OS_SCHED_LOCK_EN > 0
void OSSchedUnlock (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register 用于储存CPU状态寄存器 */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSRunning == OS_TRUE) { /* Make sure multitasking is running 系统已启动 */
OS_ENTER_CRITICAL();
if (OSLockNesting > 0) { /* Do not decrement if already 0 调度器已上锁 */
OSLockNesting--; /* Decrement lock nesting level 调度器上锁层次减一 */
if (OSLockNesting == 0) { /* See if scheduler is enabled and ... 调度器上锁层次为0 */
if (OSIntNesting == 0) { /* ... not in an ISR 并不在中断中,则任务调度 */
OS_EXIT_CRITICAL();
OS_Sched(); /* See if a HPT is ready 任务调度 */
} else {
OS_EXIT_CRITICAL();
}
} else {
OS_EXIT_CRITICAL();
}
} else {
OS_EXIT_CRITICAL();
}
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* START MULTITASKING
*
* Description: This function is used to start the multitasking process which lets uC/OS-II manages the
* task that you have created. Before you can call OSStart(), you MUST have called OSInit()
* and you MUST have created at least one task.
*
* Arguments : none
*
* Returns : none
*
* Note : OSStartHighRdy() MUST:
* a) Call OSTaskSwHook() then,
* b) Set OSRunning to OS_TRUE.
* c) Load the context of the task pointed to by OSTCBHighRdy.
* d_ Execute the task.
*********************************************************************************************************
*/
void OSStart (void)
{
if (OSRunning == OS_FALSE) {
OS_SchedNew(); /* Find highest priority's task priority number 系统未启动 */
OSPrioCur = OSPrioHighRdy; /* 修改当前优先级 */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run 获取最高级就绪任务任务控制块指针 */
OSTCBCur = OSTCBHighRdy; /* 修改当前任务任务控制块指针 */
OSStartHighRdy(); /* Execute target specific code to start task 进入最高级就绪任务 */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* STATISTICS INITIALIZATION
*
* Description: This function is called by your application to establish CPU usage by first determining
* how high a 32-bit counter would count to in 1 second if no other tasks were to execute
* during that time. CPU usage is then determined by a low priority task which keeps track
* of this 32-bit counter every second but this time, with other tasks running. CPU usage is
* determined by:
*
* OSIdleCtr
* CPU Usage (%) = 100 * (1 - ------------)
* OSIdleCtrMax
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
#if OS_TASK_STAT_EN > 0
void OSStatInit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register 用于储存CPU状态寄存器 */
OS_CPU_SR cpu_sr = 0;
#endif
OSTimeDly(2); /* Synchronize with clock tick 时钟同步 */
OS_ENTER_CRITICAL();
OSIdleCtr = 0L; /* Clear idle counter 清除空闲计数值 */
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC / 10); /* Determine MAX. idle counter value for 1/10 second 延时十分一秒 */
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr; /* Store maximum idle counter count in 1/10 second 获取十分一秒后空闲计数值 */
OSStatRdy = OS_TRUE; /* 统计任务就绪 */
OS_EXIT_CRITICAL();
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* PROCESS SYSTEM TICK
*
* Description: This function is used to signal to uC/OS-II the occurrence of a 'system tick' (also known
* as a 'clock tick'). This function should be called by the ticker ISR but, can also be
* called by a high priority task.
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void OSTimeTick (void)
{
OS_TCB *ptcb;
#if OS_TICK_STEP_EN > 0
BOOLEAN step;
#endif
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register 用于储存CPU状态寄存器 */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_TIME_TICK_HOOK_EN > 0
OSTimeTickHook(); /* Call user definable hook 调用用户定义的定时中断勾子函数 */
#endif
#if OS_TIME_GET_SET_EN > 0
OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter 刷新系统时间 */
OSTime++;
OS_EXIT_CRITICAL();
#endif
if (OSRunning == OS_TRUE) {
#if OS_TICK_STEP_EN > 0
switch (OSTickStepState) { /* Determine whether we need to process a tick */
case OS_TICK_STEP_DIS: /* Yes, stepping is disabled */
step = OS_TRUE;
break;
case OS_TICK_STEP_WAIT: /* No, waiting for uC/OS-View to set ... */
step = OS_FALSE; /* .. OSTickStepState to OS_TICK_STEP_ONCE */
break;
case OS_TICK_STEP_ONCE: /* Yes, process tick once and wait for next ... */
step = OS_TRUE; /* ... step command from uC/OS-View */
OSTickStepState = OS_TICK_STEP_WAIT;
break;
default: /* Invalid case, correct situation */
step = OS_TRUE;
OSTickStepState = OS_TICK_STEP_DIS;
break;
}
if (step == OS_FALSE) { /* Return if waiting for step command */
return;
}
#endif
ptcb = OSTCBList; /* Point at first TCB in TCB list 从任务链表第一个任务开始 */
while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) { /* Go through all TCBs in TCB list 编历整个任务链表 */
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) { /* No, Delayed or waiting for event with TO 任务需要延时处理 */
if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay 任务延时减一,减一后延时结束了吗?*/
/* Check for timeout */
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) { /* 任务等待某系统的服务 */
ptcb->OSTCBStat &= ~(INT8U)OS_STAT_PEND_ANY; /* Yes, Clear status flag 清除等待系统的服务标志位 */
ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout 设置任务等待系统的服务超时标志位 */
} else {
ptcb->OSTCBStatPend = OS_STAT_PEND_OK; /* 任务仅是延时,设置任务等待超时成功标志位 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -