This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/PROCESSOR-SDK-AM335X: Trouble with USB connection to Linux host.

Part Number: PROCESSOR-SDK-AM335X

Tool/software: Linux

Hi,

I'm working on a device based on BeagleBone black and ti-processor-sdk-linux-am335x-evm-01.00.00.03. and have problem with getting the USB working.

I'm using the attached script and it works fine with Windows host. However, it has problem in linux. The host machine detects my device but it does not assign an ip number.

user@ubuntu:~$ ifconfig 
~~~
usb0      Link encap:Ethernet  HWaddr 12:00:00:00:00:00  
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:90 (90.0 B)

The network settings dialog show the device but it says the cable is not plugged in.

Could some one help me figure out what is going on?

Thank you

Brian

#!/bin/bash

# USB Gadget for Corelis CEC hardware

set -e

g=/sys/kernel/config/usb_gadget/g1
kernel_config=/sys/kernel/config
device="musb-hdrc.0.auto"

cec_usb_up() {
    modprobe libcomposite
	if [ ! -d ${g} ]; then
	  mount -t configfs none ${kernel_config}
	fi
    usb_ver="0x0200" # USB 2.0
    dev_class="2" # Communications
    vid="0x0B1E" # EWA
    pid="0x9010" # NetUSB II
    mfg="Corelis, Inc." # 
    prod="NetUSB II" # 
    # Read bluetooth mac address from eeprom - this is what LEGO firmware uses for serial
    serial="$(grep Serial /proc/cpuinfo | sed 's/Serial\s*: 0000\(\w*\)/\1/')"
    attr="0xC0" # Self powered
    pwr="1" # 2mA
    cfg1="RNDIS"
    cfg2="CDC"
    # add colons for MAC address format
    mac="$(echo ${serial} | sed 's/\(\w\w\)/:\1/g' | cut -b 2-)"
    # Change the first number for each MAC address - the second digit of 2 indicates
    # that these are "locally assigned (b2=1), unicast (b1=0)" addresses. This is
    # so that they don't conflict with any existing vendors. Care should be taken
    # not to change these two bits.
    dev_mac1="22$(echo ${mac} | cut -b 3-)"
    host_mac1="32$(echo ${mac} | cut -b 3-)"
    dev_mac2="02$(echo ${mac} | cut -b 3-)"
    host_mac2="12$(echo ${mac} | cut -b 3-)"
    ms_vendor_code="0xcd" # Microsoft
    ms_qw_sign="MSFT100" # also Microsoft (if you couldn't tell)
    ms_compat_id="RNDIS" # matches Windows RNDIS Drivers
    ms_subcompat_id="5162001" # matches Windows RNDIS 6.0 Driver

#    tmpdir=$(mktemp -d)
#    mount /dev/mmcblk0p1 $tmpdir
#    if [ -f $tmpdir/cecdev.txt ]; then
#        cdc_only=$(grep -i "^cdc_only=\(true\|yes\|1\)" $tmpdir/cecdev.txt | cut -b 10-)
#    fi
#    umount $tmpdir

    if [ -d ${g} ]; then
        if [ "$(cat ${g}/UDC)" != "" ]; then
            echo "Gadget is already up."
            exit 1
        fi
        echo "Cleaning up old directory..."
        cec_usb_down
    fi
    echo "Setting up gadget..."

    # Create a new gadget

    mkdir ${g}
    echo "${usb_ver}" > ${g}/bcdUSB
    echo "${dev_class}" > ${g}/bDeviceClass
    echo "${vid}" > ${g}/idVendor
    echo "${pid}" > ${g}/idProduct
    mkdir ${g}/strings/0x409
    echo "${mfg}" > ${g}/strings/0x409/manufacturer
    echo "${prod}" > ${g}/strings/0x409/product
    echo "${serial}" > ${g}/strings/0x409/serialnumber

    # Create 2 configurations. The first will be RNDIS, which is required by
    # Windows to be first. The second will be CDC. Linux and Mac are smart
    # enough to ignore RNDIS and load the CDC configuration.

    # There is a bug in OS X 10.11 that makes Mac no longer smart enough to
    # use the second configuration. So we've added the cdc_only check to
    # work around this.

    if [ -z $cdc_only ]; then

        # config 1 is for RNDIS

        mkdir ${g}/configs/c.1
        echo "${attr}" > ${g}/configs/c.1/bmAttributes
        echo "${pwr}" > ${g}/configs/c.1/MaxPower
        mkdir ${g}/configs/c.1/strings/0x409
        echo "${cfg1}" > ${g}/configs/c.1/strings/0x409/configuration

        # On Windows 7 and later, the RNDIS 5.1 driver would be used by default,
        # but it does not work very well. The RNDIS 6.0 driver works better. In
        # order to get this driver to load automatically, we have to use a
        # Microsoft-specific extension of USB.

        echo "1" > ${g}/os_desc/use
        echo "${ms_vendor_code}" > ${g}/os_desc/b_vendor_code
        echo "${ms_qw_sign}" > ${g}/os_desc/qw_sign

        # Create the RNDIS function, including the Microsoft-specific bits

        mkdir ${g}/functions/rndis.usb0
        echo "${dev_mac1}" > ${g}/functions/rndis.usb0/dev_addr
        echo "${host_mac1}" > ${g}/functions/rndis.usb0/host_addr
        echo "${ms_compat_id}" > ${g}/functions/rndis.usb0/os_desc/interface.0/compatible_id
        echo "${ms_subcompat_id}" > ${g}/functions/rndis.usb0/os_desc/interface.0/sub_compatible_id
    fi

    # config 2 is for CDC

    mkdir ${g}/configs/c.2
    echo "${attr}" > ${g}/configs/c.2/bmAttributes
    echo "${pwr}" > ${g}/configs/c.2/MaxPower
    mkdir ${g}/configs/c.2/strings/0x409
    echo "${cfg2}" > ${g}/configs/c.2/strings/0x409/configuration

    # Create the CDC function

    mkdir ${g}/functions/ecm.usb0
    echo "${dev_mac2}" > ${g}/functions/ecm.usb0/dev_addr
    echo "${host_mac2}" > ${g}/functions/ecm.usb0/host_addr

    # Link everything up and bind the USB device

    if [ -z $cdc_only ]; then
        ln -s ${g}/functions/rndis.usb0 ${g}/configs/c.1
        ln -s ${g}/configs/c.1 ${g}/os_desc
    fi
    ln -s ${g}/functions/ecm.usb0 ${g}/configs/c.2
    echo "${device}" > ${g}/UDC

    # bring up network interface
    ifup usb0
    sleep 1
    udhcpd /etc/udhcpd.conf

    echo "Done."
}

cec_usb_down() {
    if [ ! -d ${g} ]; then
        echo "Gadget is already down."
        exit 1
    fi
    echo "Taking down gadget..."
    
    # deconfigure so it will work next time
    ifdown usb0

    # Have to unlink and remove directories in reverse order.
    # Checks allow to finish takedown after error.

    if [ "$(cat ${g}/UDC)" != "" ]; then
        echo "" > ${g}/UDC
    fi
    rm -f ${g}/os_desc/c.1
    rm -f ${g}/configs/c.2/ecm.usb0
    rm -f ${g}/configs/c.1/rndis.usb0
    [ -d ${g}/functions/ecm.usb0 ] && rmdir ${g}/functions/ecm.usb0
    [ -d ${g}/functions/rndis.usb0 ] && rmdir ${g}/functions/rndis.usb0
    [ -d ${g}/configs/c.2/strings/0x409 ] && rmdir ${g}/configs/c.2/strings/0x409
    [ -d ${g}/configs/c.2 ] && rmdir ${g}/configs/c.2
    [ -d ${g}/configs/c.1/strings/0x409 ] && rmdir ${g}/configs/c.1/strings/0x409
    [ -d ${g}/configs/c.1 ] && rmdir ${g}/configs/c.1
    [ -d ${g}/strings/0x409 ] && rmdir ${g}/strings/0x409
    rmdir ${g}
	
    umount ${kernel_config}
	
    echo "Done."
}

case $@ in

up)
    cec_usb_up
    ;;
down)
    cec_usb_down
    ;;
*)
    echo "Usage: usb_ether.sh up|down"
    exit 1
    ;;
esac

  • Hi Brian,

    Have you verified that both board & host pc use stitc ip settings or dhcp?

    Best Regards,
    Yordan
  • My device uses 192.168.7.2 as its static IP and has DHCPD configured to give 192.168.7.1 to the host. This works under windows.

    When I force set the IP to 192.168.7.1 on linux host it still does not work.

    user@ubuntu:~$ sudo ifconfig eth0 192.168.0.1 netmask 255.255.255.0
    [sudo] password for user: 
    user@ubuntu:~$ ifconfig 
    eth0      Link encap:Ethernet  HWaddr 00:0c:29:27:43:e8  
              inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
              inet6 addr: fe80::20c:29ff:fe27:43e8/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:1250963 errors:1 dropped:8760 overruns:0 frame:0
              TX packets:346125 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:180779172 (180.7 MB)  TX bytes:257333787 (257.3 MB)
              Interrupt:19 Base address:0x2000 
    
    lo        Link encap:Local Loopback  
              inet addr:127.0.0.1  Mask:255.0.0.0
              inet6 addr: ::1/128 Scope:Host
              UP LOOPBACK RUNNING  MTU:65536  Metric:1
              RX packets:881 errors:0 dropped:0 overruns:0 frame:0
              TX packets:881 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:0 
              RX bytes:245829 (245.8 KB)  TX bytes:245829 (245.8 KB)
    
    usb0      Link encap:Ethernet  HWaddr 12:00:00:00:00:00  
              inet addr:192.168.7.1  Bcast:192.168.7.255  Mask:255.255.255.0
              UP BROADCAST MULTICAST  MTU:1500  Metric:1
              RX packets:0 errors:0 dropped:0 overruns:0 frame:0
              TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    
    user@ubuntu:~$ ping 192.168.7.2
    PING 192.168.7.2 (192.168.7.2) 56(84) bytes of data.
    From 192.168.7.1 icmp_seq=1 Destination Host Unreachable
    From 192.168.7.1 icmp_seq=2 Destination Host Unreachable
    From 192.168.7.1 icmp_seq=3 Destination Host Unreachable
    From 192.168.7.1 icmp_seq=4 Destination Host Unreachable
    From 192.168.7.1 icmp_seq=5 Destination Host Unreachable
    From 192.168.7.1 icmp_seq=6 Destination Host Unreachable
    ^C
    --- 192.168.7.2 ping statistics ---
    

  • Hi Brian,

    How have you connected the host and the device through LAN? or Are they directly connected via ethernet(one end to device and the other end to host) ?

    What is the ifconfig in the device ?
    If you set dhcpd(this means dhcp server, which gives IP to others, then why static config), what is the IP range in the settings ?
  • "How have you connected the host and the device through LAN? or Are they directly connected via ethernet(one end to device and the other end to host) ?"
    The device is on a lan and both the host and the device are connected to the same ethernet hub.

    "What is the ifconfig in the device ?"
    root@am335x-evm:~# ifconfig
    eth0 Link encap:Ethernet HWaddr B0:D5:CC:C4:93:91
    inet addr:192.168.1.146 Bcast:192.168.1.255 Mask:255.255.255.0
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:77538 errors:0 dropped:15 overruns:0 frame:0
    TX packets:13474 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:19059371 (18.1 MiB) TX bytes:1635204 (1.5 MiB)
    Interrupt:56

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    UP LOOPBACK RUNNING MTU:65536 Metric:1
    RX packets:2671 errors:0 dropped:0 overruns:0 frame:0
    TX packets:2671 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:415816 (406.0 KiB) TX bytes:415816 (406.0 KiB)

    usb0 Link encap:Ethernet HWaddr 22:00:00:00:00:00
    inet addr:192.168.7.2 Bcast:192.168.7.255 Mask:255.255.255.0
    UP BROADCAST MULTICAST MTU:1500 Metric:1
    RX packets:1050 errors:0 dropped:451 overruns:0 frame:0
    TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:250561 (244.6 KiB) TX bytes:1648 (1.6 KiB)

    "If you set dhcpd(this means dhcp server, which gives IP to others, then why static config), what is the IP range in the settings ?"
    I did that as a troubleshooting step.

    from /etc/udhcpd.conf
    # The start and end of the IP lease block
    start 192.168.7.1
    end 192.168.7.3

    Brian
  • Hi Brian,

    I missed out that USB ether is being used. So have you tried:

    1. making cdc_only in cecdev.txt script ?
    2. Can you make sure udhcpc in host is using usb0 interface if using udhcpd in device side ?
    3. You can also give a try of ifconfig eth0 down and check in both device and host.
  • Forcing making cdc_only in the script make it work. What does it mean? Does it mean that I can't have support for both Linux and Windows at the same time?

  • It turned out that using RNDIS only, without CDC, works fine on Windows host and Linux host. Doh!!!

    Thanks everyone for the help.

    Brian