How to create USB Ethernet gadget for Jetson through configfs

From RidgeRun Developer Connection
Revision as of 11:45, 9 July 2021 by Aflores (talk | contribs) (Create introduction and gadget creation sections)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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 steps are based NVIDIA's 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#creating-the-configurations

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


Create and set up the gadget

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 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


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"


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 Adresses are needed.

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"


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


Bash script to create and enable the gadget

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

touch ecm_usb_start.sh

4) 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