📄 ucos_iif.c
字号:
#endif
OSCtxSwCtr = 0; /* Clear the context switch counter */
OSRdyGrp = 0; /* Clear the ready list */
for (i = 0; i < OS_RDY_TBL_SIZE; i++) {
OSRdyTbl[i] = 0;
}
OSPrioCur = 0;
OSPrioHighRdy = 0;
OSTCBHighRdy = (OS_TCB *)0; /* TCB Initialization */
OSTCBCur = (OS_TCB *)0;
OSTCBList = (OS_TCB *)0;
for (i = 0; i < (OS_LOWEST_PRIO + 1); i++) { /* Clear the priority table */
OSTCBPrioTbl[i] = (OS_TCB *)0;
}
for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) { /* Init. list of free TCBs */
OSTCBTbl[i].OSTCBNext = &OSTCBTbl[i + 1];
}
OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS - 1].OSTCBNext = (OS_TCB *)0; /* Last OS_TCB */
OSTCBFreeList = &OSTCBTbl[0];
#if OS_MAX_EVENTS >= 2
for (i = 0; i < (OS_MAX_EVENTS - 1); i++) { /* Init. list of free EVENT control blocks */
OSEventTbl[i].OSEventPtr = (OS_EVENT *)&OSEventTbl[i + 1];
}
OSEventTbl[OS_MAX_EVENTS - 1].OSEventPtr = (OS_EVENT *)0;
OSEventFreeList = &OSEventTbl[0];
#endif
#if OS_Q_EN && (OS_MAX_QS >= 2)
OSQInit(); /* Initialize the message queue structures */
#endif
#if OS_MEM_EN && OS_MAX_MEM_PART >= 2
OSMemInit(); /* Initialize the memory manager */
#endif
#if OS_STK_GROWTH == 1
#if OS_TASK_CREATE_EXT_EN
OSTaskCreateExt(OSTaskIdle,
(void *)0, /* No arguments passed to OSTaskIdle() */
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack */
OS_IDLE_PRIO, /* Lowest priority level */
OS_TASK_IDLE_ID,
&OSTaskIdleStk[0], /* Set Bottom-Of-Stack */
OS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#else
OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], OS_IDLE_PRIO);
#endif
#else
#if OS_TASK_CREATE_EXT_EN
OSTaskCreateExt(OSTaskIdle,
(void *)0, /* No arguments passed to OSTaskIdle() */
&OSTaskIdleStk[0], /* Set Top-Of-Stack */
OS_IDLE_PRIO, /* Lowest priority level */
OS_TASK_IDLE_ID,
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */
OS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#else
OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[0], OS_IDLE_PRIO);
#endif
#endif
#if OS_TASK_STAT_EN
#if OS_TASK_CREATE_EXT_EN
#if OS_STK_GROWTH == 1
OSTaskCreateExt(OSTaskStat,
(void *)0, /* No args passed to OSTaskStat() */
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],/* Set Top-Of-Stack */
OS_STAT_PRIO, /* One higher than the idle task */
OS_TASK_STAT_ID,
&OSTaskStatStk[0], /* Set Bottom-Of-Stack */
OS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#else
OSTaskCreateExt(OSTaskStat,
(void *)0, /* No args passed to OSTaskStat() */
&OSTaskStatStk[0], /* Set Top-Of-Stack */
OS_STAT_PRIO, /* One higher than the idle task */
OS_TASK_STAT_ID,
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],/* Set Bottom-Of-Stack */
OS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#endif
#else
#if OS_STK_GROWTH == 1
OSTaskCreate(OSTaskStat,
(void *)0, /* No args passed to OSTaskStat() */
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */
OS_STAT_PRIO); /* One higher than the idle task */
#else
OSTaskCreate(OSTaskStat,
(void *)0, /* No args passed to OSTaskStat() */
&OSTaskStatStk[0], /* Set Top-Of-Stack */
OS_STAT_PRIO); /* One higher than the idle task */
#endif
#endif
#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) Your ISR can directly increment OSIntNesting without calling this function because
* 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)
{
OS_ENTER_CRITICAL();
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)
{
OS_ENTER_CRITICAL();
if ((--OSIntNesting | OSLockNesting) == 0) { /* Reschedule only if all ISRs completed & not locked */
OSIntExitY = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
if (OSPrioHighRdy != OSPrioCur) { /* No context switch if current task is highest ready */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++; /* Keep track of the number of context switches */
OSIntCtxSw(); /* Perform interrupt level context switch */
}
}
OS_EXIT_CRITICAL();
}
/*$PAGE*/
/*
*********************************************************************************************************
* SCHEDULER
*
* Description: This function is called by other uC/OS-II 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
*
* Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it.
* 2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
*********************************************************************************************************
*/
void OSSched (void)
{
INT8U y;
OS_ENTER_CRITICAL();
if ((OSLockNesting | OSIntNesting) == 0) { /* Task scheduling must be enabled and not ISR level */
y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to highest priority task ready to run */
OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
if (OSPrioHighRdy != OSPrioCur) { /* No context switch if current task is highest ready */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++; /* Increment context switch counter */
OS_TASK_SW(); /* Perform a 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().
*********************************************************************************************************
*/
void OSSchedLock (void)
{
if (OSRunning == TRUE) { /* Make sure multitasking is running */
OS_ENTER_CRITICAL();
OSLockNesting++; /* Increment lock nesting level */
OS_EXIT_CRITICAL();
}
}
/*$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().
*********************************************************************************************************
*/
void OSSchedUnlock (void)
{
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 | OSIntNesting) == 0) { /* See if scheduling re-enabled and not an ISR */
OS_EXIT_CRITICAL();
OSSched(); /* See if a higher priority task is ready */
} else {
OS_EXIT_CRITICAL();
}
} else {
OS_EXIT_CRITICAL();
}
}
}
/*$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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -