📄 os_core.c
字号:
#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
}
void OSIntEnter (void)
{
OS_ENTER_CRITICAL();
OSIntNesting++; /* Increment ISR nesting level */
OS_EXIT_CRITICAL();
}
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();
}
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();
}
void OSSchedLock (void)
{
if (OSRunning == TRUE) { /* Make sure multitasking is running */
OS_ENTER_CRITICAL();
OSLockNesting++; /* Increment lock nesting level */
OS_EXIT_CRITICAL();
}
}
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();
}
}
}
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 */
}
}
void OSTaskIdle (void *pdata)
{
pdata = pdata; /* Prevent compiler warning for not using 'pdata' */
for (;;) {
OS_ENTER_CRITICAL();
OSIdleCtr++;
OS_EXIT_CRITICAL();
}
}
INT8U OSTCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT16U stk_size, void *pext, INT16U opt)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */
if (ptcb != (OS_TCB *)0) {
OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */
OS_EXIT_CRITICAL();
ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */
ptcb->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */
ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */
ptcb->OSTCBDly = 0; /* Task is not delayed */
#if OS_TASK_CREATE_EXT_EN
ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */
ptcb->OSTCBStkSize = stk_size; /* Store stack size */
ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */
ptcb->OSTCBOpt = opt; /* Store task options */
ptcb->OSTCBId = id; /* Store task ID */
#else
pext = pext; /* Prevent compiler warning if not used */
stk_size = stk_size;
pbos = pbos;
opt = opt;
id = id;
#endif
#if OS_TASK_DEL_EN
ptcb->OSTCBDelReq = OS_NO_ERR;
#endif
ptcb->OSTCBY = prio >> 3; /* Pre-compute X, Y, BitX and BitY */
ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX = prio & 0x07;
ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
#if OS_MBOX_EN || OS_SEM_EN
ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on an event */
#endif
#if OS_MBOX_EN
ptcb->OSTCBMsg = (void *)0; /* No message received */
#endif
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = ptcb;
ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */
ptcb->OSTCBPrev = (OS_TCB *)0;
if (OSTCBList != (OS_TCB *)0) {
OSTCBList->OSTCBPrev = ptcb;
}
OSTCBList = ptcb;
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
} else {
OS_EXIT_CRITICAL();
return (OS_NO_MORE_TCB);
}
}
void OSTimeTick (void)
{
OS_TCB *ptcb;
OSTimeTickHook(); /* Call user definable hook */
ptcb = OSTCBList; /* Point at first TCB in TCB list */
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { /* Go through all TCBs in TCB list */
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0) { /* Delayed or waiting for event with TO */
if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { /* Is task suspended? */
OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make task Rdy to Run (timed out)*/
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
} else { /* Yes, Leave 1 tick to prevent ... */
ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */
} /* ... suspension is removed. */
}
}
ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
OS_EXIT_CRITICAL();
}
OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
OSTime++;
OS_EXIT_CRITICAL();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -