📄 os_task.c
字号:
/*$PAGE*/
/*
*********************************************************************************************************
* STACK CHECKING
*
* Description: This function is called to check the amount of free memory left on the specified task's
* stack.
*
* Arguments : prio is the task priority
*
* p_stk_data is a pointer to a data structure of type OS_STK_DATA.
*
* Returns : OS_NO_ERR upon success
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
* OS_TASK_NOT_EXIST if the desired task has not been created or is assigned to a Mutex PIP
* OS_TASK_OPT_ERR if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
*********************************************************************************************************
*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *p_stk_data)
{
OS_TCB *ptcb;
OS_STK *pchk;
INT32U free;
INT32U size;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
cpu_sr = 0; /* Prevent compiler warning */
#endif
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO) { /* Make sure task priority is valid */
if (prio != OS_PRIO_SELF) {
return (OS_PRIO_INVALID);
}
}
#endif
p_stk_data->OSFree = 0; /* Assume failure, set to 0 size */
p_stk_data->OSUsed = 0;
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if check for SELF */
prio = OSTCBCur->OSTCBPrio;
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Make sure task exist */
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST);
}
if (ptcb == (OS_TCB *)1) {
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST);
}
if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set */
OS_EXIT_CRITICAL();
return (OS_TASK_OPT_ERR);
}
free = 0;
size = ptcb->OSTCBStkSize;
pchk = ptcb->OSTCBStkBottom;
OS_EXIT_CRITICAL();
#if OS_STK_GROWTH == 1
while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */
free++;
}
#else
while (*pchk-- == (OS_STK)0) {
free++;
}
#endif
p_stk_data->OSFree = free * sizeof(OS_STK); /* Compute number of free bytes on the stack */
p_stk_data->OSUsed = (size - free) * sizeof(OS_STK); /* Compute number of bytes used on the stack */
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* SUSPEND A TASK
*
* Description: This function is called to suspend a task. The task can be the calling task if the
* priority passed to OSTaskSuspend() is the priority of the calling task or OS_PRIO_SELF.
*
* Arguments : prio is the priority of the task to suspend. If you specify OS_PRIO_SELF, the
* calling task will suspend itself and rescheduling will occur.
*
* Returns : OS_NO_ERR if the requested task is suspended
* OS_TASK_SUSPEND_IDLE if you attempted to suspend the idle task which is not allowed.
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. >= OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
* OS_TASK_SUSPEND_PRIO if the task to suspend does not exist
* OS_TASK_NOT_EXITS if the task is assigned to a Mutex PIP
*
* Note : You should use this function with great care. If you suspend a task that is waiting for
* an event (i.e. a message, a semaphore, a queue ...) you will prevent this task from
* running when the event arrives.
*********************************************************************************************************
*/
#if OS_TASK_SUSPEND_EN > 0
INT8U OSTaskSuspend (INT8U prio)
{
BOOLEAN self;
OS_TCB *ptcb;
INT8U y;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
cpu_sr = 0; /* Prevent compiler warning */
#endif
#if OS_ARG_CHK_EN > 0
if (prio == OS_IDLE_PRIO) { /* Not allowed to suspend idle task */
return (OS_TASK_SUSPEND_IDLE);
}
if (prio >= OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
return (OS_PRIO_INVALID);
}
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if suspend SELF */
prio = OSTCBCur->OSTCBPrio;
self = TRUE;
} else if (prio == OSTCBCur->OSTCBPrio) { /* See if suspending self */
self = TRUE;
} else {
self = FALSE; /* No suspending another task */
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Task to suspend must exist */
OS_EXIT_CRITICAL();
return (OS_TASK_SUSPEND_PRIO);
}
if (ptcb == (OS_TCB *)1) { /* See if assigned to Mutex */
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST);
}
y = ptcb->OSTCBY;
OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Make task not ready */
if (OSRdyTbl[y] == 0x00) {
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* Status of task is 'SUSPENDED' */
OS_EXIT_CRITICAL();
if (self == TRUE) { /* Context switch only if SELF */
OS_Sched();
}
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* QUERY A TASK
*
* Description: This function is called to obtain a copy of the desired task's TCB.
*
* Arguments : prio is the priority of the task to obtain information from.
*
* p_task_data is a pointer to where the desired task's OS_TCB will be stored.
*
* Returns : OS_NO_ERR if the requested task is suspended
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
* OS_PRIO_ERR if the desired task has not been created
* OS_TASK_NOT_EXIST if the task is assigned to a Mutex PIP
*********************************************************************************************************
*/
#if OS_TASK_QUERY_EN > 0
INT8U OSTaskQuery (INT8U prio, OS_TCB *p_task_data)
{
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
cpu_sr = 0; /* Prevent compiler warning */
#endif
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
return (OS_PRIO_INVALID);
}
}
#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_PRIO_ERR);
}
if (ptcb == (OS_TCB *)1) { /* Task to query must not be assigned to a Mutex */
OS_EXIT_CRITICAL();
return (OS_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_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CLEAR TASK STACK
*
* Description: This function is used to clear the stack of a task (i.e. write all zeros)
*
* Arguments : pbos is a pointer to the task's bottom of stack. If the configuration constant
* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
* memory to low memory). 'pbos' will thus point to the lowest (valid) memory
* location of the stack. If OS_STK_GROWTH is set to 0, 'pbos' will point to the
* highest memory location of the stack and the stack will grow with increasing
* memory locations. 'pbos' MUST point to a valid 'free' data item.
*
* size is the number of 'stack elements' to clear.
*
* opt contains additional information (or options) about the behavior of the task. The
* LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
* specific. See OS_TASK_OPT_??? in uCOS-II.H.
*
* Returns : none
*********************************************************************************************************
*/
#if OS_TASK_CREATE_EXT_EN > 0
void OS_TaskStkClr (OS_STK *pbos, INT32U size, INT16U opt)
{
if ((opt & OS_TASK_OPT_STK_CHK) != 0x0000) { /* See if stack checking has been enabled */
if ((opt & OS_TASK_OPT_STK_CLR) != 0x0000) { /* See if stack needs to be cleared */
#if OS_STK_GROWTH == 1
while (size > 0) { /* Stack grows from HIGH to LOW memory */
size--;
*pbos++ = (OS_STK)0; /* Clear from bottom of stack and up! */
}
#else
while (size > 0) { /* Stack grows from LOW to HIGH memory */
size--;
*pbos-- = (OS_STK)0; /* Clear from bottom of stack and down */
}
#endif
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -