Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1152714
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2279
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-27 19:53
个人简介

JustForFun

文章分类

全部博文(241)

文章存档

2023年(8)

2022年(2)

2021年(3)

2020年(30)

2019年(11)

2018年(27)

2017年(54)

2016年(83)

2015年(23)

我的朋友

分类: 嵌入式

2015-07-21 22:25:13

* Version : V3.00.4
os.h中
struct os_tcb {
    CPU_STK             *StkPtr;                            /* Pointer to current top of stack                        */
    void                *ExtPtr;                            /* Pointer to user definable data for TCB extension       */
    CPU_STK             *StkLimitPtr;                       /* Pointer used to set stack 'watermark' limit            */
    OS_TCB              *NextPtr;                           /* Pointer to next     TCB in the TCB list                */
    OS_TCB              *PrevPtr;                           /* Pointer to previous TCB in the TCB list                */
    OS_TCB              *TickNextPtr;
    OS_TCB              *TickPrevPtr;
    OS_TICK_SPOKE       *TickSpokePtr;                      /* Pointer to tick spoke if task is in the tick list      */
    CPU_CHAR            *NamePtr;                           /* Pointer to task name                                   */
    CPU_STK             *StkBasePtr;                        /* Pointer to base address of stack                       */
    OS_TASK_PTR          TaskEntryAddr;                     /* Pointer to task entry point address                    */
    void                *TaskEntryArg;                      /* Argument passed to task when it was created            */
    OS_PEND_DATA        *PendDataTblPtr;                    /* Pointer to list containing objects pended on           */
    OS_STATE             PendOn;                            /* Indicates what task is pending on                      */
    OS_STATUS            PendStatus;                        /* Pend status                                            */
    OS_STATE             TaskState;                         /* See OS_TASK_STATE_xxx                                  */
    OS_PRIO              Prio;                              /* Task priority (0 == highest)                           */
    CPU_STK_SIZE         StkSize;                           /* Size of task stack (in number of stack elements)       */
    OS_OPT               Opt;                               /* Task options as passed by OSTaskCreate()               */
    OS_OBJ_QTY           PendDataTblEntries;                /* Size of array of objects to pend on                    */
    CPU_TS               TS;                                /* Timestamp                                              */
    OS_SEM_CTR           SemCtr;                            /* Task specific semaphore counter                        */
                                                            /* DELAY / TIMEOUT                                        */
    OS_TICK              TickCtrPrev;                       /* Previous time when task was            ready           */
    OS_TICK              TickCtrMatch;                      /* Absolute time when task is going to be ready           */
    OS_TICK              TickRemain;                        /* Number of ticks remaining for a match (updated at ...  */
                                                            /* ... run-time by OS_StatTask()                          */
    OS_TICK              TimeQuanta;
    OS_TICK              TimeQuantaCtr;
#if OS_MSG_EN > 0u
    void                *MsgPtr;                            /* Message received                                       */
    OS_MSG_SIZE          MsgSize;
#endif
#if OS_CFG_TASK_Q_EN > 0u
    OS_MSG_Q             MsgQ;                              /* Message queue associated with task                     */
#if OS_CFG_TASK_PROFILE_EN > 0u
    CPU_TS               MsgQPendTime;                      /* Time it took for signal to be received                 */
    CPU_TS               MsgQPendTimeMax;                   /* Max amount of time it took for signal to be received   */

#endif
#endif
#if OS_CFG_TASK_REG_TBL_SIZE > 0u
    OS_REG               RegTbl[OS_CFG_TASK_REG_TBL_SIZE];  /* Task specific registers                                */
#endif
#if OS_CFG_FLAG_EN > 0u
    OS_FLAGS             FlagsPend;                         /* Event flag(s) to wait on                               */
    OS_FLAGS             FlagsRdy;                          /* Event flags that made task ready to run                */
    OS_OPT               FlagsOpt;                          /* Options (See OS_OPT_FLAG_xxx)                          */
#endif
#if OS_CFG_TASK_SUSPEND_EN > 0u
    OS_NESTING_CTR       SuspendCtr;                        /* Nesting counter for OSTaskSuspend()                    */
#endif
#if OS_CFG_TASK_PROFILE_EN > 0u
    OS_CPU_USAGE         CPUUsage;                          /* CPU Usage of task (0-100%)                             */
    OS_CTX_SW_CTR        CtxSwCtr;                          /* Number of time the task was switched in                */
    CPU_TS               CyclesDelta;                       /* value of OS_TS_GET() - .CyclesStart                    */
    CPU_TS               CyclesStart;                       /* Snapshot of cycle counter at start of task resumption  */
    OS_CYCLES            CyclesTotal;                       /* Total number of # of cycles the task has been running  */
    OS_CYCLES            CyclesTotalPrev;                   /* Snapshot of previous # of cycles                       */
    CPU_TS               SemPendTime;                       /* Time it took for signal to be received                 */
    CPU_TS               SemPendTimeMax;                    /* Max amount of time it took for signal to be received   */
#endif
#if OS_CFG_STAT_TASK_STK_CHK_EN > 0u
    CPU_STK_SIZE         StkUsed;                           /* Number of stack elements used from the stack           */
    CPU_STK_SIZE         StkFree;                           /* Number of stack elements free on   the stack           */
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
    CPU_TS               IntDisTimeMax;                     /* Maximum interrupt disable time                         */
#endif
#if OS_CFG_SCHED_LOCK_TIME_MEAS_EN > 0u
    CPU_TS               SchedLockTimeMax;                  /* Maximum scheduler lock time                            */
#endif
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
os.h
struct  os_q {
    OS_OBJ_TYPE          Type;                              /* Message Queue                                          */
    CPU_CHAR            *NamePtr;                           /* Should be set to OS_OBJ_TYPE_Q                         */
    OS_PEND_LIST         PendList;                          /* Pointer to Message Queue (NUL terminated ASCII)        */

#if OS_CFG_DBG_EN > 0u
    OS_Q                *DbgPrevPtr;
    OS_Q                *DbgNextPtr;
    CPU_CHAR            *DbgNamePtr;
#endif
    OS_MSG_Q             MsgQ;                              /* List of tasks waiting on event flag group              */
};
typedef  struct  os_msg_q            OS_MSG_Q;
struct  os_msg_q {                                          /* OS_MSG_Q                                               */
    OS_MSG              *InPtr;                             /* Pointer to next OS_MSG to be inserted  in   the queue  */
    OS_MSG              *OutPtr;                            /* Pointer to next OS_MSG to be extracted from the queue  */
    OS_MSG_QTY           NbrEntriesSize;                    /* Maximum allowable number of entries in the queue       */
    OS_MSG_QTY           NbrEntries;                        /* Current number of entries in the queue                 */
    OS_MSG_QTY           NbrEntriesMax;                     /* Peak number of entries in the queue                    */
};
typedef  struct  os_msg              OS_MSG;
struct  os_msg {                                            /* MESSAGE CONTROL BLOCK                                  */
    OS_MSG              *NextPtr;                           /* Pointer to next message                                */
    void                *MsgPtr;                            /* Actual message                                         */
    OS_MSG_SIZE          MsgSize;                           /* Size of the message (in # bytes)                       */
    CPU_TS               MsgTS;                             /* Time stamp of when message was sent                    */
};
struct  os_msg_pool {                                       /* OS_MSG POOL                                            */
    OS_MSG              *NextPtr;                           /* Pointer to next message                                */
    OS_MSG_QTY           NbrFree;                           /* Number of messages available from this pool            */
    OS_MSG_QTY           NbrUsed;                           /* Number of messages used                                */
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if OS_CFG_TASK_Q_EN > 0u
os_task.c
OS_MSG_QTY  OSTaskQFlush (OS_TCB  *p_tcb, OS_ERR  *p_err)
{
    OS_MSG_QTY  entries;
    CPU_SR_ALLOC();                                                   
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* Can't flush a message queue from an ISR                */
        *p_err = OS_ERR_FLUSH_ISR;
        return ((OS_MSG_QTY)0);
    }
#endif
   
    if (p_tcb == (OS_TCB *)0) {                             /* Flush message queue of calling task?                   */
        CPU_CRITICAL_ENTER();
        p_tcb = OSTCBCurPtr;
        CPU_CRITICAL_EXIT();
    }

    OS_CRITICAL_ENTER();
    entries = OS_MsgQFreeAll(&p_tcb->MsgQ);                 /* Return all OS_MSGs to the OS_MSG pool                  */
    OS_CRITICAL_EXIT();
    *p_err  = OS_ERR_NONE;
    return (entries);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
************************************************************************************************************************
*                                        RELEASE ALL MESSAGE IN MESSAGE QUEUE
*
* Description: This function returns all the messages in a message queue to the free list.
*
* Arguments  : p_msg_q       is a pointer to the OS_MSG_Q structure containing messages to free.
*              -------
*
* Returns    : the number of OS_MSGs returned to the free list
*
* Note(s)    : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
os_msg.c
OS_MSG_QTY  OS_MsgQFreeAll (OS_MSG_Q  *p_msg_q)
{
    OS_MSG      *p_msg;
    OS_MSG_QTY   qty;
    qty = p_msg_q->NbrEntries;                              /* Get the number of OS_MSGs being freed                  */
    if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
        p_msg                   = p_msg_q->InPtr;           /* Point to end of message chain                          */
        p_msg->NextPtr          = OSMsgPool.NextPtr;  
        OSMsgPool.NextPtr       = p_msg_q->OutPtr;          /* Point to beginning of message chain                    */
        OSMsgPool.NbrUsed      -= p_msg_q->NbrEntries;      /* Update statistics for free list of messages            */
        OSMsgPool.NbrFree      += p_msg_q->NbrEntries;
        p_msg_q->NbrEntries     = (OS_MSG_QTY)0;            /* Flush the message queue                                */
        p_msg_q->NbrEntriesMax  = (OS_MSG_QTY)0;
        p_msg_q->InPtr          = (OS_MSG   *)0;
        p_msg_q->OutPtr         = (OS_MSG   *)0;
    }
    return (qty);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
************************************************************************************************************************
*                                               POST MESSAGE TO A TASK
*
* Description: This function sends a message to a task
*
* Arguments  : p_tcb      is a pointer to the TCB of the task receiving a message.  If you specify a NULL pointer then
*                         the message will be posted to the task's queue of the calling task.  In other words, you'd be
*                         posting a message to yourself.
*
*              p_void     is a pointer to the message to send.
*
*              msg_size   is the size of the message sent (in #bytes)
*
*              opt        specifies whether the post will be FIFO or LIFO:
*
*                             OS_OPT_POST_FIFO       Post at the end   of the queue
*                             OS_OPT_POST_LIFO       Post at the front of the queue
*
*                             OS_OPT_POST_NO_SCHED   Do not run the scheduler after the post
*
*                          Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
*
*
*              p_err      is a pointer to a variable that will hold the error code associated
*                         with the outcome of this call.  Errors can be:
*
*                             OS_ERR_NONE            The call was successful and the message was sent
*                             OS_ERR_Q_MAX           If the queue is full
*                             OS_ERR_MSG_POOL_EMPTY  If there are no more OS_MSGs available from the pool
*
* Returns    : none
************************************************************************************************************************
os_task.c
void  OSTaskQPost (OS_TCB      *p_tcb,
                   void        *p_void,
                   OS_MSG_SIZE  msg_size,
                   OS_OPT       opt,
                   OS_ERR      *p_err)

{
    CPU_TS   ts;
                                                           


#ifdef OS_SAFETY_CRITICAL_RELEASE
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
    }
#endif

    ts = OS_TS_GET();                                       /* Get timestamp                                          */                                                          
   
#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {
        OS_IntQPost((OS_OBJ_TYPE)OS_OBJ_TYPE_TASK_MSG,      /* Post to ISR queue                                      */
                    (void      *)p_tcb,
                    (void      *)p_void,
                    (OS_MSG_SIZE)msg_size,
                    (OS_FLAGS   )0,
                    (OS_OPT     )opt,
                    (CPU_TS     )ts,
                    (OS_ERR    *)p_err);
        return;
    }
#endif

    OS_TaskQPost(p_tcb,
                 p_void,
                 msg_size,
                 opt,
                 ts,
                 p_err);
}
//////////////////
#define  OS_OBJ_TYPE_NONE           (OS_OBJ_TYPE)(0x454E4F4Eu)  /* "NONE" in ASCII.                                   */
#define  OS_OBJ_TYPE_SEM            (OS_OBJ_TYPE)(0x414D4553u)  /* "SEMA" in ASCII.                                   */
#define  OS_OBJ_TYPE_Q              (OS_OBJ_TYPE)(0x55455551u)  /* "QUEU" in ASCII.                                   */
#define  OS_OBJ_TYPE_MUTEX          (OS_OBJ_TYPE)(0x5854554Du)  /* "MUTX" in ASCII.                                   */
#define  OS_OBJ_TYPE_FLAG           (OS_OBJ_TYPE)(0x47414C46u)  /* "FLAG" in ASCII.                                   */
#define  OS_OBJ_TYPE_TMR            (OS_OBJ_TYPE)(0x524D2054u)  /* "TMR " in ASCII.                                   */
#define  OS_OBJ_TYPE_TASK_MSG       (OS_OBJ_TYPE)(0x47534D54u)  /* "TMSG" in ASCII.                                   */
#define  OS_OBJ_TYPE_TASK_SIGNAL    (OS_OBJ_TYPE)(0x47495354u)  /* "TSIG" in ASCII.                                   */
#define  OS_OBJ_TYPE_TICK           (OS_OBJ_TYPE)(0x4B434954u)  /* "TICK" in ASCII.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
os_int.c
/*
************************************************************************************************************************
*                                                   POST TO ISR QUEUE
*
* Description: This function places contents of posts into an intermediate queue to help defer processing of interrupts
*              at the task level.
*
* Arguments  : type       is the type of kernel object the post is destined to:
*
*                             OS_OBJ_TYPE_SEM       
*                             OS_OBJ_TYPE_Q         
*                             OS_OBJ_TYPE_FLAG      
*                             OS_OBJ_TYPE_TASK_MSG  
*                             OS_OBJ_TYPE_TASK_SIGNAL
*
*              p_obj      is a pointer to the kernel object to post to.  This can be a pointer to a semaphore,
*              -----      a message queue or a task control clock.
*
*              p_void     is a pointer to a message that is being posted.  This is used when posting to a message
*                         queue or directly to a task.
*
*              msg_size   is the size of the message being posted
*
*              flags      if the post is done to an event flag group then this corresponds to the falgs being
*                         posted
*
*              ts         is a timestamp as to when the post was done
*
*              opt        this corresponds to post options and applies to:
*
*                             OSFlagPost()
*                             OSSemPost()
*                             OSQPost()
*                             OSTaskQPost()
*
*              p_err      is a pointer to a variable that will contain an error code returned by this function.
*
*                             OS_ERR_NONE         if the post to the ISR queue was successful
*                             OS_ERR_INT)Q_FULL   if the ISR queue is full and cannot accepts any further posts.  This
*                                                 generally indicates that you are receiving interrupts faster than you
*                                                 can process them or, that you didn't make the ISR queue large enough.
*
* Returns    : none
*             
* Note(s)    : none
************************************************************************************************************************
*/

void  OS_IntQPost (OS_OBJ_TYPE    type,
                   void          *p_obj,
                   void          *p_void,
                   OS_MSG_SIZE    msg_size,
                   OS_FLAGS       flags,
                   OS_OPT         opt,
                   CPU_TS         ts,
                   OS_ERR        *p_err)

{
    CPU_SR_ALLOC();



#ifdef OS_SAFETY_CRITICAL_RELEASE
    if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
    }
#endif
                                                          
    CPU_CRITICAL_ENTER();
    if (OSIntQNbrEntries < OSCfg_IntQSize) {                /* Make sure we haven't already filled the ISR queue      */
        OSIntQNbrEntries++;
        OSIntQInPtr->Type       = type;
        OSIntQInPtr->ObjPtr     = p_obj;
        OSIntQInPtr->MsgPtr     = p_void;
        OSIntQInPtr->MsgSize    = msg_size;
        OSIntQInPtr->Flags      = flags;
        OSIntQInPtr->Opt        = opt;
        OSIntQInPtr->TS         = ts;
        OSIntQInPtr             =  OSIntQInPtr->NextPtr;
        OSRdyList[0].NbrEntries = (OS_OBJ_QTY)1;            /* Add to ready list                                      */
        OSRdyList[0].HeadPtr    = &OSIntQTaskTCB;
        OSRdyList[0].TailPtr    = &OSIntQTaskTCB;
        OS_PrioInsert(0u);                                  /* Add task priority 0 in the priority table              */
        OSPrioSaved             = OSPrioCur;                /* Save current priority                                  */
        *p_err                  = OS_ERR_NONE;
    } else {
        OSIntQOvfCtr++;                                     /* Count the number of ISR queue overflows                */
        *p_err                  = OS_ERR_INT_Q_FULL;
    }
    CPU_CRITICAL_EXIT();
}
////////////////////////
OS_EXT            OS_INT_Q              *OSIntQInPtr;
OS_EXT            OS_INT_Q              *OSIntQOutPtr;
OS_EXT            OS_OBJ_QTY             OSIntQNbrEntries;
OS_EXT            OS_OBJ_QTY             OSIntQOvfCtr;
OS_EXT            OS_TCB                 OSIntQTaskTCB;
OS_EXT            CPU_TS                 OSIntQTaskTimeMax;
struct  os_int_q {
    OS_OBJ_TYPE          Type;
    OS_INT_Q            *NextPtr;
    void                *ObjPtr;
    void                *MsgPtr;
    OS_MSG_SIZE          MsgSize;
    OS_FLAGS             Flags;
    OS_OPT               Opt;
    CPU_TS               TS;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
os_task.c
/*
************************************************************************************************************************
*                                               POST MESSAGE TO A TASK
*
* Description: This function sends a message to a task
*
* Arguments  : p_tcb      is a pointer to the TCB of the task receiving a message.  If you specify a NULL pointer then
*                         the message will be posted to the task's queue of the calling task.  In other words, you'd be
*                         posting a message to yourself.
*
*              p_void     is a pointer to the message to send.
*
*              msg_size   is the size of the message sent (in #bytes)
*
*              opt        specifies whether the post will be FIFO or LIFO:
*
*                             OS_OPT_POST_FIFO       Post at the end   of the queue
*                             OS_OPT_POST_LIFO       Post at the front of the queue
*
*                             OS_OPT_POST_NO_SCHED   Do not run the scheduler after the post
*
*                          Note(s): 1) OS_OPT_POST_NO_SCHED can be added with one of the other options.
*
*
*              ts         is a timestamp indicating when the post occurred. 
*
*              p_err      is a pointer to a variable that will hold the error code associated
*                         with the outcome of this call.  Errors can be:
*
*                             OS_ERR_NONE            The call was successful and the message was sent
*                             OS_ERR_MSG_POOL_EMPTY  If there are no more OS_MSGs available from the pool
*                             OS_ERR_Q_MAX           If the queue is full
*                             OS_ERR_STATE_INVALID   If the task is in an invalid state.  This should never happen
*                                                    and if it does, would be considered a system failure.
*
* Returns    : none
*
* Note(s)    : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/

#if OS_CFG_TASK_Q_EN > 0u
void  OS_TaskQPost (OS_TCB      *p_tcb,
                    void        *p_void,
                    OS_MSG_SIZE  msg_size,
                    OS_OPT       opt,
                    CPU_TS       ts,
                    OS_ERR      *p_err)

{
    CPU_SR_ALLOC();
                                                           


    OS_CRITICAL_ENTER();
    if (p_tcb == (OS_TCB *)0) {                             /* Post msg to 'self'?                                    */
        p_tcb = OSTCBCurPtr;
    }
    *p_err  = OS_ERR_NONE;                                  /* Assume we won't have any errors                        */              
    switch (p_tcb->TaskState) {
        case OS_TASK_STATE_RDY:
        case OS_TASK_STATE_DLY:
        case OS_TASK_STATE_SUSPENDED:
        case OS_TASK_STATE_DLY_SUSPENDED:
             OS_MsgQPut(&p_tcb->MsgQ,                       /* Deposit the message in the queue                       */
                        p_void,
                        msg_size,
                        opt,
                        ts,
                        p_err);               
             OS_CRITICAL_EXIT();
             break;

        case OS_TASK_STATE_PEND:
        case OS_TASK_STATE_PEND_TIMEOUT:
        case OS_TASK_STATE_PEND_SUSPENDED:         
        case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
             if (p_tcb->PendOn == OS_TASK_PEND_ON_TASK_Q) { /* Is task waiting for a message to be sent to it?        */
                 OS_Post((OS_PEND_OBJ *)0,
                         p_tcb,                  
                         p_void,
                         msg_size,
                         ts);
                 OS_CRITICAL_EXIT_NO_SCHED();
                 if ((opt & OS_OPT_POST_NO_SCHED) == (OS_OPT)0) {
                     OSSched();                             /* Run the scheduler                                      */
                 }
             } else {                                      
                 OS_MsgQPut(&p_tcb->MsgQ,                   /* No,  Task is pending on something else ...             */
                            p_void,                         /*      ... Deposit the message in the task's queue       */
                            msg_size,
                            opt,
                            ts,
                            p_err);               
                 OS_CRITICAL_EXIT();
             }
             break;
            
        default:
             OS_CRITICAL_EXIT();
             *p_err = OS_ERR_STATE_INVALID;
             break;
    }
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
------------------------------------------------------------------------------------------------------------------------
*                                           PEND DATA, PEND LIST and PEND OBJ
------------------------------------------------------------------------------------------------------------------------
*/

struct  os_pend_data {
    OS_PEND_DATA        *PrevPtr;
    OS_PEND_DATA        *NextPtr;
    OS_TCB              *TCBPtr;
    OS_PEND_OBJ         *PendObjPtr;
    OS_PEND_OBJ         *RdyObjPtr;
    void                *RdyMsgPtr;
    OS_MSG_SIZE          RdyMsgSize;
    CPU_TS               RdyTS;
};



struct  os_pend_list {
    OS_PEND_DATA        *HeadPtr;
    OS_PEND_DATA        *TailPtr;
    OS_OBJ_QTY           NbrEntries;
};



struct  os_pend_obj {
    OS_OBJ_TYPE          Type;
    CPU_CHAR            *NamePtr;
    OS_PEND_LIST         PendList;                          /* List of tasks pending on object                        */
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
************************************************************************************************************************
*                                             BLOCK A TASK PENDING ON EVENT
*
* Description: This function is called to place a task in the blocked state waiting for an event to occur. This function
*              exist because it is common to a number of OSxxxPend() services.
*
* Arguments  : p_pend_data    is a pointer to an object used to link the task being blocked to the list of task(s)
*              -----------    pending on the desired object.

*              p_obj          is a pointer to the object to pend on.  If there are no object used to pend on then
*              -----          the caller must pass a NULL pointer.
*
*              pending_on     Specifies what the task will be pending on:
*
*                                 OS_TASK_PEND_ON_FLAG
*                                 OS_TASK_PEND_ON_TASK_Q     <- No object (pending for a message sent to the task)
*                                 OS_TASK_PEND_ON_MUTEX
*                                 OS_TASK_PEND_ON_Q    
*                                 OS_TASK_PEND_ON_SEM  
*                                 OS_TASK_PEND_ON_TASK_SEM   <- No object (pending on a signal sent to the task)
*
*              timeout        Is the amount of time the task will wait for the event to occur.
*
* Returns    : none
*
* Note(s)    : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
************************************************************************************************************************
*/
os_core.c
void  OS_Pend (OS_PEND_DATA  *p_pend_data,
               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                                        */
    }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*
************************************************************************************************************************
*                                                   POST TO A TASK
*
* Description: This function is called to post to a task.  This function exist because it is common to a number of
*              OSxxxPost() services.
*
* Arguments  : p_obj          Is a pointer to the object being posted to or NULL pointer if there is no object
*              -----
*
*              p_tcb          Is a pointer to the OS_TCB that will receive the 'post'
*              -----
*
*              p_void         If we are posting a message to a task, this is the message that the task will receive
*
*              msg_size       If we are posting a message to a task, this is the size of the message
*
*              ts             The timestamp as to when the post occurred
*
* Returns    : none
*
* Note(s)    : This function is INTERNAL to uC/OS-III and your application should not call it.
************************************************************************************************************************
*/
os_core.c
void   OS_Post (OS_PEND_OBJ  *p_obj,
                OS_TCB       *p_tcb,
                void         *p_void,
                OS_MSG_SIZE   msg_size,
                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 Post a suspended task                      */
        case OS_TASK_STATE_DLY_SUSPENDED:                        /* Cannot Post 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_Post1(p_obj,                                 /* Indicate which object was posted to               */
                          p_tcb,
                          p_void,
                          msg_size,
                          ts);
             } else {
                 p_tcb->MsgPtr  = p_void;                        /* Deposit message in OS_TCB of task waiting         */
                 p_tcb->MsgSize = msg_size;                      /* ... assuming posting a message                    */
                 p_tcb->TS      = ts;                          
             }
             if (p_obj != (OS_PEND_OBJ *)0) {
                 OS_PendListRemove(p_tcb);                       /* Remove task from wait list(s)                     */
             }
             OS_TaskRdy(p_tcb);                                  /* Make task ready to run                            */
             p_tcb->TaskState  = OS_TASK_STATE_RDY;          
             p_tcb->PendStatus = OS_STATUS_PEND_OK;              /* Clear pend status                                 */
             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_Post1(p_obj,                                 /* Indicate which object was posted to               */
                          p_tcb,
                          p_void,
                          msg_size,
                          ts);
             } else {
                 p_tcb->MsgPtr  = p_void;                        /* Deposit message in OS_TCB of task waiting         */
                 p_tcb->MsgSize = msg_size;                      /* ... assuming posting a message                    */
                 p_tcb->TS      = ts;                             
             }
             OS_TickListRemove(p_tcb);                           /* Cancel any timeout                                */
             if (p_obj != (OS_PEND_OBJ *)0) {
                 OS_PendListRemove(p_tcb);                       /* Remove task from wait list(s)                     */
             }
             p_tcb->TaskState  = OS_TASK_STATE_SUSPENDED;          
             p_tcb->PendStatus = OS_STATUS_PEND_OK;              /* Clear pend status                                 */
             p_tcb->PendOn     = OS_TASK_PEND_ON_NOTHING;        /* Indicate no longer pending                        */
             break;
            
        default:
             break;
    } 
}
阅读(2624) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~