Linux Virtual USB device driver - linux

My goal is to create a virtual USB char device (not block device) for Linux 2.6.32 and above (I use debian squeeze) that would be recognize by the system.
I would like that this device be listed with lsusb as a normal USB device, and that every application could use libusb in order to open the device, and send control message, and make bulk write/read. But behind this virtual device, it's behavior would be set by my application. I want to set it's product ID, it's vendor ID, answer to USB status, and bulk read.
I've read some posts about how to use USB/IP in order to create a virtual USB device, and that's exactly what I want to do
Installation and emulation of virtual USB Device
http://breaking-the-system.blogspot.fr/2014/08/emulating-usb-devices-in-python-with-no.html
But unfortunately, when I tried with 2.6.32 kernel and above, I didn't succeed making it work. So I looked at how to create a kernel module that would create the virtual device :
http://pete.akeo.ie/2011/08/writing-linux-device-driver-for-kernels.html
This one looks great also, but the sample provided doest not indicate how to make it an USB device.
I've seen some post talking about it with windows but none that could help me with Linux.
I would like to avoid buying some USB programmable cards when it can be done with software.
Have anyone any leads on how to make the first methods works under newer kernel, or convert the sample code of the second method for making an USB device ?

I have fixed the code of http://breaking-the-system.blogspot.fr/2014/08/emulating-usb-devices-in-python-with-no.html (first method using USB/IP) to work with linux 4.3.
In the original code are missing USB requests like set configuration and get status. Without the implementation of all USB requests used for the OS driver the code will not work.
The fixed code can be downloaded in https://github.com/lcgamboa/USB-Emulation .

I guess raw-gadget kernel module is the thing that you want?
you can check the dummy_hcd and tests directory inside the repo, it will guide you how to create a virtual USB device

Related

USB dongle (non-storage device) not recognized after rebooted while plugged in

We have a programmable proprietary USB dongle (that is not a storage device) that we insert into a machine running Windows CE7. With the dongle there is an API we can use. One simple API function is the "checkIfDongleInserted" function.
The USB dongle is recognized when inserted on the running machine, i.e. it is listed in the Wince Registry under HKLM\Drivers\Active and we can find it with the checkIfDongleInserted function.
However if we restart the machine while the dongle stays inserted, the device is not recognized anymore, i.e. it doesn't show up in the registry and the API function fails. If we reinsert the dongle by hand then it is recognized again.
Funny enough other devices (USB sticks, USB keyboards, USB mouses) work and are recognized perfectly well after a reboot of the machine while said devices stay inserted.
Upon inspecting the USB dongle's driver I found that it implements the interface USBInstallDriver. Researching this interface led me to https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms923254(v=msdn.10), where in the remarks it says that
The USB driver module calls this function when an unrecognized
device is attached to the USB port
So my guess is that restarting this "USB driver module" (from a client application) while the machine is running could be an idea to recognize the USB dongle. Though I don't see this happening from a client application.
What could be the reason for this specific device not being detected upon boot while it is inserted?
Is there a way to recognize it without having to reinsert it manually?
Inspired by this post I found the solution.
I was right in the assumption that I had to restart the USB controller, I just didn't know how.
After further research I found that HCD (Host Controller Driver) is the driver that detects the inserted USB devices and that I need to reload again. Upon doing that it would detect my already inserted USB dongle again.
Use FindFirstDevice to find the device (in this case the Host controller), then unload the driver with DeactivateDevice() and soon after load the driver again with ActivateDeviceEx().
Here's the code without any error handling (I'm on a different PC and too lazy to copy everything over, so I just roughly wrote the above steps in C)
DeviceSearchType searchType = DeviceSearchByDeviceName;
DEVMGR_DEVICE_INFORMATION deviceInfo;
//Find HCD
handle = FindFirstDevice(searchType,L"HCD*",&deviceInfo);
//Save the deviceKey to later be able to ActivateDeviceEx()
WCHAR* deviceKey = deviceInfo.szDeviceKey;
DeactivateDevice(deviceInfo.hDevice);
Sleep(100); //to make sure
ActivateDeviceEx(deviceKey,NULL,0,NULL);

CDC class vid:pid to use for my STM32F3 based equipment

I am plannig to use usb connection to let PC communicate with my equipment based on STM32F373VC.
I tried the CDC class using the example in STM32CubeF3 V1.9.0 by removing the uart peripheral management.
PC detects a usb device with vid:pid 0483:5740. Linux automatically recognizes CDC class (STMicroelectronics STM32F407), loads the cdc_acm module, and the ttyACM0 VCP is created. I don't know about Windows, but reading the readme of the example it seems that a driver should be installed.
I have some questions:
Can I use VID:PID 0483:5740 for my product?
Does the various versions of Windows automatically recognize the device (and associate it with the CDC driver) or is it really necessary to install a driver?
If I can't use these VID:PID, can I ask ST for a PID assigned to me for small productions (as other silicon vendors do)?
Could ST assign me a PID that the various versions of Windows, Linux and Mac automatically recognize as CDCs without needing to install drivers or configure anything?
If not, do VID:PID pairs exist that are automatically recognized by the various versions of Windows, Linux and Mac as CDC class without needing to install drivers or configure and that I can legally use for my small production?
About drivers recognizing your device:
If your device is of class CDC, driver should be able to be loaded no matter what VID:PID is used (as long as selected VID:PID is not assigned to other device that has device specific driver). For Windows please refer to this document.
You should be able to test Linux CDC class driver by altering device descriptor in your device library code (which should be possible, if I correctly understand available ST documentation).
About having your own VID:PID:
There is some thread on github about this here. It should cover all possible options including the ones you asked about.

WebUSB with FT230x serial chip

I'm hoping to use the newly released WebUSB API to communicate with a device i developed. This devices uses a FT230X USB to serial chip. The drivers of this chip are installed on most devices and communicating with it using minicom works smoothly. Now i want to try communicate with it through the browser. I started by downloading this example for arduino: webusb arduino. I set the filter to { 'vendorId': 0x0403, 'productId': 0x6015 } which shows the device. I'm able to find the device but when i try to connect i get the error: NotFoundError: Device unavailable.
Is there a way to find more specific errors? Should i set up a different interface or do i need to change some other configurations? I'm new to USB drivers so any help getting me on my way would be nice. I did read the (short) getting started documentation here. I use Ubuntu 16.04
The FT230X USB to serial chip does not provide an USB interface that Chrome can take control of. This is because, as you mention, the drivers for this chip are available with your operating system. With the serial driver attached Chrome cannot make the device available to your page through the WebUSB API.
The Arduino example programs the Atmel 32u4 chip on many Arduino and Arduino-compatible boards to add an additional USB interface which is not claimed by any system driver and is therefore available to Chrome.
Some developers have also had success either changing the vendor and product ID of their device so that the OS drivers do not claim it or by manually unbinding the driver.

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".

pre notifcation of an inserted usb device, before enumeration starts in linux?

Please help me, How can i get the pre notifcation of an inserted usb device, before enumeration starts in linux ?
You can use libudev to get notifications of added/removed devices.
Here's a tutorial for libudev. You can also use the code here to get started.
There's also libusb available for usb events/manipulation.

Resources