안경잡이개발자

728x90
반응형

  리눅스에서는 USB Gadget 목적으로 사용할 수 있는  usb_f_gser.ko 리눅스 커널 모듈을 제공한다. 이는 단순히 하나의 Bulk Transfer를 기반으로 하는 Interface를 생성할 수 있도록 해준다. 사실 일반적으로 Serial 통신을 사용다고 하면 CDC(Communication Device Class)를 이용하는데, 이러한 CDC는 ACM, OBEX 등 다양한 서브 클래스를 가진다. CDC는 시리얼 통신을 기반으로 동작하는데, 비단 Serial 뿐 아니라 Ethernet 등의 기능도 제공할 수 있도록 한다.

 

  하지만 만약에 그냥 Raw Bulk Transfer를 이용하는 인터페이스를 이용하고자 한다면 기본적인 Serial Function인 usb_f_gser.ko를 이용하면 된다. 예를 들어 자신이 직접 USB 장치를 만들고, 필요하다면 호스트 쪽 드라이버를 직접 작성하고자 한다면 이것이 좋은 선택이 될 수 있다.

 

※ USB Configuration 파일 생성 ※

 

  간단히 USB Configuration 파일을 생성해보자. 단순히 두 개의 Bulk Transfer를 정의한 상태이다. 필자는 /usr/bin/my_usb라는 경로에 해당 설정 파일을 만들었고, chmod 명령어로 실행 권한을 부여했다.

 

#!/bin/bash
cd /sys/kernel/config/usb_gadget/
mkdir -p my_usb
cd my_usb

# 기본적인 USB 클래스 명시
echo 0x1D6B > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB 2.0

# 내가 만들 USB 장치의 기본적인 이름
mkdir -p strings/0x409
echo "0123456789abcdef" > strings/0x409/serialnumber
echo "Dongbin Na" > strings/0x409/manufacturer
echo "My USB" > strings/0x409/product

# 하나의 Configuration 정보 작성
mkdir -p configs/c.1/strings/0x409
echo "My USB Config 1" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower

################# Bulk Transfer 1 #################
mkdir -p functions/gser.usb0
ln -s functions/gser.usb0 configs/c.1/

################# Bulk Transfer 2 #################
mkdir -p functions/gser.usb1
ln -s functions/gser.usb1 configs/c.1/

# UDC (Usb Device Controller)
ls /sys/class/udc > UDC

 

  이후에 해당 환경 파일을 실행하면, Rapsberry Pi Zero W가 2개의 Bulk Transfer 통신 기능을 가지는 기기로 동작한다. 다만 CDC ACM과 같이 이미 잘 알려진 클래스를 사용하는 것이 아니기 때문에 다음과 같이 "드라이버를 찾을 수 없다"는 메시지가 출력되는 것을 확인할 수 있다.

 

 

  물론 이처럼 드라이버를 찾을 수 없다고 출력이 되더라도 USB Descriptor는 정상적으로 전달이 되기 때문에, 호스트(Host) PC 입장에서는 해당 Bulk Transfer의 엔드포인트(endpoint)에 접근할 수 있다. 실제로 USB Descriptor를 확인할 수 있는 프로그램을 사용하여 정보를 출력하면 다음과 같이 나온다. 이때 윈도우(Windows)의 Thesycon USB Descriptor Dumper를 사용하거나, 우분투(Ubuntu)의 lsusb 명령어를 사용할 수 있다.

 

  확인 결과 2개의 인터페이스(Interface)가 존재하며, 필요한 최소한의 엔드포인트만을 가지고 있는 것을 알 수 있다. 참고로 CDC ACM과 같은 클래스는 단순히 Bulk Transfer만 가지고 있는 것이 아니며, 더 많은 기능을 포함하고 있어서 엔드포인트(endpoint)가 더 많이 붙어 있다.  아무튼 Interface Descriptor를 출력한 결과는 다음과 같다.

 

 

※ Device 프로그램 ※

 

  Device 쪽 프로그램에서는 단순히 데이터를 읽어 올 때는 cat /dev/{장치명}을 하고, 데이터를 출력할 때는 echo를 이용해 /dev/{장치명}에 데이터를 쓰면 된다. 참고로 단순히 데이터를 보내게 되면 개행 문자가 자동으로 치환되어서 raw 데이터가 잘 안 보내질 수 있다. 따라서 다음의 명령어를 먼저 실행해준다.

 

sudo stty -F /dev/ttyGS1 raw
sudo stty -F /dev/ttyGS2 raw

 

  매번 다음의 명령어를 실행해주지 않는다면, 호스트(Host) PC에서 개행문자를 포함할 때에만 정상적으로 데이터가 전송된다. 따라서 이를 참고하자.

728x90
반응형

Comment +0