Beispiel #1
0
OS_OBJ_QTY  OS_PendMultiGetRdy (OS_PEND_DATA  *p_pend_data_tbl,
                                OS_OBJ_QTY     tbl_size)
{
    OS_OBJ_QTY   i;
    OS_OBJ_QTY   nbr_obj_rdy;
#if OS_CFG_Q_EN > 0u
    OS_ERR       err;
    OS_MSG_SIZE  msg_size;
    OS_Q        *p_q;
    void        *p_void;
    CPU_TS       ts;
#endif
#if OS_CFG_SEM_EN  > 0u
    OS_SEM      *p_sem;
#endif



    nbr_obj_rdy = (OS_OBJ_QTY)0;
    for (i = 0u; i < tbl_size; i++) {
        p_pend_data_tbl->RdyObjPtr  = (OS_PEND_OBJ  *)0;         /* Clear all fields                                  */
        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->NextPtr    = (OS_PEND_DATA *)0;
        p_pend_data_tbl->PrevPtr    = (OS_PEND_DATA *)0;
        p_pend_data_tbl->TCBPtr     = (OS_TCB       *)0;
#if OS_CFG_Q_EN > 0u
        p_q = (OS_Q *)((void *)p_pend_data_tbl->PendObjPtr);     /* Assume we are pointing to a message queue object  */
        if (p_q->Type == OS_OBJ_TYPE_Q) {                        /* Is it a message queue?                            */
            p_void = OS_MsgQGet(&p_q->MsgQ,                      /* Yes, Any message waiting in the message queue?    */
                                &msg_size,
                                &ts,
                                &err);
            if (err == OS_ERR_NONE) {
                p_pend_data_tbl->RdyObjPtr  = p_pend_data_tbl->PendObjPtr;
                p_pend_data_tbl->RdyMsgPtr  = p_void;            /*      Yes, save the message received               */
                p_pend_data_tbl->RdyMsgSize = msg_size;
                p_pend_data_tbl->RdyTS      = ts;
                nbr_obj_rdy++;
            }
        }
#endif

#if OS_CFG_SEM_EN > 0u
        p_sem = (OS_SEM *)((void *)p_pend_data_tbl->PendObjPtr); /* Assume we are pointing to a semaphore object      */
        if (p_sem->Type == OS_OBJ_TYPE_SEM) {                    /* Is it a semaphore?                                */
            if (p_sem->Ctr > 0u) {                               /* Yes, Semaphore has been signaled?                 */
                p_sem->Ctr--;                                    /*      Yes, caller may proceed                      */
                p_pend_data_tbl->RdyObjPtr  = p_pend_data_tbl->PendObjPtr;
                p_pend_data_tbl->RdyTS      = p_sem->TS;
                nbr_obj_rdy++;
            }
        }
#endif

        p_pend_data_tbl++;
    }
    return (nbr_obj_rdy);
}
Beispiel #2
0
void  *OSQPend (OS_Q         *p_q,
                OS_TICK       timeout,
                OS_OPT        opt,
                OS_MSG_SIZE  *p_msg_size,
                CPU_TS       *p_ts,
                OS_ERR       *p_err)
{
    OS_PEND_DATA  pend_data;
    void         *p_void;
    CPU_SR_ALLOC();



#ifdef OS_SAFETY_CRITICAL
    if (p_err == (OS_ERR *)0) {
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
        TRACE_OS_Q_PEND_FAILED(p_q);                        /* Record the event.                                      */
#endif
        OS_SAFETY_CRITICAL_EXCEPTION();
        return ((void *)0);
    }
#endif

#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
    if (OSIntNestingCtr > (OS_NESTING_CTR)0) {              /* Not allowed to call from an ISR                        */
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
        TRACE_OS_Q_PEND_FAILED(p_q);                        /* Record the event.                                      */
#endif
       *p_err = OS_ERR_PEND_ISR;
        return ((void *)0);
    }
#endif

#if OS_CFG_ARG_CHK_EN > 0u
    if (p_q == (OS_Q *)0) {                                 /* Validate arguments                                     */
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
        TRACE_OS_Q_PEND_FAILED(p_q);                        /* Record the event.                                      */
#endif
       *p_err = OS_ERR_OBJ_PTR_NULL;
        return ((void *)0);
    }
    if (p_msg_size == (OS_MSG_SIZE *)0) {
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
        TRACE_OS_Q_PEND_FAILED(p_q);                        /* Record the event.                                      */
#endif
       *p_err = OS_ERR_PTR_INVALID;
        return ((void *)0);
    }
    switch (opt) {
        case OS_OPT_PEND_BLOCKING:
        case OS_OPT_PEND_NON_BLOCKING:
             break;

        default:
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
             TRACE_OS_Q_PEND_FAILED(p_q);                   /* Record the event.                                      */
#endif
            *p_err = OS_ERR_OPT_INVALID;
             return ((void *)0);
    }
#endif

#if OS_CFG_OBJ_TYPE_CHK_EN > 0u
    if (p_q->Type != OS_OBJ_TYPE_Q) {                       /* Make sure message queue was created                    */
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
        TRACE_OS_Q_PEND_FAILED(p_q);                        /* Record the event.                                      */
#endif
       *p_err = OS_ERR_OBJ_TYPE;
        return ((void *)0);
    }
#endif

    if (p_ts != (CPU_TS *)0) {
       *p_ts  = (CPU_TS  )0;                                /* Initialize the returned timestamp                      */
    }

    CPU_CRITICAL_ENTER();
    p_void = OS_MsgQGet(&p_q->MsgQ,                         /* Any message waiting in the message queue?              */
                        p_msg_size,
                        p_ts,
                        p_err);
    if (*p_err == OS_ERR_NONE) {
        CPU_CRITICAL_EXIT();
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
        TRACE_OS_Q_PEND(p_q);                               /* Record the event.                                      */
#endif
        return (p_void);                                    /* Yes, Return message received                           */
    }

    if ((opt & OS_OPT_PEND_NON_BLOCKING) != (OS_OPT)0) {    /* Caller wants to block if not available?                */
        CPU_CRITICAL_EXIT();
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
        TRACE_OS_Q_PEND_FAILED(p_q);                        /* Record the event.                                      */
#endif
       *p_err = OS_ERR_PEND_WOULD_BLOCK;                    /* No                                                     */
        return ((void *)0);
    } else {
        if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {    /* Can't pend when the scheduler is locked                */
            CPU_CRITICAL_EXIT();
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
            TRACE_OS_Q_PEND_FAILED(p_q);                    /* Record the event.                                      */
#endif
           *p_err = OS_ERR_SCHED_LOCKED;
            return ((void *)0);
        }
    }
                                                            /* Lock the scheduler/re-enable interrupts                */
    OS_CRITICAL_ENTER_CPU_EXIT();
    OS_Pend(&pend_data,                                     /* Block task pending on Message Queue                    */
            (OS_PEND_OBJ *)((void *)p_q),
            OS_TASK_PEND_ON_Q,
            timeout);
    OS_CRITICAL_EXIT_NO_SCHED();
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
    TRACE_OS_Q_PEND_BLOCK(p_q);                             /* Record the event.                                      */
#endif
    OSSched();                                              /* Find the next highest priority task ready to run       */

    CPU_CRITICAL_ENTER();
    switch (OSTCBCurPtr->PendStatus) {
        case OS_STATUS_PEND_OK:                             /* Extract message from TCB (Put there by Post)           */
             p_void     = OSTCBCurPtr->MsgPtr;
            *p_msg_size = OSTCBCurPtr->MsgSize;
             if (p_ts  != (CPU_TS *)0) {
                *p_ts   =  OSTCBCurPtr->TS;
             }
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
             TRACE_OS_Q_PEND(p_q);                          /* Record the event.                                      */
#endif
            *p_err      = OS_ERR_NONE;
             break;

        case OS_STATUS_PEND_ABORT:                          /* Indicate that we aborted                               */
             p_void     = (void      *)0;
            *p_msg_size = (OS_MSG_SIZE)0;
             if (p_ts  != (CPU_TS *)0) {
                *p_ts   =  OSTCBCurPtr->TS;
             }
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
             TRACE_OS_Q_PEND_FAILED(p_q);                   /* Record the event.                                      */
#endif
            *p_err      = OS_ERR_PEND_ABORT;
             break;

        case OS_STATUS_PEND_TIMEOUT:                        /* Indicate that we didn't get event within TO            */
             p_void     = (void      *)0;
            *p_msg_size = (OS_MSG_SIZE)0;
             if (p_ts  != (CPU_TS *)0) {
                *p_ts   = (CPU_TS  )0;
             }
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
             TRACE_OS_Q_PEND_FAILED(p_q);                   /* Record the event.                                      */
#endif
            *p_err      = OS_ERR_TIMEOUT;
             break;

        case OS_STATUS_PEND_DEL:                            /* Indicate that object pended on has been deleted        */
             p_void     = (void      *)0;
            *p_msg_size = (OS_MSG_SIZE)0;
             if (p_ts  != (CPU_TS *)0) {
                *p_ts   =  OSTCBCurPtr->TS;
             }
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
             TRACE_OS_Q_PEND_FAILED(p_q);                   /* Record the event.                                      */
#endif
            *p_err      = OS_ERR_OBJ_DEL;
             break;

        default:
             p_void     = (void      *)0;
            *p_msg_size = (OS_MSG_SIZE)0;
#if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u))
             TRACE_OS_Q_PEND_FAILED(p_q);                   /* Record the event.                                      */
#endif
            *p_err      = OS_ERR_STATUS_INVALID;
             break;
    }
    CPU_CRITICAL_EXIT();
    return (p_void);
}