/** * @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(); } }
bool_t gfxSemWaitI(gfxSem *psem) { if (chSemGetCounterI(&psem->sem) <= 0) return FALSE; chSemFastWaitI(&psem->sem); return TRUE; }
/** * @brief Posts an high priority message into a mailbox. * @details This variant is non-blocking, the function returns a timeout * condition if the queue is full. * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox * @return The operation status. * @retval RDY_OK if a message has been correctly posted. * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be * posted. * * @iclass */ msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) { chDbgCheck(mbp != NULL, "chMBPostAheadI"); if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) return RDY_TIMEOUT; chSemFastWaitI(&mbp->mb_emptysem); if (--mbp->mb_rdptr < mbp->mb_buffer) mbp->mb_rdptr = mbp->mb_top - 1; *mbp->mb_rdptr = msg; chSemSignalI(&mbp->mb_fullsem); return RDY_OK; }
/** * @brief Posts a message into a mailbox. * @details This variant is non-blocking, the function returns a timeout * condition if the queue is full. * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox * @return The operation status. * @retval RDY_OK if a message has been correctly posted. * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be * posted. * * @iclass */ msg_t chMBPostI(Mailbox *mbp, msg_t msg) { chDbgCheck(mbp != NULL, "chMBPostI"); if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) return RDY_TIMEOUT; chSemFastWaitI(&mbp->mb_emptysem); *mbp->mb_wrptr++ = msg; if (mbp->mb_wrptr >= mbp->mb_top) mbp->mb_wrptr = mbp->mb_buffer; chSemSignalI(&mbp->mb_fullsem); return RDY_OK; }
/** * @brief Retrieves a message from a mailbox. * @details This variant is non-blocking, the function returns a timeout * condition if the queue is empty. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[out] msgp pointer to a message variable for the received message * @return The operation status. * @retval MSG_OK if a message has been correctly fetched. * @retval MSG_TIMEOUT if the mailbox is empty and a message cannot be * fetched. * * @iclass */ msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp) { chDbgCheckClassI(); chDbgCheck((mbp != NULL) && (msgp != NULL)); if (chSemGetCounterI(&mbp->mb_fullsem) <= 0) return MSG_TIMEOUT; chSemFastWaitI(&mbp->mb_fullsem); *msgp = *mbp->mb_rdptr++; if (mbp->mb_rdptr >= mbp->mb_top) mbp->mb_rdptr = mbp->mb_buffer; chSemSignalI(&mbp->mb_emptysem); return MSG_OK; }
/** * @brief Posts an high priority message into a mailbox. * @details This variant is non-blocking, the function returns a timeout * condition if the queue is full. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @return The operation status. * @retval MSG_OK if a message has been correctly posted. * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be * posted. * * @iclass */ msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) { chDbgCheckClassI(); chDbgCheck(mbp != NULL); if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) return MSG_TIMEOUT; chSemFastWaitI(&mbp->mb_emptysem); if (--mbp->mb_rdptr < mbp->mb_buffer) mbp->mb_rdptr = mbp->mb_top - 1; *mbp->mb_rdptr = msg; chSemSignalI(&mbp->mb_fullsem); return MSG_OK; }
/** * @brief Posts a message into a mailbox. * @details This variant is non-blocking, the function returns a timeout * condition if the queue is full. * * @param[in] mbp the pointer to an initialized @p mailbox_t object * @param[in] msg the message to be posted on the mailbox * @return The operation status. * @retval MSG_OK if a message has been correctly posted. * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be * posted. * * @iclass */ msg_t chMBPostI(mailbox_t *mbp, msg_t msg) { chDbgCheckClassI(); chDbgCheck(mbp != NULL); if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) return MSG_TIMEOUT; chSemFastWaitI(&mbp->mb_emptysem); *mbp->mb_wrptr++ = msg; if (mbp->mb_wrptr >= mbp->mb_top) mbp->mb_wrptr = mbp->mb_buffer; chSemSignalI(&mbp->mb_fullsem); return MSG_OK; }