[STM32] USB CDC Debugging
내가 사용하고 있는 보드 STM32F412ZG 는 ST-LINK 의 USB 포트 외에 추가 포트 1개가 더 있다. 아래 사진은 F412ZG는 아니지만 붉은색 박스와 같은 위치에 포트가 있다. (LAN 포트만 없다고 생각하면 된다)
이 USB 포트를 이용해서 UART 출력이 가능하다. 즉, 디버깅을 UART-USB 컨버터 필요 없이 간단하게 USB 케이블만 있으면 가능하다는 말이다. 매우 편리하다. 바로 적용에 앞서 해당 USB 에 대해 간단하게 기능을 짚고 넘어간다.
USB OTG란?
USB 온더고
(USB On-The-Go, USB OTG)는 2001년 말에 동의한 뒤 나중에 개정된 USB 2.0 규격에 제공된 한 기능으로, 컴퓨터를 통하지 않더라도 자료를 주고받을 수 있게 하는 USB 형식의 프로토콜이다. 'USB 호스트 기능' 으로도 불리며, 이 규격을 만족하는 물리적 장치는 'OTG 포트'라 한다.
USB OTG 기능을 사용하면 ST 보드와 주변기기 (예: 플래쉬 메모리)를 연결해서 ST 보드에서 직접 접근할 수 있게 HOST 역할을 지원하게 된다. 즉, ST 보드는 HOST와 Device 모두 지원한다는 뜻이다.
STM32F412ZG 에서 USB OTG를 사용하기 위해서는 아래와 같은 조건이 있다.
HOST 기능이 아닌 Device 기능으로 사용하기 때문에 Configuration - Connectivity - USB_OTG_FS 에서 Mode를 Device 로 변경한다.
VBUS에 대한 내용은 아래와 같다.
VBUS는 USB 시스템에서 전원 공급을 담당하는 전압 라인으로, USB 호스트가 디바이스에 전력을 공급하거나 디바이스가 연결 상태를 감지하는 데 중요한 역할을 합니다. STM32와 같은 마이크로컨트롤러에서도 USB OTG 모드에서 VBUS 핀을 통해 전원 관리와 장치 감지를 처리할 수 있습니다.
Middleware - USB_DEVICE 에서는 Class For FS IP 를 Communication Device Class 로 변경한다. 용어 CDC와 VCP에 대한 내용이다.
USB CDC (Communication Device Class) is a protocol specification for USB communication. There are many other USB classes that specify various protocols over the USB physical layer to enable communication of (data, audio, video devices, HID devices, mass storage, wireless controllers, and much more).
Virtual COM Port (VCP) is a Microsoft Windows interface to access different communication channels (e.g. Serial RS232, USB, etc) as if they were connected to a physical COM port. Therefore, the baud rate value in a serial terminal is meaningless for VCP.
출처: https://deepbluembedded.com/stm32-usb-cdc-virtual-com-port-vcp-examples/#stm32-usb-cdc-printf-example
Debugging을 위한 Serial 통신 write는 ST에서 제공하는 함수 CDC_Transmit_FS 로 구현 가능하다. 이 함수는 USB_DEVICE/App/usbd_cbc_if.c 에 정의되어 있다. 이 함수를 이용한 printf 구현은 아래와 같이 작성한다.
#include "usbd_cdc_if.h"
int _write(int file, char *ptr, int len)
{
uint8_t ret;
ret = CDC_Transmit_FS((uint8_t*) ptr, len);
if(USBD_OK != ret)
{
return (int)ret;
}
return len;
}
int main(void)
{
printf("hello, world\r\n");
HAL_Delay(500);
}
_write 함수는 syscalls.c 에 __attribute__((weak)) 로 정의되어 있어, 작성한 _write가 오버라이드 한다.
115200bps로 com port를 연결 후 "hello, world" 가 출력되는지 확인한다.