Exemplo n.º 1
0
void  OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr)
{
    INT8U      pend_stat;
#if OS_CRITICAL_METHOD == 3                           /* Allocate storage for CPU status register      */
    OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_ARG_CHK_EN > 0
    if (perr == (INT8U *)0) {                         /* Validate 'perr'                               */
        return;
    }
    if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */
        *perr = OS_ERR_PEVENT_NULL;
        return;
    }
#endif
    if (pevent->OSEventType != OS_EVENT_TYPE_SEM) {   /* Validate event block type                     */
        *perr = OS_ERR_EVENT_TYPE;
        return;
    }
    if (OSIntNesting > 0) {                           /* See if called from ISR ...                    */
        *perr = OS_ERR_PEND_ISR;                      /* ... can't PEND from an ISR                    */
        return;
    }
    if (OSLockNesting > 0) {                          /* See if called with scheduler locked ...       */
        *perr = OS_ERR_PEND_LOCKED;                   /* ... can't PEND when locked                    */
        return;
    }
    OS_ENTER_CRITICAL();
    if (pevent->OSEventCnt > 0) {                     /* If sem. is positive, resource available ...   */
        pevent->OSEventCnt--;                         /* ... decrement semaphore only if positive.     */
        OS_EXIT_CRITICAL();
        *perr = OS_ERR_NONE;
        return;
    }
                                                      /* Otherwise, must wait until event occurs       */
    OSTCBCur->OSTCBStat     |= OS_STAT_SEM;           /* Resource not available, pend on semaphore     */
    OSTCBCur->OSTCBStatPend  = OS_STAT_PEND_OK;
    OSTCBCur->OSTCBDly       = timeout;               /* Store pend timeout in TCB                     */
    OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
    OS_EXIT_CRITICAL();
    OS_Sched();                                       /* Find next highest priority task ready         */
    OS_ENTER_CRITICAL();
    if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we timed-out or aborted                */
        pend_stat = OSTCBCur->OSTCBStatPend;
        OS_EventTOAbort(pevent);
        OS_EXIT_CRITICAL();
        switch (pend_stat) {
            case OS_STAT_PEND_TO:
            default:
                 *perr = OS_ERR_TIMEOUT;              /* Indicate that didn't get event within TO      */
                 break;

            case OS_STAT_PEND_ABORT:
                 *perr = OS_ERR_PEND_ABORT;           /* Indicate that we aborted                      */
                 break;
        }
        return;
    }
    OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
    OS_EXIT_CRITICAL();
    *perr = OS_ERR_NONE;
}
Exemplo n.º 2
0
void  *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr)
{
    void      *pmsg;
    INT8U      pend_stat;
#if OS_CRITICAL_METHOD == 3                           /* Allocate storage for CPU status register      */
    OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_ARG_CHK_EN > 0
    if (perr == (INT8U *)0) {                         /* Validate 'perr'                               */
        return ((void *)0);
    }
    if (pevent == (OS_EVENT *)0) {                    /* Validate 'pevent'                             */
        *perr = OS_ERR_PEVENT_NULL;
        return ((void *)0);
    }
#endif
    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {  /* Validate event block type                     */
        *perr = OS_ERR_EVENT_TYPE;
        return ((void *)0);
    }
    if (OSIntNesting > 0) {                           /* See if called from ISR ...                    */
        *perr = OS_ERR_PEND_ISR;                      /* ... can't PEND from an ISR                    */
        return ((void *)0);
    }
    if (OSLockNesting > 0) {                          /* See if called with scheduler locked ...       */
        *perr = OS_ERR_PEND_LOCKED;                   /* ... can't PEND when locked                    */
        return ((void *)0);
    }
    OS_ENTER_CRITICAL();
    pmsg = pevent->OSEventPtr;
    if (pmsg != (void *)0) {                          /* See if there is already a message             */
        pevent->OSEventPtr = (void *)0;               /* Clear the mailbox                             */
        OS_EXIT_CRITICAL();
        *perr = OS_ERR_NONE;
        return (pmsg);                                /* Return the message received (or NULL)         */
    }
    OSTCBCur->OSTCBStat     |= OS_STAT_MBOX;          /* Message not available, task will pend         */
    OSTCBCur->OSTCBStatPend  = OS_STAT_PEND_OK;
    OSTCBCur->OSTCBDly       = timeout;               /* Load timeout in TCB                           */
    OS_EventTaskWait(pevent);                         /* Suspend task until event or timeout occurs    */
    OS_EXIT_CRITICAL();
    OS_Sched();                                       /* Find next highest priority task ready to run  */
    OS_ENTER_CRITICAL();
    if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we weren't given the message           */
        pend_stat = OSTCBCur->OSTCBStatPend;
        OS_EventTOAbort(pevent);                      /* Timed out, Make task ready                    */
        OS_EXIT_CRITICAL();
        switch (pend_stat) {
            case OS_STAT_PEND_TO:
            default:
                 *perr = OS_ERR_TIMEOUT;              /* Indicate that a timeout occured               */
                 break;

            case OS_STAT_PEND_ABORT:
                 *perr = OS_ERR_PEND_ABORT;           /* Indicate that we aborted                      */
                 break;
        }
        return ((void *)0);                           /* Return a NULL message                         */
    }
    pmsg                    = OSTCBCur->OSTCBMsg;
    OSTCBCur->OSTCBMsg      = (void *)0;              /* Yes, clear message received                   */
    OSTCBCur->OSTCBStat     = OS_STAT_RDY;
    OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;          /* No longer waiting for event                   */
    OS_EXIT_CRITICAL();
    *perr                   = OS_ERR_NONE;
    return (pmsg);                                    /* Return the message received                   */
}