Difference between revisions of "How to use the UVC gadget driver in Linux"

From RidgeRun Developer Connection
Jump to: navigation, search
(Configuring UVC function)
m
Line 1: Line 1:
<seo title="UVC gadget driver in Linux | UVC gadget driver | RidgeRun" titlemode="replace" keywords=" GStreamer, Embedded Linux, NVIDIA, Xilinx, TI, NXP, Freescale, Linux Software development, Embedded Linux SDK, GStreamer Multimedia Framework, UVC, USB Video Class, UVC gadget driver, USB Video Class Gadget Library, libGuvc, UVC gadget driver, UVC Gadget, usb webcam, usb specification, UVC, USB Video Class, UVC specification, Video Class device, UVC control"  description="This wiki page explains about how to configure and use the linux UVC gadget driver in Linux."></seo>
+
<seo title="UVC gadget driver in Linux | UVC gadget driver | RidgeRun" titlemode="replace" keywords=" GStreamer, Embedded Linux, NVIDIA, Xilinx, TI, NXP, Freescale, Linux Software development, Embedded Linux SDK, GStreamer Multimedia Framework, UVC, USB Video Class, UVC gadget driver, USB Video Class Gadget Library, libGuvc, UVC gadget driver, UVC Gadget, usb webcam, USB specification, UVC, USB Video Class, UVC specification, Video Class device, UVC control"  description="This wiki page explains about how to configure and use the Linux UVC gadget driver in Linux."></seo>
  
 
{{Ambox
 
{{Ambox
Line 11: Line 11:
 
UVC or USB Video Class is a USB specification created by the USB Implementers Forum ([https://www.usb.org 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.  
 
UVC or USB Video Class is a USB specification created by the USB Implementers Forum ([https://www.usb.org 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 other, 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 [https://github.com/torvalds/linux/blob/master/drivers/usb/gadget/function/f_uvc.c UVC gadget driver] to its mainline in order to help developers to create Linux based devices with UVC support. Beside those efforts, the current UVC driver does not implement all the UVC specification 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.
+
Linux-based operating systems as well as other, 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 [https://github.com/torvalds/linux/blob/master/drivers/usb/gadget/function/f_uvc.c 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.  
+
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 the instructions for both methods.
+
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 ===
 
=== Using kernel g_webcam module ===
Line 46: Line 46:
 
=== Using configfs ===
 
=== Using configfs ===
  
Configfs allows Userspace-driven kernel object configuration.
+
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
 
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.
 
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 read and write.
+
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.
 
Unlike sysfs, the lifetime of the representation is completely driven by userspace. The kernel modules backing the items must respond to this.
  
 
==== Enabling configfs ====
 
==== Enabling configfs ====
  
First you have to make sure that configfs is enabled:
+
First, you have to make sure that configfs is enabled:
  
 
<pre>
 
<pre>
Line 104: Line 104:
 
</pre>
 
</pre>
  
Now lets setup some information for the device:
+
Now let's set up some information for the device:
  
 
<pre>
 
<pre>
Line 118: Line 118:
 
</pre>
 
</pre>
  
Lets start creating the device:
+
Let's start creating the device:
  
 
'''1. Create the gadget'''
 
'''1. Create the gadget'''
Line 152: Line 152:
 
</pre>
 
</pre>
  
'''4. Add manufacturer, serial number and product information'''
+
'''4. Add manufacturer, serial number, and product information'''
  
 
<pre>
 
<pre>
Line 283: Line 283:
 
</pre>
 
</pre>
  
'''NOTE:''' Some devices might need to configure the USB role to be a peripheral. In such case, something like this might be needed:
+
{{Ambox
 +
|type=notice
 +
|small=left
 +
|issue='''NOTE:''' Some devices might need to configure the USB role to be peripheral. In such a case, something like this might be needed:
 +
|style=width:unset;
 +
}}
 +
 
 
<pre>
 
<pre>
 
echo peripheral > $UDC_ROLE
 
echo peripheral > $UDC_ROLE
Line 294: Line 300:
 
gadget
 
gadget
 
</pre>
 
</pre>
 +
 +
{{ContactUs}}
 +
 +
[[Category:Jetson V4L2 Drivers]]

Revision as of 13:49, 19 December 2021

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 other, 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 here for 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 ../../../control
mkdir 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
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


RidgeRun Resources

Quick Start Client Engagement Process RidgeRun Blog Homepage
Technical and Sales Support RidgeRun Online Store RidgeRun Videos Contact Us

OOjs UI icon message-progressive.svg Contact Us

Visit our Main Website for the RidgeRun Products and Online Store. RidgeRun Engineering informations are available in RidgeRun Professional Services, RidgeRun Subscription Model and Client Engagement Process wiki pages. Please email to support@ridgerun.com for technical questions and contactus@ridgerun.com for other queries. Contact details for sponsoring the RidgeRun GStreamer projects are available in Sponsor Projects page. Ridgerun-logo.svg
RR Contact Us.png