diff --git a/pkg/mpaland-printf/Makefile b/pkg/mpaland-printf/Makefile new file mode 100644 index 000000000000..9a7f1f490f9f --- /dev/null +++ b/pkg/mpaland-printf/Makefile @@ -0,0 +1,10 @@ +PKG_NAME=mpaland-printf +PKG_URL=https://github.com/mpaland/printf +# 4.0.0 +PKG_VERSION=0dd4b64bc778bf55229428cefccba4c0a81f384b +PKG_LICENSE=MIT + +include $(RIOTBASE)/pkg/pkg.mk + +all: + $(QQ)"$(MAKE)" -C $(PKG_SOURCE_DIR) -f $(RIOTPKG)/$(PKG_NAME)/$(PKG_NAME).mk diff --git a/pkg/mpaland-printf/Makefile.dep b/pkg/mpaland-printf/Makefile.dep new file mode 100644 index 000000000000..d509d368da60 --- /dev/null +++ b/pkg/mpaland-printf/Makefile.dep @@ -0,0 +1,4 @@ +# mpaland's printf does not implement non-standard format specifiers. For +# AVR MCUs we do need the ability to print from PROGMEM, though. Hence, this +# is not compatible with AVR MCUs. +FEATURES_BLACKLIST += arch_avr8 diff --git a/pkg/mpaland-printf/Makefile.include b/pkg/mpaland-printf/Makefile.include new file mode 100644 index 000000000000..4fc5dfab45f6 --- /dev/null +++ b/pkg/mpaland-printf/Makefile.include @@ -0,0 +1,9 @@ +# wrap stdio functions to use mpaland's printf instead of the one from the +# standard C lib +LINKFLAGS += -Wl,-wrap=printf +LINKFLAGS += -Wl,-wrap=sprintf +LINKFLAGS += -Wl,-wrap=snprintf +LINKFLAGS += -Wl,-wrap=vprintf +LINKFLAGS += -Wl,-wrap=vsnprintf +LINKFLAGS += -Wl,-wrap=putchar +LINKFLAGS += -Wl,-wrap=puts diff --git a/pkg/mpaland-printf/doc.txt b/pkg/mpaland-printf/doc.txt new file mode 100644 index 000000000000..955426d4bf9b --- /dev/null +++ b/pkg/mpaland-printf/doc.txt @@ -0,0 +1,29 @@ +/** + * @defgroup pkg_mpaland-printf mpaland's printf + * @ingroup pkg + * @brief mpaland's printf implementation is a lean, thread-safe and + * feature-complete printf implementation + * + * # License + * + * Licensed under the MIT license. + * + * # Usage + * + * Add `USEPKG += mpaland-printf` to the application's `Makefile` or compile + * using `USEPKG=mpaland-printf make BOARD= -C `. + * + * # Features + * + * The package implements all standard format specifiers. However, support + * for floating point is disabled by default due to the immense ROM overhead + * on MCUs without FPU. + * + * @note Support for floating point formatting can be enabled + * `printf_float` module, e.g. by adding + * `USEMODULE += printf_float` to the application's `Makefile`. + * @note Support for non-standard format specifiers such as needed for + * printing from flash on AVR MCUs are not implemented. + * + * @see https://github.com/mpaland/printf + */ diff --git a/pkg/mpaland-printf/mpaland-printf.mk b/pkg/mpaland-printf/mpaland-printf.mk new file mode 100644 index 000000000000..2d559d90ba11 --- /dev/null +++ b/pkg/mpaland-printf/mpaland-printf.mk @@ -0,0 +1,7 @@ +MODULE := mpaland-printf + +SRC := \ + printf.c \ + # + +include $(RIOTBASE)/Makefile.base diff --git a/pkg/mpaland-printf/patches/0001-RIOT-integration.patch b/pkg/mpaland-printf/patches/0001-RIOT-integration.patch new file mode 100644 index 000000000000..9b84cf577b6c --- /dev/null +++ b/pkg/mpaland-printf/patches/0001-RIOT-integration.patch @@ -0,0 +1,50 @@ +From 875a37ec418c41ffd060e39b2153357a32175ac5 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Sat, 11 May 2024 17:51:01 +0200 +Subject: [PATCH 1/2] RIOT integration + +Use stdio_write() from stdio_base.h for output +--- + printf.c | 8 ++++++++ + printf.h | 2 +- + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/printf.c b/printf.c +index 8a700ad..fd83570 100644 +--- a/printf.c ++++ b/printf.c +@@ -34,6 +34,7 @@ + #include + + #include "printf.h" ++#include "stdio_base.h" + + + // define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the +@@ -912,3 +913,10 @@ int fctprintf(void (*out)(char character, void* arg), void* arg, const char* for + va_end(va); + return ret; + } ++ ++ ++/* RIOT integration: Use stdio_write for output */ ++static void _putchar(char character) ++{ ++ stdio_write(&character, sizeof(character)); ++} +diff --git a/printf.h b/printf.h +index 6075bc2..e185911 100644 +--- a/printf.h ++++ b/printf.h +@@ -46,7 +46,7 @@ extern "C" { + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ +-void _putchar(char character); ++static void _putchar(char character); + + + /** +-- +2.45.0 + diff --git a/pkg/mpaland-printf/patches/0002-Wrapper-targets-Add-endpoints-for-Wl-wrap.patch b/pkg/mpaland-printf/patches/0002-Wrapper-targets-Add-endpoints-for-Wl-wrap.patch new file mode 100644 index 000000000000..16126cd938b5 --- /dev/null +++ b/pkg/mpaland-printf/patches/0002-Wrapper-targets-Add-endpoints-for-Wl-wrap.patch @@ -0,0 +1,66 @@ +From 6fcc450e49791de23446b26cb4b2dc388590c763 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Sat, 11 May 2024 17:51:38 +0200 +Subject: [PATCH 2/2] Wrapper targets: Add endpoints for -Wl,wrap=... + +This adds aliases needed to wrap printf() and friends. +--- + printf.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/printf.c b/printf.c +index fd83570..4694bab 100644 +--- a/printf.c ++++ b/printf.c +@@ -32,6 +32,7 @@ + + #include + #include ++#include + + #include "printf.h" + #include "stdio_base.h" +@@ -920,3 +921,40 @@ static void _putchar(char character) + { + stdio_write(&character, sizeof(character)); + } ++ ++ ++/* provide entry points for linker to redirect stdio */ ++__attribute__((alias("printf_"))) ++int __wrap_printf(const char* format, ...); ++ ++ ++__attribute__((alias("sprintf_"))) ++int __wrap_sprintf(char* buffer, const char* format, ...); ++ ++ ++__attribute__((alias("snprintf_"))) ++int __wrap_snprintf(char* buffer, size_t count, const char* format, ...); ++ ++ ++__attribute__((alias("vprintf_"))) ++int __wrap_vprintf(const char* format, va_list va); ++ ++ ++__attribute__((alias("vsnprintf_"))) ++int __wrap_vsnprintf(char* buffer, size_t count, const char* format, va_list va); ++ ++ ++int __wrap_putchar(int c) ++{ ++ _putchar((char)c); ++ return 1; ++} ++ ++ ++int __wrap_puts(const char *s) ++{ ++ size_t len = strlen(s); ++ stdio_write(s, len); ++ stdio_write("\n", 1); ++ return len + 1; ++} +-- +2.45.0 + diff --git a/pkg/mpaland-printf/patches/0003-RIOT-integration-Enable-floating-support-based-on-mo.patch b/pkg/mpaland-printf/patches/0003-RIOT-integration-Enable-floating-support-based-on-mo.patch new file mode 100644 index 000000000000..5b096d4cc5c0 --- /dev/null +++ b/pkg/mpaland-printf/patches/0003-RIOT-integration-Enable-floating-support-based-on-mo.patch @@ -0,0 +1,131 @@ +From 8436eab79cda1de6e81d5d1d00c379036efa3900 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Sat, 11 May 2024 18:38:51 +0200 +Subject: [PATCH 3/3] RIOT integration: Enable floating support based on module + selection + +--- + printf.c | 94 ++++++++++++++++++++++++++++---------------------------- + 1 file changed, 47 insertions(+), 47 deletions(-) + +diff --git a/printf.c b/printf.c +index e06c9aa..c4980e3 100644 +--- a/printf.c ++++ b/printf.c +@@ -32,10 +32,10 @@ + + #include + #include +-#include ++#include + + #include "printf.h" +-#include "stdio_base.h" ++#include "stdio_base.h" + + + // define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the +@@ -62,7 +62,7 @@ + + // support for the floating point type (%f) + // default: activated +-#ifndef PRINTF_DISABLE_SUPPORT_FLOAT ++#ifdef MODULE_PRINTF_FLOAT + #define PRINTF_SUPPORT_FLOAT + #endif + +@@ -914,47 +914,47 @@ int fctprintf(void (*out)(char character, void* arg), void* arg, const char* for + va_end(va); + return ret; + } +- +- +-/* RIOT integration: Use stdio_write for output */ +-static void _putchar(char character) +-{ +- stdio_write(&character, sizeof(character)); +-} +- +- +-/* provide entry points for linker to redirect stdio */ +-__attribute__((alias("printf_"))) +-int __wrap_printf(const char* format, ...); +- +- +-__attribute__((alias("sprintf_"))) +-int __wrap_sprintf(char* buffer, const char* format, ...); +- +- +-__attribute__((alias("snprintf_"))) +-int __wrap_snprintf(char* buffer, size_t count, const char* format, ...); +- +- +-__attribute__((alias("vprintf_"))) +-int __wrap_vprintf(const char* format, va_list va); +- +- +-__attribute__((alias("vsnprintf_"))) +-int __wrap_vsnprintf(char* buffer, size_t count, const char* format, va_list va); +- +- +-int __wrap_putchar(int c) +-{ +- _putchar((char)c); +- return 1; +-} +- +- +-int __wrap_puts(const char *s) +-{ +- size_t len = strlen(s); +- stdio_write(s, len); +- stdio_write("\n", 1); +- return len + 1; +-} ++ ++ ++/* RIOT integration: Use stdio_write for output */ ++static void _putchar(char character) ++{ ++ stdio_write(&character, sizeof(character)); ++} ++ ++ ++/* provide entry points for linker to redirect stdio */ ++__attribute__((alias("printf_"))) ++int __wrap_printf(const char* format, ...); ++ ++ ++__attribute__((alias("sprintf_"))) ++int __wrap_sprintf(char* buffer, const char* format, ...); ++ ++ ++__attribute__((alias("snprintf_"))) ++int __wrap_snprintf(char* buffer, size_t count, const char* format, ...); ++ ++ ++__attribute__((alias("vprintf_"))) ++int __wrap_vprintf(const char* format, va_list va); ++ ++ ++__attribute__((alias("vsnprintf_"))) ++int __wrap_vsnprintf(char* buffer, size_t count, const char* format, va_list va); ++ ++ ++int __wrap_putchar(int c) ++{ ++ _putchar((char)c); ++ return 1; ++} ++ ++ ++int __wrap_puts(const char *s) ++{ ++ size_t len = strlen(s); ++ stdio_write(s, len); ++ stdio_write("\n", 1); ++ return len + 1; ++} +-- +2.45.0 + diff --git a/pkg/mpaland-printf/patches/0004-Fix-parsing-of-int8_t.patch b/pkg/mpaland-printf/patches/0004-Fix-parsing-of-int8_t.patch new file mode 100644 index 000000000000..7b2ead068330 --- /dev/null +++ b/pkg/mpaland-printf/patches/0004-Fix-parsing-of-int8_t.patch @@ -0,0 +1,28 @@ +From 24d4f4ef60aaaef3c471eb248799ebefde33cc03 Mon Sep 17 00:00:00 2001 +From: Marian Buschsieweke +Date: Sat, 11 May 2024 22:42:21 +0200 +Subject: [PATCH 4/4] Fix parsing of `int8_t` + +The code assumes that `char` is signed, but the C standard allows +`char` to be either signed or unsigned. Instead, `singed char` and +`unsigned char` need to be used for portable code. +--- + printf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/printf.c b/printf.c +index 5266cf7..440cfa6 100644 +--- a/printf.c ++++ b/printf.c +@@ -734,7 +734,7 @@ static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else { +- const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); ++ const int value = (flags & FLAGS_CHAR) ? (signed char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int); + idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } +-- +2.45.0 +