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 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();
  }
}
Example #2
0
/**
 * @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();
  }
}
Example #3
0
bool_t gfxSemWaitI(gfxSem *psem)
{
	if (chSemGetCounterI(&psem->sem) <= 0)
		return FALSE;
	chSemFastWaitI(&psem->sem);
	return TRUE;
}
Example #4
0
/**
 * @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;
}
Example #5
0
/**
 * @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;
}
Example #6
0
/**
 * @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;
}
Example #7
0
/**
 * @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;
}
Example #8
0
/**
 * @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;
}