/** * @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 callback is invoked after writing each character into the * buffer. * * @param[in] oqp pointer to an @p output_queue_t structure * @param[in] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred, the * value 0 is reserved * @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 number of bytes effectively transferred. * * @api */ size_t oqWriteTimeout(output_queue_t *oqp, const uint8_t *bp, size_t n, systime_t timeout) { qnotify_t nfy = oqp->q_notify; size_t w = 0; osalDbgCheck(n > 0U); osalSysLock(); while (true) { while (oqIsFullI(oqp)) { if (osalThreadEnqueueTimeoutS(&oqp->q_waiting, timeout) != Q_OK) { osalSysUnlock(); return w; } } oqp->q_counter--; *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) { oqp->q_wrptr = oqp->q_buffer; } if (nfy != NULL) { nfy(oqp); } osalSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; if (--n == 0U) { return w; } osalSysLock(); } }
/** * @brief Direct output check on a @p SerialDriver. * @note This function bypasses the indirect access to the channel and * checks directly the output queue. This is faster but cannot * be used to check different channels implementations. * * @param[in] sdp pointer to a @p SerialDriver structure * @return The queue status. * @retval false if the next write operation would not block. * @retval true if the next write operation would block. * * @deprecated * * @api */ bool sdPutWouldBlock(SerialDriver *sdp) { bool b; osalSysLock(); b = oqIsFullI(&sdp->oqueue); osalSysUnlock(); return b; }
/** * @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. * @note The callback is invoked after writing the character into the * buffer. * * @param[in] oqp pointer to an @p output_queue_t structure * @param[in] b the byte value to be written in the queue * @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 status. * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue has been reset. * * @api */ msg_t oqPutTimeout(output_queue_t *oqp, uint8_t b, systime_t timeout) { osalSysLock(); while (oqIsFullI(oqp)) { msg_t msg = osalThreadEnqueueTimeoutS(&oqp->q_waiting, timeout); if (msg < Q_OK) { osalSysUnlock(); return msg; } } oqp->q_counter--; *oqp->q_wrptr++ = b; if (oqp->q_wrptr >= oqp->q_top) { oqp->q_wrptr = oqp->q_buffer; } if (oqp->q_notify != NULL) { oqp->q_notify(oqp); } osalSysUnlock(); return Q_OK; }