Fixed bug #828 (to be tested).
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_16.1.x@10161 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
51d8ce8923
commit
4f48f576d0
|
@ -42,10 +42,6 @@
|
||||||
/* Derived constants and error checks. */
|
/* Derived constants and error checks. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if CH_CFG_USE_SEMAPHORES == FALSE
|
|
||||||
#error "CH_CFG_USE_MAILBOXES requires CH_CFG_USE_SEMAPHORES"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Module data structures and types. */
|
/* Module data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -60,10 +56,10 @@ typedef struct {
|
||||||
after the buffer. */
|
after the buffer. */
|
||||||
msg_t *mb_wrptr; /**< @brief Write pointer. */
|
msg_t *mb_wrptr; /**< @brief Write pointer. */
|
||||||
msg_t *mb_rdptr; /**< @brief Read pointer. */
|
msg_t *mb_rdptr; /**< @brief Read pointer. */
|
||||||
semaphore_t mb_fullsem; /**< @brief Full counter
|
cnt_t mb_cnt; /**< @brief Messages in queue. */
|
||||||
@p semaphore_t. */
|
bool mb_reset; /**< @brief True in reset state. */
|
||||||
semaphore_t mb_emptysem; /**< @brief Empty counter
|
threads_queue_t mb_qw; /**< @brief Queued writers. */
|
||||||
@p semaphore_t. */
|
threads_queue_t mb_qr; /**< @brief Queued readers. */
|
||||||
} mailbox_t;
|
} mailbox_t;
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -84,8 +80,10 @@ typedef struct {
|
||||||
(msg_t *)(buffer) + size, \
|
(msg_t *)(buffer) + size, \
|
||||||
(msg_t *)(buffer), \
|
(msg_t *)(buffer), \
|
||||||
(msg_t *)(buffer), \
|
(msg_t *)(buffer), \
|
||||||
_SEMAPHORE_DATA(name.mb_fullsem, 0), \
|
(cnt_t)0, \
|
||||||
_SEMAPHORE_DATA(name.mb_emptysem, size), \
|
false, \
|
||||||
|
_THREADS_QUEUE_DATA(name.mb_qw), \
|
||||||
|
_THREADS_QUEUE_DATA(name.mb_qr), \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,27 +126,39 @@ extern "C" {
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the mailbox buffer size.
|
* @brief Returns the mailbox buffer size as number of messages.
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized mailbox_t object
|
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||||
* @return The size of the mailbox.
|
* @return The size of the mailbox.
|
||||||
*
|
*
|
||||||
* @iclass
|
* @iclass
|
||||||
*/
|
*/
|
||||||
static inline size_t chMBGetSizeI(mailbox_t *mbp) {
|
static inline cnt_t chMBGetSizeI(mailbox_t *mbp) {
|
||||||
|
|
||||||
/*lint -save -e9033 [10.8] Perfectly safe pointers
|
/*lint -save -e9033 [10.8] Perfectly safe pointers
|
||||||
arithmetic.*/
|
arithmetic.*/
|
||||||
return (size_t)(mbp->mb_top - mbp->mb_buffer);
|
return (cnt_t)(mbp->mb_top - mbp->mb_buffer);
|
||||||
/*lint -restore*/
|
/*lint -restore*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the number of used message slots into a mailbox.
|
||||||
|
*
|
||||||
|
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||||
|
* @return The number of queued messages.
|
||||||
|
* @retval QUEUE_RESET if the queue is in reset state.
|
||||||
|
*
|
||||||
|
* @iclass
|
||||||
|
*/
|
||||||
|
static inline cnt_t chMBGetUsedCountI(mailbox_t *mbp) {
|
||||||
|
|
||||||
|
chDbgCheckClassI();
|
||||||
|
|
||||||
|
return mbp->mb_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the number of free message slots into a mailbox.
|
* @brief Returns the number of free message slots into a mailbox.
|
||||||
* @note Can be invoked in any system state but if invoked out of a locked
|
|
||||||
* state then the returned value may change after reading.
|
|
||||||
* @note The returned value can be less than zero when there are waiting
|
|
||||||
* threads on the internal semaphore.
|
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized mailbox_t object
|
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||||
* @return The number of empty message slots.
|
* @return The number of empty message slots.
|
||||||
|
@ -159,26 +169,7 @@ static inline cnt_t chMBGetFreeCountI(mailbox_t *mbp) {
|
||||||
|
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
|
|
||||||
return chSemGetCounterI(&mbp->mb_emptysem);
|
return chMBGetSizeI(mbp) - chMBGetUsedCountI(mbp);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the number of used message slots into a mailbox.
|
|
||||||
* @note Can be invoked in any system state but if invoked out of a locked
|
|
||||||
* state then the returned value may change after reading.
|
|
||||||
* @note The returned value can be less than zero when there are waiting
|
|
||||||
* threads on the internal semaphore.
|
|
||||||
*
|
|
||||||
* @param[in] mbp the pointer to an initialized mailbox_t object
|
|
||||||
* @return The number of queued messages.
|
|
||||||
*
|
|
||||||
* @iclass
|
|
||||||
*/
|
|
||||||
static inline cnt_t chMBGetUsedCountI(mailbox_t *mbp) {
|
|
||||||
|
|
||||||
chDbgCheckClassI();
|
|
||||||
|
|
||||||
return chSemGetCounterI(&mbp->mb_fullsem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,6 +191,18 @@ static inline msg_t chMBPeekI(mailbox_t *mbp) {
|
||||||
return *mbp->mb_rdptr;
|
return *mbp->mb_rdptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Terminates the reset state.
|
||||||
|
*
|
||||||
|
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||||
|
*
|
||||||
|
* @xclass
|
||||||
|
*/
|
||||||
|
static inline void chMBResumeX(mailbox_t *mbp) {
|
||||||
|
|
||||||
|
mbp->mb_reset = false;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CH_CFG_USE_MAILBOXES == TRUE */
|
#endif /* CH_CFG_USE_MAILBOXES == TRUE */
|
||||||
|
|
||||||
#endif /* _CHMBOXES_H_ */
|
#endif /* _CHMBOXES_H_ */
|
||||||
|
|
|
@ -91,14 +91,19 @@ void chMBObjectInit(mailbox_t *mbp, msg_t *buf, cnt_t n) {
|
||||||
mbp->mb_rdptr = buf;
|
mbp->mb_rdptr = buf;
|
||||||
mbp->mb_wrptr = buf;
|
mbp->mb_wrptr = buf;
|
||||||
mbp->mb_top = &buf[n];
|
mbp->mb_top = &buf[n];
|
||||||
chSemObjectInit(&mbp->mb_emptysem, n);
|
mbp->mb_cnt = (cnt_t)0;
|
||||||
chSemObjectInit(&mbp->mb_fullsem, (cnt_t)0);
|
mbp->mb_reset = false;
|
||||||
|
chThdQueueObjectInit(&mbp->mb_qw);
|
||||||
|
chThdQueueObjectInit(&mbp->mb_qr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resets a @p mailbox_t object.
|
* @brief Resets a @p mailbox_t object.
|
||||||
* @details All the waiting threads are resumed with status @p MSG_RESET and
|
* @details All the waiting threads are resumed with status @p MSG_RESET and
|
||||||
* the queued messages are lost.
|
* the queued messages are lost.
|
||||||
|
* @post The mailbox is in reset state, all operations will fail and
|
||||||
|
* return @p MSG reset until the mailbox is enabled again using
|
||||||
|
* @p chMBResumeX().
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
*
|
*
|
||||||
|
@ -116,6 +121,9 @@ void chMBReset(mailbox_t *mbp) {
|
||||||
* @brief Resets a @p mailbox_t object.
|
* @brief Resets a @p mailbox_t object.
|
||||||
* @details All the waiting threads are resumed with status @p MSG_RESET and
|
* @details All the waiting threads are resumed with status @p MSG_RESET and
|
||||||
* the queued messages are lost.
|
* the queued messages are lost.
|
||||||
|
* @post The mailbox is in reset state, all operations will fail and
|
||||||
|
* return @p MSG reset until the mailbox is enabled again using
|
||||||
|
* @p chMBResumeX().
|
||||||
*
|
*
|
||||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||||
*
|
*
|
||||||
|
@ -128,8 +136,10 @@ void chMBResetI(mailbox_t *mbp) {
|
||||||
|
|
||||||
mbp->mb_wrptr = mbp->mb_buffer;
|
mbp->mb_wrptr = mbp->mb_buffer;
|
||||||
mbp->mb_rdptr = mbp->mb_buffer;
|
mbp->mb_rdptr = mbp->mb_buffer;
|
||||||
chSemResetI(&mbp->mb_emptysem, (cnt_t)(mbp->mb_top - mbp->mb_buffer));
|
mbp->mb_cnt = (cnt_t)0;
|
||||||
chSemResetI(&mbp->mb_fullsem, (cnt_t)0);
|
mbp->mb_reset = true;
|
||||||
|
chThdDequeueAllI(&mbp->mb_qw, MSG_RESET);
|
||||||
|
chThdDequeueAllI(&mbp->mb_qr, MSG_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,7 +156,7 @@ void chMBResetI(mailbox_t *mbp) {
|
||||||
* .
|
* .
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly posted.
|
* @retval MSG_OK if a message has been correctly posted.
|
||||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
@ -175,7 +185,7 @@ msg_t chMBPost(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||||
* .
|
* .
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly posted.
|
* @retval MSG_OK if a message has been correctly posted.
|
||||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
|
@ -186,16 +196,31 @@ msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
chDbgCheck(mbp != NULL);
|
chDbgCheck(mbp != NULL);
|
||||||
|
|
||||||
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout);
|
do {
|
||||||
if (rdymsg == MSG_OK) {
|
/* If the mailbox is in reset state then returns immediately.*/
|
||||||
|
if (mbp->mb_reset) {
|
||||||
|
return MSG_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is there a free message slot in queue? if so then post.*/
|
||||||
|
if (chMBGetFreeCountI(mbp) > (cnt_t)0) {
|
||||||
*mbp->mb_wrptr++ = msg;
|
*mbp->mb_wrptr++ = msg;
|
||||||
if (mbp->mb_wrptr >= mbp->mb_top) {
|
if (mbp->mb_wrptr >= mbp->mb_top) {
|
||||||
mbp->mb_wrptr = mbp->mb_buffer;
|
mbp->mb_wrptr = mbp->mb_buffer;
|
||||||
}
|
}
|
||||||
chSemSignalI(&mbp->mb_fullsem);
|
mbp->mb_cnt++;
|
||||||
|
|
||||||
|
/* If there is a reader waiting then makes it ready.*/
|
||||||
|
chThdDequeueNextI(&mbp->mb_qr, MSG_OK);
|
||||||
chSchRescheduleS();
|
chSchRescheduleS();
|
||||||
|
|
||||||
|
return MSG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No space in the queue, waiting for a slot to become available.*/
|
||||||
|
rdymsg = chThdEnqueueTimeoutS(&mbp->mb_qw, timeout);
|
||||||
|
} while (rdymsg == MSG_OK);
|
||||||
|
|
||||||
return rdymsg;
|
return rdymsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +233,7 @@ msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly posted.
|
* @retval MSG_OK if a message has been correctly posted.
|
||||||
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
|
* @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
|
||||||
* posted.
|
* posted.
|
||||||
*
|
*
|
||||||
|
@ -218,18 +244,27 @@ msg_t chMBPostI(mailbox_t *mbp, msg_t msg) {
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck(mbp != NULL);
|
chDbgCheck(mbp != NULL);
|
||||||
|
|
||||||
if (chSemGetCounterI(&mbp->mb_emptysem) <= (cnt_t)0) {
|
/* If the mailbox is in reset state then returns immediately.*/
|
||||||
return MSG_TIMEOUT;
|
if (mbp->mb_reset) {
|
||||||
|
return MSG_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
chSemFastWaitI(&mbp->mb_emptysem);
|
/* Is there a free message slot in queue? if so then post.*/
|
||||||
|
if (chMBGetFreeCountI(mbp) > (cnt_t)0) {
|
||||||
*mbp->mb_wrptr++ = msg;
|
*mbp->mb_wrptr++ = msg;
|
||||||
if (mbp->mb_wrptr >= mbp->mb_top) {
|
if (mbp->mb_wrptr >= mbp->mb_top) {
|
||||||
mbp->mb_wrptr = mbp->mb_buffer;
|
mbp->mb_wrptr = mbp->mb_buffer;
|
||||||
}
|
}
|
||||||
chSemSignalI(&mbp->mb_fullsem);
|
mbp->mb_cnt++;
|
||||||
|
|
||||||
|
/* If there is a reader waiting then makes it ready.*/
|
||||||
|
chThdDequeueNextI(&mbp->mb_qr, MSG_OK);
|
||||||
|
|
||||||
return MSG_OK;
|
return MSG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No space, immediate timeout.*/
|
||||||
|
return MSG_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,7 +281,7 @@ msg_t chMBPostI(mailbox_t *mbp, msg_t msg) {
|
||||||
* .
|
* .
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly posted.
|
* @retval MSG_OK if a message has been correctly posted.
|
||||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
@ -275,7 +310,7 @@ msg_t chMBPostAhead(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||||
* .
|
* .
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly posted.
|
* @retval MSG_OK if a message has been correctly posted.
|
||||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
|
@ -286,16 +321,31 @@ msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
chDbgCheck(mbp != NULL);
|
chDbgCheck(mbp != NULL);
|
||||||
|
|
||||||
rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout);
|
do {
|
||||||
if (rdymsg == MSG_OK) {
|
/* If the mailbox is in reset state then returns immediately.*/
|
||||||
|
if (mbp->mb_reset) {
|
||||||
|
return MSG_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is there a free message slot in queue? if so then post.*/
|
||||||
|
if (chMBGetFreeCountI(mbp) > (cnt_t)0) {
|
||||||
if (--mbp->mb_rdptr < mbp->mb_buffer) {
|
if (--mbp->mb_rdptr < mbp->mb_buffer) {
|
||||||
mbp->mb_rdptr = mbp->mb_top - 1;
|
mbp->mb_rdptr = mbp->mb_top - 1;
|
||||||
}
|
}
|
||||||
*mbp->mb_rdptr = msg;
|
*mbp->mb_rdptr = msg;
|
||||||
chSemSignalI(&mbp->mb_fullsem);
|
mbp->mb_cnt++;
|
||||||
|
|
||||||
|
/* If there is a reader waiting then makes it ready.*/
|
||||||
|
chThdDequeueNextI(&mbp->mb_qr, MSG_OK);
|
||||||
chSchRescheduleS();
|
chSchRescheduleS();
|
||||||
|
|
||||||
|
return MSG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No space in the queue, waiting for a slot to become available.*/
|
||||||
|
rdymsg = chThdEnqueueTimeoutS(&mbp->mb_qw, timeout);
|
||||||
|
} while (rdymsg == MSG_OK);
|
||||||
|
|
||||||
return rdymsg;
|
return rdymsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,6 +358,7 @@ msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||||
* @param[in] msg the message to be posted on the mailbox
|
* @param[in] msg the message to be posted on the mailbox
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly posted.
|
* @retval MSG_OK if a message has been correctly posted.
|
||||||
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
|
* @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
|
||||||
* posted.
|
* posted.
|
||||||
*
|
*
|
||||||
|
@ -318,17 +369,27 @@ msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) {
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck(mbp != NULL);
|
chDbgCheck(mbp != NULL);
|
||||||
|
|
||||||
if (chSemGetCounterI(&mbp->mb_emptysem) <= (cnt_t)0) {
|
/* If the mailbox is in reset state then returns immediately.*/
|
||||||
return MSG_TIMEOUT;
|
if (mbp->mb_reset) {
|
||||||
|
return MSG_RESET;
|
||||||
}
|
}
|
||||||
chSemFastWaitI(&mbp->mb_emptysem);
|
|
||||||
|
/* Is there a free message slot in queue? if so then post.*/
|
||||||
|
if (chMBGetFreeCountI(mbp) > (cnt_t)0) {
|
||||||
if (--mbp->mb_rdptr < mbp->mb_buffer) {
|
if (--mbp->mb_rdptr < mbp->mb_buffer) {
|
||||||
mbp->mb_rdptr = mbp->mb_top - 1;
|
mbp->mb_rdptr = mbp->mb_top - 1;
|
||||||
}
|
}
|
||||||
*mbp->mb_rdptr = msg;
|
*mbp->mb_rdptr = msg;
|
||||||
chSemSignalI(&mbp->mb_fullsem);
|
mbp->mb_cnt++;
|
||||||
|
|
||||||
|
/* If there is a reader waiting then makes it ready.*/
|
||||||
|
chThdDequeueNextI(&mbp->mb_qr, MSG_OK);
|
||||||
|
|
||||||
return MSG_OK;
|
return MSG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No space, immediate timeout.*/
|
||||||
|
return MSG_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -345,7 +406,7 @@ msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) {
|
||||||
* .
|
* .
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly fetched.
|
* @retval MSG_OK if a message has been correctly fetched.
|
||||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
|
@ -374,7 +435,7 @@ msg_t chMBFetch(mailbox_t *mbp, msg_t *msgp, systime_t timeout) {
|
||||||
* .
|
* .
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly fetched.
|
* @retval MSG_OK if a message has been correctly fetched.
|
||||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
|
@ -385,16 +446,31 @@ msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t timeout) {
|
||||||
chDbgCheckClassS();
|
chDbgCheckClassS();
|
||||||
chDbgCheck((mbp != NULL) && (msgp != NULL));
|
chDbgCheck((mbp != NULL) && (msgp != NULL));
|
||||||
|
|
||||||
rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, timeout);
|
do {
|
||||||
if (rdymsg == MSG_OK) {
|
/* If the mailbox is in reset state then returns immediately.*/
|
||||||
|
if (mbp->mb_reset) {
|
||||||
|
return MSG_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is there a message in queue? if so then fetch.*/
|
||||||
|
if (chMBGetUsedCountI(mbp) > (cnt_t)0) {
|
||||||
*msgp = *mbp->mb_rdptr++;
|
*msgp = *mbp->mb_rdptr++;
|
||||||
if (mbp->mb_rdptr >= mbp->mb_top) {
|
if (mbp->mb_rdptr >= mbp->mb_top) {
|
||||||
mbp->mb_rdptr = mbp->mb_buffer;
|
mbp->mb_rdptr = mbp->mb_buffer;
|
||||||
}
|
}
|
||||||
chSemSignalI(&mbp->mb_emptysem);
|
mbp->mb_cnt--;
|
||||||
|
|
||||||
|
/* If there is a writer waiting then makes it ready.*/
|
||||||
|
chThdDequeueNextI(&mbp->mb_qw, MSG_OK);
|
||||||
chSchRescheduleS();
|
chSchRescheduleS();
|
||||||
|
|
||||||
|
return MSG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No message in the queue, waiting for a message to become available.*/
|
||||||
|
rdymsg = chThdEnqueueTimeoutS(&mbp->mb_qr, timeout);
|
||||||
|
} while (rdymsg == MSG_OK);
|
||||||
|
|
||||||
return rdymsg;
|
return rdymsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,6 +483,7 @@ msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t timeout) {
|
||||||
* @param[out] msgp pointer to a message variable for the received message
|
* @param[out] msgp pointer to a message variable for the received message
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK if a message has been correctly fetched.
|
* @retval MSG_OK if a message has been correctly fetched.
|
||||||
|
* @retval MSG_RESET if the mailbox has been reset.
|
||||||
* @retval MSG_TIMEOUT if the mailbox is empty and a message cannot be
|
* @retval MSG_TIMEOUT if the mailbox is empty and a message cannot be
|
||||||
* fetched.
|
* fetched.
|
||||||
*
|
*
|
||||||
|
@ -417,17 +494,27 @@ msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp) {
|
||||||
chDbgCheckClassI();
|
chDbgCheckClassI();
|
||||||
chDbgCheck((mbp != NULL) && (msgp != NULL));
|
chDbgCheck((mbp != NULL) && (msgp != NULL));
|
||||||
|
|
||||||
if (chSemGetCounterI(&mbp->mb_fullsem) <= (cnt_t)0) {
|
/* If the mailbox is in reset state then returns immediately.*/
|
||||||
return MSG_TIMEOUT;
|
if (mbp->mb_reset) {
|
||||||
|
return MSG_RESET;
|
||||||
}
|
}
|
||||||
chSemFastWaitI(&mbp->mb_fullsem);
|
|
||||||
|
/* Is there a message in queue? if so then fetch.*/
|
||||||
|
if (chMBGetUsedCountI(mbp) > (cnt_t)0) {
|
||||||
*msgp = *mbp->mb_rdptr++;
|
*msgp = *mbp->mb_rdptr++;
|
||||||
if (mbp->mb_rdptr >= mbp->mb_top) {
|
if (mbp->mb_rdptr >= mbp->mb_top) {
|
||||||
mbp->mb_rdptr = mbp->mb_buffer;
|
mbp->mb_rdptr = mbp->mb_buffer;
|
||||||
}
|
}
|
||||||
chSemSignalI(&mbp->mb_emptysem);
|
mbp->mb_cnt--;
|
||||||
|
|
||||||
|
/* If there is a writer waiting then makes it ready.*/
|
||||||
|
chThdDequeueNextI(&mbp->mb_qw, MSG_OK);
|
||||||
|
|
||||||
return MSG_OK;
|
return MSG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No message, immediate timeout.*/
|
||||||
|
return MSG_TIMEOUT;
|
||||||
}
|
}
|
||||||
#endif /* CH_CFG_USE_MAILBOXES == TRUE */
|
#endif /* CH_CFG_USE_MAILBOXES == TRUE */
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** 16.1.8 ***
|
*** 16.1.8 ***
|
||||||
|
- RT: Fixed race condition in chBMReset() (bug #828).
|
||||||
- HAL: Fixed wrong number of EXTI lines for STM32F303x8 (bug #827).
|
- HAL: Fixed wrong number of EXTI lines for STM32F303x8 (bug #827).
|
||||||
- HAL: Fixed invalid SDC OCR initialization value (bug #826).
|
- HAL: Fixed invalid SDC OCR initialization value (bug #826).
|
||||||
- HAL: Fixed osThreadSetPriority() returns old priority instead of a status
|
- HAL: Fixed osThreadSetPriority() returns old priority instead of a status
|
||||||
|
|
Loading…
Reference in New Issue