Is it possible for a USB device to support multiple drivers? I'd like to support my own proprietary driver but also CCID as a second choice. When the device is plugged in, the user can select which one to use. The driver to use is determined by what the USB descriptor says, right? If that is so, is it possible to indicate that both drivers are supported? Is the idea of supporting two drivers doable?
On Windows, having two supported drivers is possible. In fact, to get Microsoft Logo certification, it is mandatory that the USB device supports this functionality. (Requirement CONNECT-0123)
However, the UI behavior you describe isn't offered by Microsoft. Driver selection is automatic.
Your USB device can indicate it supports two interfaces. In that case, both drivers will be loaded.
I am sure that it is not possible for a device to use two drivers at the same time but what is possible is for the device to enumerate using one class type and driver and then during its operation, in response to some command over the USB or operation of the device, for it to disconnect and then re-enumerate as a different type of device using the second driver.
As an example the product that I am developing normally enumerates as a CDC (serial port emulation) but when I need to reload the code it re-enumerates as a different device type and uses the chip vendor supplied driver to perform the code download. Once this completes then the device re-enumerates itself again as a CDC device type and resumes its serial port emulation.
You therefore need to provide a "command" interface that will trigger the transition between the two operating modes and to ensure that the two drivers are installed on the host computer ready for the mode switch.
Related
I'm at the beginning of trying to develop a USB HID bootloader for a Kinetis processor, and getting no help from that department. I have made some modifications to Kinetis firmware designed for a similar processor(I'm using the KL26Z, the original code is for KL25Z), and I do now see the beginning of the USB enumeration(on a PC running W7). However, the PC asks for driver software, and I don't understand why, as I thought the whole point of going the HID route was that one didn't need to install drivers. So the device shows up under device manager, but as a non-working problem device. My problem is that I don't really know what should happen. Any insights would be welcome.
Here's what should happen: the computer will ask your device for its USB descriptors when it detects your device. The descriptors must have certain fields like bDeviceClass set properly to indicate that it is an HID. If the computer sees those fields, it will attach the HID driver to your device.
In the Device Manager, you should look at the "Compatible Ids" of your device. Do you see USB\Class_03 in that list? If so, that should match the driver input.inf that comes with Windows, so the INF file will be applied to your device, and you device will show up as "USB Input Device" in the Device Manager. If you don't see USB\Class_03 in your list then there is probably some problem with your device's USB descriptors or its USB stack.
I am working on a product with an LPC1788 which needs the following USB features:
Firmware download (from host PC to device, not through a USB
key).
File upload (from device to host).
Ideally we'd also be able to get some information from the device like serial number etc.
The device should only work with a custom Windows application, so simply using a mass-storage device as-is will not do. There are quite a lot of data to upload (200MB +), so using USB bulk transfers seem necessary to me.
What is the best way to approach this? I imagine I would need to create some sort of USB composite device(?). However, I was hoping to use nxpUSBlib or winUSB so I don't have to go through the Windows driver validation process.... What are my options? Perhaps there some way to make the mass-storage device invisible for Windows?
Thanks!
Dirk
I think you'll definitely want to go with a vendor specific bulk device and you can easily use WinUSB for all of this. This should be sufficient for everything you've specified here.
For your firmware loader I'd recommend looking at the DFU (device firmware update) specification. You'll probably want make some command for your device that when sent will cause it to reenumerate itself in to DFU mode for update (rather than a composite device that is always exposed - this restricts the issue of the other interface being in use while you're flashing your device). Then you can flash it and reset it so it will reenumerate as your vendor specific bulk device again.
I wouldn't recommend mucking with mass storage, from your requirements it will be better to implement your own protocol and create some application or DLL that consumes the WinUSB API to communicate with your device, including the firmware update.
I'm developing an embedded USB device which needs to be available to two different hosts.
The first is a normal PC, where it will be used as a MSC (mass storage) device, and the second is a specific hardware which the USB device needs to comunicate with a CDC profile.
during the enumeration, the USB device send descriptor table where it declares its capabilities.
Is there a way in the enumeration process to know to which host the device was connected to ?
The simplest solution perhaps would be to implement a "USB Composite Device", where the single device presented both the MSC and CDC class interfaces simultaneously. The host PC would see both interfaces, but you could simply leave one unused. The "specific hardware" would probably simply ignore the MSC class if it had no support for it.
There is any way to I disable/enable a specific USB Port with my application ?
I'm not aware of any way to do this from user space, and even within the kernel it could be tricky: I think you would need to install a dummy I/O Kit driver which matches all USB devices and/or interfaces. This could be tricky as existing drivers would take precedence, so you'd need to work around that. Once matched, you would check the port in the driver's probe() method and return true if it was one of the disallowed ports. This would stop other drivers from grabbing the device, which would essentially disable it.
I am writing an Usb driver and I have an issue.
When I insmod the driver with the device already plugged in before hand, the probe function is not called. It is only called after I disconnect the device and plug it again.
I want to make it so that it works when I start my pc with the device already plugged in.
Could someone please help me?
From Documentation/driver-model/binding.txt:
When a new device is added, the bus's list of drivers is iterated over
to find one that supports it. In order to determine that, the device
ID of the device must match one of the device IDs that the driver
supports. The format and semantics for comparing IDs is bus-specific.
From the same source:
The process is almost identical for when a new driver is added.
The bus's list of devices is iterated over to find a match. Devices
that already have a driver are skipped. All the devices are iterated
over, to bind as many devices as possible to the driver.
So it looks like you have a problem in the ID matching, that is in your case specific to the USB bus, see the usb_device_match function in drivers/usb/core/driver.c.
Or it may be that your device already is bound to a device that is unloaded when the device is unplugged (you can check that by controlling if there is a symlink to a driver in the corresponding /sys/bus/usb/xxxxx directory)
"Or it may be that your device already is bound to a device that is unloaded when the device is unplugged (you can check that by controlling if there is a symlink to a driver in the corresponding /sys/bus/usb/xxxxx directory)"
And if there is a symlink?
This can be solved by writing a proper udev rule for your device. Look for examples at /etc/udev/rules.d/