aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/kernel/include/chqueues.h17
-rw-r--r--os/kernel/src/chqueues.c44
-rw-r--r--readme.txt1
-rw-r--r--test/testqueues.c2
4 files changed, 52 insertions, 12 deletions
diff --git a/os/kernel/include/chqueues.h b/os/kernel/include/chqueues.h
index 1f4f3f25a..76a0b63a5 100644
--- a/os/kernel/include/chqueues.h
+++ b/os/kernel/include/chqueues.h
@@ -37,9 +37,6 @@
#error "CH_USE_QUEUES requires CH_USE_SEMAPHORES"
#endif
-/** @brief Queue notification callback type.*/
-typedef void (*qnotify_t)(void);
-
/** @brief Returned by the queue functions if the operation is successful.*/
#define Q_OK RDY_OK
/** @brief Returned by the queue functions if a timeout occurs.*/
@@ -53,6 +50,14 @@ typedef void (*qnotify_t)(void);
/**
* @brief Type of a generic I/O queue structure.
+ */
+typedef struct GenericQueue GenericQueue;
+
+/** @brief Queue notification callback type.*/
+typedef void (*qnotify_t)(GenericQueue *qp);
+
+/**
+ * @brief Generic I/O queue structure.
* @details This structure represents a generic Input or Output asymmetrical
* queue. The queue is asymmetrical because one end is meant to be
* accessed from a thread context, and thus can be blocking, the other
@@ -60,7 +65,7 @@ typedef void (*qnotify_t)(void);
* lock zone (see <b>I-Locked</b> and <b>S-Locked</b> states in
* @ref system_states) and is non-blocking.
*/
-typedef struct {
+struct GenericQueue {
uint8_t *q_buffer; /**< @brief Pointer to the queue buffer.*/
uint8_t *q_top; /**< @brief Pointer to the first location
after the buffer. */
@@ -68,7 +73,7 @@ typedef struct {
uint8_t *q_rdptr; /**< @brief Read pointer. */
Semaphore q_sem; /**< @brief Counter @p Semaphore. */
qnotify_t q_notify; /**< @brief Data notification callback. */
-} GenericQueue;
+};
/**
* @brief Returns the queue's buffer size.
@@ -266,6 +271,7 @@ typedef GenericQueue OutputQueue;
extern "C" {
#endif
void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy);
+ size_t chIQGetFullI(InputQueue *iqp);
void chIQResetI(InputQueue *iqp);
msg_t chIQPutI(InputQueue *iqp, uint8_t b);
msg_t chIQGetTimeout(InputQueue *iqp, systime_t time);
@@ -273,6 +279,7 @@ extern "C" {
size_t n, systime_t time);
void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy);
+ size_t chOQGetFullI(OutputQueue *oqp);
void chOQResetI(OutputQueue *oqp);
msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time);
msg_t chOQGetI(OutputQueue *oqp);
diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c
index 87a82acf2..4a195fa9b 100644
--- a/os/kernel/src/chqueues.c
+++ b/os/kernel/src/chqueues.c
@@ -70,6 +70,22 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) {
}
/**
+ * @brief Returns the filled space into an input queue.
+ *
+ * @param[in] iqp pointer to an @p InputQueue structure
+ *
+ * @iclass
+ */
+size_t chIQGetFullI(InputQueue *iqp) {
+ cnt_t cnt;
+
+ cnt = chQSpaceI(iqp);
+ if (cnt < 0)
+ return 0;
+ return (size_t)cnt;
+}
+
+/**
* @brief Resets an input queue.
* @details All the data in the input queue is erased and lost, any waiting
* thread is resumed with status @p Q_RESET.
@@ -136,7 +152,7 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) {
chSysLock();
if (iqp->q_notify)
- iqp->q_notify();
+ iqp->q_notify(iqp);
if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) {
chSysUnlock();
@@ -185,7 +201,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
while (TRUE) {
if (chIQIsEmptyI(iqp)) {
if (nfy)
- nfy();
+ nfy(iqp);
if ((chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK)) {
chSysUnlock();
return r;
@@ -201,7 +217,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp,
if (--n == 0) {
chSysLock();
if (nfy)
- nfy();
+ nfy(iqp);
chSysUnlock();
return r;
}
@@ -233,6 +249,22 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) {
}
/**
+ * @brief Returns the filled space into an output queue.
+ *
+ * @param[in] oqp pointer to an @p OutputQueue structure
+ *
+ * @iclass
+ */
+size_t chOQGetFullI(OutputQueue *oqp) {
+ cnt_t cnt;
+
+ cnt = chQSpaceI(oqp);
+ if (cnt < 0)
+ return chQSizeI(oqp);
+ return chQSizeI(oqp) - (size_t)cnt;
+}
+
+/**
* @brief Resets an output queue.
* @details All the data in the output queue is erased and lost, any waiting
* thread is resumed with status @p Q_RESET.
@@ -282,7 +314,7 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) {
oqp->q_wrptr = oqp->q_buffer;
if (oqp->q_notify)
- oqp->q_notify();
+ oqp->q_notify(oqp);
chSysUnlock();
return Q_OK;
@@ -346,7 +378,7 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
while (TRUE) {
if (chOQIsFullI(oqp)) {
if (nfy)
- nfy();
+ nfy(oqp);
if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) {
chSysUnlock();
return w;
@@ -362,7 +394,7 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp,
if (--n == 0) {
chSysLock();
if (nfy)
- nfy();
+ nfy(oqp);
chSysUnlock();
return w;
}
diff --git a/readme.txt b/readme.txt
index 548de2c07..bc5298062 100644
--- a/readme.txt
+++ b/readme.txt
@@ -75,6 +75,7 @@
multiple project files, the code is exactly the same.
- NEW: Added an USB clock configuration in the STM32 HAL driver (LD, MD, HD).
- NEW: New semaphore API chSemSetCounterI().
+- NEW: New queues APIs chIQGetFullI() and chOQGetFullI().
- CHANGE: Modified the ADC and CAN drivers to allow a NULL pointer for
the configuration structure if it is not required by the implementation.
- CHANGE: Modified the MMC_SPI driver to *require* a NULL as pointer to
diff --git a/test/testqueues.c b/test/testqueues.c
index 27f533142..8cd89fd0d 100644
--- a/test/testqueues.c
+++ b/test/testqueues.c
@@ -57,7 +57,7 @@
#define TEST_QUEUES_SIZE 4
-static void notify(void) {}
+static void notify(GenericQueue *qp) {}
/*
* Note, the static initializers are not really required because the