diff --git a/Makefile.dep b/Makefile.dep index 5e5872a9e7..50b222968a 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -405,6 +405,11 @@ ifneq (,$(filter isrpipe,$(USEMODULE))) USEMODULE += tsrb endif +ifneq (,$(filter isrpipe_read_timeout,$(USEMODULE))) + USEMODULE += isrpipe + USEMODULE += xtimer +endif + ifneq (,$(filter shell_commands,$(USEMODULE))) ifneq (,$(filter fib,$(USEMODULE))) USEMODULE += posix_inet diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index cdf6366c37..050617707e 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -34,6 +34,7 @@ ifneq (,$(filter at,$(USEMODULE))) USEMODULE += fmt USEMODULE += xtimer USEMODULE += isrpipe + USEMODULE += isrpipe_read_timeout endif ifneq (,$(filter at30tse75x,$(USEMODULE))) diff --git a/drivers/at/at.c b/drivers/at/at.c index 52646de19f..e784ef2002 100644 --- a/drivers/at/at.c +++ b/drivers/at/at.c @@ -12,6 +12,7 @@ #include "at.h" #include "fmt.h" #include "isrpipe.h" +#include "isrpipe/read_timeout.h" #include "periph/uart.h" #include "xtimer.h" diff --git a/sys/Makefile b/sys/Makefile index 5a7f2c340b..8fb54c382f 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -4,6 +4,9 @@ endif ifneq (,$(filter eepreg,$(USEMODULE))) DIRS += eepreg endif +ifneq (,$(filter isrpipe_read_timeout,$(USEMODULE))) + DIRS += isrpipe/read_timeout +endif ifneq (,$(filter posix_inet,$(USEMODULE))) DIRS += posix/inet endif diff --git a/sys/include/isrpipe.h b/sys/include/isrpipe.h index 056b98cc09..356eef82cc 100644 --- a/sys/include/isrpipe.h +++ b/sys/include/isrpipe.h @@ -75,40 +75,6 @@ int isrpipe_write_one(isrpipe_t *isrpipe, char c); */ int isrpipe_read(isrpipe_t *isrpipe, char *buf, size_t count); -/** - * @brief Read data from isrpipe (with timeout, blocking) - * - * Currently, the timeout parameter is applied on every underlying read, which - * might be *per single byte*. - * - * @note This function might return less than @p count bytes - * - * @param[in] isrpipe isrpipe object to operate on - * @param[in] buf buffer to write to - * @param[in] count number of bytes to read - * @param[in] timeout timeout in microseconds - * - * @returns number of bytes read - * @returns -ETIMEDOUT on timeout - */ -int isrpipe_read_timeout(isrpipe_t *isrpipe, char *buf, size_t count, uint32_t timeout); - -/** - * @brief Read data from isrpipe (with timeout, blocking, wait until all read) - * - * This function is like @ref isrpipe_read_timeout, but will only return on - * timeout or when @p count bytes have been received. - * - * @param[in] isrpipe isrpipe object to operate on - * @param[in] buf buffer to write to - * @param[in] count number of bytes to read - * @param[in] timeout timeout in microseconds - * - * @returns number of bytes read - * @returns -ETIMEDOUT on timeout - */ -int isrpipe_read_all_timeout(isrpipe_t *isrpipe, char *buf, size_t count, uint32_t timeout); - #ifdef __cplusplus } #endif diff --git a/sys/include/isrpipe/read_timeout.h b/sys/include/isrpipe/read_timeout.h new file mode 100644 index 0000000000..f37947f19a --- /dev/null +++ b/sys/include/isrpipe/read_timeout.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2016 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup isr_pipe_read_timeout Read timeouts with ISR pipe + * @ingroup isr_pipe + * @brief ISR -> userspace pipe with timeout + * + * @{ + * @file + * @brief isrpipe read timeout Interface + * + * @author Kaspar Schleiser + * + */ + +#ifndef ISRPIPE_READ_TIMEOUT_H +#define ISRPIPE_READ_TIMEOUT_H + +#include "isrpipe.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Read data from isrpipe (with timeout, blocking) + * + * Currently, the timeout parameter is applied on every underlying read, which + * might be *per single byte*. + * + * @note This function might return less than @p count bytes + * + * @param[in] isrpipe isrpipe object to operate on + * @param[in] buf buffer to write to + * @param[in] count number of bytes to read + * @param[in] timeout timeout in microseconds + * + * @returns number of bytes read + * @returns -ETIMEDOUT on timeout + */ +int isrpipe_read_timeout(isrpipe_t *isrpipe, char *buf, size_t count, uint32_t timeout); + +/** + * @brief Read data from isrpipe (with timeout, blocking, wait until all read) + * + * This function is like @ref isrpipe_read_timeout, but will only return on + * timeout or when @p count bytes have been received. + * + * @param[in] isrpipe isrpipe object to operate on + * @param[in] buf buffer to write to + * @param[in] count number of bytes to read + * @param[in] timeout timeout in microseconds + * + * @returns number of bytes read + * @returns -ETIMEDOUT on timeout + */ +int isrpipe_read_all_timeout(isrpipe_t *isrpipe, char *buf, size_t count, uint32_t timeout); + +#ifdef __cplusplus +} +#endif +/** @} */ +#endif /* ISRPIPE_READ_TIMEOUT_H */ diff --git a/sys/isrpipe/isrpipe.c b/sys/isrpipe/isrpipe.c index c9f6e1926a..2a9cf9e2f3 100644 --- a/sys/isrpipe/isrpipe.c +++ b/sys/isrpipe/isrpipe.c @@ -17,10 +17,7 @@ * @} */ -#include - #include "isrpipe.h" -#include "xtimer.h" void isrpipe_init(isrpipe_t *isrpipe, char *buf, size_t bufsize) { @@ -49,56 +46,3 @@ int isrpipe_read(isrpipe_t *isrpipe, char *buffer, size_t count) } return res; } - -typedef struct { - mutex_t *mutex; - int flag; -} _isrpipe_timeout_t; - -static void _cb(void *arg) -{ - _isrpipe_timeout_t *_timeout = (_isrpipe_timeout_t *) arg; - - _timeout->flag = 1; - mutex_unlock(_timeout->mutex); -} - -int isrpipe_read_timeout(isrpipe_t *isrpipe, char *buffer, size_t count, uint32_t timeout) -{ - int res; - - _isrpipe_timeout_t _timeout = { .mutex = &isrpipe->mutex, .flag = 0 }; - - xtimer_t timer = { .callback = _cb, .arg = &_timeout }; - - xtimer_set(&timer, timeout); - while (!(res = tsrb_get(&isrpipe->tsrb, buffer, count))) { - mutex_lock(&isrpipe->mutex); - if (_timeout.flag) { - res = -ETIMEDOUT; - break; - } - } - - xtimer_remove(&timer); - return res; -} - - -int isrpipe_read_all_timeout(isrpipe_t *isrpipe, char *buffer, size_t count, uint32_t timeout) -{ - char *pos = buffer; - - while (count) { - int res = isrpipe_read_timeout(isrpipe, pos, count, timeout); - if (res >= 0) { - count -= res; - pos += res; - } - else { - return res; - } - } - - return pos - buffer; -} diff --git a/sys/isrpipe/read_timeout/Makefile b/sys/isrpipe/read_timeout/Makefile new file mode 100644 index 0000000000..92dff564d3 --- /dev/null +++ b/sys/isrpipe/read_timeout/Makefile @@ -0,0 +1,3 @@ +MODULE = isrpipe_read_timeout + +include $(RIOTBASE)/Makefile.base diff --git a/sys/isrpipe/read_timeout/read_timeout.c b/sys/isrpipe/read_timeout/read_timeout.c new file mode 100644 index 0000000000..f2d2e7e2fa --- /dev/null +++ b/sys/isrpipe/read_timeout/read_timeout.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 Kaspar Schleiser + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup isr_pipe_read_timeout + * @{ + * @file + * @brief ISR -> userspace pipe with timeout implementation + * + * @author Kaspar Schleiser + * + * @} + */ + +#include + +#include "isrpipe/read_timeout.h" +#include "xtimer.h" + +typedef struct { + mutex_t *mutex; + int flag; +} _isrpipe_timeout_t; + +static void _cb(void *arg) +{ + _isrpipe_timeout_t *_timeout = (_isrpipe_timeout_t *) arg; + + _timeout->flag = 1; + mutex_unlock(_timeout->mutex); +} + +int isrpipe_read_timeout(isrpipe_t *isrpipe, char *buffer, size_t count, uint32_t timeout) +{ + int res; + + _isrpipe_timeout_t _timeout = { .mutex = &isrpipe->mutex, .flag = 0 }; + + xtimer_t timer = { .callback = _cb, .arg = &_timeout }; + + xtimer_set(&timer, timeout); + while (!(res = tsrb_get(&isrpipe->tsrb, buffer, count))) { + mutex_lock(&isrpipe->mutex); + if (_timeout.flag) { + res = -ETIMEDOUT; + break; + } + } + + xtimer_remove(&timer); + return res; +} + + +int isrpipe_read_all_timeout(isrpipe_t *isrpipe, char *buffer, size_t count, uint32_t timeout) +{ + char *pos = buffer; + + while (count) { + int res = isrpipe_read_timeout(isrpipe, pos, count, timeout); + if (res >= 0) { + count -= res; + pos += res; + } + else { + return res; + } + } + + return pos - buffer; +}