A utility library that redirects standard input/output (printf/scanf) to a UART port or any custom I/O implementation, enabling STDIO console output from embedded firmware with a single initialization call.
Select the backend for your project in your application Makefile:
| Mode | Condition | Notes |
|---|---|---|
| HAL v3 (MTB-HAL) | COMPONENT_MTB_HAL set by device package | Requires a pre-initialized HAL UART object |
| HAL v2 (CY-HAL) | CY_USING_HAL set by device package | Library initializes UART from TX/RX pin arguments |
| PDL-only | Neither HAL component present | Requires a pre-initialized SCB UART; not thread-safe |
| Custom | DEFINES += COMPONENT_RETARGET_IO_CUSTOM in Makefile | Application provides cy_retarget_io_getchar/putchar |
Note: Only one interface mode can be active at a time. The HAL mode (HAL v3 or HAL v2) is determined automatically by the device package in your BSP and is not manually configurable.
Add these to the DEFINES variable in your Makefile as needed:
| Define | Effect |
|---|---|
| CY_RETARGET_IO_CONVERT_LF_TO_CRLF | Appends \r before each \n on STDOUT; recommended for full terminal compatibility |
| CY_RETARGET_IO_NO_FLOAT | Disables floating-point printf support to reduce flash usage |
| CY_RTOS_AWARE | Enables mutex-based thread safety for Newlib (GCC_ARM) in RTOS environments |
Optional – change baud rate at runtime:
The host terminal must also be switched to the new baud rate.
Optional – register a deepsleep callback (only needed if your application enters deepsleep): the SCB clock stops during deepsleep, so without a callback any in-flight UART transmission is corrupted and the peripheral may be left in an undefined state on wakeup. The callback drains the TX FIFO before sleep entry and re-enables the UART on wakeup. In HAL v2 (CY-HAL) this is registered automatically; in HAL v3 (MTB-HAL) and PDL-only mode you must register it explicitly using Cy_SysPm_RegisterCallback with mtb_syspm_scb_uart_deepsleep_callback from the syspm-callbacks asset, or provide a custom callback. Refer to the PDL documentation.
Note: CYBSP_DEBUG_UART_TX and CYBSP_DEBUG_UART_RX are defined in the BSP. CY_RETARGET_IO_BAUDRATE defaults to 115200.
For flow control, use cy_retarget_io_init_fc() directly (see the Reference Guide section below).
Note: PDL-only mode is not thread-safe. Use printf() from a single thread or guard calls with a mutex.
Example (USB CDC backend):
Note: When using COMPONENT_RETARGET_IO_CUSTOM, a valid object/pointer must still be passed to cy_retarget_io_init() even though UART hardware is not used for I/O (in HAL modes this also initializes the RTOS mutex).
Note: The C standard library is not consistent in how it treats I/O streams. Many implementations buffer output by default and do not flush until the buffer is full — so if your printf() output does not appear, the data is likely sitting in an unflushed buffer rather than being sent to the UART. You must be aware of how your toolchain buffers data and choose an explicit flushing strategy. If you supply a buffer to setvbuf(), it must remain valid for the lifetime of the stream.
Buffer size: The default buffer size is defined by the BUFSIZ constant in <stdio.h>, which varies by compiler (typically 512–1024 bytes for embedded toolchains). This buffer is owned by the C standard library, not by retarget-io. The retarget-io library implements low-level I/O redirection (the _write/_read hooks that the standard library calls), so standard library buffering still applies on top of it unless explicitly disabled with setvbuf().
To ensure immediate output, follow the guidance for your toolchain:
GCC_ARM, LLVM, and ARM Compilers: These compilers support automatic buffer flushing control. You can disable buffering entirely:
IAR Compiler: IAR has limited standard library support in embedded projects. Buffer flushing requires explicit control:
Newlib-nano note: Floating-point f is unsupported by default. Add -u _printf_float to the linker command line to enable it.
ISR note: Do not call printf() from ISR context, especially when CY_RTOS_AWARE is defined.
UART terminals typically require \r\n (CRLF) to move the cursor to the beginning of the next line. Using \n alone may cause staircase output on some terminals:
To avoid this, define CY_RETARGET_IO_CONVERT_LF_TO_CRLF in your Makefile:
The library will then automatically prepend \r before each \n on STDOUT. No conversion occurs if \r\n is already present in the string. Alternatively, use \r\n explicitly in all printf() format strings.
For the full API documentation including all function signatures, parameters, and return values, see the Reference Guide.
This library is licensed under the Apache License, Version 2.0.
© Copyright 2018-2026 Infineon Technologies AG and its affiliates. All rights reserved.