/** * @brief Output queue write with timeout. * @details The function writes data from a buffer to an output queue. The * operation completes when the specified amount of data has been * transferred or after the specified timeout or if the queue has * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. * @note The queue callback is invoked before entering a sleep state and at * the end of the transfer. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[out] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred, the * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The number of bytes effectively transferred. * * @api */ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, size_t n, systime_t time) { qnotify_t nfy = oqp->q_notify; size_t w = 0; chDbgCheck(n > 0, "chOQWriteTimeout"); chSysLock(); while (TRUE) { if (chOQIsFullI(oqp)) { if (nfy) nfy(oqp); if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) { chSysUnlock(); return w; } } else chSemFastWaitI(&oqp->q_sem); *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; if (--n == 0) { chSysLock(); if (nfy) nfy(oqp); chSysUnlock(); return w; } chSysLock(); } }
/** * @brief Input queue read with timeout. * @details The function reads data from an input queue into a buffer. The * operation completes when the specified amount of data has been * transferred or after the specified timeout or if the queue has * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. * @note The queue callback is invoked before entering a sleep state and at * the end of the transfer. * * @param[in] iqp pointer to an @p InputQueue structure * @param[out] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred, the * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The number of bytes effectively transferred. * * @api */ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, size_t n, systime_t time) { qnotify_t nfy = iqp->q_notify; size_t r = 0; chDbgCheck(n > 0, "chIQReadTimeout"); chSysLock(); while (TRUE) { if (chIQIsEmptyI(iqp)) { if (nfy) nfy(iqp); if ((chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK)) { chSysUnlock(); return r; } } else chSemFastWaitI(&iqp->q_sem); *bp++ = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ r++; if (--n == 0) { chSysLock(); if (nfy) nfy(iqp); chSysUnlock(); return r; } chSysLock(); } }
/** * @brief Performs a wait operation on a semaphore with timeout specification. * * @param[in] sp pointer to a @p Semaphore structure * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return A message specifying how the invoking thread has been * released from the semaphore. * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). * @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within * the specified timeout. * * @api */ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { msg_t msg; chSysLock(); msg = chSemWaitTimeoutS(sp, time); chSysUnlock(); return msg; }
datatype * DataListener< datatype >::peekI(uint32_t timeout_ms){ datatype * dst; if(RDY_OK == chSemWaitTimeoutS(&sem, timeout_ms)){ chSemSignalI(&sem); dst = rd_head; return dst; } return nullptr; }
/** * @brief Allocates an object from a guarded memory pool. * @pre The guarded memory pool must already be initialized. * * @param[in] gmp pointer to a @p guarded_memory_pool_t structure * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The pointer to the allocated object. * @retval NULL if the operation timed out. * * @sclass */ void *chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp, sysinterval_t timeout) { msg_t msg; msg = chSemWaitTimeoutS(&gmp->sem, timeout); if (msg != MSG_OK) { return NULL; } return chPoolAllocI(&gmp->pool); }
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { systime_t time, tmo; osalSysLock(); tmo = timeout > 0 ? (systime_t)timeout : TIME_INFINITE; time = osalOsGetSystemTimeX(); if (chSemWaitTimeoutS(*sem, tmo) != MSG_OK) time = SYS_ARCH_TIMEOUT; else time = osalOsGetSystemTimeX() - time; osalSysUnlock(); return time; }
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { systime_t time, tmo; chSysLock(); tmo = timeout > 0 ? (systime_t)timeout : TIME_INFINITE; time = chTimeNow(); if (chSemWaitTimeoutS(*sem, tmo) != RDY_OK) time = SYS_ARCH_TIMEOUT; else time = chTimeNow() - time; chSysUnlock(); return time; }
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { systime_t tmo, start, remaining; osalSysLock(); tmo = timeout > 0 ? MS2ST((systime_t)timeout) : TIME_INFINITE; start = osalOsGetSystemTimeX(); if (chSemWaitTimeoutS(*sem, tmo) != MSG_OK) { osalSysUnlock(); return SYS_ARCH_TIMEOUT; } remaining = osalOsGetSystemTimeX() - start; osalSysUnlock(); return (u32_t)ST2MS(remaining); }
/** * @brief Retrieves a message from a mailbox. * @details The invoking thread waits until a message is posted in the mailbox * or the specified time runs out. * * @param[in] mbp the pointer to an initialized Mailbox object * @param[out] msgp pointer to a message variable for the received message * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK if a message has been correctly fetched. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. * * @sclass */ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchS"); rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, time); if (rdymsg == RDY_OK) { *msgp = *mbp->mb_rdptr++; if (mbp->mb_rdptr >= mbp->mb_top) mbp->mb_rdptr = mbp->mb_buffer; chSemSignalI(&mbp->mb_emptysem); chSchRescheduleS(); } return rdymsg; }
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { systime_t tmo; u32_t time; osalSysLock(); tmo = timeout > 0 ? MS2ST((systime_t)timeout) : TIME_INFINITE; time = (u32_t)ST2MS(osalOsGetSystemTimeX()); if (chSemWaitTimeoutS(*sem, tmo) != MSG_OK) time = SYS_ARCH_TIMEOUT; else time = (u32_t)ST2MS(osalOsGetSystemTimeX()) - time; chSchRescheduleS(); osalSysUnlock(); return time; }
/** * @brief Posts an high priority message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK if a message has been correctly posted. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. * * @sclass */ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; chDbgCheck(mbp != NULL, "chMBPostAheadS"); rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); if (rdymsg == RDY_OK) { if (--mbp->mb_rdptr < mbp->mb_buffer) mbp->mb_rdptr = mbp->mb_top - 1; *mbp->mb_rdptr = msg; chSemSignalI(&mbp->mb_fullsem); chSchRescheduleS(); } return rdymsg; }
/** * @brief Posts a message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK if a message has been correctly posted. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. * * @sclass */ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; chDbgCheck(mbp != NULL, "chMBPostS"); rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); if (rdymsg == RDY_OK) { *mbp->mb_wrptr++ = msg; if (mbp->mb_wrptr >= mbp->mb_top) mbp->mb_wrptr = mbp->mb_buffer; chSemSignalI(&mbp->mb_fullsem); chSchRescheduleS(); } return rdymsg; }
bool DataListener< datatype >::receive_to(datatype & dst, uint32_t timeout_ms){ chSysLock(); if(RDY_OK == chSemWaitTimeoutS(&sem, timeout_ms)){ dst = *rd_head; if(rd_head == buf_head + len - 1){ rd_head = buf_head; } else { rd_head += 1; } chSysUnlock(); return true; } chSysUnlock(); return false; }
/** * @brief Waits for completion. * @details If the conversion is not completed or not yet started then the * invoking thread waits for a conversion completion event. * * @param[in] adcp pointer to the @p ADCDriver object * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation result. * @retval RDY_OK conversion finished. * @retval RDY_TIMEOUT conversion not finished within the specified time. */ msg_t adcWaitConversion(ADCDriver *adcp, systime_t timeout) { chSysLock(); chDbgAssert((adcp->ad_state == ADC_READY) || (adcp->ad_state == ADC_RUNNING) || (adcp->ad_state == ADC_COMPLETE), "adcWaitConversion(), #1", "invalid state"); if (adcp->ad_state != ADC_COMPLETE) { if (chSemWaitTimeoutS(&adcp->ad_sem, timeout) == RDY_TIMEOUT) { chSysUnlock(); return RDY_TIMEOUT; } } chSysUnlock(); return RDY_OK; }
datatype * DataListener< datatype >::receive(uint32_t timeout_ms){ datatype * dst; chSysLock(); if(RDY_OK == chSemWaitTimeoutS(&sem, timeout_ms)){ dst = rd_head; if(rd_head == buf_head + len - 1){ rd_head = buf_head; } else { rd_head += 1; } chSysUnlock(); return dst; } chSysUnlock(); return nullptr; }
/** * @brief Waits for a received frame. * @details Stops until a frame is received and buffered. If a frame is * not immediately available then the invoking thread is queued * until one is received. * * @param[in] macp pointer to the @p MACDriver object * @param[out] rdp pointer to a @p MACReceiveDescriptor structure * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK the descriptor was obtained. * @retval RDY_TIMEOUT the operation timed out, descriptor not initialized. */ msg_t macWaitReceiveDescriptor(MACDriver *macp, MACReceiveDescriptor *rdp, systime_t time) { msg_t msg; while (((msg = max_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) && (time > 0)) { chSysLock(); systime_t now = chTimeNow(); if ((msg = chSemWaitTimeoutS(&macp->md_rdsem, time)) == RDY_TIMEOUT) break; if (time != TIME_INFINITE) time -= (chTimeNow() - now); chSysUnlock(); } return msg; }
/** * @brief Output queue write with timeout. * @details This function writes a byte value to an output queue. If the queue * is full then the calling thread is suspended until there is space * in the queue or a timeout occurs. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[in] b the byte value to be written in the queue * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. * * @api */ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { msg_t msg; chSysLock(); if ((msg = chSemWaitTimeoutS(&oqp->q_sem, time)) < RDY_OK) { chSysUnlock(); return msg; } *oqp->q_wrptr++ = b; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; if (oqp->q_notify) oqp->q_notify(oqp); chSysUnlock(); return Q_OK; }
/** * @brief Can frame transmission. * @details The specified frame is queued for transmission, if the hardware * queue is full then the invoking thread is queued. * @note Trying to transmit while in sleep mode simply enqueues the thread. * * @param[in] canp pointer to the @p CANDriver object * @param[in] ctfp pointer to the CAN frame to be transmitted * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation result. * @retval RDY_OK the frame has been queued for transmission. * @retval RDY_TIMEOUT The operation has timed out. * @retval RDY_RESET The driver has been stopped while waiting. * * @api */ msg_t canTransmit(CANDriver *canp, const CANTxFrame *ctfp, systime_t timeout) { chDbgCheck((canp != NULL) && (ctfp != NULL), "canTransmit"); chSysLock(); chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP), "canTransmit(), #1", "invalid state"); while ((canp->state == CAN_SLEEP) || !can_lld_can_transmit(canp)) { msg_t msg = chSemWaitTimeoutS(&canp->txsem, timeout); if (msg != RDY_OK) { chSysUnlock(); return msg; } } can_lld_transmit(canp, ctfp); chSysUnlock(); return RDY_OK; }
/** * @brief Can frame receive. * @details The function waits until a frame is received. * @note Trying to receive while in sleep mode simply enqueues the thread. * * @param[in] canp pointer to the @p CANDriver object * @param[out] crfp pointer to the buffer where the CAN frame is copied * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout (useful in an * event driven scenario where a thread never blocks * for I/O). * - @a TIME_INFINITE no timeout. * . * @return The operation result. * @retval RDY_OK a frame has been received and placed in the buffer. * @retval RDY_TIMEOUT The operation has timed out. * @retval RDY_RESET The driver has been stopped while waiting. * * @api */ msg_t canReceive(CANDriver *canp, CANRxFrame *crfp, systime_t timeout) { chDbgCheck((canp != NULL) && (crfp != NULL), "canReceive"); chSysLock(); chDbgAssert((canp->state == CAN_READY) || (canp->state == CAN_SLEEP), "canReceive(), #1", "invalid state"); while ((canp->state == CAN_SLEEP) || !can_lld_can_receive(canp)) { msg_t msg = chSemWaitTimeoutS(&canp->rxsem, timeout); if (msg != RDY_OK) { chSysUnlock(); return msg; } } can_lld_receive(canp, crfp); chSysUnlock(); return RDY_OK; }
/** * @brief Input queue read with timeout. * @details This function reads a byte value from an input queue. If the queue * is empty then the calling thread is suspended until a byte arrives * in the queue or a timeout occurs. * * @param[in] iqp pointer to an @p InputQueue structure * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return A byte value from the queue. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. * * @api */ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { uint8_t b; msg_t msg; chSysLock(); if (iqp->q_notify) iqp->q_notify(iqp); if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) { chSysUnlock(); return msg; } b = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; chSysUnlock(); return b; }
/** * @brief Waits for a received frame. * @details Stops until a frame is received and buffered. If a frame is * not immediately available then the invoking thread is queued * until one is received. * * @param[in] macp pointer to the @p MACDriver object * @param[out] rdp pointer to a @p MACReceiveDescriptor structure * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK the descriptor was obtained. * @retval RDY_TIMEOUT the operation timed out, descriptor not initialized. * * @api */ msg_t macWaitReceiveDescriptor(MACDriver *macp, MACReceiveDescriptor *rdp, systime_t time) { msg_t msg; chDbgCheck((macp != NULL) && (rdp != NULL), "macWaitReceiveDescriptor"); chDbgAssert(macp->state == MAC_ACTIVE, "macWaitReceiveDescriptor(), #1", "not active"); while (((msg = max_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) && (time > 0)) { chSysLock(); systime_t now = chTimeNow(); if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == RDY_TIMEOUT) { chSysUnlock(); break; } if (time != TIME_INFINITE) time -= (chTimeNow() - now); chSysUnlock(); } return msg; }
/** * @brief Waits for a received frame. * @details Stops until a frame is received and buffered. If a frame is * not immediately available then the invoking thread is queued * until one is received. * * @param[in] macp pointer to the @p MACDriver object * @param[out] rdp pointer to a @p MACReceiveDescriptor structure * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval RDY_OK the descriptor was obtained. * @retval RDY_TIMEOUT the operation timed out, descriptor not initialized. * * @api */ msg_t macWaitReceiveDescriptor(MACDriver *macp, MACReceiveDescriptor *rdp, systime_t time) { msg_t msg; systime_t now; osalDbgCheck((macp != NULL) && (rdp != NULL)); osalDbgAssert(macp->state == MAC_ACTIVE, "not active"); while (((msg = mac_lld_get_receive_descriptor(macp, rdp)) != MSG_OK) && (time > 0)) { osalSysLock(); now = osalOsGetSystemTimeX(); if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == MSG_TIMEOUT) { osalSysUnlock(); break; } if (time != TIME_INFINITE) time -= (osalOsGetSystemTimeX() - now); osalSysUnlock(); } return msg; }
msg_t CounterSemaphore::waitTimeoutS(systime_t time) { return chSemWaitTimeoutS(&sem, time); }
inline bool Semaphore_::wait_unsafe(const Time &timeout) { return chSemWaitTimeoutS(&impl, US2ST(timeout.to_us_raw())) == RDY_OK; }