aboutsummaryrefslogtreecommitdiffstats
path: root/os/lib
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2018-09-26 11:53:05 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2018-09-26 11:53:05 +0000
commit687ea96f1528fbe47f447e2c3622ba0b65b70a5d (patch)
tree1c8dcb20368a1164b6a9f7d6950fc4c93347b318 /os/lib
parent5111601c13e6a1151dfd39a02a48d7fd0efd68cd (diff)
downloadChibiOS-687ea96f1528fbe47f447e2c3622ba0b65b70a5d.tar.gz
ChibiOS-687ea96f1528fbe47f447e2c3622ba0b65b70a5d.tar.bz2
ChibiOS-687ea96f1528fbe47f447e2c3622ba0b65b70a5d.zip
Added pipes to OSLIB.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12295 110e8d01-0319-4d1e-a829-52ad28d1bb01
Diffstat (limited to 'os/lib')
-rw-r--r--os/lib/include/chlib.h119
-rw-r--r--os/lib/include/chpipes.h30
-rw-r--r--os/lib/lib.mk4
-rw-r--r--os/lib/src/chpipes.c168
4 files changed, 235 insertions, 86 deletions
diff --git a/os/lib/include/chlib.h b/os/lib/include/chlib.h
index 02f50e9c2..ab55d333b 100644
--- a/os/lib/include/chlib.h
+++ b/os/lib/include/chlib.h
@@ -83,6 +83,61 @@
#error "OS check failed, must be included after ch.h"
#endif
+/* Configuration file checks.*/
+#if !defined(CH_CFG_USE_MAILBOXES)
+#error "CH_CFG_USE_MAILBOXES not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_USE_MEMCORE)
+#error "CH_CFG_USE_MEMCORE not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_USE_HEAP)
+#error "CH_CFG_USE_HEAP not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_USE_MEMPOOLS)
+#error "CH_CFG_USE_MEMPOOLS not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_USE_OBJ_FIFOS)
+#error "CH_CFG_USE_OBJ_FIFOS not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_USE_PIPES)
+//#error "CH_CFG_USE_PIPES not defined in chconf.h"
+#define CH_CFG_USE_PIPES FALSE /* temporary */
+#endif
+
+/* Objects factory options checks.*/
+#if !defined(CH_CFG_USE_FACTORY)
+#error "CH_CFG_USE_FACTORY not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
+#error "CH_CFG_FACTORY_MAX_NAMES_LENGTH not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
+#error "CH_CFG_FACTORY_OBJECTS_REGISTRY not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
+#error "CH_CFG_FACTORY_GENERIC_BUFFERS not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_FACTORY_SEMAPHORES)
+#error "CH_CFG_FACTORY_SEMAPHORES not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_FACTORY_MAILBOXES)
+#error "CH_CFG_FACTORY_MAILBOXES not defined in chconf.h"
+#endif
+
+#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
+#error "CH_CFG_FACTORY_OBJ_FIFOS not defined in chconf.h"
+#endif
+
/* License checks.*/
#if !defined(CH_CUSTOMER_LIC_LIB) || !defined(CH_LICENSE_FEATURES)
#error "malformed chlicense.h"
@@ -108,7 +163,7 @@
#define CH_CFG_USE_FACTORY FALSE
-#endif /* (CH_CUSTOMER_LIC_LIB == FALSE) || \
+#endif /* (CH_CUSTOMER_LIC_LIB == FALSE) ||
(CH_LICENSE_FEATURES == CH_FEATURES_INTERMEDIATE) ||
(CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */
@@ -129,67 +184,9 @@
#define CH_CFG_USE_OBJ_FIFOS FALSE
#define CH_CFG_USE_PIPES FALSE
-#endif /* (CH_CUSTOMER_LIC_LIB == FALSE) || \
+#endif /* (CH_CUSTOMER_LIC_LIB == FALSE) ||
(CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */
-/* Configuration file checks.*/
-#if !defined(CH_CFG_USE_SEMAPHORES)
-#error "CH_CFG_USE_SEMAPHORES not defined in chconf.h"
-#endif
-
-#if !defined(CH_CFG_USE_MAILBOXES)
-#error "CH_CFG_USE_MAILBOXES not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_USE_MEMCORE)
-#error "CH_CFG_USE_MEMCORE not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_USE_HEAP)
-#error "CH_CFG_USE_HEAP not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_USE_MEMPOOLS)
-#error "CH_CFG_USE_MEMPOOLS not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_USE_OBJ_FIFOS)
-#error "CH_CFG_USE_OBJ_FIFOS not defined in chlibconf.h"
-#endif
-
-//#if !defined(CH_CFG_USE_PIPES)
-//#error "CH_CFG_USE_PIPES not defined in chlibconf.h"
-//#endif
-
-/* Objects factory options checks.*/
-#if !defined(CH_CFG_USE_FACTORY)
-#error "CH_CFG_USE_FACTORY not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
-#error "CH_CFG_FACTORY_MAX_NAMES_LENGTH not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
-#error "CH_CFG_FACTORY_OBJECTS_REGISTRY not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
-#error "CH_CFG_FACTORY_GENERIC_BUFFERS not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_FACTORY_SEMAPHORES)
-#error "CH_CFG_FACTORY_SEMAPHORES not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_FACTORY_MAILBOXES)
-#error "CH_CFG_FACTORY_MAILBOXES not defined in chlibconf.h"
-#endif
-
-#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
-#error "CH_CFG_FACTORY_OBJ_FIFOS not defined in chlibconf.h"
-#endif
-
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
@@ -213,7 +210,7 @@
#include "chmemheaps.h"
#include "chmempools.h"
#include "chobjfifos.h"
-//#include "chpipes.h"
+#include "chpipes.h"
#include "chfactory.h"
#endif /* CHLIB_H */
diff --git a/os/lib/include/chpipes.h b/os/lib/include/chpipes.h
index c66c48d68..a09b3c72a 100644
--- a/os/lib/include/chpipes.h
+++ b/os/lib/include/chpipes.h
@@ -56,7 +56,7 @@ typedef struct {
after the buffer. */
uint8_t *wrptr; /**< @brief Write pointer. */
uint8_t *rdptr; /**< @brief Read pointer. */
- size_t cnt; /**< @brief Messages in queue. */
+ size_t cnt; /**< @brief Bytes in the pipe. */
bool reset; /**< @brief True if in reset state. */
threads_queue_t qw; /**< @brief Queued writers. */
threads_queue_t qr; /**< @brief Queued readers. */
@@ -145,9 +145,9 @@ extern "C" {
* @param[in] pp the pointer to an initialized @p pipe_t object
* @return The size of the pipe.
*
- * @iclass
+ * @api
*/
-static inline size_t chPipeGetSizeI(const pipe_t *pp) {
+static inline size_t chPipeGetSize(const pipe_t *pp) {
/*lint -save -e9033 [10.8] Perfectly safe pointers
arithmetic.*/
@@ -161,11 +161,9 @@ static inline size_t chPipeGetSizeI(const pipe_t *pp) {
* @param[in] pp the pointer to an initialized @p pipe_t object
* @return The number of queued bytes.
*
- * @iclass
+ * @api
*/
-static inline size_t chPipeGetUsedCountI(const pipe_t *pp) {
-
- chDbgCheckClassI();
+static inline size_t chPipeGetUsedCount(const pipe_t *pp) {
return pp->cnt;
}
@@ -176,13 +174,11 @@ static inline size_t chPipeGetUsedCountI(const pipe_t *pp) {
* @param[in] pp the pointer to an initialized @p pipe_t object
* @return The number of empty byte slots.
*
- * @iclass
+ * @api
*/
-static inline size_t chPipeGetFreeCountI(const pipe_t *pp) {
-
- chDbgCheckClassI();
+static inline size_t chPipeGetFreeCount(const pipe_t *pp) {
- return chPipeGetSizeI(pp) - chPipeGetUsedCountI(pp);
+ return chPipeGetSize(pp) - chPipeGetUsedCount(pp);
}
/**
@@ -195,11 +191,9 @@ static inline size_t chPipeGetFreeCountI(const pipe_t *pp) {
* @param[in] pp the pointer to an initialized @p pipe_t object
* @return The next byte in queue.
*
- * @iclass
+ * @api
*/
-static inline uint8_t chPipePeekI(const pipe_t *pp) {
-
- chDbgCheckClassI();
+static inline uint8_t chPipePeek(const pipe_t *pp) {
return *pp->rdptr;
}
@@ -209,9 +203,9 @@ static inline uint8_t chPipePeekI(const pipe_t *pp) {
*
* @param[in] pp the pointer to an initialized @p pipe_t object
*
- * @xclass
+ * @api
*/
-static inline void chPipeResumeX(pipe_t *pp) {
+static inline void chPipeResume(pipe_t *pp) {
pp->reset = false;
}
diff --git a/os/lib/lib.mk b/os/lib/lib.mk
index c84dd322f..0f42055d6 100644
--- a/os/lib/lib.mk
+++ b/os/lib/lib.mk
@@ -22,6 +22,9 @@ endif
ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHLIBCONF)),)
LIBSRC += $(CHIBIOS)/os/lib/src/chmempools.c
endif
+ifneq ($(findstring CH_CFG_USE_PIPES TRUE,$(CHLIBCONF)),)
+LIBSRC += $(CHIBIOS)/os/lib/src/chpipes.c
+endif
ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHLIBCONF)),)
LIBSRC += $(CHIBIOS)/os/lib/src/chfactory.c
endif
@@ -30,6 +33,7 @@ LIBSRC := $(CHIBIOS)/os/lib/src/chmboxes.c \
$(CHIBIOS)/os/lib/src/chmemcore.c \
$(CHIBIOS)/os/lib/src/chmemheaps.c \
$(CHIBIOS)/os/lib/src/chmempools.c \
+ $(CHIBIOS)/os/lib/src/chmpipes.c \
$(CHIBIOS)/os/lib/src/chfactory.c
endif
diff --git a/os/lib/src/chpipes.c b/os/lib/src/chpipes.c
index 65df6d530..34c8870fb 100644
--- a/os/lib/src/chpipes.c
+++ b/os/lib/src/chpipes.c
@@ -37,6 +37,8 @@
* @{
*/
+#include <string.h>
+
#include "ch.h"
#if (CH_CFG_USE_PIPES == TRUE) || defined(__DOXYGEN__)
@@ -72,6 +74,98 @@
/* Module local functions. */
/*===========================================================================*/
+/**
+ * @brief Non-blocking pipe write.
+ * @details The function writes data from a buffer to a pipe. The
+ * operation completes when the specified amount of data has been
+ * transferred or when the pipe buffer has been filled.
+ *
+ * @param[in] pp the pointer to an initialized @p pipe_t object
+ * @param[in] bp pointer to the data buffer
+ * @param[in] n the maximum amount of data to be transferred, the
+ * value 0 is reserved
+ * @return The number of bytes effectively transferred.
+ *
+ * @notapi
+ */
+static size_t pipe_write(pipe_t *pp, const uint8_t *bp, size_t n) {
+ size_t s1, s2;
+
+ /* Number of bytes that can be written in a single atomic operation.*/
+ if (n > chPipeGetFreeCount(pp)) {
+ n = chPipeGetFreeCount(pp);
+ }
+
+ /* Number of bytes before buffer limit.*/
+ /*lint -save -e9033 [10.8] Checked to be safe.*/
+ s1 = (size_t)(pp->top - pp->wrptr);
+ /*lint -restore*/
+ if (n < s1) {
+ memcpy((void *)pp->wrptr, (const void *)bp, n);
+ pp->wrptr += n;
+ }
+ else if (n > s1) {
+ memcpy((void *)pp->wrptr, (const void *)bp, s1);
+ bp += s1;
+ s2 = n - s1;
+ memcpy((void *)pp->buffer, (const void *)bp, s2);
+ pp->wrptr = pp->buffer + s2;
+ }
+ else { /* n == s1 */
+ memcpy((void *)pp->wrptr, (const void *)bp, n);
+ pp->wrptr = pp->buffer;
+ }
+
+ pp->cnt += n;
+ return n;
+}
+
+/**
+ * @brief Non-blocking pipe read.
+ * @details The function reads data from a pipe into a buffer. The
+ * operation completes when the specified amount of data has been
+ * transferred or when the pipe buffer has been emptied.
+ *
+ * @param[in] pp the pointer to an initialized @p pipe_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
+ * @return The number of bytes effectively transferred.
+ *
+ * @notapi
+ */
+static size_t pipe_read(pipe_t *pp, uint8_t *bp, size_t n) {
+ size_t s1, s2;
+
+ /* Number of bytes that can be read in a single atomic operation.*/
+ if (n > chPipeGetFreeCount(pp)) {
+ n = chPipeGetFreeCount(pp);
+ }
+
+ /* Number of bytes before buffer limit.*/
+ /*lint -save -e9033 [10.8] Checked to be safe.*/
+ s1 = (size_t)(pp->top - pp->rdptr);
+ /*lint -restore*/
+ if (n < s1) {
+ memcpy((void *)bp, (void *)pp->rdptr, n);
+ pp->rdptr += n;
+ }
+ else if (n > s1) {
+ memcpy((void *)bp, (void *)pp->rdptr, s1);
+ bp += s1;
+ s2 = n - s1;
+ memcpy((void *)bp, (void *)pp->buffer, s2);
+ pp->rdptr = pp->buffer + s2;
+ }
+ else { /* n == s1 */
+ memcpy((void *)bp, (void *)pp->rdptr, n);
+ pp->rdptr = pp->buffer;
+ }
+
+ pp->cnt -= n;
+ return n;
+}
+
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
@@ -118,15 +212,15 @@ void chPipeReset(pipe_t *pp) {
P_LOCK(pp);
chSysLock();
- pipe_t->wrptr = pipe_t->buffer;
- pipe_t->rdptr = pipe_t->buffer;
- pipe_t->cnt = (size_t)0;
- pipe_t->reset = true;
- chThdDequeueAllI(&pipe_t->qw, MSG_RESET);
- chThdDequeueAllI(&pipe_t->qr, MSG_RESET);
+ pp->wrptr = pp->buffer;
+ pp->rdptr = pp->buffer;
+ pp->cnt = (size_t)0;
+ pp->reset = true;
+ chThdDequeueAllI(&pp->qw, MSG_RESET);
+ chThdDequeueAllI(&pp->qr, MSG_RESET);
chSchRescheduleS();
chSysUnlock();
- P_UNLOCK();
+ P_UNLOCK(pp);
}
/**
@@ -153,7 +247,37 @@ void chPipeReset(pipe_t *pp) {
*/
size_t chPipeWriteTimeout(pipe_t *pp, const uint8_t *bp,
size_t n, sysinterval_t timeout) {
+ size_t max = n;
+
+ chDbgCheck(n > 0U);
+
+ P_LOCK(pp);
+
+ while (n > 0U) {
+ size_t done;
+ done = pipe_write(pp, bp, n);
+ if (done == (size_t)0) {
+ msg_t msg;
+
+ chSysLock();
+ msg = chThdEnqueueTimeoutS(&pp->qw, timeout);
+ chSysUnlock();
+
+ /* Anything except MSG_OK causes the operation to stop.*/
+ if (msg != MSG_OK) {
+ break;
+ }
+ }
+ else {
+ n -= done;
+ bp += done;
+ }
+ }
+
+ P_UNLOCK(pp);
+
+ return max - n;
}
/**
@@ -180,7 +304,37 @@ size_t chPipeWriteTimeout(pipe_t *pp, const uint8_t *bp,
*/
size_t chPipeReadTimeout(pipe_t *pp, uint8_t *bp,
size_t n, sysinterval_t timeout) {
+ size_t max = n;
+
+ chDbgCheck(n > 0U);
+
+ P_LOCK(pp);
+
+ while (n > 0U) {
+ size_t done;
+
+ done = pipe_read(pp, bp, n);
+ if (done == (size_t)0) {
+ msg_t msg;
+
+ chSysLock();
+ msg = chThdEnqueueTimeoutS(&pp->qr, timeout);
+ chSysUnlock();
+
+ /* Anything except MSG_OK causes the operation to stop.*/
+ if (msg != MSG_OK) {
+ break;
+ }
+ }
+ else {
+ n -= done;
+ bp += done;
+ }
+ }
+
+ P_UNLOCK(pp);
+ return max - n;
}
#endif /* CH_CFG_USE_MAILBOXES == TRUE */