参考資料
Zynq Linux USB Device Driver
XilinxのWikiで、基本はこれを見ればUSB Gadgetの構成は出来る。Linux USB gadget configured through configfs
Linuxのドキュメントで、XilinxのWikiには書いていないGadgetの削除の方法が分かる。Raspberry Pi Zero as Multiple USB Gadgets
Raspberry Piで複数Gadgetを使う方法や、RNDISをWindowsに認識させる方法のヒントが書いてある。
やること
Linux Kernel Config
比較的新しいconfigfsでのUSB Gadget制御の仕組みを使うため、以下を有効にする。
その他必要な設定はおそらくデフォルトで有効になっているが、不安な場合はZynq Linux USB Device Driverを確認のこと。
Device Drivers > USB support > USB Gadget Support <M> USB functions configurable through configfs [*] RNDIS [*] Mass storage
Device Tree Source
- dr_mode: peripheralに変更(OTGでも大丈夫かもしれないが未確認)
- usb-phy: 指定が必要
--- a/xsdk/devicetree_bsp/pcw.dtsi Tue Jul 11 11:08:17 2017 +0900 +++ b/xsdk/devicetree_bsp/pcw.dtsi Fri Sep 15 20:48:37 2017 +0900 @@ -82,12 +82,24 @@ status = "okay"; }; &usb0 { - dr_mode = "host"; + dr_mode = "peripheral"; // for USB Gadget change from "host" phy_type = "ulpi"; status = "okay"; usb-reset = <&gpio0 7 0>; + usb-phy = <&usb_phy0>; // for USB Gadget }; &clkc { fclk-enable = <0x1>; ps-clk-frequency = <33333333>; }; + +// for USB Gadget +/ { + usb_phy0: phy0 { + compatible = "ulpi-phy"; + #phy-cells = <0>; + reg = <0xe0002000 0x1000>; + view-port = <0x170>; + drv-vbus; + }; +}; \ No newline at end of file
Gadgetの有効化
以下(usb_config_multi.sh
)を実行する。出来る限りコメントを書いた。
#!/bin/sh # https:/github.com/torvalds/linux/blob/master/Documentation/usb/gadget_configfs.txt # http:/irq5.io/2016/12/22/raspberry-pi-zero-as-multiple-usb-gadgets/ # 上記2つを参考に同時に二つのガジェットを有効化する。 # 1. mass storageで、SDカードをUSBメモリとして見せる # 2. rndisで、USBをetherデバイスとして見せる # ドライバを依存関係含めてロード modprobe usb_f_rndis modprobe usb_f_mass_storage # configfsをマウント mount -t configfs none /sys/kernel/config # usb_gadgetの下に任意のディレクトリを生成する g=/sys/kernel/config/usb_gadget/multi mkdir ${g} # USBの各種設定(VID/PIDは必須) echo "64" > ${g}/bMaxPacketSize0 echo "0x200" > ${g}/bcdUSB # USB2.0 echo "0x100" > ${g}/bcdDevice # 適当 echo "0x03FD" > ${g}/idVendor # Xilinx echo "0x0104" > ${g}/idProduct # Multifunction Composite Gadget # 複数functionのcomposite USB向けの設定 # refer: https://msdn.microsoft.com/en-us/library/windows/hardware/ff540054.aspx echo "0xEF" > ${g}/bDeviceClass echo "0x02" > ${g}/bDeviceSubClass echo "0x01" > ${g}/bDeviceProtocol # functionsに登録 mkdir ${g}/functions/rndis.rn0 mkdir ${g}/functions/mass_storage.ms0 # rndis固有の設定(設定しないとランダムなmacアドレスを生成する) # echo "${dev_mac}" > ${g}/functions/rndis.rn0/dev_addr # echo "${host_mac}" > ${g}/functions/rndis.rn0/host_addr # mass storage固有の設定 # fileにストレージとして見せるデバイスを指定する echo /dev/mmcblk0p1 > ${g}/functions/mass_storage.ms0/lun.0/file echo 1 > ${g}/functions/mass_storage.ms0/lun.0/removable # functionとconfigを関連付け mkdir ${g}/configs/c.1 ln -s ${g}/functions/rndis.rn0 ${g}/configs/c.1/ ln -s ${g}/functions/mass_storage.ms0 ${g}/configs/c.1/ # rndisをwindowsで見えるようにするための設定 echo "1" > ${g}/os_desc/use echo "0xcd" > ${g}/os_desc/b_vendor_code echo "MSFT100" > ${g}/os_desc/qw_sign echo "RNDIS" > ${g}/functions/rndis.rn0/os_desc/interface.rndis/compatible_id echo "5162001" > ${g}/functions/rndis.rn0/os_desc/interface.rndis/sub_compatible_id ln -s ${g}/configs/c.1 ${g}/os_desc # デバイス有効化 echo "ci_hdrc.0" > ${g}/UDC
Gadgetの動作確認
Mass Storageは接続するだけでSDカードの中身が見える。
Etherは、Zynq側で以下を実行しておくとPCで接続したときにネットワークデバイスとして見える。
ifconfig usb0 192.168.1.2 # 好きなIPアドレスを設定 ifconfig usb0 up # network起動
Gadgetの削除
以下(usb_remove_multi.sh
)を実行する。Gadgetの有効化で使用したusb_config_multi.sh
と対応している。
#!/bin/sh # https://github.com/torvalds/linux/blob/master/Documentation/usb/gadget_configfs.txt # http://irq5.io/2016/12/22/raspberry-pi-zero-as-multiple-usb-gadgets/ # 上記を参考にusb_config_multi.shで追加したガジェット2つを無効化する。 # ガジェットを無効化 g=/sys/kernel/config/usb_gadget/multi echo "" > ${g}/UDC # functionsのsimlink先を削除 rm ${g}/os_desc/c.1 rm ${g}/configs/c.1/rndis.rn0 rm ${g}/configs/c.1/mass_storage.ms0 # Configurationsを削除 rmdir ${g}/configs/c.1/ # functionsのsimlink元を削除 rmdir ${g}/functions/rndis.rn0 rmdir ${g}/functions/mass_storage.ms0 # gadget本体を削除 rmdir ${g} # ドライバを依存関係含めてアンロード modprobe -r usb_f_rndis modprobe -r usb_f_mass_storage # configfsをアンマウント umount /sys/kernel/config