How to create USB Ethernet gadget for Jetson through configfs

From RidgeRun Developer Connection
Jump to: navigation, search
Nvidia-preferred-partner-badge-rgb-for-screen.png

RR Contact Us.png

Introduction

This wiki will guide you through the creation of an USB ethernet gadget using the ECM protocol. For this gadget a Jetson Nano Developer Kit with Jetpack 4.4 was used. The following sections are based on NVIDIA's USB services scripts located at

/opt/nvidia/l4t-usb-device-mode/

and kernel documentation that you can find on the following links

https://www.kernel.org/doc/html/v5.8/usb/gadget_configfs.html

https://www.kernel.org/doc/Documentation/ABI/testing/


Initial requirements

1) First, verify that your kernel has support for configfs

fgrep configfs /proc/filesystems

with the expected output being:

nodev configfs


2) You also need to disable the current devices that NVIDIA creates on start.

sudo systemctl stop nv-l4t-usb-device-mode.service


Create and set up the gadget

Create the gadget

1) Set CONFIGFS_HOME as the mount point for configfs.

CONFIGFS_HOME=/sys/kernel/config


2) Setup some device information.

GADGET_NAME="l4t"
VID="0x0955"
PID="0x7020"
SERIAL="no-serial"
MANUF="RR"
PRODUCT="RR gadget"


3) For each gadget to be created its corresponding directory must be created.

mkdir -p "$CONFIGFS_HOME/usb_gadget/$GADGET_NAME"
cd "$CONFIGFS_HOME/usb_gadget/$GADGET_NAME"


4) Each gadget needs to have its vendor id and product id specified.

echo "$VID" > idVendor
echo "$PID" > idProduct


5) A gadget needs serial number, manufacturer and product strings. You need to create a strings subdirectory for each language to store them.

mkdir strings/0x409


6) Then the strings can be specified.

echo "$SERIAL" > strings/0x409/serialnumber
echo "$MANUF" > strings/0x409/manufacturer
echo "$PRODUCT" > strings/0x409/product


Create the configurations

7) Each gadget consists of a number of configurations. You need to create a directory for each configuration.

CFG="c.1"
CFG_STR="ECM"
mkdir -p "configs/$CFG"


Create the functions

8) Create a directory for your gadget's functions.

FUNC_NAME="ecm"
INSTANCE_NAME="usb0"
FUNC="functions/$FUNC_NAME.$INSTANCE_NAME"
mkdir -p "$FUNC"

FUNC_NAME corresponds to one of allowed function names and INSTANCE_NAME is an arbitrary string allowed in a filesystem.


9) Each function provides its specific set of attributes. For an ECM gadget, MAC Addresses are needed. Create some random MAC Addresses.

mac_ecm_h="7a:68:46:2f:bd:aa"
mac_ecm_d="7a:68:46:2f:bd:ab"


10) Add the attributes.

echo "$mac_ecm_h" > "$FUNC/host_addr"
echo "$mac_ecm_d" > "$FUNC/dev_addr"


11) Link functions with their configurations.

ln -sf "$FUNC" "configs/$CFG"


12) Create english string for configuration.

mkdir -p "configs/$CFG/strings/0x409"
echo "$CFG_STR" > "configs/$CFG/strings/0x409/configuration"


Create network bridge and enable the gadget

13) Create and configure the network bridge. Set the device to "down" initially, the interface will be set to "up" in response to cable presence.

/sbin/brctl addbr l4tbr0
/sbin/ifconfig l4tbr0 down


14) In order to enable the gadget it must be bound to a UDC (USB Device Controller).

UDC_DEV=`ls /sys/class/udc`
echo "$UDC_DEV" > UDC


15) Ethernet devices require additional configuration. This assigns the Ethernet device to an Ethernet bridge, and assigns the static IP to that bridge.

/sbin/brctl addif l4tbr0 "$(cat $FUNC/ifname)"
/sbin/ifconfig "$(cat $FUNC/ifname)" up


Create and enable the gadget with bash script

1) Check the Initial requirements to create the gadget, then create a file for the bash script.

touch ecm_usb_start.sh

2) Copy the following into ecm_usb_start.sh file.

#!/bin/bash

set -e

CONFIGFS_HOME=/sys/kernel/config
GADGET_NAME="l4t"
VID="0x0955"
PID="0x7020"
SERIAL="no-serial"
MANUF="RR"
PRODUCT="RR gadget"

mkdir -p "$CONFIGFS_HOME/usb_gadget/$GADGET_NAME"
cd "$CONFIGFS_HOME/usb_gadget/$GADGET_NAME"

echo "$VID" > idVendor
echo "$PID" > idProduct

mkdir -p strings/0x409

echo "$SERIAL" > strings/0x409/serialnumber
echo "$MANUF" > strings/0x409/manufacturer
echo "$PRODUCT" > strings/0x409/product

CFG="c.1"
CFG_STR="ECM"
mkdir -p "configs/$CFG"

FUNC_NAME="ecm"
INSTANCE_NAME="usb0"
FUNC="functions/$FUNC_NAME.$INSTANCE_NAME"
mkdir -p "$FUNC"

mac_ecm_h="7a:68:46:2f:bd:aa"
mac_ecm_d="7a:68:46:2f:bd:ab"

echo "$mac_ecm_h" > "$FUNC/host_addr"
echo "$mac_ecm_d" > "$FUNC/dev_addr"
ln -sf "$FUNC" "configs/$CFG"

mkdir -p "configs/$CFG/strings/0x409"
echo "$CFG_STR" > "configs/$CFG/strings/0x409/configuration"

/sbin/brctl addbr l4tbr0
/sbin/ifconfig l4tbr0 down

UDC_DEV=`ls /sys/class/udc`
echo "$UDC_DEV" > UDC

/sbin/brctl addif l4tbr0 "$(cat $FUNC/ifname)"
/sbin/ifconfig "$(cat $FUNC/ifname)" up

exit 0

3) Enable execution permissions.

chmod u+x ecm_usb_start.sh

4) Run the script.

sudo ./ecm_usb_start.sh


Test the gadget

To verify that your gadget is set up and working, use a simple X forward test:


1) Connect your device with the configured gadget via USB to your host PC.


2) On your device run the following.

ifconfig l4tbr0

You should see the information of the l4tbr0 network bridge previously configured. Copy the bridge's IP address for the following step.


2) Run the following command on your host PC to connect via SSH to your device.

ssh -X <device-user-name>@<device-ip>

You must replace <device-user-name> with your device's user name and <device-ip> with the bridge's IP address.


3) On your device, run

gst-launch-1.0 videotestsrc ! xvimagesink

A new windows labeled gst-launch-1.0 showing color bars should open and your device is ready to use.


Stop the gadget with bash script

In order to disable the gadget you need to unbound it from the UDC and then cleanup the created directories.

1) Create a file for a bash script.

touch ecm_usb_stop.sh

2) Copy the following into the ecm_usb_stop.sh file.

#!/bin/bash

CONFIGFS_HOME=/sys/kernel/config
GADGET_NAME="l4t"
CFG="c.1"
FUNC_NAME="ecm"
INSTANCE_NAME="usb0"
FUNC="functions/$FUNC_NAME.$INSTANCE_NAME"

cd "$CONFIGFS_HOME/usb_gadget"
echo "" > "$GADGET_NAME/UDC"
rmdir "$GADGET_NAME/configs/$CFG/strings/0x409"
rm -f "$GADGET_NAME/configs/$CFG/$FUNC_NAME.$INSTANCE_NAME"
rmdir "$GADGET_NAME/$FUNC/"
rm -f "$GADGET_NAME/os_desc/$CFG"
rmdir "$GADGET_NAME/configs/$CFG/"
rmdir "$GADGET_NAME/strings/0x409"
rmdir "$GADGET_NAME"
/sbin/ifconfig l4tbr0 down
/sbin/brctl delbr l4tbr0

service nv-l4t-usb-device-mode-runtime stop

exit 0


3) Enable execution permissions.

chmod u+x ecm_usb_stop.sh

4) Run the script.

sudo ./ecm_usb_stop.sh