git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8619 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
f6616d5708
commit
ddcc89f8d1
|
@ -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.
|
||||
* @brief Type of a generic queue of buffers.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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 to the buffers boundary.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
uint8_t *buffers;
|
||||
/**
|
||||
* @brief Pointer for R/W sequential access.
|
||||
*/
|
||||
uint8_t *ptr;
|
||||
/**
|
||||
* @brief Queue of buffer objects.
|
||||
*/
|
||||
io_buffer_t buffers[HAL_BUFFERS_QUEUE_SIZE];
|
||||
/**
|
||||
* @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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -195,7 +195,7 @@ typedef io_queue_t output_queue_t;
|
|||
/**
|
||||
* @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
|
||||
|
@ -210,7 +210,7 @@ typedef io_queue_t output_queue_t;
|
|||
* @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
|
||||
|
@ -220,7 +220,7 @@ typedef io_queue_t output_queue_t;
|
|||
/**
|
||||
* @brief Returns the queue application-defined link.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @xclass
|
||||
|
@ -293,7 +293,7 @@ static inline size_t chIQGetEmptyI(input_queue_t *iqp) {
|
|||
/**
|
||||
* @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.
|
||||
|
@ -310,7 +310,7 @@ static inline bool chIQIsEmptyI(input_queue_t *iqp) {
|
|||
/**
|
||||
* @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.
|
||||
|
@ -376,7 +376,7 @@ static inline size_t chOQGetEmptyI(output_queue_t *oqp) {
|
|||
/**
|
||||
* @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.
|
||||
|
@ -393,7 +393,7 @@ static inline bool chOQIsEmptyI(output_queue_t *oqp) {
|
|||
/**
|
||||
* @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.
|
||||
|
|
Loading…
Reference in New Issue