Overview
This application note explains how to configure the i.MX RT running uClinux as the composite USB gadget. As an example of how the composite USB gadget can be used, the application note shows how an USB Ethernet gadget and a USB Mass Storage gadgets are configured over the USB OTG High-Speed link.
In practical embedded applications:
- The Ethernet Gadget can be used for TCP/IP-based communications between the USB host and the i.MX RT over the USB physical link.
- The Mass Storage Gadget can be used to share data on a physical or virtual storage of the IMXRT with the USB host. To give an example of a practical use of this functionality, the SD Card or a Flash partition of the i.MX RT can be mounted as a disk from the USB host.
Note that other USB gadget functions can be enabled on the i.MX RT in a similar manner.
Configuration and Build
To enable the USB Gadgets functionality in the uClinux rootfs project, do the following:
- On the development host, activate the cross-development environment:
$ . ./ACTIVATE.sh
$ cd projects/rootfs
- Select the appropriate USB gadgets in the Linux configuration menu. To do so for the Ethernet and Mass Storage gadgets, go to the Device Drivers -> USB support -> USB Gadget Support -> USB Gadget functions configurable through configfs menu. Select the RNDIS and Mass storage options):
$ make kmenuconfig
- Build the project:
$ make
- Boot the resultant rootfs.uImage on the target.
- Configure the USB gadgets on the target board from the Linux shell, at the run time. Note that while the sample session below makes uses of the interactive shell commands to configure the USB gadgets, in a practical application, such configuration commands can be taken into a shell script (which could then be a part of the Linux start-up scripts):
- Mount the configfs file system:
/ # mount -t configfs configfs /sys/kernel/config/
- Create a new composite USB gadget:
/ # mkdir /sys/kernel/config/usb_gadget/g1
- Add a description for the newly created gadget:
/ # cd /sys/kernel/config/usb_gadget/g1
/sys/kernel/config/usb_gadget/g1 # echo 0x525 > idVendor
/sys/kernel/config/usb_gadget/g1 # echo 0xa4a7 > idProduct
/sys/kernel/config/usb_gadget/g1 # mkdir strings/0x409
/sys/kernel/config/usb_gadget/g1 # echo 00001 > strings/0x409/serialnumber
/sys/kernel/config/usb_gadget/g1 # echo user > strings/0x409/manufacturer
/sys/kernel/config/usb_gadget/g1 # echo mygadget > strings/0x409/product
- Create the configuration for the composite device:
/sys/kernel/config/usb_gadget/g1 # mkdir configs/c.1
/sys/kernel/config/usb_gadget/g1 # mkdir configs/c.1/strings/0x409
/sys/kernel/config/usb_gadget/g1 # echo composite > configs/c.1/
strings/0x409/configuration
/sys/kernel/config/usb_gadget/g1 # echo 120 > configs/c.1/MaxPower
- Define the Mass Storage function:
/sys/kernel/config/usb_gadget/g1 # mkdir functions/mass_storage.0
Mass Storage Function, version: 2009/09/11
LUN: removable file: (no medium)
- Link the entire SD card to the Mass Storage gadget:
/sys/kernel/config/usb_gadget/g1 # echo /dev/mmcblk0 > functions/
mass_storage.0/lun.0/file
- Define the Ethernet gadget (RNDIS) function:
/sys/kernel/config/usb_gadget/g1 # mkdir functions/rndis.usb0
using random self ethernet address
using random host ethernet address
- Link the Gadget functions to the composite device:
/sys/kernel/config/usb_gadget/g1 # ln -s functions/mass_storage.0/
configs/c.1/
/sys/kernel/config/usb_gadget/g1 # ln -s functions/rndis.usb0
configs/c.1
- Enable the USB Gadget on either the USB1 (ci_hdrc.0) or USB2 (ci_hdrc.1) port of the i.MX RT:
/sys/kernel/config/usb_gadget/g1 # echo ci_hdrc.1 > UDC
Connect to the Linux Host
Given the configuration above, the USB host will detect the i.MX RT as 2 USB devices:
- RNDIS Ethernet
- USB Mass Storage.
Run the following command on the USB host (assuming a Linux host PC or a notebook), to verify availability of the i.MX RT-based USB devices:
$ dmesg | tail
[81641.785983] usb 3-3.1.2: new high-speed USB device number 20 using xhci_hcd
[81641.888722] usb 3-3.1.2: New USB device found, idVendor=0525, idProduct=a4a7,
bcdDevice= 5.15
[81641.888729] usb 3-3.1.2: New USB device strings: Mfr=1, Product=2,
SerialNumber=3
[81641.888731] usb 3-3.1.2: Product: mygadget
[81641.888732] usb 3-3.1.2: Manufacturer: user
[81641.888734] usb 3-3.1.2: SerialNumber: 00001
[81641.945525] usb-storage 3-3.1.2:1.0: USB Mass Storage device detected
[81641.945761] scsi host10: usb-storage 3-3.1.2:1.0
[81641.949113] rndis_host 3-3.1.2:1.1 usb0: register 'rndis_host' at
usb-0000:2f:00.3-3.1.2,
RNDIS device, fe:bc:a0:60:1b:d5
[81641.954094] rndis_host 3-3.1.2:1.1 enxfebca0601bd5: renamed from usb0
[81642.958387] scsi 10:0:0:0: Direct-Access Linux File-Stor
Gadget 0515 PQ: 0 ANSI: 2
[81642.958655] sd 10:0:0:0: Attached scsi generic sg9 type 0
[81642.958903] sd 10:0:0:0: Power-on or device reset occurred
[81642.959298] sd 10:0:0:0: [sdi] 62521344 512-byte logical blocks:
(32.0 GB/29.8 GiB)
[81642.959546] sd 10:0:0:0: [sdi] Write Protect is off
[81642.959549] sd 10:0:0:0: [sdi] Mode Sense: 0f 00 00 00
[81642.959807] sd 10:0:0:0: [sdi] Write cache: enabled, read cache:
enabled, doesn't support DPO or FUA
[81642.961618] sdi: sdi1
[81642.961847] sd 10:0:0:0: [sdi] Attached SCSI removable disk
Using the Ethernet Gadget Interface
Step through the following procedure to configure the Ethernet Gadget interface:
- Set up an IP address of the USB Ethernet interface on the i.MX RT side. Make sure to select an address that will not conflict with the other network sub nets in the system (if any are present):
/ # ifconfig usb0 192.168.2.2
- Set up an IP address of the USB Ethernet interface on the USB host side. Obviously, select an address from the same sub-net as the gadget:
$ sudo ifconfig enxfebca0601bd5 192.168.2.1
- Check the TCP/IP link between i.MX RT and the USB host:
On the i.MXRT:
/ # ping 192.168.2.1 -c 3
PING 192.168.2.1 (192.168.2.1): 56 data bytes
64 bytes from 192.168.2.1: seq=0 ttl=64 time=0.798 ms
64 bytes from 192.168.2.1: seq=1 ttl=64 time=0.428 ms
64 bytes from 192.168.2.1: seq=2 ttl=64 time=0.389 ms
--- 192.168.2.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.389/0.538/0.798 ms
/ #
On the USB host:
$ ping 192.168.2.2 -c 3
PING 192.168.2.2 (192.168.2.2) 56(84) bytes of data.
64 bytes from 192.168.2.2: icmp_seq=1 ttl=64 time=0.339 ms
64 bytes from 192.168.2.2: icmp_seq=2 ttl=64 time=0.280 ms
64 bytes from 192.168.2.2: icmp_seq=3 ttl=64 time=0.292 ms
--- 192.168.2.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2030ms
rtt min/avg/max/mdev = 0.280/0.303/0.339/0.025 ms
Using the Mass Storage Interface
Step through the following procedure to configure the Mass Storage interface:
- On the Linux host check the Mass Storage gadget has been automatically mounted:
$ mount | grep "/dev/sdi"
/dev/sdi1 on /media/user/C11B-9AA7 type vfat (rw,nosuid,nodev,relatime,
uid=1000,
gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,
shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2)
- Verify that the mounted media (which is the SD Card on the i.MX RT, in the above example) contains the uClinux boot image:
$ ls /media/user/C11B-9AA7
rootfs.uImage
Configuration USB Multifunction Composite Gadget via a Script
For convenience the usb_gadget.sh script is included into the rootfs project.
- To configure USB Gadget as a mass storage device the following command can be used on the target board:
/ # usb_gadget.sh -m -p 0
Mass Storage Function, version: 2009/09/11
LUN: removable file: (no medium)
USB Gadet config done
/ #
To configure USB Gadget as a network device the following command can be used on the target board:
/ # usb_gadget.sh -r -p 0
using random self ethernet address
using random host ethernet address
usb0: HOST MAC 5a:32:a9:e7:72:85
usb0: MAC 22:ff:72:5f:e5:64
USB Gadet config done
/ #
To configure USB Gadget as a mass storage and a network devices the following command can be used on the target board:
/ # usb_gadget.sh -m -r -p 0
Mass Storage Function, version: 2009/09/11
LUN: removable file: (no medium)
using random self ethernet address
using random host ethernet address
usb0: HOST MAC 06:b2:3f:33:72:e8
usb0: MAC a6:b2:16:ae:fa:e1
USB Gadet config done
/ #
To deactivate configured USB composite gadget the following command can be used on the target board:
/ # usb_gadget.sh -d
USB gadgets deactivated
/ #