Discussion:
[libhid-discuss] HID vs. vendor specific class
John Parsons
2010-07-22 02:51:05 UTC
Permalink
I've been reading the recent discussion here re HID vs. vendor specific
classes with great interest. Like Rene, I am primarily a hardware
designer. I plan to add USB connectivity to an existing product. BTW,
I am also the firmware developer, chief marketer and bean counter!

The product is a proximity sensor, and is built around a Microchip
PIC18F14K50, their low cost 20-pin device with USB connection. Though
this device is not exactly human interactive, I initially planned to
release this as a HID because it only transfers a few bytes of data, HID
routines are included in Microchip's example code libraries, all OS's
come with HID drivers, and it seems very simple to implement, at least
on Windows.

Statements such as the following seemed to validate my reasoning:
"If you have the time and funds you can implement using ?vendor
defined? interfaces which are included within the USB specification as
an option. But while you are moving along this difficult and
time-consuming path don?t be surprised if your competitor introduces a
similar product using a collection of standard drivers and captures most
of the available customer base. I am a STRONG advocate of OS-supplied
and vendor-supplied drivers and always recommend that everyone use this
route. I maintain that you need an extremely compelling reason to
embark on writing your own device driver; most people don?t."
-- John Hyde, _Embedded USB Design by Example_ p. 13.

But I want Mac and Linux app writers to be able to use this product with
the same ease as Windows app writers. Peter Stuge makes a strong case
for vendor-specific class devices. I am willing to go that route, but
could use some help getting started. Pointers to resources would be
appreciated... something like "USB vendor specific classes for dummies!"

Thanks in advance,
John
--
--
http://www.fastmail.fm - Or how I learned to stop worrying and
love email again
Xiaofan Chen
2010-07-22 05:32:08 UTC
Permalink
Post by John Parsons
The product is a proximity sensor, and is built around a Microchip
PIC18F14K50, their low cost 20-pin device with USB connection. ?Though
this device is not exactly human interactive, I initially planned to
release this as a HID because it only transfers a few bytes of data, HID
routines are included in Microchip's example code libraries, all OS's
come with HID drivers, and it seems very simple to implement, at least
on Windows.
I have mixed feeling with HID, I like HID. But I also agree with Peter
Stuge that at current situation, generic HID may not be a very good
solution for cross-platform application.

With libusb-1.0 Windows backend, HID device can be used with
libusb-1.0 API. Linux is also okay since you have the capability to
detach the kernel driver. The only main issue is with Mac OS X.
You need to write a codeless kext to prevent the kernel from
claim the HID device.

So I have created an feature request for libusb-1.0 Mac OS X HID backend.
http://www.libusb.org/ticket/33

If that is done, I think generic HID device will be good for most
applications require cross-OS support. Okay, here I only mention
the three major OS in the market. But FreeBSD 8.0+ will also be
good since they have libusb-1.0 compatible API which seems to
work for generic HID device as well.

BTW, despite the name libhid, I think libhid is not really meant
for generic HID device. Its strong point is the HID report parser.
For generic HID device, you do not really need libhid, rather generic
libusb-1.0 will be easier.
Post by John Parsons
But I want Mac and Linux app writers to be able to use this product with
the same ease as Windows app writers. ?Peter Stuge makes a strong case
for vendor-specific class devices. ?I am willing to go that route, but
could use some help getting started. ?Pointers to resources would be
appreciated... something like "USB vendor specific classes for dummies!"
It is very easy to convert an HID based generic device to a vendor specific
device on the firmware side. Basically you just need to modify the descriptor to
remove the HID class specific descriptor, and you have a vendor specific device.

On the host side, the HID IN/OUT report can normally be converted to
interrupt in/out transfer. The HID feature report can easily be converted
to generic control transfer. If you use libusb, it is not that difficult.
--
Xiaofan http://sourceforge.net/projects/libusb-win32/
Xiaofan Chen
2010-07-22 05:41:15 UTC
Permalink
Post by Xiaofan Chen
BTW, despite the name libhid, I think libhid is not really meant
for generic HID device. Its strong point is the HID report parser.
For generic HID device, you do not really need libhid, rather generic
libusb-1.0 will be easier.
Another potential solution for cross-platform HID API. The Linux
support is based on hidraw which is quite new under Linux and
seems still not as mature. But the Windows and Mac codes are
based on native HID API. So this could be a good alternative
to libhid and libusb for generic HID device.
http://github.com/signal11/hidapi
--
Xiaofan http://sourceforge.net/projects/libusb-win32/
Peter Stuge
2010-07-22 18:18:17 UTC
Permalink
Hi John,
Post by John Parsons
I've been reading the recent discussion here re HID vs. vendor specific
classes with great interest. Like Rene, I am primarily a hardware
designer. I plan to add USB connectivity to an existing product. BTW,
I am also the firmware developer, chief marketer and bean counter!
:)
Post by John Parsons
initially planned to release this as a HID
..
Post by John Parsons
"If you have the time and funds you can implement using ?vendor
defined? interfaces which are included within the USB specification as
an option. But while you are moving along this difficult and
time-consuming path don?t be surprised if your competitor introduces a
similar product using a collection of standard drivers and captures most
of the available customer base. I am a STRONG advocate of OS-supplied
and vendor-supplied drivers and always recommend that everyone use this
route. I maintain that you need an extremely compelling reason to
embark on writing your own device driver; most people don?t."
-- John Hyde, _Embedded USB Design by Example_ p. 13.
This is a great book, and I agree with the author that standard
drivers are best - *if they fit the task*. The most important point
about (ab)using the HID class for a device which should not really
tie into the kernel's input subsystem, is just that - you're creating
a device which announces to the world that it is a human interface
device, when in fact it's a foam missile cannon, or a proximity
interface. There is no device class for those things, and I don't
think there should/could be.

I don't care about the "abuse" per se, sometimes abusing a protocol
can be a really neat hack, but with HID I think the disadvantages far
outweigh the single advantage of trivial access on Windows systems.

With vendor specific, libusb-1.0 and WinUSB, it's still very easy to
access the device on Windows. libwdi can even be used to transparently
and automatically bind the WinUSB.sys driver to the device.

(The Hyde book is fairly old, WinUSB and userspace drivers in general
are fairly new, on the most common systems.)
Post by John Parsons
But I want Mac and Linux app writers to be able to use this product
with the same ease as Windows app writers. Peter Stuge makes a
strong case for vendor-specific class devices.
Thank you! You just made my day. :)
Post by John Parsons
I am willing to go that route, but could use some help getting
started. Pointers to resources would be appreciated... something
like "USB vendor specific classes for dummies!"
One of the points I try to make about vendor specific is that it
actually means *less* requirements than a standard device class.
There's no kernel driver that will hog the device and there are no
restrictions on how to write descriptors or how to transfer data.

Everything on the USB sm?rg?sbord is available.

The flip side is that firmware developers need to actually design the
USB interfaces; choose endpoints and transfer types that the device
should use, and this does indeed require more knowledge than
copypasting a HID example and basically avoiding going into any depth
about USB. (I'm not saying that this is the case for you, John.)

When not being held back by a particular device class, it's also
possible to consider making the device have multiple interfaces or
even configurations. Sometimes this doesn't make sense, other times I
think it's a significant advantage.

I'm happy to help with suggestions about what endpoints to choose, as
are several others. Please describe the major characteristics of the
data flow between PC and your device?

It's quite possible that you'll still use interrupt transfers, like
HID does, but then it'll still be simpler because you don't have to
deal with reports and can just use the transfers as the binary
packets that they are.
Post by John Parsons
Post by Xiaofan Chen
For generic HID device, you do not really need libhid, rather
generic libusb-1.0 will be easier.
Yes, I agree with this. Although there is the report mess to deal
with manually, for simple reports it might be OK. Still, no reports
at all is easier still. :)
Post by John Parsons
Another potential solution for cross-platform HID API. The Linux
support is based on hidraw which is quite new under Linux and
seems still not as mature. But the Windows and Mac codes are
based on native HID API. So this could be a good alternative
to libhid and libusb for generic HID device.
http://github.com/signal11/hidapi
For the above reasons I don't really like HID for generic devices.
It forces USB devices into the HID box which is rarely a good fit.
That said, I also think there will be a HID layer in libusb, to
better take advantage of the native HID APIs where they are available
and easy to use. In general though, vendor specific all the way! :)


//Peter
John Parsons
2010-07-23 18:20:00 UTC
Permalink
Thank you Peter and Xiaofan for your replies. I'm encouraged to wade
into the vendor-specific class jungle!

[Now that I'm getting off the HID topic, would you prefer that I
continue this discussion in some other venue?]
Post by Peter Stuge
With vendor specific, libusb-1.0 and WinUSB, it's still very easy to
access the device on Windows. libwdi can even be used to transparently
and automatically bind the WinUSB.sys driver to the device.
...
One of the points I try to make about vendor specific is that it
actually means *less* requirements than a standard device class.
There's no kernel driver that will hog the device and there are no
restrictions on how to write descriptors or how to transfer data.
Good. I'm into easy. I don't mind digging into USB details, but given
that we're a Ma & Pa shop, and Ma and I both have day jobs, I need to
spend my time carefully.

I've had a look at http://sourceforge.net/projects/libusb-win32 (thank
you, Xiaofan) and am ready to give it a try. I've never written a
windows app, so we'll see how it goes.
Post by Peter Stuge
I'm happy to help with suggestions about what endpoints to choose, as
are several others. Please describe the major characteristics of the
data flow between PC and your device?
Thanks. This device is a dual proximity sensor, it senses the presence
or absence of objects at two locations.

It reports to the host the presence/absence status of the two sensors,
plus some timing and device configuration data. All this fits in 6
bytes. Currently communication is done via the interrupt end point.

The device also accepts 8 configuration commands from the host. One of
the commands is to return the above status info, which currently (HID)
is done by returning a 64-byte packet.

Thanks again,
John
--
--
http://www.fastmail.fm - The way an email service should be
Loading...