aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src/hal_buffers.c
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-12-20 10:25:41 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-12-20 10:25:41 +0000
commita952f3cfafaf147df144cd37cc017ed46aac9c6b (patch)
tree334a771e422fc57844fc78bc5e1d9a518fd111e3 /os/hal/src/hal_buffers.c
parentddcc89f8d136acd94bba873c2e851a5d2f50e67c (diff)
downloadChibiOS-a952f3cfafaf147df144cd37cc017ed46aac9c6b.tar.gz
ChibiOS-a952f3cfafaf147df144cd37cc017ed46aac9c6b.tar.bz2
ChibiOS-a952f3cfafaf147df144cd37cc017ed46aac9c6b.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8620 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src/hal_buffers.c')
-rw-r--r--os/hal/src/hal_buffers.c79
1 files changed, 74 insertions, 5 deletions
diff --git a/os/hal/src/hal_buffers.c b/os/hal/src/hal_buffers.c
index f6a3e9319..286f3cf50 100644
--- a/os/hal/src/hal_buffers.c
+++ b/os/hal/src/hal_buffers.c
@@ -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;
@@ -124,6 +125,52 @@ void ibqPostBufferI(io_buffers_queue_t *ibqp, size_t size) {
}
/**
+ * @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
* the queue is empty then the calling thread is suspended until a
@@ -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;
}
/**