안경잡이개발자

728x90
반응형

※ 기초 설정 ※

 

  /boot/config.txt 파일을 열어서 제일 마지막 줄에 다음의 코드를 추가한다.

 

dtoverlay=dwc2

 

  /etc/modules의 마지막 줄에 다음 두 개의 커널 모듈을 넣어주자. 

 

dwc2 
libcomposite 

 

  이후에 Mass Storage Class의 기능을 위해 하나의 블록 디바이스(block device)를 생성한다.

 

mkdir -p /home/pi/images

# 1Gb 이미지 생성
dd if=/dev/zero of=/home/pi/images/usbdisk1.img bs=1048576 count=1024
mkdosfs /home/pi/images/usbdisk1.img

 

※ Configuration 1 ※

 

  첫 번째 Configuration인 /usr/bin/my_usb1을 생성해 보자.

 

sudo touch /usr/bin/my_usb1 # 파일 생성
sudo chmod +x /usr/bin/my_usb1 # 실행할 수 있도록 만들기
sudo nano /usr/bin/my_usb1 # 스크립트 작성하기

 

  구체적인 스크립트는 다음과 같다.

 

#!/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/acm.usb0
ln -s functions/acm.usb0 configs/c.1/

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

################# Mass Storage 1 #################
# 첫 번째 이미지 지정하기
FILE1=/home/pi/images/usbdisk1.img

# 해당 이미지에 마운트(mount) 진행하기
mkdir -p ${FILE1/img/d}
mount -o loop,ro, -t vfat $FILE1 ${FILE1/img/d} # 라즈베리 파이 입장에서는 읽기 전용(read-only)

# USB 기능(function) 작성하기 (kernel.org reference 참고하기)
mkdir -p functions/mass_storage.usb0
echo 1 > functions/mass_storage.usb0/stall
echo 0 > functions/mass_storage.usb0/lun.0/cdrom
echo 0 > functions/mass_storage.usb0/lun.0/ro # 호스트 입장에서는 쓰기 가능
echo 0 > functions/mass_storage.usb0/lun.0/nofua
echo $FILE1 > functions/mass_storage.usb0/lun.0/file # 이미지 파일 명시하기

# 만들어진 기능(function) 사용할 수 있도록 설정
ln -s functions/mass_storage.usb0 configs/c.1/

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

 

※ Configuration 2 ※

 

  두 번째 Configuration인 /usr/bin/my_usb2를 생성해 보자.

 

sudo touch /usr/bin/my_usb2 # 파일 생성
sudo chmod +x /usr/bin/my_usb2 # 실행할 수 있도록 만들기
sudo nano /usr/bin/my_usb2 # 스크립트 작성하기

 

  구체적인 스크립트는 다음과 같다.

 

#!/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/acm.usb0
ln -s functions/acm.usb0 configs/c.1/

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

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

 

※ 스크립트 자동 실행 ※

 

  스크립트를 부팅 시 자동 실행하도록 만들기 위해 /etc/rc.local을 수정한다.

 

sudo nano /etc/rc.local

 

  이후에 exit 0 위쪽 라인에 /usr/bin/my_usb1을 추가하자. 재부팅 이후에 USB device가 잡히는 것을 확인할 수 있다.

 

 

※ 선택적으로 USB Configuration 변경하기 ※

 

  이제 /etc/rc.local에 내용을 더 추가하자.

 

cat /dev/ttyGS0 >> /home/pi/test.dat &

 

 

  기본적으로 test.dat은 첫 번째 USB Configuration 정보를 가지도록 한다.

 

echo A > /home/pi/test.dat

 

  이후에 /etc/rc.local을 아래 내용을 넣는 방식으로 바꾼다. test.dat의 가장 마지막 문자열이 A일 때는 첫 번째 Configuration, B일 때는 두 번째 Configuration을 이용한다.

 

var=$(cat /home/pi/test.dat)
flag="${var: -1}"

if [ $flag == "A" ]
then
    /usr/bin/my_usb1
else
    /usr/bin/my_usb2
fi

 

 

  만약 정상적으로 동작이 안 된다면 동일한 스크립트를 작성한 뒤에 sudo bash 명령으로 실행해보자. 호스트 쪽에서 신호를 보낼 때는 다음과 같이 한다.

 

import serial

s = serial.Serial("COM6", 115200)
s.write(b'A\n')
s.close()
728x90
반응형