Example #1
0
/**
 * @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();
  }
}
Example #2
0
/**
 * @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;
}
Example #3
0
/**
 * @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;
}