📄 os_core.c
字号:
OS_PEND_OBJ *p_obj,
OS_STATE pending_on,
OS_TICK timeout)
{
OS_PEND_LIST *p_pend_list;
OSTCBCurPtr->PendOn = pending_on; /* Resource not available, wait until it is */
OSTCBCurPtr->PendStatus = OS_STATUS_PEND_OK;
OS_TaskBlock(OSTCBCurPtr, /* Block the task and add it to the tick list if needed */
timeout);
if (p_obj != (OS_PEND_OBJ *)0) { /* Add the current task to the pend list ... */
p_pend_list = &p_obj->PendList; /* ... if there is an object to pend on */
p_pend_data->PendObjPtr = p_obj; /* Save the pointer to the object pending on */
OS_PendDataInit((OS_TCB *)OSTCBCurPtr, /* Initialize the remaining field */
(OS_PEND_DATA *)p_pend_data,
(OS_OBJ_QTY )1);
OS_PendListInsertPrio(p_pend_list, /* Insert in the pend list in priority order */
p_pend_data);
} else {
OSTCBCurPtr->PendDataTblEntries = (OS_OBJ_QTY )0; /* If no object being pended on the clear these fields */
OSTCBCurPtr->PendDataTblPtr = (OS_PEND_DATA *)0; /* ... in the TCB */
}
#if OS_CFG_DBG_EN > 0u
OS_PendDbgNameAdd(p_obj,
OSTCBCurPtr);
#endif
}
/*$PAGE*/
/*
************************************************************************************************************************
* ABORT PENDING
*
* Description: This function is called by OSxxxPendAbort() functions to abort pending on an event.
*
* Arguments : p_obj Is a pointer to the object to pend abort.
* -----
*
* p_tcb Is a pointer to the OS_TCB of the task that we'll abort the pend for
* -----
*
* ts The is a timestamp as to when the pend abort occurred
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_PendAbort (OS_PEND_OBJ *p_obj,
OS_TCB *p_tcb,
CPU_TS ts)
{
switch (p_tcb->TaskState) {
case OS_TASK_STATE_RDY: /* Cannot Pend Abort a task that is ready */
case OS_TASK_STATE_DLY: /* Cannot Pend Abort a task that is delayed */
case OS_TASK_STATE_SUSPENDED: /* Cannot Pend Abort a suspended task */
case OS_TASK_STATE_DLY_SUSPENDED: /* Cannot Pend Abort a suspended task that was also dly'd */
break;
case OS_TASK_STATE_PEND:
case OS_TASK_STATE_PEND_TIMEOUT:
if (p_tcb->PendOn == OS_TASK_PEND_ON_MULTI) {
OS_PendAbort1(p_obj, /* Indicate which object was pend aborted */
p_tcb,
ts);
}
#if (OS_MSG_EN > 0u)
p_tcb->MsgPtr = (void *)0;
p_tcb->MsgSize = (OS_MSG_SIZE)0u;
#endif
p_tcb->TS = ts;
if (p_obj != (OS_PEND_OBJ *)0) {
OS_PendListRemove(p_tcb); /* Remove task from all pend lists */
}
OS_TaskRdy(p_tcb);
p_tcb->TaskState = OS_TASK_STATE_RDY; /* Task will be ready */
p_tcb->PendStatus = OS_STATUS_PEND_ABORT; /* Indicate pend was aborted */
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
break;
case OS_TASK_STATE_PEND_SUSPENDED:
case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
if (p_tcb->PendOn == OS_TASK_PEND_ON_MULTI) {
OS_PendAbort1(p_obj, /* Indicate which object was pend aborted */
p_tcb,
ts);
}
#if (OS_MSG_EN > 0u)
p_tcb->MsgPtr = (void *)0;
p_tcb->MsgSize = (OS_MSG_SIZE)0u;
#endif
p_tcb->TS = ts;
if (p_obj != (OS_PEND_OBJ *)0) {
OS_PendListRemove(p_tcb); /* Remove task from all pend lists */
}
OS_TickListRemove(p_tcb); /* Cancel the timeout */
p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; /* Pend Aborted task is still suspended */
p_tcb->PendStatus = OS_STATUS_PEND_ABORT; /* Indicate pend was aborted */
p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */
break;
default:
break;
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* PEND ABORT A TASK PENDING ON MULTIPLE OBJECTS
*
* Description: This function is called when a task is pending on multiple objects and one of the objects has been pend
* aborted. This function needs to indicate to the caller which object was pend aborted by placing the
* address of the object in the OS_PEND_DATA table corresponding to the pend aborted object.
*
* For example, if the task pends on six (6) objects, the address of those 6 objects are placed in the
* .PendObjPtr field of the OS_PEND_DATA table as shown below. Note that the .PendDataTblEntries of the
* OS_TCB would be set to six (6) in this case. As shown, when the pend call returns because a task pend
* aborted 'Obj C' then, only the one entry contains the .RdyObjPtr filled in data and the other entries
* contains NULL pointers and zero data.
*
* You should note that the NULL pointers are zero data values are actually filled in by the pend call.
*
*
* .PendObjPtr .RdyObjPtr .RdyMsgPtr .RdyMsgSize .RdyTS
* +--------------+--------------+--------------+--------------+--------------+
* p_tcb->PendDataTblPtr -> | Obj A | 0 | 0 | 0 | 0 |
* +--------------+--------------+--------------+--------------+--------------+
* | Obj B | 0 | 0 | 0 | 0 |
* +--------------+--------------+--------------+--------------+--------------+
* | Obj C | Obj C | 0 | 0 | TS |
* +--------------+--------------+--------------+--------------+--------------+
* | Obj D | 0 | 0 | 0 | 0 |
* +--------------+--------------+--------------+--------------+--------------+
* | Obj E | 0 | 0 | 0 | 0 |
* +--------------+--------------+--------------+--------------+--------------+
* | Obj F | 0 | 0 | 0 | 0 |
* +--------------+--------------+--------------+--------------+--------------+
*
*
* Arguments : p_obj is a pointer to the object being pend aborted to
* -----
*
* p_tcb is a pointer to the OS_TCB of the task that we'll abort he pend for
* -----
*
* ts is the time stamp of when the pend abort occurred
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
void OS_PendAbort1 (OS_PEND_OBJ *p_obj,
OS_TCB *p_tcb,
CPU_TS ts)
{
OS_OBJ_QTY n_pend_list; /* Number of pend lists */
OS_PEND_DATA *p_pend_data;
p_pend_data = p_tcb->PendDataTblPtr; /* Point to the first OS_PEND_DATA to remove */
n_pend_list = p_tcb->PendDataTblEntries; /* Get number of entries in the table */
while (n_pend_list > (OS_OBJ_QTY)0) { /* Mark posted object in OS_PEND_DATA table */
if (p_obj == p_pend_data->PendObjPtr) { /* Did we find the object pend aborted? */
p_pend_data->RdyObjPtr = p_obj; /* Yes, indicate the object in the .RdyObjPtr */
p_pend_data->RdyTS = ts; /* save the timestamp of the pend abort */
break;
}
p_pend_data++;
n_pend_list--;
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE A WAIT LIST TABLE
*
* Description: This function is called to initialize the fields of a table of OS_PEND_DATA entries. It's assumed that
* the .PendObjPtr field of each entry in the table is set by the caller and thus will NOT be touched by
* this function.
*
* Arguments : p_tcb is a pointer to the TCB of the task that we want to pend abort.
* -----
*
* p_pend_data_tbl is a pointer to a table (see below) of OS_PEND_DATA elements to initialize.
* ---------------
*
* .PendObjPtr .RdyObjPtr .RdyMsgPtr .RdyMsgSize .RdyTS .TCBPtr .NextPtr .PrevPtr
* +-----------+----------+----------+-----------+------+-------+--------+--------+ ^
* p_pend_data_tbl-> | ? | 0 | 0 | 0 | 0 | p_tcb | 0 | 0 | |
* +-----------+----------+----------+-----------+------+-------+--------+--------+ |
* | ? | 0 | 0 | 0 | 0 | p_tcb | 0 | 0 | |
* +-----------+----------+----------+-----------+------+-------+--------+--------+ |
* | ? | 0 | 0 | 0 | 0 | p_tcb | 0 | 0 | |
* +-----------+----------+----------+-----------+------+-------+--------+--------+ size
* | ? | 0 | 0 | 0 | 0 | p_tcb | 0 | 0 | |
* +-----------+----------+----------+-----------+------+-------+--------+--------+ |
* | ? | 0 | 0 | 0 | 0 | p_tcb | 0 | 0 | |
* +-----------+----------+----------+-----------+------+-------+--------+--------+ |
* | ? | 0 | 0 | 0 | 0 | p_tcb | 0 | 0 | |
* +-----------+----------+----------+-----------+------+-------+--------+--------+ V
*
* tbl_size is the size of the table in number of entries
*
* Returns : none
*
* Note(s) : 1) This function is INTERNAL to uC/OS-III and your application must not call it.
*
* 2) It's possible for the table to be of size 1 when multi-pend is not used
*
* 3) Note that the .PendObjPtr is NOT touched because it's assumed to be set by the caller.
************************************************************************************************************************
*/
void OS_PendDataInit (OS_TCB *p_tcb,
OS_PEND_DATA *p_pend_data_tbl,
OS_OBJ_QTY tbl_size)
{
OS_OBJ_QTY i;
p_tcb->PendDataTblEntries = tbl_size; /* Link the TCB to the beginning of the table */
p_tcb->PendDataTblPtr = p_pend_data_tbl;
for (i = 0u; i < tbl_size; i++) {
p_pend_data_tbl->NextPtr = (OS_PEND_DATA *)0; /* Initialize all the fields */
p_pend_data_tbl->PrevPtr = (OS_PEND_DATA *)0;
p_pend_data_tbl->RdyObjPtr = (void *)0;
p_pend_data_tbl->RdyMsgPtr = (void *)0;
p_pend_data_tbl->RdyMsgSize = (OS_MSG_SIZE )0;
p_pend_data_tbl->RdyTS = (CPU_TS )0;
p_pend_data_tbl->TCBPtr = p_tcb; /* Every entry points back to the TCB of the task */
p_pend_data_tbl++;
}
}
/*$PAGE*/
/*
************************************************************************************************************************
* ADD/REMOVE DEBUG NAMES TO PENDED OBJECT AND OS_TCB
*
* Description: These functions are used to add pointers to ASCII 'names' of objects so they can easily be displayed
* using a kernel aware tool.
*
* Arguments : p_obj is a pointer to the object being pended on
*
* p_tcb is a pointer to the OS_TCB of the task pending on the object
*
* Returns : none
*
* Note(s) : 1) These functions are INTERNAL to uC/OS-III and your application must not call it.
************************************************************************************************************************
*/
#if OS_CFG_DBG_EN > 0u
void OS_PendDbgNameAdd (OS_PEND_OBJ *p_obj,
OS_TCB *p_tcb)
{
OS_PEND_LIST *p_pend_list;
OS_PEND_DATA *p_pend_data;
OS_TCB *p_tcb1;
if (p_obj != (OS_PEND_OBJ *)0) {
p_tcb->DbgNamePtr = p_obj->NamePtr; /* Task pending on this object ... save name in TCB */
p_pend_list = &p_obj->PendList; /* Find name of HP task pending on this object ... */
p_pend_data = p_pend_list->HeadPtr;
p_tcb1 = p_pend_data->TCBPtr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -