📄 emos_core.c
字号:
#else
emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], EMOS_IDLE_PRIO);
#endif
#else
#if EMOS_TASK_CREATE_EXT_EN
emosTaskCreateExt(emosTaskIdle,
(void *)0, /* No arguments passed to gEmosTaskIdle() */
&emosTaskIdleStk[0], /* Set Top-Of-Stack */
EMOS_IDLE_PRIO, /* Lowest priority level*/
EMOS_TASK_IDLE_ID,
&emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */
EMOS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension*/
EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#else
emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[0], EMOS_IDLE_PRIO);
#endif
#endif
#if EMOS_TASK_STAT_EN
#if EMOS_TASK_CREATE_EXT_EN
#if EMOS_STK_GROWTH == 1
emosTaskCreateExt(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1],/* Set Top-Of-Stack */
EMOS_STAT_PRIO, /* One higher than the idle task*/
EMOS_TASK_STAT_ID,
&emosTaskStatStk[0], /* Set Bottom-Of-Stack*/
EMOS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#else
emosTaskCreateExt(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[0], /* Set Top-Of-Stack */
EMOS_STAT_PRIO, /* One higher than the idle task */
EMOS_TASK_STAT_ID,
&emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */
EMOS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#endif
#else
#if EMOS_STK_GROWTH == 1
emosTaskCreate(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */
EMOS_STAT_PRIO); /* One higher than the idle task */
#else
emosTaskCreate(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[0], /* Set Top-Of-Stack */
EMOS_STAT_PRIO); /* One higher than the idle task */
#endif
#endif
#endif /*end of STAT_EN*/
#endif
emosInitStart();
return ;
}
/*adjust the Idle and Stat task to the seperated callback,
to fix init errors*/
static void emosInitIdleStatTask()
{
#if EMOS_STK_GROWTH == 1
#if EMOS_TASK_CREATE_EXT_EN
emosTaskCreateExt(emosTaskIdle,
(void *)0, /* No arguments passed to gEmosTaskIdle() */
&emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack*/
EMOS_IDLE_PRIO, /* Lowest priority level */
EMOS_TASK_IDLE_ID,
&emosTaskIdleStk[0], /* Set Bottom-Of-Stack */
EMOS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension*/
EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#else
emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], EMOS_IDLE_PRIO);
#endif
#else
#if EMOS_TASK_CREATE_EXT_EN
emosTaskCreateExt(emosTaskIdle,
(void *)0, /* No arguments passed to gEmosTaskIdle() */
&emosTaskIdleStk[0], /* Set Top-Of-Stack */
EMOS_IDLE_PRIO, /* Lowest priority level*/
EMOS_TASK_IDLE_ID,
&emosTaskIdleStk[EMOS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack */
EMOS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension*/
EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#else
emosTaskCreate(emosTaskIdle, (void *)0, &emosTaskIdleStk[0], EMOS_IDLE_PRIO);
#endif
#endif
#if EMOS_TASK_STAT_EN
#if EMOS_TASK_CREATE_EXT_EN
#if EMOS_STK_GROWTH == 1
emosTaskCreateExt(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1],/* Set Top-Of-Stack */
EMOS_STAT_PRIO, /* One higher than the idle task*/
EMOS_TASK_STAT_ID,
&emosTaskStatStk[0], /* Set Bottom-Of-Stack*/
EMOS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#else
emosTaskCreateExt(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[0], /* Set Top-Of-Stack */
EMOS_STAT_PRIO, /* One higher than the idle task */
EMOS_TASK_STAT_ID,
&emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */
EMOS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
EMOS_TASK_OPT_STK_CHK | EMOS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#endif
#else
#if EMOS_STK_GROWTH == 1
emosTaskCreate(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[EMOS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */
EMOS_STAT_PRIO); /* One higher than the idle task */
#else
emosTaskCreate(emosTaskStat,
(void *)0, /* No args passed to gEmosTaskStat() */
&emosTaskStatStk[0], /* Set Top-Of-Stack */
EMOS_STAT_PRIO); /* One higher than the idle task */
#endif
#endif
#endif /*end of STAT_EN*/
}
void emosInitStart(void)
{
/*Adjus the idle and Stat task to emosStart,
other wise there are problems for task using timeDly()/Sem()/MsgQ() etc*/
emosInitIdleStatTask();
#if EMOS_TASK_STAT_EN
emosStatInit();
#endif
return;
}
/**********************************************************************************************************
* ENTER ISR
*
* Description: This function is used to notify EMOS that you are about to service an interrupt
* service routine (ISR). This allows EMOS 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 emosIntEnter (void)
{
EMOS_ENTER_CRITICAL();
gEmosIntNesting++; /* Increment ISR nesting level */
EMOS_EXIT_CRITICAL();
}
/**********************************************************************************************************
* EXIT ISR
*
* Description: This function is used to notify EMOS that you have completed serviving an ISR. When
* the last nested ISR has completed, EMOS 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 emosIntExit (void)
{
EMOS_ENTER_CRITICAL();
if ((--gEmosIntNesting | gEmosLockNesting) == 0)
{
/* Reschedule only if all ISRs completed & not locked */
emosIntExitY = gEmosUnMapTbl[gEmosRdyGrp];
gEmosPrioHighRdy = (uint8)((emosIntExitY << 3) + gEmosUnMapTbl[gEmosRdyTbl[emosIntExitY]]);
if (gEmosPrioHighRdy != gEmosPrioCur)
{ /* No context switch if current task is highest ready */
gEmosTCBHighRdy = gEmosTCBPrioTbl[gEmosPrioHighRdy];
gEmosCtxSwCtr++; /* Keep track of the number of context switches */
emosIntCtxSw(); /* Perform interrupt level context switch */
}
}
EMOS_EXIT_CRITICAL();
}
/**********************************************************************************************************
* SCHEDULER
* Description: This function is called by other EMOS 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 EMOS and your application should not call it.
* 2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
*********************************************************************************************************
*/
void emosSched (void)
{
uint8 y;
EMOS_ENTER_CRITICAL();
if ((gEmosLockNesting | gEmosIntNesting) == 0)
{
/* Task scheduling must be enabled and not ISR level */
y = gEmosUnMapTbl[gEmosRdyGrp]; /* Get pointer to highest priority task ready to run */
gEmosPrioHighRdy = (uint8)((y << 3) + gEmosUnMapTbl[gEmosRdyTbl[y]]);
if (gEmosPrioHighRdy != gEmosPrioCur)
{
/* No context switch if current task is highest ready */
gEmosTCBHighRdy = gEmosTCBPrioTbl[gEmosPrioHighRdy];
gEmosCtxSwCtr++; /* Increment context switch counter */
EMOS_TASK_SW(); /* Perform a context switch */
}
}
/*EMOS_Printf("==>emosShed Returning pTCBCur=%08x pri=%d\r\n",
(int)gEmosTCBCur,(int)gEmosTCBCur->osTCBPrio);*/
EMOS_EXIT_CRITICAL();
}
/**********************************************************************************************************
* 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 emosSchedLock (void)
{
if (gEmosRunning == EMOS_TRUE)
{
/* Make sure multitasking is running */
EMOS_ENTER_CRITICAL();
gEmosLockNesting++; /* Increment lock nesting level*/
EMOS_EXIT_CRITICAL();
}
}
/**********************************************************************************************************
* 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 emosSchedUnlock (void)
{
if (gEmosRunning == EMOS_TRUE)
{
/* Make sure multitasking is running */
EMOS_ENTER_CRITICAL();
if (gEmosLockNesting > 0)
{
/* Do not decrement if already 0 */
gEmosLockNesting--; /* Decrement lock nesting level */
if ((gEmosLockNesting | gEmosIntNesting) == 0)
{
/* See if scheduling re-enabled and not an ISR */
EMOS_EXIT_CRITICAL();
emosSched(); /* See if a higher priority task is ready */
}
else
{
EMOS_EXIT_CRITICAL();
}
}
else
{
EMOS_EXIT_CRITICAL();
}
}
}
/**********************************************************************************************************
* START MULTITASKING
* Description: This function is used to start the multitasking process which lets EMOS 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -