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); }
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); }