μC/OS-II—Task management 2 (os_task.c)

Directory

    • Change task priority
    • Task hangs
    • Task recovery
    • Task information acquisition
    • Task scheduler lock (os_core.c)
    • Task scheduler unlocking (os_core.c)

Change Task priority

#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 bite_new;
OS_PRIO bitx_new;
OS_PRIO bite_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
\t
if (oldprio >= OS_LOWEST_PRIO)
{<!-- -->
if (oldprio != OS_PRIO_SELF)
{<!-- -->
return (OS_ERR_PRIO_INVALID);
}
}
\t
if (newprio >= OS_LOWEST_PRIO)
{<!-- -->
return (OS_ERR_PRIO_INVALID);
}
\t
#endif
OS_ENTER_CRITICAL();
\t
if (OSTCBPrioTbl[newprio] != (OS_TCB *)0) /* New priority must not already exist */
{<!-- -->
OS_EXIT_CRITICAL();
return (OS_ERR_PRIO_EXIST);
}
\t
if (oldprio == OS_PRIO_SELF) /* See if changing self */
{<!-- -->
oldprio = OSTCBCur->OSTCBPrio; /* Yes, get priority */
}
\t
ptcb = OSTCBPrioTbl[oldprio];
\t
if (ptcb == (OS_TCB *)0) /* Does task to change exist? */
{<!-- -->
OS_EXIT_CRITICAL(); /* No, can't change its priority! */
return (OS_ERR_PRIO);
}
\t
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);
}
\t
#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) & amp; 0x0Fu);
x_new = (INT8U) (newprio & amp; 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;
\t
if ((OSRdyTbl[y_old] & amp; bitx_old) != 0u) /* If task is ready make it not */
{<!-- -->
OSRdyTbl[y_old] & amp;= (OS_PRIO)~bitx_old;
\t\t
if (OSRdyTbl[y_old] == 0u)
{<!-- -->
OSRdyGrp & amp;= (OS_PRIO)~bity_old;
}
\t\t
OSRdyGrp |= bity_new; /* Make new priority ready to run */
OSRdyTbl[y_new] |= bitx_new;
}
\t
#if (OS_EVENT_EN)
pevent = ptcb->OSTCBEventPtr;
\t
if (pevent != (OS_EVENT *)0)
{<!-- -->
pevent->OSEventTbl[y_old] & amp;= (OS_PRIO)~bitx_old; /* Remove old task prio from wait list */
\t\t
if (pevent->OSEventTbl[y_old] == 0u)
{<!-- -->
pevent->OSEventGrp & amp;= (OS_PRIO)~bity_old;
}
\t\t
pevent->OSEventGrp |= bity_new; /* Add new task prio to wait list */
pevent->OSEventTbl[y_new] |= bitx_new;
}
\t
#if (OS_EVENT_MULTI_EN > 0u)
\t
if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0)
{<!-- -->
pevents = ptcb->OSTCBEventMultiPtr;
pevent = *pevents;
\t\t
while (pevent != (OS_EVENT *)0)
{<!-- -->
pevent->OSEventTbl[y_old] & amp;= (OS_PRIO)~bitx_old; /* Remove old task prio from wait lists */
\t\t\t
if (pevent->OSEventTbl[y_old] == 0u)
{<!-- -->
pevent->OSEventGrp & amp;= (OS_PRIO)~bity_old;
}
\t\t\t
pevent->OSEventGrp |= bity_new; /* Add new task prio to wait lists */
pevent->OSEventTbl[y_new] |= bitx_new;
pevents + + ;
pevent = *pevents;
}
}
\t
#endif
#endif
ptcb->OSTCBPrio = newprio; /* Set new task priority */
ptcb->OSTCBY = y_new;
ptcb->OSTCBX = x_new;
ptcb->OSTCBBitY = bite_new;
ptcb->OSTCBBitX = bitx_new;
OS_EXIT_CRITICAL();
\t
if (OSRunning == OS_TRUE)
{<!-- -->
OS_Sched(); /* Find new highest priority task */
}
\t
return (OS_ERR_NONE);
}
#endif

Task hangs

#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
\t\t
if (prio == OS_TASK_IDLE_PRIO) /* Not allowed to suspend idle task */
{<!-- -->
return (OS_ERR_TASK_SUSPEND_IDLE);
}
\t\t
if (prio >= OS_LOWEST_PRIO) /* Task priority valid? */
{<!-- -->
if (prio != OS_PRIO_SELF)
{<!-- -->
return (OS_ERR_PRIO_INVALID);
}
}
\t\t
#endif
OS_ENTER_CRITICAL();
\t\t
if (prio == OS_PRIO_SELF) /* See if suspend SELF */
{<!-- -->
prio = OSTCBCur->OSTCBPrio;
self = OS_TRUE;
}
\t\t
else if (prio == OSTCBCur->OSTCBPrio) /* See if suspending self */
{<!-- -->
self = OS_TRUE;
}
\t\t
else
{<!-- -->
self = OS_FALSE; /* No suspending another task */
}
\t\t
ptcb = OSTCBPrioTbl[prio];
\t\t
if (ptcb == (OS_TCB *)0) /* Task to suspend must exist */
{<!-- -->
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_SUSPEND_PRIO);
}
\t\t
if (ptcb == OS_TCB_RESERVED) /* See if assigned to Mutex */
{<!-- -->
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
\t\t
y = ptcb->OSTCBY;
OSRdyTbl[y] & amp;= (OS_PRIO)~ptcb->OSTCBBitX; /* Make task not ready */
\t\t
if (OSRdyTbl[y] == 0u)
{<!-- -->
OSRdyGrp & amp;= (OS_PRIO)~ptcb->OSTCBBitY;
}
\t\t
ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */
OS_EXIT_CRITICAL();
\t\t
if (self == OS_TRUE) /* Context switch only if SELF */
{<!-- -->
OS_Sched(); /* Find new highest priority task */
}
\t\t
return (OS_ERR_NONE);
}
#endif

Task recovery

#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
\t
if (prio >= OS_LOWEST_PRIO) /* Make sure task priority is valid */
{<!-- -->
return (OS_ERR_PRIO_INVALID);
}
\t
#endif
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio];
\t
if (ptcb == (OS_TCB *)0) /* Task to suspend must exist */
{<!-- -->
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_RESUME_PRIO);
}
\t
if (ptcb == OS_TCB_RESERVED) /* See if assigned to Mutex */
{<!-- -->
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
\t
if ((ptcb->OSTCBStat & amp; OS_STAT_SUSPEND) != OS_STAT_RDY) /* Task must be suspended */
{<!-- -->
ptcb->OSTCBStat & amp;= (INT8U)~ (INT8U)OS_STAT_SUSPEND; /* Remove suspension */
\t\t
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();
\t\t\t\t
if (OSRunning == OS_TRUE)
{<!-- -->
OS_Sched(); /* Find new highest priority task */
}
}
\t\t\t
else
{<!-- -->
OS_EXIT_CRITICAL();
}
}
\t\t
else /* Must be pending on event */
{<!-- -->
OS_EXIT_CRITICAL();
}
\t\t
return (OS_ERR_NONE);
}
\t
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_SUSPENDED);
}
#endif

Task information acquisition

#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
\t
if (prio > OS_LOWEST_PRIO) /* Task priority valid? */
{<!-- -->
if (prio != OS_PRIO_SELF)
{<!-- -->
return (OS_ERR_PRIO_INVALID);
}
}
\t
if (p_task_data == (OS_TCB *)0) /* Validate 'p_task_data' */
{<!-- -->
return (OS_ERR_PDATA_NULL);
}
\t
#endif
OS_ENTER_CRITICAL();
\t
if (prio == OS_PRIO_SELF) /* See if suspend SELF */
{<!-- -->
prio = OSTCBCur->OSTCBPrio;
}
\t
ptcb = OSTCBPrioTbl[prio];
\t
if (ptcb == (OS_TCB *)0) /* Task to query must exist */
{<!-- -->
OS_EXIT_CRITICAL();
return (OS_ERR_PRIO);
}
\t
if (ptcb == OS_TCB_RESERVED) /* Task to query must not be assigned to a Mutex */
{<!-- -->
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST);
}
\t
/* 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 scheduler lock (os_core.c)

#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
\t
if (OSRunning == OS_TRUE) /* Make sure multitasking is running */
{<!-- -->
OS_ENTER_CRITICAL();
\t\t
if (OSIntNesting == 0u) /* Can't call from an ISR */
{<!-- -->
if (OSLockNesting < 255u) /* Prevent OSLockNesting from wrapping back to 0 */
{<!-- -->
OSLockNesting + + ; /* Increment lock nesting level */
}
}
\t\t
OS_EXIT_CRITICAL();
}
}
#endif

Task scheduler unlocking (os_core.c)

#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
\t
if (OSRunning == OS_TRUE) /* Make sure multitasking is running */
{<!-- -->
OS_ENTER_CRITICAL();
\t\t
if (OSIntNesting == 0u) /* Can't call from an ISR */
{<!-- -->
if (OSLockNesting > 0u) /* Do not decrement if already 0 */
{<!-- -->
OSLockNesting--; /* Decrement lock nesting level */
\t\t\t\t
if (OSLockNesting == 0u) /* See if scheduler is enabled */
{<!-- -->
OS_EXIT_CRITICAL();
OS_Sched(); /* See if a HPT is ready */
}
\t\t\t\t
else
{<!-- -->
OS_EXIT_CRITICAL();
}
}
\t\t\t
else
{<!-- -->
OS_EXIT_CRITICAL();
}
}
\t\t
else
{<!-- -->
OS_EXIT_CRITICAL();
}
}
}
#endif