Why doesn't Zaber device show up in dev directory? - linux

My Zaber device is X-MCB2, which is connected to my computer through USB. Command lsusb can show its information as below, but cannot find it in /dev directory.
Bus 003 Device 023: ID 2939:495b
There is another Arduino device connected to my computer as well. Unlike Zaber device, this Arduino device works well, its name in /dev is ttyACM0.
Even if I plugged out the Arduino device, the Zaber device still does NOT show up in /dev directory.
My linux kernel is 2.6.32, and this Zaber device shouldn't need additional driver.

I resolved this issue according to the following link: https://github.com/arduino/Arduino/issues/1389.
echo "0x2939 0x495b" > /sys/bus/usb/drivers/cdc_acm/new_id

Thanks for posting your answer Jeff.
The likely cause of the issue is that Zaber controllers implement USB using CDC ACM, and set 0 for the Protocol field of the USB interface descriptor (indicating that the device doesn't accept AT commands).
In Linux 2.6.32, the CDC ACM kernel driver, which should handle devices
of this type, is written in such a way that it doesn’t take control of
devices whose Protocol field is 0 (instead it has a specific list of
Protocol numbers which it accepts, but that list does not include 0). Instead, you must manually attach it as in the posted solution.
This issue was fixed in kernel 2.6.36.
Here are a list of the commands that will manually attach the Zaber controllers with USB:
X-MCB2:
echo "0x2939 0x495b" > /sys/bus/usb/drivers/cdc_acm/new_id
X-MCB1:
echo "0x2939 0x495a" > /sys/bus/usb/drivers/cdc_acm/new_id
A-MCB2:
echo "0x2939 0x459" > /sys/bus/usb/drivers/cdc_acm/new_id

Related

Linux tool to send a SET_CONFIGURATION message to a device connected to the USB bus

I have developed a kernel driver for a USB device. Such a device has some pins that can provide functionality both as CDC ACM serial port or as input buttons. So to implement that I had to use two different USB configuration descriptors.
The driver works as expected, but I have to hardcode the chosen setup before compiling and loading the firmware to the micro-controller. I am searching a mechanism to change that device configuration from userspace.
I read about a SET_CONFIGURATION message on USB documentation, but coudn't find any Linux tool to send such kind of standard USB messages from userspace to the USB bus.
Does some of you (with more experience on this topic) know some userspace Linux tool to send a SET_CONFIGURATION message to a device connected to the USB bus?
Thanks in advance! :)
The function libusb_set_configuration() in LibUSB could do that in theory, but there is no need.
One can simply put both HID (for the button) and CDC (serial port) into one configuration using an "Interface association descriptor" (IAD).
This github repo resolves my issue:
https://github.com/avtolstoy/usbtool
No need for any special tools. You can simply do it via sysfs:
Find your device cd /sys/bus/usb/devices/X-Y/ where X is the bus number and Y is the device number.
Edit bConfigurationValue e.g., using sudoedit
Set the file contents to the desired configuration number and save it
That’s it!

C++ Detecting USB serial device plugged/unplugged

I need to detect when a USB serial device is plugged or unplugged on my embedded system and know what is the tty associated with it.
My system runs over a 2.6 Linux Kernel.
Since I don't have write access to udev rules, nowadays I'm trying to get this information from the file system, looking for modifications in /sys/bus/usb/devices directory. However, I'm facing some problems with this approach.
I know what is the Id BUS of the USB port connected (e.g 1-1.3). So, I search for the associated tty (looking for a directory in /sys/bus/usb/devices/<Id BUS>:1.0/tty/ - e.g. /sys/bus/usb/devices/1-1.3:1.0/tty/ttyACM0). This way I know that I should use /dev/ttyACM0 to communicate with my device.
But, sometimes, this device (/dev/ttyACM0) does not exist.
Is there any better way to get this information?
I even thought trying to get this information from the syslog, but I don't know whether this is a pretty good idea.
Edit:
Only to clarify, my system needs to be able to detect state changes in the USB bus, i.e. detecting when a new device is plugged (and getting the tty name linked to it) or an existing one is unplugged.
The system is monitoring up to N USB/serial devices, which are plugged to it using an USB HUB. During its normal execution new devices can be plugged, existing devices can be removed (or rebooted by a remote command - out of this scope). When a device is rebooted, it could receive a different tty from the previous one used before (e.g. ttyACM0 -> ttyACM3), since the kernel designates to it a tty which is free at the moment, and it is a big problem to me.
Netlink is the preferred mechanism for communication between kernel and userspace.
You would create a Netlink socket with family NETLINK_KOBJECT_UEVENT, listen on that socket and filter out messages that contain SUBSYSTEM=usb and ACTION=add for USB plug events or ACTION=remove for USB unplug events.
I wrote a USB abstraction library called libusbp. You should look at its port_name example, which shows how to use libusbp to get the serial port name (e.g. /dev/ttyACM0) for a USB serial device. Behind the scenes, libusbp gets this information using libudev.
Check if the virtual file is deleted using stat.
#include <sys/statvfs.h>
...
struct stat sb;
return (stat("/dev/ttyUSB0", &sb) == 0); // true if open, false otherwise

How to detect when a usb cable is connected/disconnected on the device side in Linux 2.6.37?

I have a embedded device that runs linux 2.6.37.
I want my application to know when the USB is connected.
Currently I can achieve this by pooling
/sys/devices/platform/musb/musb-hdrc.0/vbus.
However this approach does not distinguish between a USB charger or a USB host.
I found this udev approach but I don't think it's available in my version of the kernel. because I did not find any USB related nodes in my /dev. This discussing also shows that it might not be feasible, ether.
I also found linux hotplug and tried the netlink example, but I didn't see any output running the example when I connect/disconnect the USB cable.
What I want to do is to detect connection type on the device, when USB is connected, and prepare (unmount file system) and switch to g_file_storage if device is connected to a host, and do nothing if device is connect to a charger.
How shall I achieve this?
To achieve that, you can use the inotify(7) feature, available in all linux kernels to be awaken as soon as some device node gets created in /sys.
To know what type of device you have, you have to read the usb info from proper usb ioctl call (or if you are not a kernel interface expert, using the libusb interface) to get the device vendor, device id and device class fields coming from the device. Normally, the hotplug software gets informed on these clase of events (via a special socket). The most probably reason you don't get the device properly initialized is some misconfiguration in the config files for udev system, which normally has one entry for each possible device vendor/device id pair and allows it to load the appropiate device driver to control it. The process continues with the device driver module creating dynamically the actual devices, and they'll appear in the /dev/ filesystem as a consequence of some other kernel event to udevd.
Read apropiate documents in <linux_src>/Documentation (this directory directory belongs to the linux kernel source code, so you'll probably need to install it), and udevd(8) man pages to be able to add a new usb.
On 2.6.37 kernel, this could be done by polling
/sys/devices/platform/musb-omap2430.0/musb-hdrc.0/mode
If handshake with host is successful then it will read as "peripheral", if fail it'll be "idle".

USB device detection on /dev directory on Linux

Using the lsusb command in Linux I have come to know about bus and device numbers, along with its name of newly attached USB devices.
But how can I know on which device directory (/dev/*) USB device get attached in Linux using command lines only?
It isn't a rule that every device has to show up directly under /dev/, but some device classes will be nested under sub-directories inside /dev/
USB device drivers are a bit different,
If you connect a valid USB device, USB HCI would read the VID:PID and will tell the usb-core that the device with VID:PID combination is connected.
If the usbcore detects any registered driver for the VID:PID combination, it will couple it with the device, and the device file creation would happen accordingly
The device will show in /dev/bus/usb/.., even if, the corresponding driver is not present, to indicate that the device was detected.
You need to have the device driver to have the device in action/operation.
You can verify whether a device driver is coupled to the device through
cat /sys/kernel/debug/usb/devices
Each detected USB device will have an entry here, and also shows the "Driver=" field, to show which driver is associated with your device.
Now, IFF there is a driver, that makes an entry in appropriate /dev tree, you will find the device there.
NOT every device will show up directly under /dev/ in the first level.
say, your mouse/keyboard will not show-up directly under /dev, but inside /dev/input/
Likewise, IF the connected USB device is a char/block device, it MAY show up there, that too have exceptions.
If your device is and ethernet/wifi device, the interface device will NOT show up under /dev/, cross-check with your existing eth0, wlan0, they will not appear directly under /dev/, but will in /proc/net/devices
sda/b/c shows up under /dev directly, because they are block devices and are managed by udev, as such.
Here is an example of lsusb output on my laptop:
Bus 004 Device 123: ID 2001:3c1b D-Link Corp. DWA-127 Wireless N 150 High-Gain Adapter(rev.A1) [Ralink RT3070]
It's the device 123 on the bus 004. /dev/bus/usb/004/123 is just the file for the interested device.
The path might vary on different kernels. The result above holds on kernel 3.15.2

Linux USB device path meaning? (need to distinguish USB-Serial converters)

I have several USB-serial converters (Prolific) attached to a USB hub. I can't find any udev information that allows me to distinguish these converters depending on the physical port they are connected to.
I hope the device path can give me that information...
/devices/pci0000:00/0000:00:0f.5/usb1/1-3/1-3.1/1-3.1:1.0/ttyUSB0
...but I could not find any documentation that explains the meaning of the numbers (hopefully one of them exactly identifies the physical port). Can somebody explain these numbers and tell me if they allow me to clearly identify the physical port?
I'm no expert in this field, but these are my interpretation of those numbers:
pci0000:00: This is your PCI controller.
0000:00:0f.5: This is the PCI identifier of your USB controller.
usb1: The usb controller itself.
1-3: The identifier of the USB hub. It may be an internal hub, or it may be absent.
1-3.1: Device connected to the first port of that hub.
1-3.1:1.0: Configuration #1, Interface #0 in that device.
So, my guess is that the physical port is identified by 1-3.1, that is the string to the left of the colon in the last piece of the device path.
I don't have a hub around but I'd bet that if you connect it via a hub you'll get something like:
/devices/pci0000:00/0000:00:0f.5/usb1/1-3/1-3.1/1-3.1.1/1-3.1.1:1.0/ttyUSB0
The physical port would be 1-3.1.1, and that last 1 would be the port used in that hub.
This site:
http://hackaday.com/2009/09/18/how-to-write-udev-rules/
references the command:
udevadm info -a -p $(udevadm info -q path -n /dev/ttyUSB0)
(okay, it's a little different, but that command works)
which tells us information like this:
KERNELS=="3-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
I've used this information in the past to put together a rule like this one:
KERNELS=="3-1", SUBSYSTEMS=="usb", DRIVERS=="usb", SYMLINK+="USBPORT1"
So every time a device gets plugged into usb port 1, it creates a simlink in the /dev folder that is consistent regardless of what order things are plugged in.

Resources