📄 os_core.c
字号:
if (OSRunning != OS_STATE_OS_RUNNING) { /* Has the OS started? */
return; /* No */
}
CPU_INT_DIS();
if (OSIntNestingCtr == (OS_NESTING_CTR)0) { /* Prevent OSIntNestingCtr from wrapping */
CPU_INT_EN();
return;
}
OSIntNestingCtr--;
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* ISRs still nested? */
CPU_INT_EN(); /* Yes */
return;
}
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Scheduler still locked? */
CPU_INT_EN(); /* Yes */
return;
}
OSPrioHighRdy = OS_PrioGetHighest(); /* Find highest priority */
OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadPtr; /* Get highest priority task ready-to-run */
if (OSTCBHighRdyPtr == OSTCBCurPtr) { /* Current task still the highest priority? */
CPU_INT_EN(); /* Yes */
return;
}
#if OS_CFG_TASK_PROFILE_EN > 0u
OSTCBHighRdyPtr->CtxSwCtr++; /* Inc. # of context switches for this new task */
#endif
OSTaskCtxSwCtr++; /* Keep track of the total number of ctx switches */
OSIntCtxSw(); /* Perform interrupt level ctx switch */
CPU_INT_EN();
}
/*$PAGE*/
/*
************************************************************************************************************************
* INDICATE THAT IT'S NO LONGER SAFE TO CREATE OBJECTS
*
* Description: This function is called by the application code to indicate that all initialization has been completed
* and that kernel objects are no longer allowed to be created.
*
* Arguments : none
*
* Returns : none
*
* Note(s) : none
************************************************************************************************************************
*/
#ifdef OS_SAFETY_CRITICAL_IEC61508
void OSSafetyCriticalStart (void)
{
OSSafetyCriticalStartFlag = DEF_TRUE;
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* SCHEDULER
*
* Description: This function is called by other uC/OS-III services to determine whether a new, high priority task has
* been made ready to run. This function is invoked by TASK level code and is not used to reschedule tasks
* from ISRs (see OSIntExit() for ISR rescheduling).
*
* Arguments : none
*
* Returns : none
*
* Note(s) : 1) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
************************************************************************************************************************
*/
void OSSched (void)
{
CPU_SR_ALLOC();
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* ISRs still nested? */
return; /* Yes ... only schedule when no nested ISRs */
}
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) { /* Scheduler locked? */
return; /* Yes */
}
CPU_INT_DIS();
OSPrioHighRdy = OS_PrioGetHighest(); /* Find the highest priority ready */
OSTCBHighRdyPtr = OSRdyList[OSPrioHighRdy].HeadPtr;
if (OSTCBHighRdyPtr == OSTCBCurPtr) { /* Current task is still highest priority task? */
CPU_INT_EN(); /* Yes ... no need to context switch */
return;
}
#if OS_CFG_TASK_PROFILE_EN > 0u
OSTCBHighRdyPtr->CtxSwCtr++; /* Inc. # of context switches to this task */
#endif
OSTaskCtxSwCtr++; /* Increment context switch counter */
OS_TASK_SW(); /* Perform a task level context switch */
CPU_INT_EN();
}
/*$PAGE*/
/*
************************************************************************************************************************
* PREVENT SCHEDULING
*
* Description: This function is used to prevent rescheduling from taking place. This allows your application to prevent
* context switches until you are ready to permit context switching.
*
* Arguments : p_err is a pointer to a variable that will receive an error code:
*
* OS_ERR_NONE The scheduler is locked
* OS_ERR_LOCK_NESTING_OVF If you attempted to nest call to this function > 250 levels
* OS_ERR_OS_NOT_RUNNING If uC/OS-III is not running yet.
* OS_ERR_SCHED_LOCK_ISR If you called this function from an ISR.
*
* Returns : none
*
* Note(s) : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every
* call to OSSchedLock() you MUST have a call to OSSchedUnlock().
************************************************************************************************************************
*/
void OSSchedLock (OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_SCHED_LOCK_ISR;
return;
}
#endif
if (OSRunning != OS_STATE_OS_RUNNING) { /* Make sure multitasking is running */
*p_err = OS_ERR_OS_NOT_RUNNING;
return;
}
if (OSSchedLockNestingCtr >= (OS_NESTING_CTR)250u) { /* Prevent OSSchedLockNestingCtr overflowing */
*p_err = OS_ERR_LOCK_NESTING_OVF;
return;
}
CPU_CRITICAL_ENTER();
OSSchedLockNestingCtr++; /* Increment lock nesting level */
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
OS_SchedLockTimeMeasStart();
#endif
CPU_CRITICAL_EXIT();
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* ENABLE SCHEDULING
*
* Description: This function is used to re-allow rescheduling.
*
* Arguments : p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE
* OS_ERR_OS_NOT_RUNNING The scheduler has been enabled
* OS_ERR_SCHED_LOCKED The scheduler is still locked, still nested
* OS_ERR_SCHED_NOT_LOCKED The scheduler was not locked
* OS_ERR_SCHED_UNLOCK_ISR If you called this function from an ISR.
*
* Returns : none
*
* Note(s) : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every call to
* OSSchedLock() you MUST have a call to OSSchedUnlock().
************************************************************************************************************************
*/
void OSSchedUnlock (OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
*p_err = OS_ERR_SCHED_UNLOCK_ISR;
return;
}
#endif
if (OSRunning != OS_STATE_OS_RUNNING) { /* Make sure multitasking is running */
*p_err = OS_ERR_OS_NOT_RUNNING;
return;
}
if (OSSchedLockNestingCtr == (OS_NESTING_CTR)0) { /* See if the scheduler is locked */
*p_err = OS_ERR_SCHED_NOT_LOCKED;
return;
}
CPU_CRITICAL_ENTER();
OSSchedLockNestingCtr--; /* Decrement lock nesting level */
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {
CPU_CRITICAL_EXIT(); /* Scheduler is still locked */
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
OS_SchedLockTimeMeasStop();
#endif
CPU_CRITICAL_EXIT(); /* Scheduler should be re-enabled */
OSSched(); /* Run the scheduler */
*p_err = OS_ERR_NONE;
}
/*$PAGE*/
/*
************************************************************************************************************************
* CONFIGURE ROUND-ROBIN SCHEDULING PARAMETERS
*
* Description: This function is called to change the round-robin scheduling parameters.
*
* Arguments : en determines whether round-robin will be enabled (when DEF_EN) or not (when DEF_DIS)
*
* dflt_time_quanta default number of ticks between time slices. 0 means assumes OSCfg_TickRate_Hz / 10.
*
* p_err is a pointer to a variable that will contain an error code returned by this function.
*
* OS_ERR_NONE The call was successful
*
* Returns : none
************************************************************************************************************************
*/
#if OS_CFG_SCHED_ROUND_ROBIN_EN > 0u
void OSSchedRoundRobinCfg (CPU_BOOLEAN en,
OS_TICK dflt_time_quanta,
OS_ERR *p_err)
{
CPU_SR_ALLOC();
#ifdef OS_SAFETY_CRITICAL
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
CPU_CRITICAL_ENTER();
if (en != DEF_ENABLED) {
OSSchedRoundRobinEn = DEF_DISABLED;
} else {
OSSchedRoundRobinEn = DEF_ENABLED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -