diff --git a/.gitmodules b/.gitmodules index 7c382da67..aef64b1df 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "lib/btstack"] path = lib/btstack url = https://github.com/bluekitchen/btstack.git +[submodule "lib/rtt"] + path = lib/rtt + url = git@github.com:adfernandes/segger-rtt.git diff --git a/lib/rtt b/lib/rtt new file mode 160000 index 000000000..5efbf0d42 --- /dev/null +++ b/lib/rtt @@ -0,0 +1 @@ +Subproject commit 5efbf0d42ced18d2893c1eda30e6654d4d7a64f7 diff --git a/src/rp2_common/CMakeLists.txt b/src/rp2_common/CMakeLists.txt index eff827b6a..9eb1336c3 100644 --- a/src/rp2_common/CMakeLists.txt +++ b/src/rp2_common/CMakeLists.txt @@ -54,6 +54,7 @@ if (NOT PICO_BARE_METAL) pico_add_subdirectory(pico_stdio) pico_add_subdirectory(pico_stdio_semihosting) pico_add_subdirectory(pico_stdio_uart) + pico_add_subdirectory(pico_stdio_rtt) pico_add_subdirectory(cmsis) pico_add_subdirectory(tinyusb) @@ -84,4 +85,4 @@ set(CMAKE_EXECUTABLE_SUFFIX "${CMAKE_EXECUTABLE_SUFFIX}" PARENT_SCOPE) pico_add_doxygen(${CMAKE_CURRENT_LIST_DIR}) pico_add_doxygen_exclude(${CMAKE_CURRENT_LIST_DIR}/cmsis) -pico_promote_common_scope_vars() \ No newline at end of file +pico_promote_common_scope_vars() diff --git a/src/rp2_common/pico_stdio/include/pico/stdio.h b/src/rp2_common/pico_stdio/include/pico/stdio.h index 430be36ff..87be11318 100644 --- a/src/rp2_common/pico_stdio/include/pico/stdio.h +++ b/src/rp2_common/pico_stdio/include/pico/stdio.h @@ -51,14 +51,14 @@ 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 - * and semihosting based on the presence of the respective libraries in the binary. + * 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 + * \see stdio_uart, stdio_usb, stdio_semihosting, stdio_rtt */ bool stdio_init_all(void); diff --git a/src/rp2_common/pico_stdio/stdio.c b/src/rp2_common/pico_stdio/stdio.c index 3656d2f11..1c7040692 100644 --- a/src/rp2_common/pico_stdio/stdio.c +++ b/src/rp2_common/pico_stdio/stdio.c @@ -32,6 +32,10 @@ #include "pico/stdio_semihosting.h" #endif +#if LIB_PICO_STDIO_RTT +#include "pico/stdio_rtt.h" +#endif + #define STDIO_HANDLE_STDIN 0 #define STDIO_HANDLE_STDOUT 1 #define STDIO_HANDLE_STDERR 2 @@ -295,6 +299,11 @@ bool stdio_init_all(void) { rc = true; #endif +#if LIB_PICO_STDIO_RTT + stdio_rtt_init(); + rc = true; +#endif + #if LIB_PICO_STDIO_USB rc |= stdio_usb_init(); #endif @@ -331,7 +340,7 @@ void stdio_set_translate_crlf(stdio_driver_t *driver, bool enabled) { // Suppress -Wunused-parameter (void)driver; (void)enabled; - + panic_unsupported(); #endif } diff --git a/src/rp2_common/pico_stdio_rtt/CMakeLists.txt b/src/rp2_common/pico_stdio_rtt/CMakeLists.txt new file mode 100644 index 000000000..f3a4db058 --- /dev/null +++ b/src/rp2_common/pico_stdio_rtt/CMakeLists.txt @@ -0,0 +1,19 @@ +pico_add_library(pico_stdio_rtt) + +target_sources(pico_stdio_rtt + INTERFACE + stdio_rtt.c + segger_rtt.c +) + +if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + set_source_files_properties(segger_rtt.c PROPERTIES COMPILE_OPTIONS "-Wno-cast-align;-Wno-cast-qual") +endif() + +target_include_directories(pico_stdio_rtt_headers + INTERFACE + ./include + ../../../lib/rtt/RTT +) + +pico_mirrored_target_link_libraries(pico_stdio_rtt INTERFACE pico_stdio) diff --git a/src/rp2_common/pico_stdio_rtt/include/pico/stdio_rtt.h b/src/rp2_common/pico_stdio_rtt/include/pico/stdio_rtt.h new file mode 100644 index 000000000..d406b0682 --- /dev/null +++ b/src/rp2_common/pico_stdio_rtt/include/pico/stdio_rtt.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PICO_STDIO_RTT_H +#define _PICO_STDIO_RTT_H + +#include "pico/stdio.h" + +/** \brief Support for stdin/stdout using SEGGER RTT + * \defgroup pico_stdio_rtt pico_stdio_rtt + * \ingroup pico_stdio + * + * Linking this library or calling `pico_enable_stdio_rtt(TARGET)` in the CMake (which + * achieves the same thing) will add RTT to the drivers used for standard output + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern stdio_driver_t stdio_rtt; + +/*! \brief Explicitly initialize stdin/stdout over RTT and add it to the current set of stdin/stdout drivers + * \ingroup pico_stdio_rtt + * + * \note this method is automatically called by \ref stdio_init_all() if `pico_stdio_rtt` is included in the build + */ +void stdio_rtt_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/rp2_common/pico_stdio_rtt/segger_rtt.c b/src/rp2_common/pico_stdio_rtt/segger_rtt.c new file mode 100644 index 000000000..989730025 --- /dev/null +++ b/src/rp2_common/pico_stdio_rtt/segger_rtt.c @@ -0,0 +1,12 @@ +/* + + We use this round-about way of including the Segger RTT source file + because we need to suppress the "cast-align" and "cast-qual" warnings, + and cmake will not let us change the COMPILE_OPTIONS for a single + source file if the target has one source file in the current directory tree + and another source file in a directory outside the current directory tree. + + See https://gitlab.kitware.com/cmake/cmake/-/issues/20128 for more details. + + */ +#include "../../../lib/rtt/RTT/SEGGER_RTT.c" diff --git a/src/rp2_common/pico_stdio_rtt/stdio_rtt.c b/src/rp2_common/pico_stdio_rtt/stdio_rtt.c new file mode 100644 index 000000000..2c6adbe1b --- /dev/null +++ b/src/rp2_common/pico_stdio_rtt/stdio_rtt.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "pico/stdio/driver.h" +#include "pico/stdio_rtt.h" +#include "SEGGER_RTT.h" + +void stdio_rtt_init(void) { + stdio_set_driver_enabled(&stdio_rtt, true); +} + +static void stdio_rtt_out_chars(const char *buf, int length) { + SEGGER_RTT_Write(0, buf, length); +} + +static int stdio_rtt_in_chars(char *buf, int length) { + return SEGGER_RTT_Read(0, buf, length); +} + +stdio_driver_t stdio_rtt = { + .out_chars = stdio_rtt_out_chars, + .in_chars = stdio_rtt_in_chars, +}; diff --git a/src/rp2_common/pico_stdlib/CMakeLists.txt b/src/rp2_common/pico_stdlib/CMakeLists.txt index 183ca52b5..5dfd33e0a 100644 --- a/src/rp2_common/pico_stdlib/CMakeLists.txt +++ b/src/rp2_common/pico_stdlib/CMakeLists.txt @@ -3,7 +3,9 @@ option(PICO_STDIO_UART "Globally enable stdio UART" 1) # PICO_CMAKE_CONFIG: PICO_STDIO_USB, OPTION: Globally enable stdio USB, default=0, group=pico_stdlib option(PICO_STDIO_USB "Globally enable stdio USB" 0) # PICO_CMAKE_CONFIG: PICO_STDIO_SEMIHOSTING, OPTION: Globally enable stdio semihosting, default=0, group=pico_stdlib -option(PICO_STDIO_SEMIHOSTING "Globally enable stdio semi-hosting" 0) +option(PICO_STDIO_SEMIHOSTING "Globally enable stdio semihosting" 0) +# PICO_CMAKE_CONFIG: PICO_STDIO_RTT, OPTION: Globally enable stdio RTT, default=0, group=pico_stdlib +option(PICO_STDIO_RTT "Globally enable stdio rtt" 0) if (NOT TARGET pico_stdlib) pico_add_impl_library(pico_stdlib) @@ -33,6 +35,10 @@ if (NOT TARGET pico_stdlib) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_SEMIHOSTING ${ENABLED}) endfunction() + function(pico_enable_stdio_rtt TARGET ENABLED) + set_target_properties(${TARGET} PROPERTIES PICO_TARGET_STDIO_RTT ${ENABLED}) + endfunction() + if (TARGET pico_stdio_uart) target_link_libraries(pico_stdlib INTERFACE $,>,${PICO_STDIO_UART},$>>,pico_stdio_uart,>) target_link_libraries(pico_stdlib_headers INTERFACE $,>,${PICO_STDIO_UART},$>>,pico_stdio_uart_headers,>) @@ -48,4 +54,9 @@ if (NOT TARGET pico_stdlib) target_link_libraries(pico_stdlib_headers INTERFACE $,>,${PICO_STDIO_SEMIHOSTING},$>>,pico_stdio_semihosting_headers,>) endif() + if (TARGET pico_stdio_rtt) + target_link_libraries(pico_stdlib INTERFACE $,>,${PICO_STDIO_RTT},$>>,pico_stdio_rtt,>) + target_link_libraries(pico_stdlib_headers INTERFACE $,>,${PICO_STDIO_RTT},$>>,pico_stdio_rtt_headers,>) + endif() + endif()