Lukas Petrikas
Lukas Petrikas

Reputation: 85

STM32F767 Nucleo board printf to console

For the last couple of days I have been trying to get printf to work to print a debug message to a STM32CubeIDE console. However, without any luck. I have gone through numerous forum threads and discussions and none of them appear to have fully solved this weird issue that is well known.

I have just generated a brand new project with STM32CubeMX and used a default configuration for the Nucleo board. I am just using a USB cable with a built-in ST-LINK to program the device.

So far, I have been suggested to add a few lines of code that apparently should have fixed the issue, but it didn’t:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif


PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);

  return ch;
}

I have also included:

#include "stdio.h"

The actual code:

int main(void)
{
  /* USER CODE BEGIN 1 */
    uint8_t uart3_data[20] = "Hello from UART 3";
    uint8_t uart1_data[20] = "Hello from UART 1";
  /* USER CODE END 1 */


  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals. Initializes the flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */


  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */


  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_USART1_UART_Init();
  MX_TIM10_Init();

  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim10);
  /* USER CODE END 2 */


  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */
      //Toggle_leds(GPIOB,GPIO_PIN_0,100);

      HAL_Delay(1000);
      printf("UART Printf Example: retarget the C library printf function to the UART \n\r");
      printf("** Test finished successfully. ** \n\r");
      HAL_UART_Transmit(&huart3,uart3_data, sizeof(uart3_data), 50); // just to see what happens

      //HAL_UART_Transmit(&huart1,uart1_data, sizeof(uart1_data), 50); // just to see what happens
  }
  /* USER CODE END 3 */


}

When I open up a terminal and connect to the device, I can see the messages coming as expected:

Enter image description here

However, I cannot understand why I am not able to see messages displayed on the STM32CubeIDE console. Am I missing some additional configuration?

Upvotes: 1

Views: 10019

Answers (1)

Lukas Petrikas
Lukas Petrikas

Reputation: 85

I have managed to get it working. Those who are having the same problem, just follow these simple steps:

  1. Add a custom _write function to syscalls.c or even main.c:

    int _write(int file, char *ptr, int len)
    {
      /* Implement your write code here. This is
         used by puts and printf for example */
      int i=0;
      for(i=0 ; i<len ; i++)
        ITM_SendChar((*ptr++));
      return len;
    }
    
  2. In the debug configuration, enable the SWV tracing and set the core clock to the SYSCLK of your device (see the image below).

    Debug configuration

  3. Debug your code and go to Windows → Show viewSWVSWV ITM Data console

    Now you should have enabled SWV data console. Check the image below:

    SWV ITM Data console

  4. Open up the SWV ITM Data console settings and make sure the port 0 is ticked (see the image below):

    Enable port 0

  5. When you run the code, make sure start tracing is enabled:

    Enable start tracing

  6. Have fun printing message to the console

A detailed guide on YouTube can be found in 5. Tutorial. Use Serial Wire Viewer (SWV/SWO) via printf to debug STM32 in STM32CubeIDE.

Unfortunately, there is still a hassle using this method. Every time you debug your code, you need to start tracing. There must be a simple method to display a message in the console without using the tracing.

Upvotes: 2

Related Questions