📄 os_core.c
字号:
* OSIntNesting has been declared 'global'. You MUST, however, be sure that the increment
* is performed 'indivisibly' by your processor to ensure proper access to this critical
* resource.
* 2) You MUST still call OSIntExit() even though you increment OSIntNesting directly.
* 3) 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.
*********************************************************************************************************
*/
void OSIntEnter (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_ENTER_CRITICAL();
/*
LSI Logic (BDA) Modification
S. Wright
08/20/2001
added check for OS running
this prevents unpredictable behavior should ISRs start prior to OSRunning == TRUE
*/
if (OSRunning == TRUE) {
if (OSIntNesting < 255) {
OSIntNesting++; /* Increment ISR nesting level */
}
}
OS_EXIT_CRITICAL();
}
/*$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 OSSchedLock())
*********************************************************************************************************
*/
void OSIntExit (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_ENTER_CRITICAL();
/*
LSI Logic (BDA) Modification
S. Wright
08/20/2001
added check for OS running
this prevents unpredictable behavior should ISRs start prior to OSRunning == TRUE
*/
if (OSRunning == TRUE) {
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
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 context switches */
OSIntCtxSw(); /* Perform interrupt level context 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 */
OS_CPU_SR cpu_sr;
#endif
if (OSRunning == TRUE) { /* Make sure multitasking is running */
OS_ENTER_CRITICAL();
if (OSLockNesting < 255) { /* 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 */
OS_CPU_SR cpu_sr;
#endif
if (OSRunning == 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) && (OSIntNesting == 0)) { /* See if sched. enabled and not an ISR */
OS_EXIT_CRITICAL();
OS_Sched(); /* See if a HPT is ready */
} 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 TRUE.
*********************************************************************************************************
*/
void OSStart (void)
{
INT8U y;
INT8U x;
if (OSRunning == FALSE) {
y = OSUnMapTbl[OSRdyGrp]; /* Find highest priority's task priority number */
x = OSUnMapTbl[OSRdyTbl[y]];
OSPrioHighRdy = (INT8U)((y << 3) + x);
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 */
OS_CPU_SR cpu_sr;
#endif
OSTimeDly(2); /* Synchronize with clock tick */
OS_ENTER_CRITICAL();
OSIdleCtr = 0L; /* Clear idle counter */
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC); /* Determine MAX. idle counter value for 1 second */
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr; /* Store maximum idle counter count in 1 second */
OSStatRdy = 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)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
/*
LSI Logic (BDA) Modification
S. Wright
08/20/2001
added enabling/disabling of OSTimeTickHook() call
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -