mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/stdio: add common stdio module
This commit is contained in:
parent
fcd734e10e
commit
c1162e4818
@ -537,6 +537,7 @@ PSEUDOMODULES += soft_uart_modecfg
|
||||
PSEUDOMODULES += stdin
|
||||
PSEUDOMODULES += stdio_available
|
||||
PSEUDOMODULES += stdio_cdc_acm
|
||||
PSEUDOMODULES += stdio_dispatch
|
||||
PSEUDOMODULES += stdio_ethos
|
||||
PSEUDOMODULES += stdio_nimble_debug
|
||||
PSEUDOMODULES += stdio_telnet
|
||||
|
@ -14,11 +14,29 @@ STDIO_MODULES = \
|
||||
stdio_usb_serial_jtag \
|
||||
#
|
||||
|
||||
STDIO_LEGACY_MODULES = \
|
||||
ethos_stdio \
|
||||
stdio_ethos \
|
||||
stdio_native # requires #19002 \
|
||||
#
|
||||
|
||||
# select stdio_uart if no other stdio module is slected
|
||||
ifeq (,$(filter $(STDIO_MODULES),$(USEMODULE)))
|
||||
USEMODULE += stdio_uart
|
||||
endif
|
||||
|
||||
ifeq (,$(filter $(STDIO_LEGACY_MODULES),$(USEMODULE)))
|
||||
USEMODULE += stdio
|
||||
endif
|
||||
|
||||
ifneq (,$(filter stdin,$(USEMODULE)))
|
||||
USEMODULE += isrpipe
|
||||
endif
|
||||
|
||||
ifneq (1, $(words $(filter $(STDIO_MODULES),$(USEMODULE))))
|
||||
USEMODULE += stdio_dispatch
|
||||
endif
|
||||
|
||||
ifneq (,$(filter stdio_cdc_acm,$(USEMODULE)))
|
||||
USEMODULE += usbus_cdc_acm
|
||||
USEMODULE += isrpipe
|
||||
|
@ -18,6 +18,7 @@
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*/
|
||||
|
||||
#ifndef STDIO_BASE_H
|
||||
@ -26,11 +27,64 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "modules.h"
|
||||
#include "isrpipe.h"
|
||||
#include "xfa.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef STDIO_RX_BUFSIZE
|
||||
/**
|
||||
* @brief Buffer size for STDIO
|
||||
*/
|
||||
#define STDIO_RX_BUFSIZE (64)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
STDIO_NULL, /**< dummy stdio */
|
||||
STDIO_UART, /**< stdio via UART */
|
||||
STDIO_RTT, /**< stdio via Segger RTT */
|
||||
STDIO_SEMIHOSTING, /**< stdio via Semihosting */
|
||||
STDIO_USBUS_CDC_ACM, /**< stdio via USB CDC ACM (usbus) */
|
||||
STDIO_TINYUSB_CDC_ACM, /**< tdio via USB CDC ACM (TinyUSB) */
|
||||
STDIO_ESP32_SERIAL_JTAG, /**< stdio via ESP32 debug Serial/JTAG */
|
||||
STDIO_NIMBLE, /**< stdio via BLE (NimBLE) */
|
||||
STDIO_UDP, /**< stdio via UDP */
|
||||
STDIO_TELNET, /**< stdio via telnet */
|
||||
STDIO_ETHOS, /**< stdio via ethos (mutiplex) */
|
||||
STDIO_SLIP, /*<< stdio via SLIP (mutiplex) */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief stdio provider struct
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Initialize and attach the stdio provider
|
||||
*/
|
||||
void (*open)(void);
|
||||
/**
|
||||
* @brief Detach the stdio provider
|
||||
*/
|
||||
void (*close)(void);
|
||||
/**
|
||||
* @brief Write @p len bytes from @p src into stdout
|
||||
*
|
||||
* @param[in] src buffer to read from
|
||||
* @param[in] len nr of bytes to write
|
||||
*
|
||||
* @return nr of bytes written
|
||||
* @return <0 on error
|
||||
*/
|
||||
ssize_t (*write)(const void *src, size_t len);
|
||||
} stdio_provider_t;
|
||||
|
||||
/**
|
||||
* @brief isrpipe for writing stdin input to
|
||||
*/
|
||||
extern isrpipe_t stdin_isrpipe;
|
||||
|
||||
/**
|
||||
* @brief initialize the module
|
||||
*/
|
||||
@ -60,7 +114,11 @@ int stdio_available(void);
|
||||
ssize_t stdio_read(void* buffer, size_t max_len);
|
||||
|
||||
/**
|
||||
* @brief write @p len bytes from @p buffer into uart
|
||||
* @brief write @p len bytes from @p buffer into STDOUT
|
||||
*
|
||||
* @note Depending on the stdio backend(s) used, not all bytes might
|
||||
* be written to stdout and accounted for if multiple backends are
|
||||
* active, as not all stdout backends will do a blocking write.
|
||||
*
|
||||
* @param[in] buffer buffer to read from
|
||||
* @param[in] len nr of bytes to write
|
||||
@ -70,6 +128,45 @@ ssize_t stdio_read(void* buffer, size_t max_len);
|
||||
*/
|
||||
ssize_t stdio_write(const void* buffer, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Disable stdio and detach stdio providers
|
||||
*/
|
||||
void stdio_close(void);
|
||||
|
||||
#if defined(MODULE_STDIO_DISPATCH) || DOXYGEN
|
||||
/**
|
||||
* @brief stdio implementation methods
|
||||
*
|
||||
* @param _type stdio provider type, for identification
|
||||
* @param _open attach / init function
|
||||
* @param _close close / disable function
|
||||
* @param _write write function
|
||||
*/
|
||||
#define STDIO_PROVIDER(_type, _open, _close, _write) \
|
||||
XFA_CONST(stdio_provider_xfa, 0) stdio_provider_t stdio_ ##_type = { \
|
||||
.open = _open, \
|
||||
.close = _close, \
|
||||
.write = _write, \
|
||||
};
|
||||
#else
|
||||
#define STDIO_PROVIDER(_type, _open, _close, _write) \
|
||||
void stdio_init(void) { \
|
||||
void (*f)(void) = _open; \
|
||||
if (f != NULL) { \
|
||||
f(); \
|
||||
} \
|
||||
} \
|
||||
void stdio_close(void) { \
|
||||
void (*f)(void) = _close; \
|
||||
if (f != NULL) { \
|
||||
f(); \
|
||||
} \
|
||||
} \
|
||||
ssize_t stdio_write(const void* buffer, size_t len) { \
|
||||
return _write(buffer, len); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
1
sys/stdio/Makefile
Normal file
1
sys/stdio/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
80
sys/stdio/stdio.c
Normal file
80
sys/stdio/stdio.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2023 ML!PA Consulting GmbH
|
||||
*
|
||||
* 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 sys_stdio
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief STDIO common layer
|
||||
*
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "errno.h"
|
||||
#include "isrpipe.h"
|
||||
#include "stdio_base.h"
|
||||
#include "macros/utils.h"
|
||||
#include "xfa.h"
|
||||
|
||||
static uint8_t _rx_buf_mem[STDIO_RX_BUFSIZE];
|
||||
isrpipe_t stdin_isrpipe = ISRPIPE_INIT(_rx_buf_mem);
|
||||
|
||||
#ifdef MODULE_STDIO_DISPATCH
|
||||
XFA_INIT_CONST(stdio_provider_t, stdio_provider_xfa);
|
||||
|
||||
void stdio_init(void)
|
||||
{
|
||||
for (unsigned i = 0; i < XFA_LEN(stdio_provider_t, stdio_provider_xfa); ++i) {
|
||||
if (stdio_provider_xfa[i].open) {
|
||||
stdio_provider_xfa[i].open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t stdio_write(const void* buffer, size_t len)
|
||||
{
|
||||
for (unsigned i = 0; i < XFA_LEN(stdio_provider_t, stdio_provider_xfa); ++i) {
|
||||
stdio_provider_xfa[i].write(buffer, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void stdio_close(void) {
|
||||
for (unsigned i = 0; i < XFA_LEN(stdio_provider_t, stdio_provider_xfa); ++i) {
|
||||
if (stdio_provider_xfa[i].close) {
|
||||
stdio_provider_xfa[i].close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MAYBE_WEAK
|
||||
#else
|
||||
#define MAYBE_WEAK __attribute__((weak))
|
||||
#endif
|
||||
|
||||
MAYBE_WEAK
|
||||
ssize_t stdio_read(void* buffer, size_t len)
|
||||
{
|
||||
if (!IS_USED(MODULE_STDIN)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return isrpipe_read(&stdin_isrpipe, buffer, len);
|
||||
}
|
||||
|
||||
#if IS_USED(MODULE_STDIO_AVAILABLE)
|
||||
MAYBE_WEAK
|
||||
int stdio_available(void)
|
||||
{
|
||||
return tsrb_avail(&stdin_isrpipe.tsrb);
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user