⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_core.c

📁 UCOS-III
💻 C
📖 第 1 页 / 共 5 页
字号:
               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 + -