USB Device Mode/Gadgets - Unable to create necessary directories for a USB Gadget Device

Hello!

So I am attempting to follow the directions from several sources:
1.https://www.kernel.org/doc/Documentation/usb/gadget_configfs.txt
2.https://elinux.org/images/e/ef/USB_Gadget_Configfs_API_0.pdf
3.https://www.collabora.com/news-and-blog/blog/2019/02/18/modern-usb-gadget-on-linux-and-how-to-integrate-it-with-systemd-(part-1)/

Which, using the utilities built into the Jetson platform, necessary directories that I need are there, most notably:

nvidia@tegra-ubuntu:/sys/kernel/config/usb_gadget

When I run the mkdir to make a new directory for a new gadget I get the following:

nvidia@tegra-ubuntu:/sys/kernal/config/usb_gadget$ sudo mkdir test_USB
mkdir: cannot create directory 'test_USB': Cannot allocate memory

I ran df -h, and do not notice anything that is taking up too much space. I have a terminal open, and no other “in the front” processes. Is there further configuration I need to do with the Jetson to be able to allocate more memory to these processes?

I am at a loss, any help is appreciated!

Please check if below post helps:
https://devtalk.nvidia.com/default/topic/1046776/jetson-tx2/usb-3-2-can-t-set-config-1-error-110/post/5314567/#5314567

Have you tried it yet?
I followed this post but I cannot find

drivers/usb/gadget/legacy/inode.c

to modify
I want to send and receive commands from Pi as a host to/from Jetson TX2 as a device.
Any help, please?

Hi,
Source code is at
https://developer.nvidia.com/embedded/dlc/sources-r2821

You can find

kernel/kernel-4.4/drivers/usb/gadget/legacy/inode.c

Hi,
I really appreciate your reply,
Your source has some different parts from the source in link (kernel 4.4.92), so that, I ignore them, right?
Or I should download source of kernel 4.4.92 and modify
What should I do later, copy the modified source to where? Because I can not find the source in TX2.

On the host PC you would have a “Linux_for_Tegra/” directory where flash was run. Find “source_sync.sh”. You can copy this to the Jetson if desired. Run this (assumes R28.2.1):

./source_sync.sh -k tegra-l4t-r28.2.1

Thanks linuxdev
I dont understand your guide,
I turned TX2 to device mode and ran as you said, but I received logs as following:

$ ./source_sync.sh -k tegra-l4t-r28.2.1
Downloading default kernel/kernel-4.4 source...
Cloning into '/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/kernel-4.4'...
remote: Counting objects: 4784725, done.
remote: Compressing objects: 100% (770491/770491), done.
fatal: read error: Connection reset by peer01.66 MiB | 604.00 KiB/s    
fatal: early EOF
fatal: index-pack failed
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/kernel-4.4 source sync failed!


Directory for kernel/t18x, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/t18x, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186604'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/t18x source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for kernel/nvgpu, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvgpu, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186604'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvgpu source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for kernel/nvhost, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvhost, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186605'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvhost source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for kernel/nvmap, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvmap, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186605'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvmap source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for kernel/nvmap-t18x, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvmap-t18x, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186606'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/nvmap-t18x source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for kernel/display, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/display, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186607'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/kernel/display source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/soc/t18x, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/soc/t18x, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186607'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/soc/t18x source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/platform/tegra/common, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/tegra/common, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186608'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/tegra/common source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/platform/t18x/common, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t18x/common, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186609'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t18x/common source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/platform/t18x/quill, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t18x/quill, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186609'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t18x/quill source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/soc/t210, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/soc/t210, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186610'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/soc/t210 source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/platform/t210/common, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t210/common, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186610'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t210/common source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/platform/t210/jetson, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t210/jetson, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186611'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/platform/t210/jetson source sync'ed to tag tegra-l4t-r28.2.1 successfully!


Directory for hardware/nvidia/soc/tegra, /home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/soc/tegra, already exists!
Syncing up with tag tegra-l4t-r28.2.1...
Switched to a new branch 'mybranch_2019-04-02-1554186612'
/home/parallels/Jetpack/64_TX2/Linux_for_Tegra/sources/hardware/nvidia/soc/tegra source sync'ed to tag tegra-l4t-r28.2.1 successfully!

I still cannot make new directory in

/sys/kernel/config/usb_gadget

because of issue: “Cannot allocate memory”

Hi linuxdev,
If I want to send commands from RasPi to TX2 and Raspi receives files such as images from TX2, but cannot use Ethernet Port of RasPi because of security (Factory does not allow), only USB or wired connection is accepted, how should I do? Is gadget of TX2 the only way?
Thanks and hope you help!

If the source_sync.sh command works, then you will have a subdirectory “sources/” added. Within that is “kernel/kernel-4.4/”, and this is the actual kernel. Some of those other directories are used during certain feature builds via a relative path.

I don’t know about that error, but it looks like a network issue (e.g., proxy or firewall).

The “best” method of communications would depend on how fast the data needs to be (the nature of what’s being sent) and how much trouble you are willing to go through. If you give more information on what is being sent in terms of say file types and data versus allowed latency, and what needs to send a command to where, then maybe some better ideas can be posted.

Gadget allows one of the standard USB classes to be emulated. The most common one is to appear as a block storage device, i.e., to have some file space on one of the systems to be treated as if it is an external disk drive. Other possibilities exist, e.g., an ethernet adapter over USB can be emulated (but then again an actual USB ethernet dongle could be used with superior results…it’d still be ethernet, but it wouldn’t touch the default ethernet connector).

Hi linuxdev,
I used to ask about my issue in https://devtalk.nvidia.com/default/topic/1048909/jetson-tx2/interface-between-raspberry-pi-and-jetson-tx2/ but could not get solutions.
I will try again with another network,
Thanks for your help, linuxdev

If you were to describe the communications as a series of events, what order would the events be?
For example (this is completely contrived just to illustrate):

  1. TX2 takes a snaphost image. // One frame per second.
  2. TX2 notifies RPi.
  3. RPi copies the image as a file to itself.
  4. RPi uses info in combination with the image. // Must do so within 500ms.
  5. ...

It is very hard to give any kind of answer without knowing a lot more detail of both what starts and event, what uses an event, and what performance is required. Also useful to know would be information on how far apart the RPi and TX2 are.

Is it correct that the TX2 already has the ethernet interface used and that this is the particular ethernet which isn’t allowed to talk to the RPi? If this is the case, then it might just be easier to add a second network card to the TX2, e.g., via USB dongle (on USB2 you’d be limited to 100Mb/s ethernet dongles).

(Sorry @ekokind if I mind you because discuss in your thread)
Hi linuxdev,
Thanks much for your help, I successfully sent strings from RPi to TX2 and received back using “pyserial” lib.
When I plugged USB cable in RPi, I saw 3 folder in “/media/pi/”: “L4T” (empty), “L4T1” (empty) and “L4T2” (contains “l4t-serial.inf” and “README.txt”) , are they “/ttyTHS0-2”? Next I want to share files from TX2 to RPi. I know that TX2 can be in mass storage mode, but I don’t know:

  1. Where is the directory can I copy to in TX2, then RPi access to this and copy (is it correct flow?)
  2. Any configuration to use TX2 as mass storage?
  3. Can I do all with python?

Sorry that is the first time I work with gadget,
Any suggestion is appreciated!

@LionelTran You are fine! I am following along to see if anything you post gets me any closer to resolving my own issues. Still having the same issue. I think I might have narrowed it down, but still on the drawing board.

Current releases have some sample code running for device mode (I am assuming you are using the dev kit). If you look at “/opt/nvidia/l4t-usb-device-mode/”, then you will find the script which starts the device mode (“gadget” in this case): “nv-l4t-usb-device-mode.sh” (and “nv-l4t-usb-device-mode-stop.sh” to stop device mode).

Look closely inside of “nv-l4t-usb-device-mode.sh”. USB can consist of more than one device on a single wire (think of HUBs…but this applies to anything, e.g., a programmable mouse can also show up as a keyboard). This script covers a gadget ethernet device (default address 192.168.55.1 and a bridge to glue it to the TX2), and also mass storage. If you want to you can actually comment out the ethernet device (which I tend to do if I’m not going to use it).

The mass storage component has multiple options. One option (the option not chosen in this script) is to name a directory tree within the actual file system. For example, one could mount an SD card, partition and format as VFAT, then mount this somewhere…and give that mount point to the gadget mass storage. That partition would be accessible over USB.

The method actually chosen is to cover a file with loopback. Note “filesystem.img”. Look for this in the script. The exact size of this file is 16777216 bytes. This is exactly divisible twice by 1024. This file is 16MB. Run this command to see what the system thinks of the file:

file filesystem.img

What you will find out is that if this file is covered with loopback, then it could be made to pretend to be an MSDOS partition. You can’t mount the same file system twice at the same time, but if you have ever flashed your Jetson, then your host will have “Linux_for_Tegra/rootfs/opt/nvidia/l4t-usb-device-mode/filesystem.img”. You can run this command to loopback mount the file:

cd /where/ever/it/is/Linux_for_Tegra/rootfs/opt/nvidia/l4t-usb-device-mode/
sudo mount -o loop filesystem.img /mnt
ls /mnt
df -H -T /mnt
sudo umount /mnt

“df -H -T” will tell you the loopback device which is used to cover the file (if you have just rebooted and not used any loopback devices, then it would probably be “/dev/loop0”). That command will also tell you file system type is “vfat”.

There are ways to use a partition instead of a loopback file. There are ways to use a subset of an existing directory tree as well (but this will be ext4 if you simply use the root file system…if the RPi understands ext4 then this is probably a good choice, but if the other end is Windows, then this is a bad choice). There are ways to make this file larger (technically there are ways to make the file smaller as well, but you’re getting to near the minimum size).

One restriction is that you might not have access to the content of the loopback file until you mount it locally (USB has access via the loop device covering it). I mention this because there can be issues if two devices try to modify the file at the same time…I haven’t really tested if it is reliable, but technically even when that loopback file is used over USB you can also “sudo mount -o loop /opt/nvidia/l4t-usb-device-mode/filesystem.img /mnt” (or “-o loop,ro” for read-only) and have it visible on “/mnt” for Linux on the TX2 at the same time.

A serial port is a good way to send commands (the dev kit already has “/dev/ttyS0”…the J21 UART…set up as a console which is logged in as account “nvidia”), and although bandwidth is limited and not so good for mass file transfer you’ll find the method is simple and reliable for actual interaction on the command line.

Hi, linuxdev,
I really appreciate your help,
I finally found out the solution for my system, as I said, I need to send commands and files, I did as following:

  1. Send commands: I simply send over gadget serial: Host (RasPi 3B) sends to /dev/ttyACM0 and Device (TX2) sends to /dev/ttyGS0

  2. Send files: I send over gadget ethernet (SFTP): I set IP for usb1 both on Host and Device and send over SFTP to these IP. (Had tested 13.3MB/s)

More additional info that I had to modify before ran “nv-l4t-usb-device-mode.sh” and “nv-l4t-usb-device-mode-stop.sh” if not, error happens e.g. permission, cannot stop, port is running
These meet our requirements yet,
Thanks, linuxdev

Something I noticed from further back worth mentioning is this excerpt related to downloading kernel source:

fatal: read error: Connection reset by peer

…this means your network failed (either a hop along the route, or a proxy or firewall).

The tty devices are probably not what you think they are. No gadget mode (nor special device mode setup) is needed for the ttyACM device. There is an actual serial UART doing that work. In a real serial UART…sometimes over USB, but not via gadget…the USB end of the cable is a device, but only the driver for the ACM would be needed and no special device mode setup. Anything associated with a ttyACM should completely cut gadget mode out of the equation.

Gadget is used when creating a synthetic/fake device using software which looks like hardware. For example, software can emulate an ethernet NIC over USB, or a sound card which doesn’t actually exist (the programming would be clever enough to make the USB look like one of those devices).

A serial UART is hardware which simply converts a parallel set of bits (a byte) into a series of bits using a serial protocol. The UART itself needs a driver. Often no USB is associated with a UART, but sometimes a host computer doesn’t have a serial port integrated and a USB version is handy (compare that to trying to solder a chip to the motherboard or adding a PCI slot card). In the case of USB the UART is not hard wired into the system and the system with the USB end needs that driver.

A ttyACM is one chipset’s naming convention, and a kernel configured to handle that chipset will have feature “CONFIG_USB_ACM” either as a module or integrated with the kernel. There are some other related ACM configs as well. On a Jetson take a look at this to see what is configured:

zcat /proc/config.gz | egrep '(USB.*ACM)'

(note htat the CONFIG_USB_CONFIGFS_ACM and USB_F_ACM probably are not needed for basic serial UART use)

If the driver is present, then the end of the USB cable which is the actual USB connector should “just work” if the port has the correct settings and the port is set up correctly (e.g., speed, parity, stop bits, and flow control settings must match at both ends of the UART).

The serial UART end of the cable does not need a driver of any kind. This other end will talk to another UART. The system which contains the other serial UART is the one which needs a driver for that brand of UART. If it happens that this other end is a Jetson, and that the UART is integrated into the Jetson, then the UART is already set up with a driver. The settings for that UART have to match the other UART for it to work, but no gadget is ever involved.

There is one serial UART already set up on the Jetson as a serial console. This is for sending commands and receiving shell replies. A second serial UART could be used for sending or receiving files. Are you sure you need gadget? What are the actual physical connectors involved and where do they connect specifically on the Jetson side?

As a side note, the content in “/opt/nvidia/” is just an example gadget mode. One of the synthetic devices created is a block storage device…it emulates a USB thumb drive. Another synthetic device created by the gadget code in “/opt/nvidia/” is an ethernet card over USB. These do probably interfere with any gadget code you might add. However, I suspect you can leave all the gadget code behind and completely ignore it since a UART is not a gadget (gadgets are fake devices, UARTs are real devices).