How to use the UVC gadget driver in Linux
This page is under construction. Please Contact RidgeRun OR email to support@ridgerun.com if you have any questions. |
UVC Gadget
UVC or USB Video Class is a USB specification created by the USB Implementers Forum (USB-IF) and it is intended to standardize the video streaming functionality on the USB, that is, if you want to create a USB embedded device capable of sending video over the USB port and compatible with most operating systems and applications, then you need to implement the UVC specification.
Linux-based operating systems as well as others, have support for UVC based devices such as webcams, acting as a host for the device. In the case of the device side, also known as the gadget, the driver support is usually proprietary depending on the manufacturer. The Linux kernel has added an implementation of a UVC gadget driver to its mainline in order to help developers to create Linux based devices with UVC support. Besides those efforts, the current UVC driver does not implement all the UVC specifications and it is quite hard to configure and use, depending heavily on a userspace application in order to complete the enumeration process and start the video streaming.
This wiki page shows you how to configure and use the Linux UVC gadget driver. The user has 2 ways of configuring a UVC gadget: using the g_webcam kernel module and through configfs. Following you will find the instructions for both methods.
Using kernel g_webcam module
The Webcam Gadget acts as a composite USB Audio and Video Class device. It provides a userspace API to process UVC control requests and stream video data to the host. In order to enable the module, make sure the CONFIG_USB_G_WEBCAM module is selected in kernel configuration:
Symbol: USB_G_WEBCAM [=m] Type : tristate Prompt: USB Webcam Gadget Location: -> Device Drivers -> USB support (USB_SUPPORT [=y]) -> USB Gadget Support (USB_GADGET [=m]) -> USB Gadget precomposed configurations (<choice> [=m]) Defined at drivers/usb/gadget/legacy/Kconfig:480 Depends on: <choice> && VIDEO_DEV [=m] Selects: USB_LIBCOMPOSITE [=m] && VIDEOBUF2_VMALLOC [=n] && \ USB_F_UVC [=n]
After the module has been enabled and built, in order to use it you have to load it as follows:
modprobe g_webcam
After this, a new /dev/videoXdevice will be created that will be used by the user space application.
Using configfs
Configfs allow Userspace-driven kernel object configuration. Configfs is a ram-based filesystem that provides the converse of sysfs's functionality. Where sysfs is a filesystem-based view of kernel objects, configfs is a filesystem-based manager of kernel objects, or config_items.
A configfs config_item is created via an explicit userspace operation: mkdir. It is destroyed via rmdir. The attributes appear at mkdir time, and can be read or modified via reading and writing. Unlike sysfs, the lifetime of the representation is completely driven by userspace. The kernel modules backing the items must respond to this.
Enabling configfs
First, you have to make sure that configfs is enabled:
Symbol: USB_CONFIGFS [=m] Type : tristate Prompt: USB Gadget functions configurable through configfs Location: -> Device Drivers -> USB support (USB_SUPPORT [=y]) -> USB Gadget Support (USB_GADGET [=m]) Defined at drivers/usb/gadget/Kconfig:220 Depends on: USB_SUPPORT [=y] && USB_GADGET [=m] Selects: USB_LIBCOMPOSITE [=m]
Then, make sure the UVC function is also selected:
Symbol: USB_CONFIGFS_F_UVC [=y] Type : boolean Prompt: USB Webcam function Location: -> Device Drivers -> USB support (USB_SUPPORT [=y]) -> USB Gadget Support (USB_GADGET [=m]) -> USB Gadget functions configurable through configfs (USB_CONFIGFS [=m]) Defined at drivers/usb/gadget/Kconfig:445 Depends on: USB_SUPPORT [=y] && USB_GADGET [=m] && \ USB_CONFIGFS [=m] && VIDEO_V4L2 [=m] && VIDEO_DEV [=m]
You can take a look at instructions on how to verify and mount configs.
Configuring UVC function
First, make sure the libcomposite module is loaded:
modprobe libcomposite
Then, in order to identify the configfs folder location you can run:
mount | grep configfs configfs on /sys/kernel/config type configfs (rw,relatime)
Now let's set up some information for the device:
UDC=`ls /sys/class/udc` UDC_ROLE=/sys/devices/platform/soc/78d9000.usb/ci_hdrc.0/role CONFIGFS="/sys/kernel/config" GADGET="$CONFIGFS/usb_gadget" VID="0x0525" PID="0x0102" SERIAL="0123456789" MANUF=$(hostname) PRODUCT="UVC Gadget"
Let's start creating the device:
1. Create the gadget
mkdir -p $GADGET/g1
you will get the following:
ls /sys/kernel/config/usb_gadget/g1/ UDC bDeviceClass bDeviceProtocol bDeviceSubClass bMaxPacketSize0 bcdDevice bcdUSB configs functions idProduct idVendor os_desc strings
2. Set vendor and product ID
cd $GADGET/g1 echo $VID > idVendor echo $PID > idProduct
3. Create English string
mkdir -p strings/0x409
You will get the following contect:
ls strings/0x409/ manufacturer product serialnumber
4. Add manufacturer, serial number, and product information
echo $SERIAL > strings/0x409/serialnumber echo $MANUF > strings/0x409/manufacturer echo $PRODUCT > strings/0x409/product
5. Create configuration
mkdir configs/c.1
You will get the following:
ls configs/c.1/ MaxPower bmAttributes strings
6. Create English string for configuration
mkdir configs/c.1/strings/0x409
you will get the following:
ls configs/c.1/strings/0x409/ configuration
7. Create UVC gadget function
CONFIG="configs/c.1" FUNCTION="uvc.0" mkdir functions/$FUNCTION
You will get the following:
ls functions/uvc.0/ control streaming streaming_interval streaming_maxburst streaming_maxpacket
8. Add resolutions
mkdir -p functions/$FUNCTION/streaming/uncompressed/u/360p
you will get:
ls functions/uvc.0/streaming/ class color_matching header mjpeg uncompressed
ls functions/uvc.0/streaming/uncompressed/u/ 360p bAspectRatioX bAspectRatioY bBitsPerPixel bDefaultFrameIndex bmInterfaceFlags bmaControls guidFormat
ls functions/uvc.0/streaming/uncompressed/u/360p/ bmCapabilities dwDefaultFrameInterval dwFrameInterval dwMaxBitRate dwMaxVideoFrameBufferSize dwMinBitRate wHeight wWidth
9. Add frame intervals to resolution
cat <<EOF > functions/$FUNCTION/streaming/uncompressed/u/360p/dwFrameInterval 666666 1000000 5000000 EOF
You will get:
cat functions/uvc.0/streaming/uncompressed/u/360p/dwFrameInterval 666666 1000000 5000000
10. Create header
mkdir functions/$FUNCTION/streaming/header/h cd functions/$FUNCTION/streaming/header/h ln -s ../../uncompressed/u cd ../../class/fs ln -s ../../header/h cd ../../class/hs ln -s ../../header/h cd ../../class/ss ln -s ../../header/h cd ../../../control mkdir -p header/h ln -s header/h class/fs ln -s header/h class/ss cd ../../../
11. Configure max packet size
echo 2048 > functions/$FUNCTION/streaming_maxpacket
12. Assign configuration to function
ln -s functions/$FUNCTION configs/c.1
13. Bind USB Device Controller (UDC)
echo $UDC > UDC
After this, a new /dev/videX device will be created that can be used by the user space application.
In order to disable the Gadget just do:
echo "" > UDC
NOTE: Some devices might need to configure the USB role to be peripheral. In such a case, something like this might be needed: |
echo peripheral > $UDC_ROLE
In case of OpenQ 410 for example, this is done by HW so this step is not needed. It can be checked as follows:
cat /sys/devices/platform/soc/78d9000.usb/ci_hdrc.0/role gadget
For direct inquiries, please refer to the contact information available on our Contact page. Alternatively, you may complete and submit the form provided at the same link. We will respond to your request at our earliest opportunity.
Links to RidgeRun Resources and RidgeRun Artificial Intelligence Solutions can be found in the footer below.