previous

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 in Core/Src folder.

  • Add the following code to the file:

    printf_conf.c
    1#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 -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
    

4. Update main.c

  • Open Core > Src > main.c. Add stdio.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