目录

改变Task优先级
cpp
#if OS_TASK_CHANGE_PRIO_EN > 0u
INT8U OSTaskChangePrio (INT8U oldprio,
INT8U newprio)
{
#if (OS_EVENT_EN)
OS_EVENT *pevent;
#if (OS_EVENT_MULTI_EN > 0u)
OS_EVENT **pevents;
#endif
#endif
OS_TCB *ptcb;
INT8U y_new;
INT8U x_new;
INT8U y_old;
OS_PRIO bity_new;
OS_PRIO bitx_new;
OS_PRIO bity_old;
OS_PRIO bitx_old;
#if OS_CRITICAL_METHOD == 3u
OS_CPU_SR cpu_sr = 0u; /* Storage for CPU status register */
#endif
/*$PAGE*/
#if OS_ARG_CHK_EN > 0u
if (oldprio >= OS_LOWEST_PRIO)
{
if (oldprio != OS_PRIO_SELF)
{
return (OS_ERR_PRIO_INVALID);
}
}
if (newprio >= OS_LOWEST_PRIO)
{
return (OS_ERR_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) /* New priority must not already exist */
{
OS_EXIT_CRITICAL();
return (OS_ERR_PRIO_EXIST);
}
if (oldprio == OS_PRIO_SELF) /* See if changing self */
{
oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */
}
ptcb = OSTCBPrioTbl[oldprio];
if (ptcb == (OS_TCB *)0) /* Does task to change exist? */
{
OS_EXIT_CRITICAL(); /* No, can't change its priority! */
return (OS_ERR_PRIO);
}
if (ptcb == OS_TCB_RESERVED) /* Is task assigned to Mutex */
{
OS_EXIT_CRITICAL(); /* No, can't change its priority! */
return (OS_ERR_TASK_NOT_EXIST);
}
#if OS_LOWEST_PRIO <= 63u
y_new = (INT8U) (newprio >> 3u); /* Yes, compute new TCB fields */
x_new = (INT8U) (newprio & 0x07u);
#else
y_new = (INT8U) ((INT8U) (newprio >> 4u) & 0x0Fu);
x_new = (INT8U) (newprio & 0x0Fu);
#endif
bity_new = (OS_PRIO) (1uL << y_new);
bitx_new = (OS_PRIO) (1uL << x_new);
OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* Remove TCB from old priority */
OSTCBPrioTbl[newprio] = ptcb; /* Place pointer to TCB @ new priority */
y_old = ptcb->OSTCBY;
bity_old = ptcb->OSTCBBitY;
bitx_old = ptcb->OSTCBBitX;
if ((OSRdyTbl[y_old] & bitx_old) != 0u) /* If task is ready make it not */
{
OSRdyTbl[y_old] &= (OS_PRIO)~bitx_old;
if (OSRdyTbl[y_old] == 0u)
{
OSRdyGrp &= (OS_PRIO)~bity_old;
}
OSRdyGrp |= bity_new; /* Make new priority ready to run */
OSRdyTbl[y_new] |= bitx_new;
}
#if (OS_EVENT_EN)
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0)
{
pevent->OSEventTbl[y_old] &= (OS_PRIO)~bitx_old; /* Remove old task prio from wait list */
if (pevent->OSEventTbl[y_old] == 0u)
{
pevent->OSEventGrp &= (OS_PRIO)~bity_old;
}
pevent->OSEventGrp |= bity_new; /* Add new task prio to wait list */
pevent->OSEventTbl[y_new] |= bitx_new;
}
#if (OS_EVENT_MULTI_EN > 0u)
if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0)
{
pevents = ptcb->OSTCBEventMultiPtr;
pevent = *pevents;
while (pevent != (OS_EVENT *)0)
{
pevent->OSEventTbl[y_old] &= (OS_PRIO)~bitx_old; /* Remove old task prio from wait lists */
if (pevent->OSEventTbl[y_old] == 0u)
{
pevent->OSEventGrp &= (OS_PRIO)~bity_old;
}
pevent->OSEventGrp |= bity_new; /* Add new task prio to wait lists */
pevent->OSEventTbl[y_new] |= bitx_new;
pevents++;
pevent = *pevents;
}
}
#endif
#endif
ptcb->OSTCBPrio = newprio; /* Set new task priority */
ptcb->OSTCBY = y_new;
ptcb->OSTCBX = x_new;
ptcb->OSTCBBitY = bity_new;
ptcb->OSTCBBitX = bitx_new;
OS_EXIT_CRITICAL();
if (OSRunning == OS_TRUE)
{
OS_Sched(); /* Find new highest priority task */
}
return (OS_ERR_NONE);
}
#endif
Task挂起
cpp
#if OS_TASK_SUSPEND_EN > 0u
INT8U OSTaskSuspend (INT8U prio)
{
BOOLEAN self;
OS_TCB *ptcb;
INT8U y;
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
if (prio == OS_TASK_IDLE_PRIO) /* Not allowed to suspend idle task */
{
return (OS_ERR_TASK_SUSPEND_IDLE);
}
if (prio >= OS_LOWEST_PRIO) /* Task priority valid ? */
{
if (prio != OS_PRIO_SELF)
{
return (OS_ERR_PRIO_INVALID);
}
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) /* See if suspend SELF */
{
prio = OSTCBCur->OSTCBPrio;
self = OS_TRUE;
}
else if (prio == OSTCBCur->OSTCBPrio) /* See if suspending self */
{
self = OS_TRUE;
}
else
{
self = OS_FALSE; /* No suspending another task */
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) /* Task to suspend must exist */
{
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_SUSPEND_PRIO);
}
if (ptcb == OS_TCB_RESERVED) /* See if assigned to Mutex */
{
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
y = ptcb->OSTCBY;
OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX; /* Make task not ready */
if (OSRdyTbl[y] == 0u)
{
OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
}
ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */
OS_EXIT_CRITICAL();
if (self == OS_TRUE) /* Context switch only if SELF */
{
OS_Sched(); /* Find new highest priority task */
}
return (OS_ERR_NONE);
}
#endif
Task恢复
cpp
#if OS_TASK_SUSPEND_EN > 0u
INT8U OSTaskResume (INT8U prio)
{
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3u /* Storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
if (prio >= OS_LOWEST_PRIO) /* Make sure task priority is valid */
{
return (OS_ERR_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) /* Task to suspend must exist */
{
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_RESUME_PRIO);
}
if (ptcb == OS_TCB_RESERVED) /* See if assigned to Mutex */
{
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY) /* Task must be suspended */
{
ptcb->OSTCBStat &= (INT8U)~ (INT8U)OS_STAT_SUSPEND; /* Remove suspension */
if (ptcb->OSTCBStat == OS_STAT_RDY) /* See if task is now ready */
{
if (ptcb->OSTCBDly == 0u)
{
OSRdyGrp |= ptcb->OSTCBBitY; /* Yes, Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
if (OSRunning == OS_TRUE)
{
OS_Sched(); /* Find new highest priority task */
}
}
else
{
OS_EXIT_CRITICAL();
}
}
else /* Must be pending on event */
{
OS_EXIT_CRITICAL();
}
return (OS_ERR_NONE);
}
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_SUSPENDED);
}
#endif
Task信息获取
cpp
#if OS_TASK_QUERY_EN > 0u
INT8U OSTaskQuery (INT8U prio,
OS_TCB *p_task_data)
{
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
if (prio > OS_LOWEST_PRIO) /* Task priority valid ? */
{
if (prio != OS_PRIO_SELF)
{
return (OS_ERR_PRIO_INVALID);
}
}
if (p_task_data == (OS_TCB *)0) /* Validate 'p_task_data' */
{
return (OS_ERR_PDATA_NULL);
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) /* See if suspend SELF */
{
prio = OSTCBCur->OSTCBPrio;
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) /* Task to query must exist */
{
OS_EXIT_CRITICAL();
return (OS_ERR_PRIO);
}
if (ptcb == OS_TCB_RESERVED) /* Task to query must not be assigned to a Mutex */
{
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
/* Copy TCB into user storage area */
OS_MemCopy ((INT8U *)p_task_data, (INT8U *)ptcb, sizeof (OS_TCB));
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
#endif
Task调度器上锁(os_core.c)
cpp
#if OS_SCHED_LOCK_EN > 0u
void OSSchedLock (void)
{
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
if (OSRunning == OS_TRUE) /* Make sure multitasking is running */
{
OS_ENTER_CRITICAL();
if (OSIntNesting == 0u) /* Can't call from an ISR */
{
if (OSLockNesting < 255u) /* Prevent OSLockNesting from wrapping back to 0 */
{
OSLockNesting++; /* Increment lock nesting level */
}
}
OS_EXIT_CRITICAL();
}
}
#endif
Task调度器开锁(os_core.c)
cpp
#if OS_SCHED_LOCK_EN > 0u
void OSSchedUnlock (void)
{
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
if (OSRunning == OS_TRUE) /* Make sure multitasking is running */
{
OS_ENTER_CRITICAL();
if (OSIntNesting == 0u) /* Can't call from an ISR */
{
if (OSLockNesting > 0u) /* Do not decrement if already 0 */
{
OSLockNesting--; /* Decrement lock nesting level */
if (OSLockNesting == 0u) /* See if scheduler is enabled */
{
OS_EXIT_CRITICAL();
OS_Sched(); /* See if a HPT is ready */
}
else
{
OS_EXIT_CRITICAL();
}
}
else
{
OS_EXIT_CRITICAL();
}
}
else
{
OS_EXIT_CRITICAL();
}
}
}
#endif