git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8620 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
Giovanni Di Sirio 2015-12-20 10:25:41 +00:00
parent ddcc89f8d1
commit a952f3cfaf
2 changed files with 80 additions and 6 deletions

View File

@ -94,8 +94,13 @@ struct io_buffers_queue {
uint8_t *buffers;
/**
* @brief Pointer for R/W sequential access.
* @note It is @p NULL if a new buffer must be fetched from the queue.
*/
uint8_t *ptr;
/**
* @brief Boundary for R/W sequential access.
*/
uint8_t *top;
/**
* @brief Data notification callback.
*/
@ -156,7 +161,7 @@ typedef io_buffers_queue_t output_buffers_queue_t;
*
* @iclass
*/
#define iqbIsEmptyI(ibqp) ((bool)(bqSpaceI(ibqp) == 0U))
#define ibqIsEmptyI(ibqp) ((bool)(bqSpaceI(ibqp) == 0U))
/**
* @brief Evaluates to @p TRUE if the specified input buffered queue is full.

View File

@ -66,17 +66,18 @@ void ibqObjectInit(input_buffers_queue_t *ibqp, uint8_t *bp,
ibqp->bcounter = 0;
ibqp->brdptr = bp;
ibqp->bwrptr = bp;
ibqp->btop = bp + (size * n); /* Pre-calculated for speed.*/
ibqp->btop = bp + (size * n); /* Pre-calculated for speed. */
ibqp->bsize = size;
ibqp->bn = n;
ibqp->buffers = bp;
ibqp->ptr = NULL;
ibqp->top = NULL;
ibqp->notify = infy;
ibqp->link = link;
}
/**
* @brief Gets a buffer for posting in the queue.
* @brief Gets the next empty buffer from the queue.
* @note The function always returns the same buffer if called repeatedly.
*
* @param[out] ibqp pointer to the @p input_buffers_queue_t object
@ -85,7 +86,7 @@ void ibqObjectInit(input_buffers_queue_t *ibqp, uint8_t *bp,
*
* @iclass
*/
uint8_t *ibqGetNextBufferI(input_buffers_queue_t *ibqp) {
uint8_t *ibqGetEmptyBufferI(input_buffers_queue_t *ibqp) {
osalDbgCheckClassI();
@ -97,7 +98,7 @@ uint8_t *ibqGetNextBufferI(input_buffers_queue_t *ibqp) {
}
/**
* @brief Posts a buffer in the queue.
* @brief Posts a new filled buffer in the queue.
*
* @param[out] ibqp pointer to the @p input_buffers_queue_t object
* @param[in] size used size of the buffer
@ -107,7 +108,7 @@ uint8_t *ibqGetNextBufferI(input_buffers_queue_t *ibqp) {
void ibqPostBufferI(io_buffers_queue_t *ibqp, size_t size) {
osalDbgCheckClassI();
osalDbgAssert(!ibqIsFullI(ibqp), "buffered queue full");
osalDbgAssert(!ibqIsFullI(ibqp), "buffers queue full");
/* Writing size field in the buffer.*/
*((size_t *)ibqp->bwrptr) = size;
@ -123,6 +124,52 @@ void ibqPostBufferI(io_buffers_queue_t *ibqp, size_t size) {
osalThreadDequeueNextI(&ibqp->waiting, MSG_OK);
}
/**
* @brief Gets the next filled buffer from the queue.
* @note The function always returns the same buffer if called repeatedly.
*
* @param[out] ibqp pointer to the @p input_buffers_queue_t object
* @return A pointer to the next buffer to be filled.
* @retval NULL if the queue is empty.
*
* @iclass
*/
uint8_t *ibqGetFullBufferI(input_buffers_queue_t *ibqp) {
osalDbgCheckClassI();
if (ibqIsEmptyI(ibqp)) {
return NULL;
}
return ibqp->brdptr + sizeof (size_t);
}
/**
* @brief Releases the next filled buffer back in the queue.
*
* @param[out] ibqp pointer to the @p input_buffers_queue_t object
*
* @iclass
*/
void ibqReleaseBufferI(io_buffers_queue_t *ibqp) {
osalDbgCheckClassI();
osalDbgAssert(!ibqIsEmptyI(ibqp), "buffers queue empty");
/* Freeing a buffer slot in the queue.*/
ibqp->bcounter--;
ibqp->brdptr += ibqp->bsize;
if (ibqp->brdptr >= ibqp->btop) {
ibqp->brdptr = ibqp->buffers;
}
/* Notifying the buffer release.*/
if (ibqp->notify != NULL) {
ibqp->notify(ibqp);
}
}
/**
* @brief Input queue read with timeout.
* @details This function reads a byte value from an input queue. If
@ -144,7 +191,29 @@ void ibqPostBufferI(io_buffers_queue_t *ibqp, size_t size) {
* @api
*/
msg_t ibqGetTimeout(input_buffers_queue_t *ibqp, systime_t timeout) {
msg_t msg;
/* This condition indicates that a new buffer must be acquired.*/
while (ibqp->ptr == NULL) {
msg = osalThreadEnqueueTimeoutS(&ibqp->waiting, timeout);
if (msg < MSG_OK) {
return msg;
}
ibqp->ptr = ibqGetFullBufferI(ibqp);
}
/* Next byte from the buffer.*/
msg = *ibqp->ptr;
ibqp->ptr++;
/* If the current buffer has been fully read then it is returned as
empty in the queue.*/
if (ibqp->ptr == ibqp->top) {
ibqReleaseBufferI(ibqp);
ibqp->ptr = NULL;
}
return msg;
}
/**