Use Cases

1. Application Logging Over UART

This use case illustrates printf-based application logging over UART. It requires:

  • UART interface configured for TX (baud rate, pins, instance).

  • Basic STDIO initialized with the selected UART interface.

  • A UART terminal or viewer connected to the target port.

@startuml

title **Basic STDIO stdout redirection over UART**



participant "User Application" as UA

participant "libc" as libc

participant "'Basic STDIO' utility" as UT_BS

participant "'Basic STDIO' interface" as I_BS

participant "HAL" as HAL



group  #LightYellow "Initialization"

	UA  --> HAL : HAL_UART_Init(&USART1, HAL_UART1);



	UA  --> UT_BS : BASIC_STDIO_Init(&USART1);

	UT_BS --> I_BS: interface_io_Init(&USART1);

end



group #LightBlue "Process: infinite loop"

	UA    --> libc  : printf("This is a log message");

	alt GCC (_write)

		libc  --> UT_BS : _write(stdout, "This is a log message")

	else IAR (__write)

		libc  --> UT_BS : __write(stdout, "This is a log message")

	else Others: armclang, older runtimes (fputc)

		libc  --> UT_BS : fputc(c)

		note right of libc

		called once per character

		end note

	end

	UT_BS --> I_BS  : interface_io_Send(puartObj,\n"This is a log message", 22);

	I_BS  --> HAL   : HAL_UART_Transmit(puartObj,\n"This is a log message", 22);

end

@enduml

This is useful for early board bring-up and lightweight runtime logging in the main loop.

2. Conditional Prints

This use case illustrates build-time conditional prints that keep or remove messages without modifying the application code. It requires:

  • A wrapper macro PRINTF(...) defined as below.

  • Build flag USE_TRACE=1 to enable, or USE_TRACE=0 to disable (calls are removed at preprocessing time and arguments are not evaluated).

  • Output interface configured and Basic STDIO initialized when enabled.

Example:

/* Conditional print macro.
 * Enable with USE_TRACE=1.
 * When disabled (USE_TRACE undefined or 0), no code is generated.
 */
#if defined(USE_TRACE) && (USE_TRACE != 0)
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif

This use case helps remove all runtime prints in production builds, skip argument evaluation (for better performance), reduce the flash footprint, and keep the original source readable without modifications.