aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-12-20 09:45:43 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-12-20 09:45:43 +0000
commitddcc89f8d136acd94bba873c2e851a5d2f50e67c (patch)
tree30496a1ecea8aa3532b53794b43e78edbe949e71 /os/hal
parentf6616d570865fce92ae7a669611e495038e9c111 (diff)
downloadChibiOS-ddcc89f8d136acd94bba873c2e851a5d2f50e67c.tar.gz
ChibiOS-ddcc89f8d136acd94bba873c2e851a5d2f50e67c.tar.bz2
ChibiOS-ddcc89f8d136acd94bba873c2e851a5d2f50e67c.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8619 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal')
-rw-r--r--os/hal/include/hal_buffers.h129
-rw-r--r--os/hal/include/hal_queues.h38
-rw-r--r--os/hal/src/hal_buffers.c141
3 files changed, 221 insertions, 87 deletions
diff --git a/os/hal/include/hal_buffers.h b/os/hal/include/hal_buffers.h
index 02f21f5cd..0acf9ebd9 100644
--- a/os/hal/include/hal_buffers.h
+++ b/os/hal/include/hal_buffers.h
@@ -29,8 +29,6 @@
/* Driver constants. */
/*===========================================================================*/
-#define HAL_BUFFERS_QUEUE_SIZE 2
-
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -44,44 +42,21 @@
/*===========================================================================*/
/**
- * @brief Type of an I/O buffer.
- */
-typedef struct hal_buffer io_buffer_t;
-
-/**
- * @brief Structure of a generic buffer.
- */
-struct hal_buffer {
- /**
- * @brief Pointer to the buffer in memory.
- */
- uint8_t *buffer;
- /**
- * @brief Pointer to the first non-used location in the buffer.
- */
- uint8_t *limit;
- /**
- * @brief Pointer to the buffer boundary.
- */
- uint8_t *top;
-};
-
-/**
- * @brief Type of a generic double buffer.
+ * @brief Type of a generic queue of buffers.
*/
-typedef struct io_double_buffer io_double_buffer_t;
+typedef struct io_buffers_queue io_buffers_queue_t;
/**
* @brief Double buffer notification callback type.
*
- * @param[in] iodbp the double buffer pointer
+ * @param[in] iodbp the buffers queue pointer
*/
-typedef void (*dbnotify_t)(io_double_buffer_t *iodbp);
+typedef void (*dbnotify_t)(io_buffers_queue_t *bqp);
/**
- * @brief Structure of a generic double buffer.
+ * @brief Structure of a generic buffers queue.
*/
-struct io_double_buffer {
+struct io_buffers_queue {
/**
* @brief Queue of waiting threads.
*/
@@ -89,23 +64,38 @@ struct io_double_buffer {
/**
* @brief Active buffers counter.
*/
- volatile size_t counter;
+ volatile size_t bcounter;
/**
* @brief Buffer write pointer.
*/
- io_buffer_t *bwrptr;
+ uint8_t *bwrptr;
/**
* @brief Buffer read pointer.
*/
- io_buffer_t *brdptr;
+ uint8_t *brdptr;
/**
- * @brief Pointer for R/W sequential access.
+ * @brief Pointer to the buffers boundary.
*/
- uint8_t *ptr;
+ uint8_t *btop;
+ /**
+ * @brief Size of buffers.
+ * @note The buffer size must be not lower than <tt>sizeof(size_t) + 2</tt>
+ * because the first bytes are used to store the used size of the
+ * buffer.
+ */
+ size_t bsize;
+ /**
+ * @brief Number of buffers.
+ */
+ size_t bn;
/**
* @brief Queue of buffer objects.
*/
- io_buffer_t buffers[HAL_BUFFERS_QUEUE_SIZE];
+ uint8_t *buffers;
+ /**
+ * @brief Pointer for R/W sequential access.
+ */
+ uint8_t *ptr;
/**
* @brief Data notification callback.
*/
@@ -117,19 +107,71 @@ struct io_double_buffer {
};
/**
- * @brief Type of an input double buffer.
+ * @brief Type of an input buffers queue.
*/
-typedef io_double_buffer_t input_double_buffer_t;
+typedef io_buffers_queue_t input_buffers_queue_t;
/**
- * @brief Type of an output double buffer.
+ * @brief Type of an output buffers queue.
*/
-typedef io_double_buffer_t output_double_buffer_t;
+typedef io_buffers_queue_t output_buffers_queue_t;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
+/**
+ * @name Macro Functions
+ * @{
+ */
+/**
+ * @brief Returns the queue's number of buffers.
+ *
+ * @param[in] bqp pointer to an @p io_buffers_queue_t structure
+ * @return The number of buffers.
+ *
+ * @xclass
+ */
+#define bqSizeX(bqp) ((bqp)->bn)
+
+/**
+ * @brief Return the ready buffers number.
+ * @details Returns the number of filled buffers if used on an input queue
+ * or the number of empty buffers if used on an output queue.
+ *
+ * @param[in] bqp pointer to an @p io_buffers_queue_t structure
+ * @return The number of ready buffers.
+ *
+ * @iclass
+ */
+#define bqSpaceI(bqp) ((bqp)->bcounter)
+
+/**
+ * @brief Evaluates to @p TRUE if the specified input buffered queue is empty.
+ *
+ * @param[in] ibqp pointer to an @p input_buffers_queue_t structure
+ * @return The queue status.
+ * @retval false if the queue is not empty.
+ * @retval true if the queue is empty.
+ *
+ * @iclass
+ */
+#define iqbIsEmptyI(ibqp) ((bool)(bqSpaceI(ibqp) == 0U))
+
+/**
+ * @brief Evaluates to @p TRUE if the specified input buffered queue is full.
+ *
+ * @param[in] ibqp pointer to an @p input_buffers_queue_t structure
+ * @return The queue status.
+ * @retval false if the queue is not full.
+ * @retval true if the queue is full.
+ *
+ * @iclass
+ */
+#define ibqIsFullI(ibqp) ((bool)(((ibqp)->bwrptr == (ibqp)->brdptr) && \
+ ((ibqp)->bcounter != 0U)))
+/** @} */
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@@ -137,9 +179,8 @@ typedef io_double_buffer_t output_double_buffer_t;
#ifdef __cplusplus
extern "C" {
#endif
- void iobInit(io_buffer_t *iobp, uint8_t *bp, size_t size);
- void idbObjectInit(input_double_buffer_t *idbp,
- uint8_t *b1p, uint8_t *b2p, size_t size,
+ void ibqObjectInit(io_buffers_queue_t *ibqp, uint8_t *bp,
+ size_t size, size_t n,
dbnotify_t infy, void *link);
#ifdef __cplusplus
}
diff --git a/os/hal/include/hal_queues.h b/os/hal/include/hal_queues.h
index da76aac8f..a2149f9fe 100644
--- a/os/hal/include/hal_queues.h
+++ b/os/hal/include/hal_queues.h
@@ -80,7 +80,7 @@ struct io_queue {
/**
* @brief Returns the queue's buffer size.
*
- * @param[in] qp pointer to a @p io_queue_t structure.
+ * @param[in] qp pointer to a @p io_queue_t structure
* @return The buffer size.
*
* @xclass
@@ -95,7 +95,7 @@ struct io_queue {
* @details Returns the used space if used on an input queue or the empty
* space if used on an output queue.
*
- * @param[in] qp pointer to a @p io_queue_t structure.
+ * @param[in] qp pointer to a @p io_queue_t structure
* @return The buffer space.
*
* @iclass
@@ -106,7 +106,7 @@ struct io_queue {
* @brief Returns the queue application-defined link.
* @note This function can be called in any context.
*
- * @param[in] qp pointer to a @p io_queue_t structure.
+ * @param[in] qp pointer to a @p io_queue_t structure
* @return The application-defined link.
*
* @special
@@ -153,24 +153,24 @@ typedef io_queue_t input_queue_t;
#define iqGetEmptyI(iqp) (qSizeX(iqp) - qSpaceI(iqp))
/**
- * @brief Evaluates to @p TRUE if the specified input queue is empty.
+ * @brief Evaluates to @p true if the specified input queue is empty.
*
- * @param[in] iqp pointer to an @p input_queue_t structure.
+ * @param[in] iqp pointer to an @p input_queue_t structure
* @return The queue status.
- * @retval FALSE if the queue is not empty.
- * @retval TRUE if the queue is empty.
+ * @retval false if the queue is not empty.
+ * @retval true if the queue is empty.
*
* @iclass
*/
#define iqIsEmptyI(iqp) ((bool)(qSpaceI(iqp) == 0U))
/**
- * @brief Evaluates to @p TRUE if the specified input queue is full.
+ * @brief Evaluates to @p true if the specified input queue is full.
*
- * @param[in] iqp pointer to an @p input_queue_t structure.
+ * @param[in] iqp pointer to an @p input_queue_t structure
* @return The queue status.
- * @retval FALSE if the queue is not full.
- * @retval TRUE if the queue is full.
+ * @retval false if the queue is not full.
+ * @retval true if the queue is full.
*
* @iclass
*/
@@ -267,12 +267,12 @@ typedef io_queue_t output_queue_t;
#define oqGetEmptyI(oqp) qSpaceI(oqp)
/**
- * @brief Evaluates to @p TRUE if the specified output queue is empty.
+ * @brief Evaluates to @p true if the specified output queue is empty.
*
- * @param[in] oqp pointer to an @p output_queue_t structure.
+ * @param[in] oqp pointer to an @p output_queue_t structure
* @return The queue status.
- * @retval FALSE if the queue is not empty.
- * @retval TRUE if the queue is empty.
+ * @retval false if the queue is not empty.
+ * @retval true if the queue is empty.
*
* @iclass
*/
@@ -280,12 +280,12 @@ typedef io_queue_t output_queue_t;
((oqp)->q_counter != 0U)))
/**
- * @brief Evaluates to @p TRUE if the specified output queue is full.
+ * @brief Evaluates to @p true if the specified output queue is full.
*
- * @param[in] oqp pointer to an @p output_queue_t structure.
+ * @param[in] oqp pointer to an @p output_queue_t structure
* @return The queue status.
- * @retval FALSE if the queue is not full.
- * @retval TRUE if the queue is full.
+ * @retval false if the queue is not full.
+ * @retval true if the queue is full.
*
* @iclass
*/
diff --git a/os/hal/src/hal_buffers.c b/os/hal/src/hal_buffers.c
index 62d1dbbb4..f6a3e9319 100644
--- a/os/hal/src/hal_buffers.c
+++ b/os/hal/src/hal_buffers.c
@@ -45,42 +45,135 @@
/*===========================================================================*/
/**
- * @brief Initializes an I/O buffer object.
+ * @brief Initializes an input double buffer object.
*
- * @param[out] iobp pointer to the @p input_double_buffer_t object
- * @param[in] bp pointer to a memory area allocated as buffer
- * @param[in] size size of the buffers
+ * @param[out] ibqp pointer to the @p io_buffers_queue_t object
+ * @param[in] bp pointer to a memory area allocated for buffers
+ * @param[in] size buffer size, including the size field which is the
+ * size of a @p size_t
+ * @param[in] n number of buffers
+ * @param[in] infy callback called when a buffer is returned to the queue
+ * @param[in] link application defined pointer
*
* @init
*/
-void iobInit(io_buffer_t *iobp, uint8_t *bp, size_t size) {
+void ibqObjectInit(input_buffers_queue_t *ibqp, uint8_t *bp,
+ size_t size, size_t n,
+ dbnotify_t infy, void *link) {
- iobp->buffer = bp;
- iobp->limit = bp;
- iobp->top = bp + size;
+ osalDbgCheck((ibqp != NULL) && (bp != NULL) && (size >= sizeof(size_t) + 2));
+
+ ibqp->bcounter = 0;
+ ibqp->brdptr = bp;
+ ibqp->bwrptr = bp;
+ ibqp->btop = bp + (size * n); /* Pre-calculated for speed.*/
+ ibqp->bsize = size;
+ ibqp->bn = n;
+ ibqp->buffers = bp;
+ ibqp->ptr = NULL;
+ ibqp->notify = infy;
+ ibqp->link = link;
}
/**
- * @brief Initializes an input double buffer object.
+ * @brief Gets a buffer for posting in the queue.
+ * @note The function always returns the same buffer if called repeatedly.
*
- * @param[out] idbp pointer to the @p input_double_buffer_t object
- * @param[in] b1p pointer to a memory area allocated as buffer 1
- * @param[in] b2p pointer to a memory area allocated as buffer 2
- * @param[in] size size of the buffers
+ * @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 full.
*
- * @init
+ * @iclass
*/
-void idbObjectInit(input_double_buffer_t *idbp,
- uint8_t *b1p, uint8_t *b2p, size_t size,
- dbnotify_t infy, void *link) {
+uint8_t *ibqGetNextBufferI(input_buffers_queue_t *ibqp) {
+
+ osalDbgCheckClassI();
+
+ if (ibqIsFullI(ibqp)) {
+ return NULL;
+ }
+
+ return ibqp->bwrptr + sizeof (size_t);
+}
+
+/**
+ * @brief Posts a buffer in the queue.
+ *
+ * @param[out] ibqp pointer to the @p input_buffers_queue_t object
+ * @param[in] size used size of the buffer
+ *
+ * @iclass
+ */
+void ibqPostBufferI(io_buffers_queue_t *ibqp, size_t size) {
+
+ osalDbgCheckClassI();
+ osalDbgAssert(!ibqIsFullI(ibqp), "buffered queue full");
+
+ /* Writing size field in the buffer.*/
+ *((size_t *)ibqp->bwrptr) = size;
+
+ /* Posting the buffer in the queue.*/
+ ibqp->bcounter++;
+ ibqp->bwrptr += ibqp->bsize;
+ if (ibqp->bwrptr >= ibqp->btop) {
+ ibqp->bwrptr = ibqp->buffers;
+ }
+
+ /* Waking up one waiting thread, if any.*/
+ osalThreadDequeueNextI(&ibqp->waiting, MSG_OK);
+}
+
+/**
+ * @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
+ * new buffer arrives in the queue or a timeout occurs.
+ * @note The callback is invoked before reading the character from the
+ * buffer or before entering the suspended state.
+ *
+ * @param[in] ibqp pointer to the @p input_buffers_queue_t object
+ * @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 A byte value from the queue.
+ * @retval MSG_TIMEOUT if the specified time expired.
+ * @retval MSG_RESET if the queue has been reset.
+ *
+ * @api
+ */
+msg_t ibqGetTimeout(input_buffers_queue_t *ibqp, systime_t timeout) {
+
+}
+
+/**
+ * @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 callback is invoked before reading each character from the
+ * buffer or before entering the state @p THD_STATE_WTQUEUE.
+ *
+ * @param[in] ibqp pointer to the @p input_buffers_queue_t object
+ * @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] 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 ibqReadTimeout(input_buffers_queue_t *ibqp, uint8_t *bp,
+ size_t n, systime_t timeout) {
- iobInit(&idbp->buffers[0], b1p, size);
- iobInit(&idbp->buffers[1], b2p, size);
- idbp->counter = 0;
- idbp->brdptr = &idbp->buffers[0];
- idbp->bwrptr = &idbp->buffers[0];
- idbp->notify = infy;
- idbp->link = link;
}
/** @} */