본문 바로가기
DSP, MCU/STM32 (ARM Cortex-M)

STM32 , printf 디버깅에 사용하기 1편 ( UART 통신 )

by eteo 2022. 6. 6.

 

STM32CubeIDE에서는 표준출력함수인 printf 를 사용하기 위해서는 표준 출력 대상인 콘솔창이 없으니 리다이렉션하여 써야하는데 이번엔 그 중 UART를 통해 printf 함수를 쓰는 방법을 소개한다.

 

SWV / ITM 통해 printf 사용하는 버전 링크 : 2022.06.06 - [MCU/STM32 (ARM Cortex-M)] - STM32 , printf 디버깅에 사용 & 변수 값 그래프로 출력하기 2편 ( SWV / ITM )

 

 

 

1. 먼저 CubeMX에서 UART 설정을 해준다.

 

 

 

 

 

 

2. 코드에 표준입출력 헤더파일을 포함한다.

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

 

 

 

 

 

 

3. main함수 들어가기전에 _write 함수나 __io_putchar 함수를 재정의해준다.

 

printf 함수가 호출되면 _write 함수가 호출되고 _write 함수가 다시 __io_putchar 함수를 호출하는 구조인데 Src폴더의 syscall.c 파일에 __attribute__((weak)) 처리되어 있다.

 

 

/* USER CODE BEGIN PFP */
int _write(int file, char* p, int len){
	HAL_UART_Transmit(&huart3, p, len, 10);
	return len;
}
/* USER CODE END PFP */

또는

/* USER CODE BEGIN PFP */
int __io_putchar(int ch){
	HAL_UART_Transmit(&huart3, &ch, 1, 1000);
    return ch;
}
/* USER CODE END PFP */

 

 

혹은 아래와 같은 방법도 가능하다.

#ifdef __GNUC__
  /* With GCC, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);

  return ch;
}

 

하나 선택해주면 된다.

 

 

 

 

4. 테스트용 소스코드 작성

  /* USER CODE BEGIN 2 */
  uint8_t count=0;
  float f = 1.234;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  printf("hello : %d, %f\r\n", count++, f++);
	  HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

 

 

 

 

 

 

 

 

 

5. 실수 출력하는방법

 

프로젝트 오른쪽 클릭 - properties

 

 

 

C/C++ Build - Settings - Tool Settings - MCU GCC Linker - Other flags 추가

추가후 Apply 하면 실수까지 출력 가능하다.

-u _printf_float

 

 

 

 

 

 

 

6. 주의점

 

printf 함수 사용시 개행문자(\n)를 써야 제대로 출력이 된다.

개행문자를 안써도 출력이 되게끔 하려면 setbuf나 servbuf함수를 사용해서 stdout 의 버퍼 mode를 바꿔야한다.