Building Linux usb device drivers with 2021.1
The guide below shows you how to build USB drivers & boot the board and then run some example configurations (Host, Device, OTG mode of PS USB controller ) on Versal platform.
The steps below use PetaLinux and assume you have some knowledge of using PetaLinux.
Table of Contents
Introduction
The USB controller can be configured as host, device, or on-the-go (OTG).
The core is compliant to USB 2.0 specification and supports high, full, and low-speed modes in all configurations.
In host mode, the USB controller is compliant with the Intel XHCI specification. In device mode, it supports up to 12 end points.
The universal low peripheral interface (ULPI) is used to connect the controller to an external PHY operating up to 480 Mb/s.
Versal supports only USB 2.0 protocol.
Provided below test cases are proven on vck190-es1 board with 2021.1 release.
ZynqMP Vs Versal USB controller support
Peripheral | Zynq UltraScale+ MPSoC | Versal Adaptive SoC |
USB 3.0 (host, device, dual-role device) | 2 controllers | N/A |
Usb 2.0 (host, device, on-the-go) | 2 controllers | 1 controller |
Hardware Setup
Boards: VCK190-ES1 Board
Host Machine: Linux Machine with USB ports (OR) Windows Machine
Software Setup
Linux Kernel image with xHCI Host enabled (static) and Mass Storage Gadget created as static or dynamic
Boot image for initial FSBL sequence
Device tree with DWC USB DWC3_DUAL mode enabled
Petalinux build steps
source <PATH TO PETALINUX INSTALLATION>/petalinux-v2021.1-final/settings.sh
petalinux-create -t project -s <PATH to BSP>/xilinx-vck190-es1-v2021.1-final.bsp
petalinux-config
petalinux-build
petalinux-package --boot --plm --psmfw --u-boot --dtb
Host Mode
USB HOST mode Jumper settings
Note: Need to short the J300 Jumper for Host Mode
Jumper 1-2 –--- short (The shield for the USB 2.0 type-A connector (J308) can be tied to GND by a jumper on header J300 pins 1-2 (default))
Kernel Configuration
By enabling the above we need to see the below mentioned Kconfig parameter enabled
CONFIG_USB_DWC3 = y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_DUAL_ROLE=y
CONFIG_USB_DWC3_OF_SIMPLE=y
# USB HID support
CONFIG_USB_HID=y
# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
# Miscellaneous USB options
CONFIG_USB_DEFAULT_PERSIST=y
CONFIG_USB_OTG=y
CONFIG_USB_OTG_FSM=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_PLATFORM=y
CONFIG_USB_STORAGE=y
# USB Physical Layer drivers
CONFIG_USB_PHY=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
CONFIG_USB_LIBCOMPOSITE=y
CONFIG_USB_U_ETHER=y
CONFIG_USB_F_RNDIS=y
CONFIG_USB_F_MASS_STORAGE=y
CONFIG_USB_F_FS=y
CONFIG_USB_F_UVC=y
CONFIG_USB_F_HID=y
CONFIG_USB_CONFIGFS=y
CONFIG_USB_CONFIGFS_RNDIS=y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
CONFIG_USB_CONFIGFS_F_FS=y
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_USB_CONFIGFS_F_UVC=y
Device Tree
Edit the following file and make the following changes.
“<path to petalinux project >/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi"
After the build is finished, we should see below device tree changes in system.dts file once after converting system.dtb to sytem.dts using " dtc -I dtb -O dts -o system.dts system.dtb" command.
Note: dtc command by default not available on host side , please install using the “sudo apt-get install device-tree-compiler” command.
Test Procedure
Connect the USB 3.0/2.0 pendrive to USB 2.0 capable board and see it getting detected in /dev/sd<x>.
Logs
Once Linux boots the below highlighted prints should be visible when we connected the mass storage device
root@xilinx-vck190-es1-2021.1 :~#root@xilinx-vck190-es1-2021.1 :~#
[ 40.344230] usb 1-1: new high-speed USB device number 2 using xhci-hcd
[ 40.497113] usb 1-1: New USB device found, idVendor=8564, idProduct=1000, bcdDevice=11.00
[ 40.505293] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 40.512428] usb 1-1: Product: Mass Storage Device
[ 40.517134] usb 1-1: Manufacturer: JetFlash
[ 40.521315] usb 1-1: SerialNumber: 152RHUF276CIFPSR
[ 40.526966] usb-storage 1-1:1.0: USB Mass Storage device detected
[ 40.533570] scsi host0: usb-storage 1-1:1.0
[ 41.949684] scsi 0:0:0:0: Direct-Access JetFlash Transcend 32GB 1100 PQ: 0 ANSI: 6
[ 41.960284] sd 0:0:0:0: [sda] 59725824 512-byte logical blocks: (30.6 GB/28.5 GiB)
[ 41.968608] sd 0:0:0:0: [sda] Write Protect is off
[ 41.973581] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 41.984408] sda: sda1
[ 41.987825] sd 0:0:0:0: [sda] Attached SCSI removable disk
[ 42.146068] FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
Peripheral Mode
USB jumper settings for Peripheral mode
Note: Need to open the J300 Jumper for device mode.
Jumper 1-2 –--- Open (The shield for the USB 2.0 type-A connector (J308) can be disconncted/floating from GND by removing the jumper on header J300 pins 1-2 (default))
Note: This same peripheral mode Jumpers can be used for all the Gadgets .
Kernel configurations
This document only explains the USB 2.0 peripheral mode configurations for MASS STORAGE gadget
Device Drivers --->[*] USB support ---> <*> USB Gadget Support --->
By enabling the above we need to see the below mentioned Kconfig parameter enabled
Device Tree
Edit the following file and make the following changes.
"<path to petalinux project >/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi"
Steps to test peripheral mode
Please use the below settings for configuring USB as MASS STORAGE profile in device mode:
Testing the mass storage functionality by connecting the board to windows host using the below steps:
Connect the cable from board to windows host machine
Format the mass storage device that got detected in windows
The windows screen shot when we the device gets detected should be as below
The board will be detected as mass storage drive with size 256 MB
5 .Copy some files into the mass storage drive , remove the cable and connect it again. We should be able to see the files that we copied into the drive.
Logs
If we connect the cable from board to Linux host machine then below are the logs:
Linux Host side logs
OTG Mode
USB jumper settings for OTG mode
Kernel Configurations
By enabling the above we need to see the below mentioned Kconfig parameter enabled
Device Tree
Edit the following file and make the following changes.
"<path to petalinux project >/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi"
Steps to test OTG
When the Linux kernel boots up, give the below commands:
Peripheral Mode
Connect board to any Host PC via USB Std-A-Male to Micro-B-Male cable.
It should be detected as a Mass Storage Device
Do some data transfers
Host Mode
Connect any pen-drive with the board via USB Micro-A-Male to Std-A-Female type connector
Check that the pen-drive is detected properly
Do some data transfers.
Note : Both Host and Peripheral mode should work without resetting/rebooting the board.
Logs
Remove the USB cable connected between host and target board & connect the USB flash storage drive(pendrive) & check is it properly detected or not.
Host machine side logs
Ethernet Gadget
Kernel Configurations
Device Drivers --->[*] USB support ---> <*> USB Gadget Support --->
By enabling the above we need to see the below mentioned Kconfig parameter enabled
Device Tree
Edit the following file and make the following changes.
"<path to petalinux project >/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi"
Steps to test Ethernet Gadget
Please use the below settings for configuring USB as ETHERNET gadget profile in device mode:
Logs
Note: After running the "ifconfig -a" , we should be able to see the usb0 interface with ipaddress 10.10.70.1
Host machine side logs
Composite gadget
Kernel configurations
By enabling the above we need to see the below mentioned Kconfig parameter enabled
Device Tree
Edit the following file and make the following changes.
<path to petalinux project >/project-spec/meta-user/recipe-bsp/device-tree/system-user.dtsi
Steps to test Composite Gadget
When the Linux kernel boots up, give the below commands:
Logs
Host machine side logs
HID Gadget
Kernel configurations
Device Drivers --->[*] USB support ---> <*> USB Gadget Support --->
By enabling the above we need to see the below mentioned Kconfig parameter enabled
Device Tree
Edit the following file and make the following changes.
"<path to petalinux project >/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi"
Steps to test HID Gadget
Logs
Host machine side logs
Audio Gadget
Kernel configurations
For reference Attaching complete kernel config file: kernel_config.txt
Device Tree
Edit the following file and make the following changes.
<path to petalinux project >/project-spec/meta-user/recipe-bsp/device-tree/system-user.dtsi
Steps to test Audio Gadget
When the Linux kernel boots up, give the below commands:
Logs
Host side machine logs
UVC Gadget
Kernel configurations
For reference Attaching complete kernel config file:
Device Tree
Edit the following file and make the following changes.
<path to petalinux project >/project-spec/meta-user/recipe-bsp/device-tree/system-user.dtsi
Steps to add uvc-gadget test application to petalinux project
Create an empty app and populate with uvc-gadget test application
petalinux-create -t apps -n uvc-gadget --enable
2. Clone the source repo in the app file folder
git clone https://github.com/wlhe/uvc-gadget.git project-spec/meta-user/recipes-apps/uvc-gadget/files/
3. Edit the recipe to add the appropriate files to the build
"project-spec/meta-user/recipes-apps/uvc-gadget/uvc-gadget.bb"
SUMMARY = "Simple uvc-gadget application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://uvc-gadget.c
file://uvc.h
file://Makefile
"
#INHIBIT_PACKAGE_STRIP = 1
S = "${WORKDIR}"
do_compile() {
oe_runmake
}
do_install() {
install -d ${D}${bindir}
install -m 0755 uvc-gadget ${D}${bindir}
}
4. Edit the Makefile so that it works with Petalinux
“project-spec/meta-user/recipes-apps/uvc-gadget/files/Makefile”
APP = uvc-gadget
APP_OBJS = uvc-gadget.o
all: $(APP)
$(APP): $(APP_OBJS)
$(CC) $(LDFLAGS) -o $@ $(APP_OBJS) $(LDLIBS)
clean:
-rm -f $(APP) *.elf *.gdb *.o
Steps to test UVC Gadget
When the Linux kernel boots up, give the below commands:
Logs
Output:
We should see the uvc gadget interface on host side.
Open zoom app -> settings -> video -> Select Camera as "UVC Camera" then it will stream the video
References
Zynq Ultrascale MPSOC Linux USB device driver
© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy