USB networking through the micro-USB port. Kernel not compiling modules.

I am trying to roll a kernel for the Jetson that allows me to use the micro-USB port for networking. I have done this on a Beaglebone Black before, but there the kernel has been pre-configured to allow this. On the Jetson it isn’t, as far as I know.

The modules that I think are essential are:
g_ether
libcomposite
u_ether
usb_f_rndis
usb_f_eem

The first two I have in my kernel, but the last three are not. I neatly followed this guide:

https://devtalk.nvidia.com/default/topic/762653/embedded-systems/-howto-build-own-kernel-for-jetson-tk1/

and configured the .config by following

http://elinux.org/BeagleBone_Usb_Networking

and

https://developer.ridgerun.com/wiki/index.php/How_to_use_USB_device_networking

, but still no success. The modules are not being build, even though I can see that the kernel source contains a source file with the same name. Also, when I read the .config file manually I can find references to RNDIS, followed by a “y”.

My question is, has anyone else tried networking over USB with the board? Or am I doing something obvious wrong while trying to build the kernel?

This uses the linux “gadget” interface, which is not automatically switched between device and host modes. The interface for the OTG starts in host mode (works with type “A” connectors)…when I’m around my development machine I can check which echo to /sys goes manually to device mode (type “B” connector).

Beware there are some issues with module removal while in device mode (such as g_ether). Here is the thread which is being worked on right now (this won’t be a quick fix):
https://devtalk.nvidia.com/default/topic/869527/embedded-systems/crash-during-usb-gadget-driver-unload/

So far as the kernel files you were seeing goes, not everything is built as a module. I have not looked at the USB networking you mention, it’s quite possible you have to install a new zImage and not just modules. I know g_ether can work as a module since I’m trying to debug that and g_mass_storage. libcomposite is a prerequisite for some of the others.

To manually switch to host mode (this is a “normal” USB connection):

echo 1 > /sys/devices/platform/tegra-otg/enable_host

To manually switch to device mode (such as for use with g_ether):

echo 1 > /sys/devices/platform/tegra-otg/enable_device

To examine the current OTG mode:

egrep '[01]' "/sys/devices/platform/tegra-otg/enable_*"

Additional notes…

Looks like the USB_ETH_RNDIS is a subset of “Ethernet Gadget” (USB_ETH), and not an individual/separate module (selecting “yes” to USB_ETH_RNDIS will add features to existing module “Ethernet Gadget”). Similar for USB_ETH_EEM.

I’m not sure about some of the others (like u_ether), but the basic idea is to go through menuconfig and see if one of the “missing” modules is listed as a subset of another feature…in which case the parent feature is the module. Also keep in mind that some of the features change over different kernel versions and may not exist in this version, or may be different.

In parallel to you I found that out too, thank you though. It is convenient to have a R21.x version to do this since R19.x does not have the “enable_*” files by default. This was a problem for me before. I think it’s a very useful function for embedded systems to have, networking over USB, so for future reference:

The micro USB port is configured as a host port by default, however, this is not what is preferred since it will be receiving its connection from a host PC. The PC will not even detect the Jetson if the Jetson USB port is not configured properly. The module in the Linux kernel that allows networking over USB is the g_ether module, and thankfully this one is built with the standard Jetson kernel, it just needs to be plugged at boot. Do this by adding it to the right file by running

echo g_ether >> /etc/modules

as a super user or do it manually. Furthermore, the port should be configured and a connection initiated. Do this by editing /etc/init/nv.conf . Look for a reference to “enable_device” and change the text block to

done
# remove power to dc.0 for jetson-tk1
machine=`cat /sys/devices/soc0/machine`
if [ "${machine}" = "jetson-tk1" ] ; then
        echo 4 > /sys/class/graphics/fb0/blank
        if [ -e /sys/devices/platform/tegra-otg/enable_host ] ; then
                echo 0 > /sys/devices/platform/tegra-otg/enable_host
        fi
        if [ -e /sys/devices/platform/tegra-otg/enable_device ] ; then
                echo 1 > /sys/devices/platform/tegra-otg/enable_device
        fi
        if [ -e /sys/devices/platform/tegra-udc.0/udc/tegra-udc.0/soft_connect ] ; then
                 echo connect > /sys/devices/platform/tegra-udc.0/udc/tegra-udc.0/soft_connect
        fi
fi

.
[i]
Notice that the order of setting the host and device has changed, which is essential since otherwise you would try to configure the port to be a host and a device at the same time, which is not allowed.

Now configure the network as described in
https://developer.ridgerun.com/wiki/index.php/How_to_use_USB_device_networking
by adding it to /etc/rc.local .
You might have to add the connection to /etc/network/interfaces as well to avoid the network manager downing the interface after a couple of seconds.
[/i]

The OTG functionality and the related “enable_*” files are part of /sys, which is driven by whether the kernel has that compiled or not. So the R19.x kernels have this too, but if the /sys files do not show up, then the kernel was compiled without that enabled. Everything you see in /sys and /proc are essentially a reflection of kernel functionality, often/mostly dependent upon something that is optional. In some cases /dev is this way too, but /dev gets interference from devfs rules and renames or alters files produced by kernel features. For example, before devfs, ethernet was always eth0…ethN, now it can be em0…emN if devfs finds a rule for renaming integrated NICs.