Printf over USB
1. Introduction
We cannot understand non character data type after printed on screen. In order to see them clearly, we need to first convert them to ASCII
using snprintf
function. Rather than using CDC_Transmit_FS
, we can overwrite the definition of printf
function to print on USB neatly.
2. Overwrite Definition of printf
Create a new file
printf_conf.c
inCore/Src
folder.Add the following code to the file:
printf_conf.c1#include "stm32f4xx_hal.h" 2#include "usbd_cdc_if.h" 3 4int _write(int file, char *data, int len) 5{ 6 CDC_Transmit_FS((uint8_t*)data, (uint16_t)len); 7 return len; 8}
3. Update Makefile or CMakeLists.txt
Add
printf_config.c
to source.C_SOURCES = \ ... \ ... \ Core/Src/printf_conf.c
# Add sources to executable target_sources(${CMAKE_PROJECT_NAME} PRIVATE # Add user sources here Core/Src/printf_conf.c )
Add
-u _printf_float
flag.Add to
LDFLAGS
.LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections LDFLAGS += -u _printf_float
Create target_link_options at the bottom.
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE -u _printf_float )
4. Update main.c
Open
Core > Src > main.c
. Addstdio.h
header./* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include <stdio.h> #include "usbd_cdc_if.h" /* USER CODE END Includes */
Update
main
function to print “Hello World” over USB./* USER CODE BEGIN 2 */ uint32_t n = 0; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { printf ("Hello World! %lu\n", n++); HAL_Delay(100); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */
Now you can build and flash the code. See the output on terminal
or Serial Monitor
as previous.
References
References are from CMSIS
documentation.
- uint32_t ITM_SendChar(uint32_t ch)
ITM Send Character.
Details: - Transmits a character via the ITM channel 0. - Just returns if no debugger is connected that has booked the output. - Is blocking if a debugger is connected, but the previous character sent has not been transmitted.
- Parameters:
ch (uint32_t) – Character to transmit.
- Returns:
The transmitted character.
- Return type:
uint32_t