A utility library to retarget the standard input/output (STDIO) messages to a UART port. With this library, you can directly print messages on a UART terminal using printf(). You can specify the TX pin, RX pin, and the baud rate when configuring the UART. When using MTB-HAL, the library also provides functionality to dynamically change the UART baud rate at runtime.
NOTE: The standard library is not standard in how it treats an I/O stream. Some implement a data buffer by default. The buffer is not flushed until it is full. In that case it may appear that your I/O is not working. You should be aware of how the library buffers data, and you should identify a buffering strategy and buffer size for a specified stream. If you supply a buffer, it must exist until the stream is closed.
Buffer Configuration: The default buffer size is typically defined by the BUFSIZ constant in <stdio.h>, which varies by compiler (usually 512-1024 bytes for embedded systems). This buffer is managed by the C standard library implementation that comes with your compiler (GCC_ARM/LLVM, ARM, IAR etc.). The retarget-io library works independently of these buffers by implementing low-level I/O redirection, but standard library buffering still applies unless explicitly disabled with setvbuf().
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 must be handled manually:
\n (newline character)fflush(stdout) if available, or use newline charactersIf automatic buffer disabling is not available, use these approaches:
Floating Point Support: If the application is built using newlib-nano, by default, floating point format strings (f) are not supported. To enable this support, you must add -u _printf_float to the linker command line.
ISR Context: In general, console prints such as printf() should not be performed in ISR context. It must definitely not be called in ISR context when CY_RTOS_AWARE is defined, as the thread safety implementation disallows such calls.
PDL-Only Mode: If the application is built without HAL support (i.e., neither COMPONENT_MTB_HAL nor CY_USING_HAL is defined), then the UART must be initialized using PDL function calls prior to being passed into the cy_retarget_io_init() function. See Quick Start (PDL Only) section below.
To avoid concurrent access to the UART peripheral in a RTOS environment, the ARM and IAR libraries use mutexes to control access to stdio streams. For Newlib (GCC_ARM), the mutex must be implemented in _write() and can be enabled by adding DEFINES+=CY_RTOS_AWARE to the Makefile. For all libraries, the program must start the RTOS kernel before calling any stdio functions.
HAL support is required for retarget-io in an RTOS environment. If your project does not include HAL support, you must manually manage concurrency in your application.
The retarget-io library provides different initialization functions based on your project configuration:
| Configuration | Function | Parameters | Notes |
|---|---|---|---|
MTB-HAL (COMPONENT_MTB_HAL) | cy_retarget_io_init() | 1 arg: MTB-HAL UART object pointer | Requires pre-configured UART |
| cy_retarget_io_change_baud_rate() | 2 args: baud rate, actual baud pointer | Changes UART baud rate dynamically on retarget-io UART | |
CY-HAL (CY_USING_HAL) | cy_retarget_io_init() | 3 args: TX pin, RX pin, baud rate | Macro calling cy_retarget_io_init_fc() |
| cy_retarget_io_init_fc() | 5 args: pins + flow control | Full control with CTS/RTS | |
| cy_retarget_io_init_hal() | 0 args | Assumes cy_retarget_io_uart_obj pre-initialized | |
| PDL-Only (no HAL) | cy_retarget_io_init() | 1 arg: SCB UART peripheral pointer | Not thread-safe |
include "cy_retarget_io.h".cy_retarget_io_init(&DEBUG_UART_hal_obj);.printf().cy_retarget_io_change_baud_rate(): Cy_SysPm_RegisterCallback either the predefined mtb_syspm_scb_uart_deepsleep_callback from the syspm-callbacks asset or a new callback function specific to the needs of the user. For more info refer to Cy_SysPm_RegisterCallback in PDL documentation.include "cy_retarget_io.h"Choose one of the initialization options:
Basic initialization (3 parameters):
With flow control (5 parameters):
Pre-initialized UART object (0 parameters):
CYBSP_DEBUG_UART_TX and CYBSP_DEBUG_UART_RX pins are defined in the BSP and CY_RETARGET_IO_BAUDRATE is set to 115200. You can use a different baud rate if you prefer.
printf()These instructions apply when the UART interface is provided by the SCB peripheral directly using a PDL configured and initialized SCB object. Only relevant when HAL is unavailable. UART interfaces other than SCB are not supported at this time.
include "cy_retarget_io.h"cy_retarget_io_init(DEBUG_UART_HW);printf()The retarget-io library provides a function to dynamically change the UART baud rate at runtime when using MTB-HAL configuration:
This function operates on the UART object that was initialized with cy_retarget_io_init(), so no UART object parameter is needed.
baud_rate: Desired baud rate (e.g., 9600, 115200, 230400)actual_baud: Pointer to store the actual baud rate achievedcy_retarget_io_init() before calling this functionmtb_hal_uart_set_baud() to leverage HAL's built-in baud rate configuration expertiseCOMPONENT_MTB_HAL is definedmtb_hal_uart_set_baud() for reliable cross-platform baud rate configurationThe difference between \n and \r\n relates to different line ending conventions:
\n (Line Feed, LF)**: Used by Unix/Linux/macOS systems\r\n (Carriage Return + Line Feed, CRLF)**: Used by Windows systems \r (Carriage Return, CR)**: Used by old Mac systems (pre-macOS)When sending text over UART to a terminal:
\n only**: Moves cursor to the next line but may not return to the beginning of the line on some terminals\r\n**: Properly moves cursor to the beginning of the next line on all terminalsIf you want to use only \n instead of \r\n for printing a new line using printf(), define the macro CY_RETARGET_IO_CONVERT_LF_TO_CRLF using the DEFINES variable in the application Makefile. The library will then automatically append \r before each \n character on the output (STDOUT). No conversion occurs if \r\n is already present in the string.
Example without conversion:
May display as:
Example with conversion (CY_RETARGET_IO_CONVERT_LF_TO_CRLF defined):
Displays correctly as:
Recommendation: For embedded UART terminals, it's generally safer to either define CY_RETARGET_IO_CONVERT_LF_TO_CRLF in your Makefile or manually use \r\n in your printf strings to ensure proper line formatting across all terminal applications.
By default, floating point support is enabled in printf. If floating point values will not be used in printed strings, this functionality can be disabled to reduce flash consumption. To disable floating support, add the following to the application makefile: DEFINES += CY_RETARGET_IO_NO_FLOAT.
© Copyright 2018-2025 Infineon Technologies Apache2