Added pipes to OSLIB.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12295 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
Giovanni Di Sirio 2018-09-26 11:53:05 +00:00
parent 5111601c13
commit 687ea96f15
5 changed files with 236 additions and 86 deletions

View File

@ -83,6 +83,61 @@
#error "OS check failed, must be included after ch.h" #error "OS check failed, must be included after ch.h"
#endif #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.*/ /* License checks.*/
#if !defined(CH_CUSTOMER_LIC_LIB) || !defined(CH_LICENSE_FEATURES) #if !defined(CH_CUSTOMER_LIC_LIB) || !defined(CH_LICENSE_FEATURES)
#error "malformed chlicense.h" #error "malformed chlicense.h"
@ -108,7 +163,7 @@
#define CH_CFG_USE_FACTORY FALSE #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_INTERMEDIATE) ||
(CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */ (CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */
@ -129,67 +184,9 @@
#define CH_CFG_USE_OBJ_FIFOS FALSE #define CH_CFG_USE_OBJ_FIFOS FALSE
#define CH_CFG_USE_PIPES 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) */ (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. */ /* Module data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
@ -213,7 +210,7 @@
#include "chmemheaps.h" #include "chmemheaps.h"
#include "chmempools.h" #include "chmempools.h"
#include "chobjfifos.h" #include "chobjfifos.h"
//#include "chpipes.h" #include "chpipes.h"
#include "chfactory.h" #include "chfactory.h"
#endif /* CHLIB_H */ #endif /* CHLIB_H */

View File

@ -56,7 +56,7 @@ typedef struct {
after the buffer. */ after the buffer. */
uint8_t *wrptr; /**< @brief Write pointer. */ uint8_t *wrptr; /**< @brief Write pointer. */
uint8_t *rdptr; /**< @brief Read 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. */ bool reset; /**< @brief True if in reset state. */
threads_queue_t qw; /**< @brief Queued writers. */ threads_queue_t qw; /**< @brief Queued writers. */
threads_queue_t qr; /**< @brief Queued readers. */ 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 * @param[in] pp the pointer to an initialized @p pipe_t object
* @return The size of the pipe. * @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 /*lint -save -e9033 [10.8] Perfectly safe pointers
arithmetic.*/ 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 * @param[in] pp the pointer to an initialized @p pipe_t object
* @return The number of queued bytes. * @return The number of queued bytes.
* *
* @iclass * @api
*/ */
static inline size_t chPipeGetUsedCountI(const pipe_t *pp) { static inline size_t chPipeGetUsedCount(const pipe_t *pp) {
chDbgCheckClassI();
return pp->cnt; 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 * @param[in] pp the pointer to an initialized @p pipe_t object
* @return The number of empty byte slots. * @return The number of empty byte slots.
* *
* @iclass * @api
*/ */
static inline size_t chPipeGetFreeCountI(const pipe_t *pp) { static inline size_t chPipeGetFreeCount(const pipe_t *pp) {
chDbgCheckClassI(); return chPipeGetSize(pp) - chPipeGetUsedCount(pp);
return chPipeGetSizeI(pp) - chPipeGetUsedCountI(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 * @param[in] pp the pointer to an initialized @p pipe_t object
* @return The next byte in queue. * @return The next byte in queue.
* *
* @iclass * @api
*/ */
static inline uint8_t chPipePeekI(const pipe_t *pp) { static inline uint8_t chPipePeek(const pipe_t *pp) {
chDbgCheckClassI();
return *pp->rdptr; 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 * @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; pp->reset = false;
} }

View File

@ -22,6 +22,9 @@ endif
ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHLIBCONF)),) ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHLIBCONF)),)
LIBSRC += $(CHIBIOS)/os/lib/src/chmempools.c LIBSRC += $(CHIBIOS)/os/lib/src/chmempools.c
endif 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)),) ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHLIBCONF)),)
LIBSRC += $(CHIBIOS)/os/lib/src/chfactory.c LIBSRC += $(CHIBIOS)/os/lib/src/chfactory.c
endif endif
@ -30,6 +33,7 @@ LIBSRC := $(CHIBIOS)/os/lib/src/chmboxes.c \
$(CHIBIOS)/os/lib/src/chmemcore.c \ $(CHIBIOS)/os/lib/src/chmemcore.c \
$(CHIBIOS)/os/lib/src/chmemheaps.c \ $(CHIBIOS)/os/lib/src/chmemheaps.c \
$(CHIBIOS)/os/lib/src/chmempools.c \ $(CHIBIOS)/os/lib/src/chmempools.c \
$(CHIBIOS)/os/lib/src/chmpipes.c \
$(CHIBIOS)/os/lib/src/chfactory.c $(CHIBIOS)/os/lib/src/chfactory.c
endif endif

View File

@ -37,6 +37,8 @@
* @{ * @{
*/ */
#include <string.h>
#include "ch.h" #include "ch.h"
#if (CH_CFG_USE_PIPES == TRUE) || defined(__DOXYGEN__) #if (CH_CFG_USE_PIPES == TRUE) || defined(__DOXYGEN__)
@ -72,6 +74,98 @@
/* Module local functions. */ /* 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. */ /* Module exported functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -118,15 +212,15 @@ void chPipeReset(pipe_t *pp) {
P_LOCK(pp); P_LOCK(pp);
chSysLock(); chSysLock();
pipe_t->wrptr = pipe_t->buffer; pp->wrptr = pp->buffer;
pipe_t->rdptr = pipe_t->buffer; pp->rdptr = pp->buffer;
pipe_t->cnt = (size_t)0; pp->cnt = (size_t)0;
pipe_t->reset = true; pp->reset = true;
chThdDequeueAllI(&pipe_t->qw, MSG_RESET); chThdDequeueAllI(&pp->qw, MSG_RESET);
chThdDequeueAllI(&pipe_t->qr, MSG_RESET); chThdDequeueAllI(&pp->qr, MSG_RESET);
chSchRescheduleS(); chSchRescheduleS();
chSysUnlock(); 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 chPipeWriteTimeout(pipe_t *pp, const uint8_t *bp,
size_t n, sysinterval_t timeout) { 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 chPipeReadTimeout(pipe_t *pp, uint8_t *bp,
size_t n, sysinterval_t timeout) { 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 */ #endif /* CH_CFG_USE_MAILBOXES == TRUE */

View File

@ -91,6 +91,7 @@
***************************************************************************** *****************************************************************************
*** Next *** *** Next ***
- NEW: Added a new "pipes" subsystem to the OS library.
- NEW: Added mcuconf.h generators for STM32L432xx, STM32L476xx, STM32L496xx - NEW: Added mcuconf.h generators for STM32L432xx, STM32L476xx, STM32L496xx
and STM32L4R5xx devices. and STM32L4R5xx devices.
- NEW: Added demo for STM32L496ZG-Nucleo144 and STM32L4R5ZI-Nucleo144 boards. - NEW: Added demo for STM32L496ZG-Nucleo144 and STM32L4R5ZI-Nucleo144 boards.