mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-17 05:15:25 +03:00
Adding RP2350 SDK and target framework (#13988)
* Adding RP2350 SDK and target framework * Spacing * Removing board definitions
This commit is contained in:
parent
462cb05930
commit
2dd6f95aad
576 changed files with 435012 additions and 0 deletions
228
lib/main/pico-sdk/rp2_common/pico_stdio/include/pico/stdio.h
Normal file
228
lib/main/pico-sdk/rp2_common/pico_stdio/include/pico/stdio.h
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _PICO_STDIO_H
|
||||
#define _PICO_STDIO_H
|
||||
|
||||
/** \file stdio.h
|
||||
* \defgroup pico_stdio pico_stdio
|
||||
* \brief Customized stdio support allowing for input and output from UART, USB, semi-hosting etc
|
||||
*
|
||||
* Note the API for adding additional input output devices is not yet considered stable
|
||||
*/
|
||||
|
||||
#include "pico.h"
|
||||
|
||||
// PICO_CONFIG: PICO_STDOUT_MUTEX, Enable/disable mutex around stdout, type=bool, default=1, group=pico_stdio
|
||||
#ifndef PICO_STDOUT_MUTEX
|
||||
#define PICO_STDOUT_MUTEX 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_ENABLE_CRLF_SUPPORT, Enable/disable CR/LF output conversion support, type=bool, default=1, group=pico_stdio
|
||||
#ifndef PICO_STDIO_ENABLE_CRLF_SUPPORT
|
||||
#define PICO_STDIO_ENABLE_CRLF_SUPPORT 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_DEFAULT_CRLF, Default for CR/LF conversion enabled on all stdio outputs, type=bool, default=1, depends=PICO_STDIO_ENABLE_CRLF_SUPPORT, group=pico_stdio
|
||||
#ifndef PICO_STDIO_DEFAULT_CRLF
|
||||
#define PICO_STDIO_DEFAULT_CRLF 1
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_STACK_BUFFER_SIZE, Define printf buffer size (on stack)... this is just a working buffer not a max output size, min=0, max=512, default=128, group=pico_stdio
|
||||
#ifndef PICO_STDIO_STACK_BUFFER_SIZE
|
||||
#define PICO_STDIO_STACK_BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_DEADLOCK_TIMEOUT_MS, Time after which to assume stdio_usb is deadlocked by use in IRQ and give up, type=int, default=1000, group=pico_stdio
|
||||
#ifndef PICO_STDIO_DEADLOCK_TIMEOUT_MS
|
||||
#define PICO_STDIO_DEADLOCK_TIMEOUT_MS 1000
|
||||
#endif
|
||||
|
||||
// PICO_CONFIG: PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS, Directly replace common stdio functions such as putchar from the C-library to avoid pulling in lots of c library code for simple output, type=bool, default=1, advanced=true, group=pico_stdio
|
||||
#ifndef PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS
|
||||
#define PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct stdio_driver stdio_driver_t;
|
||||
|
||||
/*! \brief Initialize all of the present standard stdio types that are linked into the binary.
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* Call this method once you have set up your clocks to enable the stdio support for UART, USB,
|
||||
* semihosting, and RTT based on the presence of the respective libraries in the binary.
|
||||
*
|
||||
* When stdio_usb is configured, this method can be optionally made to block, waiting for a connection
|
||||
* via the variables specified in \ref stdio_usb_init (i.e. \ref PICO_STDIO_USB_CONNECT_WAIT_TIMEOUT_MS)
|
||||
*
|
||||
* \return true if at least one output was successfully initialized, false otherwise.
|
||||
* \see stdio_uart, stdio_usb, stdio_semihosting, stdio_rtt
|
||||
*/
|
||||
bool stdio_init_all(void);
|
||||
|
||||
/*! \brief Deinitialize all of the present standard stdio types that are linked into the binary.
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* This method currently only supports stdio_uart and stdio_semihosting
|
||||
*
|
||||
* \return true if all outputs was successfully deinitialized, false otherwise.
|
||||
* \see stdio_uart, stdio_usb, stdio_semihosting, stdio_rtt
|
||||
*/
|
||||
bool stdio_deinit_all(void);
|
||||
|
||||
/*! \brief Flushes any buffered output.
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
void stdio_flush(void);
|
||||
|
||||
/*! \brief Return a character from stdin if there is one available within a timeout
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* \param timeout_us the timeout in microseconds, or 0 to not wait for a character if none available.
|
||||
* \return the character from 0-255 or PICO_ERROR_TIMEOUT if timeout occurs
|
||||
*/
|
||||
int stdio_getchar_timeout_us(uint32_t timeout_us);
|
||||
|
||||
/*! \brief Alias for \ref stdio_getchar_timeout_us for backwards compatibility
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
static inline int getchar_timeout_us(uint32_t timeout_us) {
|
||||
return stdio_getchar_timeout_us(timeout_us);
|
||||
}
|
||||
|
||||
/*! \brief Adds or removes a driver from the list of active drivers used for input/output
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* \note this method should always be called on an initialized driver and is not re-entrant
|
||||
* \param driver the driver
|
||||
* \param enabled true to add, false to remove
|
||||
*/
|
||||
void stdio_set_driver_enabled(stdio_driver_t *driver, bool enabled);
|
||||
|
||||
/*! \brief Control limiting of output to a single driver
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* \note this method should always be called on an initialized driver
|
||||
*
|
||||
* \param driver if non-null then output only that driver will be used for input/output (assuming it is in the list of enabled drivers).
|
||||
* if NULL then all enabled drivers will be used
|
||||
*/
|
||||
void stdio_filter_driver(stdio_driver_t *driver);
|
||||
|
||||
/*! \brief control conversion of line feeds to carriage return on transmissions
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* \note this method should always be called on an initialized driver
|
||||
*
|
||||
* \param driver the driver
|
||||
* \param translate If true, convert line feeds to carriage return on transmissions
|
||||
*/
|
||||
void stdio_set_translate_crlf(stdio_driver_t *driver, bool translate);
|
||||
|
||||
/*! \brief putchar variant that skips any CR/LF conversion if enabled
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
int stdio_putchar_raw(int c);
|
||||
|
||||
/*! \brief Alias for \ref stdio_putchar_raw for backwards compatibility
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
static inline int putchar_raw(int c) {
|
||||
return stdio_putchar_raw(c);
|
||||
}
|
||||
|
||||
/*! \brief puts variant that skips any CR/LF conversion if enabled
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
int stdio_puts_raw(const char *s);
|
||||
|
||||
/*! \brief Alias for \ref stdio_puts_raw for backwards compatibility
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
static inline int puts_raw(const char *s) {
|
||||
return stdio_puts_raw(s);
|
||||
}
|
||||
|
||||
/*! \brief get notified when there are input characters available
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* \param fn Callback function to be called when characters are available. Pass NULL to cancel any existing callback
|
||||
* \param param Pointer to pass to the callback
|
||||
*/
|
||||
void stdio_set_chars_available_callback(void (*fn)(void*), void *param);
|
||||
|
||||
/*! \brief Waits until a timeout to reard at least one character into a buffer
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* This method returns as soon as input is available, but more characters may
|
||||
* be returned up to the end of the buffer.
|
||||
*
|
||||
* \param buf the buffer to read into
|
||||
* \param len the length of the buffer
|
||||
* \return the number of characters read or PICO_ERROR_TIMEOUT
|
||||
* \param until the time after which to return PICO_ERROR_TIMEOUT if no characters are available
|
||||
*/
|
||||
int stdio_get_until(char *buf, int len, absolute_time_t until);
|
||||
|
||||
/*! \brief Prints a buffer to stdout with optional newline and carriage return insertion
|
||||
* \ingroup pico_stdio
|
||||
*
|
||||
* This method returns as soon as input is available, but more characters may
|
||||
* be returned up to the end of the buffer.
|
||||
*
|
||||
* \param s the characters to print
|
||||
* \param len the length of s
|
||||
* \param newline true if a newline should be added after the string
|
||||
* \param cr_translation true if line feed to carriage return translation should be performed
|
||||
* \return the number of characters written
|
||||
*/
|
||||
int stdio_put_string(const char *s, int len, bool newline, bool cr_translation);
|
||||
|
||||
/*! \brief stdio_getchar Alias for \ref getchar that definitely does not go thru the implementation
|
||||
* in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0
|
||||
*
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
int stdio_getchar(void);
|
||||
|
||||
/*! \brief stdio_getchar Alias for \ref putchar that definitely does not go thru the implementation
|
||||
* in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0
|
||||
*
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
int stdio_putchar(int);
|
||||
|
||||
/*! \brief stdio_getchar Alias for \ref puts that definitely does not go thru the implementation
|
||||
* in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0
|
||||
*
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
int stdio_puts(const char *s);
|
||||
|
||||
/*! \brief stdio_getchar Alias for \ref vprintf that definitely does not go thru the implementation
|
||||
* in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0
|
||||
*
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
int stdio_vprintf(const char *format, va_list va);
|
||||
|
||||
/*! \brief stdio_getchar Alias for \ref printf that definitely does not go thru the implementation
|
||||
* in the standard C library even when \ref PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS == 0
|
||||
*
|
||||
* \ingroup pico_stdio
|
||||
*/
|
||||
int __printflike(1, 0) stdio_printf(const char* format, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _PICO_STDIO_DRIVER_H
|
||||
#define _PICO_STDIO_DRIVER_H
|
||||
|
||||
#include "pico/stdio.h"
|
||||
|
||||
struct stdio_driver {
|
||||
void (*out_chars)(const char *buf, int len);
|
||||
void (*out_flush)(void);
|
||||
int (*in_chars)(char *buf, int len);
|
||||
void (*set_chars_available_callback)(void (*fn)(void*), void *param);
|
||||
stdio_driver_t *next;
|
||||
#if PICO_STDIO_ENABLE_CRLF_SUPPORT
|
||||
bool last_ended_with_cr;
|
||||
bool crlf_enabled;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
391
lib/main/pico-sdk/rp2_common/pico_stdio/stdio.c
Normal file
391
lib/main/pico-sdk/rp2_common/pico_stdio/stdio.c
Normal file
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "pico.h"
|
||||
#if LIB_PICO_PRINTF_PICO
|
||||
#include "pico/printf.h"
|
||||
#endif
|
||||
#include "pico/stdio.h"
|
||||
#include "pico/stdio/driver.h"
|
||||
#include "pico/time.h"
|
||||
#if PICO_STDOUT_MUTEX
|
||||
#include "pico/mutex.h"
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_UART
|
||||
#include "pico/stdio_uart.h"
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_USB
|
||||
#include "pico/stdio_usb.h"
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_SEMIHOSTING
|
||||
#include "pico/stdio_semihosting.h"
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_RTT
|
||||
#include "pico/stdio_rtt.h"
|
||||
#endif
|
||||
|
||||
static stdio_driver_t *drivers;
|
||||
static stdio_driver_t *filter;
|
||||
|
||||
#if PICO_STDOUT_MUTEX
|
||||
auto_init_mutex(print_mutex);
|
||||
|
||||
bool stdout_serialize_begin(void) {
|
||||
return mutex_try_enter_block_until(&print_mutex, make_timeout_time_ms(PICO_STDIO_DEADLOCK_TIMEOUT_MS));
|
||||
}
|
||||
|
||||
void stdout_serialize_end(void) {
|
||||
mutex_exit(&print_mutex);
|
||||
}
|
||||
|
||||
#else
|
||||
static bool stdout_serialize_begin(void) {
|
||||
return true;
|
||||
}
|
||||
static void stdout_serialize_end(void) {
|
||||
}
|
||||
#endif
|
||||
static void stdio_out_chars_no_crlf(stdio_driver_t *driver, const char *s, int len) {
|
||||
driver->out_chars(s, len);
|
||||
}
|
||||
|
||||
static void stdio_out_chars_crlf(stdio_driver_t *driver, const char *s, int len) {
|
||||
#if PICO_STDIO_ENABLE_CRLF_SUPPORT
|
||||
if (!driver->crlf_enabled) {
|
||||
driver->out_chars(s, len);
|
||||
return;
|
||||
}
|
||||
int first_of_chunk = 0;
|
||||
static const char crlf_str[] = {'\r', '\n'};
|
||||
for (int i = 0; i < len; i++) {
|
||||
bool prev_char_was_cr = i > 0 ? s[i - 1] == '\r' : driver->last_ended_with_cr;
|
||||
if (s[i] == '\n' && !prev_char_was_cr) {
|
||||
if (i > first_of_chunk) {
|
||||
driver->out_chars(&s[first_of_chunk], i - first_of_chunk);
|
||||
}
|
||||
driver->out_chars(crlf_str, 2);
|
||||
first_of_chunk = i + 1;
|
||||
}
|
||||
}
|
||||
if (first_of_chunk < len) {
|
||||
driver->out_chars(&s[first_of_chunk], len - first_of_chunk);
|
||||
}
|
||||
if (len > 0) {
|
||||
driver->last_ended_with_cr = s[len - 1] == '\r';
|
||||
}
|
||||
#else
|
||||
driver->out_chars(s, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
int stdio_put_string(const char *s, int len, bool newline, bool cr_translation) {
|
||||
bool serialized = stdout_serialize_begin();
|
||||
if (!serialized) {
|
||||
#if PICO_STDIO_IGNORE_NESTED_STDOUT
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
if (len == -1) len = (int)strlen(s);
|
||||
void (*out_func)(stdio_driver_t *, const char *, int) = cr_translation ? stdio_out_chars_crlf : stdio_out_chars_no_crlf;
|
||||
for (stdio_driver_t *driver = drivers; driver; driver = driver->next) {
|
||||
if (!driver->out_chars) continue;
|
||||
if (filter && filter != driver) continue;
|
||||
out_func(driver, s, len);
|
||||
if (newline) {
|
||||
const char c = '\n';
|
||||
out_func(driver, &c, 1);
|
||||
}
|
||||
}
|
||||
if (serialized) {
|
||||
stdout_serialize_end();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int stdio_get_until(char *buf, int len, absolute_time_t until) {
|
||||
do {
|
||||
// todo round robin might be nice on each call, but then again hopefully
|
||||
// no source will starve the others
|
||||
for (stdio_driver_t *driver = drivers; driver; driver = driver->next) {
|
||||
if (filter && filter != driver) continue;
|
||||
if (driver->in_chars) {
|
||||
int read = driver->in_chars(buf, len);
|
||||
if (read > 0) {
|
||||
return read;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (time_reached(until)) {
|
||||
return PICO_ERROR_TIMEOUT;
|
||||
}
|
||||
// we sleep here in case the in_chars methods acquire mutexes or disable IRQs and
|
||||
// potentially starve out what they are waiting on (have seen this with USB)
|
||||
busy_wait_us(1);
|
||||
} while (true);
|
||||
}
|
||||
|
||||
int stdio_putchar_raw(int c) {
|
||||
char cc = (char)c;
|
||||
stdio_put_string(&cc, 1, false, false);
|
||||
return c;
|
||||
}
|
||||
|
||||
int stdio_puts_raw(const char *s) {
|
||||
int len = (int)strlen(s);
|
||||
stdio_put_string(s, len, true, false);
|
||||
stdio_flush();
|
||||
return len;
|
||||
}
|
||||
|
||||
void stdio_set_driver_enabled(stdio_driver_t *driver, bool enable) {
|
||||
stdio_driver_t **prev = &drivers;
|
||||
while (*prev) {
|
||||
if (*prev == driver) {
|
||||
if (!enable) {
|
||||
*prev = driver->next;
|
||||
driver->next = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
prev = &(*prev)->next;
|
||||
}
|
||||
if (enable) {
|
||||
*prev = driver;
|
||||
}
|
||||
}
|
||||
|
||||
void stdio_flush(void) {
|
||||
for (stdio_driver_t *d = drivers; d; d = d->next) {
|
||||
if (d->out_flush) d->out_flush();
|
||||
}
|
||||
}
|
||||
|
||||
#if LIB_PICO_PRINTF_PICO
|
||||
typedef struct stdio_stack_buffer {
|
||||
int used;
|
||||
char buf[PICO_STDIO_STACK_BUFFER_SIZE];
|
||||
} stdio_stack_buffer_t;
|
||||
|
||||
static void stdio_stack_buffer_flush(stdio_stack_buffer_t *buffer) {
|
||||
if (buffer->used) {
|
||||
for (stdio_driver_t *d = drivers; d; d = d->next) {
|
||||
if (!d->out_chars) continue;
|
||||
if (filter && filter != d) continue;
|
||||
stdio_out_chars_crlf(d, buffer->buf, buffer->used);
|
||||
}
|
||||
buffer->used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void stdio_buffered_printer(char c, void *arg) {
|
||||
stdio_stack_buffer_t *buffer = (stdio_stack_buffer_t *)arg;
|
||||
if (buffer->used == PICO_STDIO_STACK_BUFFER_SIZE) {
|
||||
stdio_stack_buffer_flush(buffer);
|
||||
}
|
||||
buffer->buf[buffer->used++] = c;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool stdio_init_all(void) {
|
||||
// todo add explicit custom, or registered although you can call stdio_enable_driver explicitly anyway
|
||||
// These are well known ones
|
||||
|
||||
bool rc = false;
|
||||
#if LIB_PICO_STDIO_UART
|
||||
stdio_uart_init();
|
||||
rc = true;
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_SEMIHOSTING
|
||||
stdio_semihosting_init();
|
||||
rc = true;
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_RTT
|
||||
stdio_rtt_init();
|
||||
rc = true;
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_USB
|
||||
rc |= stdio_usb_init();
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool stdio_deinit_all(void) {
|
||||
// todo add explicit custom, or registered although you can call stdio_enable_driver explicitly anyway
|
||||
// These are well known ones
|
||||
|
||||
// First flush, to make sure everything is printed
|
||||
stdio_flush();
|
||||
|
||||
bool rc = false;
|
||||
#if LIB_PICO_STDIO_UART
|
||||
stdio_uart_deinit();
|
||||
rc = true;
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_SEMIHOSTING
|
||||
stdio_semihosting_deinit();
|
||||
rc = true;
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_RTT
|
||||
stdio_rtt_deinit();
|
||||
rc = true;
|
||||
#endif
|
||||
|
||||
#if LIB_PICO_STDIO_USB
|
||||
rc = stdio_usb_deinit();
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
int stdio_getchar_timeout_us(uint32_t timeout_us) {
|
||||
char buf[1];
|
||||
int rc = stdio_get_until(buf, sizeof(buf), make_timeout_time_us(timeout_us));
|
||||
if (rc < 0) return rc;
|
||||
assert(rc);
|
||||
return (uint8_t)buf[0];
|
||||
}
|
||||
|
||||
void stdio_filter_driver(stdio_driver_t *driver) {
|
||||
filter = driver;
|
||||
}
|
||||
|
||||
void stdio_set_translate_crlf(stdio_driver_t *driver, bool enabled) {
|
||||
#if PICO_STDIO_ENABLE_CRLF_SUPPORT
|
||||
if (enabled && !driver->crlf_enabled) {
|
||||
driver->last_ended_with_cr = false;
|
||||
}
|
||||
driver->crlf_enabled = enabled;
|
||||
#else
|
||||
// Suppress -Wunused-parameter
|
||||
(void)driver;
|
||||
(void)enabled;
|
||||
|
||||
panic_unsupported();
|
||||
#endif
|
||||
}
|
||||
|
||||
void stdio_set_chars_available_callback(void (*fn)(void*), void *param) {
|
||||
for (stdio_driver_t *s = drivers; s; s = s->next) {
|
||||
if (s->set_chars_available_callback) s->set_chars_available_callback(fn, param);
|
||||
}
|
||||
}
|
||||
|
||||
#if PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS
|
||||
#define PRIMARY_STDIO_FUNC(x) WRAPPER_FUNC(x)
|
||||
#else
|
||||
#define PRIMARY_STDIO_FUNC(x) stdio_ ## x
|
||||
#endif
|
||||
|
||||
int PRIMARY_STDIO_FUNC(getchar)(void) {
|
||||
char buf[1];
|
||||
int len = stdio_get_until(buf, 1, at_the_end_of_time);
|
||||
if (len < 0) return len;
|
||||
assert(len == 1);
|
||||
return (uint8_t)buf[0];
|
||||
}
|
||||
|
||||
int PRIMARY_STDIO_FUNC(putchar)(int c) {
|
||||
char cc = (char)c;
|
||||
stdio_put_string(&cc, 1, false, true);
|
||||
return c;
|
||||
}
|
||||
|
||||
int PRIMARY_STDIO_FUNC(puts)(const char *s) {
|
||||
int len = (int)strlen(s);
|
||||
stdio_put_string(s, len, true, true);
|
||||
stdio_flush();
|
||||
return len;
|
||||
}
|
||||
|
||||
int REAL_FUNC(vprintf)(const char *format, va_list va);
|
||||
|
||||
int PRIMARY_STDIO_FUNC(vprintf)(const char *format, va_list va) {
|
||||
bool serialzed = stdout_serialize_begin();
|
||||
if (!serialzed) {
|
||||
#if PICO_STDIO_IGNORE_NESTED_STDOUT
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
int ret;
|
||||
#if LIB_PICO_PRINTF_PICO
|
||||
struct stdio_stack_buffer buffer;
|
||||
buffer.used = 0;
|
||||
ret = vfctprintf(stdio_buffered_printer, &buffer, format, va);
|
||||
stdio_stack_buffer_flush(&buffer);
|
||||
stdio_flush();
|
||||
#elif LIB_PICO_PRINTF_NONE
|
||||
((void)format);
|
||||
((void)va);
|
||||
extern void printf_none_assert(void);
|
||||
printf_none_assert();
|
||||
ret = 0;
|
||||
#else
|
||||
ret = REAL_FUNC(vprintf)(format, va);
|
||||
#endif
|
||||
if (serialzed) {
|
||||
stdout_serialize_end();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __printflike(1, 0) PRIMARY_STDIO_FUNC(printf)(const char* format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
int ret = vprintf(format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if PICO_STDIO_SHORT_CIRCUIT_CLIB_FUNCS
|
||||
// define the stdio_ versions to be the same as our wrappers
|
||||
int stdio_getchar(void) __attribute__((alias(__XSTRING(WRAPPER_FUNC(getchar)))));
|
||||
int stdio_putchar(int) __attribute__((alias(__XSTRING(WRAPPER_FUNC(putchar)))));
|
||||
int stdio_puts(const char *s) __attribute__((alias(__XSTRING(WRAPPER_FUNC(puts)))));
|
||||
int stdio_vprintf(const char *format, va_list va) __attribute__((alias(__XSTRING(WRAPPER_FUNC(vprintf)))));
|
||||
int __printflike(1, 0) stdio_printf(const char* format, ...) __attribute__((alias(__XSTRING(WRAPPER_FUNC(printf)))));
|
||||
#else
|
||||
// todo there is no easy way to avoid the wrapper functions since they are in the CMake, so lets just forward for now
|
||||
|
||||
int REAL_FUNC(getchar)(void);
|
||||
int REAL_FUNC(putchar)(int);
|
||||
int REAL_FUNC(puts)(const char *s);
|
||||
int __printflike(1, 0) REAL_FUNC(printf)(const char* format, ...);
|
||||
|
||||
int WRAPPER_FUNC(getchar)(void) {
|
||||
return REAL_FUNC(getchar)();
|
||||
}
|
||||
int WRAPPER_FUNC(putchar)(int c) {
|
||||
return REAL_FUNC(putchar)(c);
|
||||
}
|
||||
int WRAPPER_FUNC(puts)(const char *s) {
|
||||
return REAL_FUNC(puts)(s);
|
||||
}
|
||||
int WRAPPER_FUNC(vprintf)(const char *format, va_list va) {
|
||||
return REAL_FUNC(vprintf)(format, va);
|
||||
}
|
||||
int __printflike(1, 0) WRAPPER_FUNC(printf)(const char* format, ...) {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
int ret = REAL_FUNC(vprintf)(format, va);
|
||||
va_end(va);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue