[libhid-discuss] Polling interrupt endpoint

Peter Stuge peter at stuge.se
Fri Jul 9 20:01:55 UTC 2010


Hi Rene,

Rene wrote:
> First of all, thank you very much for replying!

You're welcome.


>>> when I "steal" the device from the kernel hid driver, do I have to
>>> see to it that this polling time is respected?
>>
>> No, not in general. However, it depends on how the device is abusing
>> HID in order to use USB. (It's an extremely bad idea to use HID for
>> devices that should not use the kernel HID driver. It's like driving
>> a tractor on the side walk, when there is a street right next to it.)
>
> To be honest, I really don't know whether I am abusing HID or not. The fact 
> that I chose HID is because for the Atmel mcu I am using there is a generic 
> HID-implementation in LUFA (the usb-framework that is available for these 
> mcus as foss) that I understand by now and can very easily tailor to my 
> needs and on the host side I came across libhid and the sample app that is 
> delivered with it and with those two, I can achieve what I want. The two 
> int eps are exactly what I need so I thought a hid would be the easiest 
> thing to use. And the function of the device, input through buttons and 
> output through a display are quite fitting to "interfacing with a human".
>
> My knowledge and experience are still too limited to judge if this was the 
> right choice, I would very much appreciate your opinion and - if you think 
> there is a better way for me to achieve my goals (which are described 
> below) - suggestions about the way I should choose (I always appreciate 
> pointers to usefull and practical places as well off course).

Ok. It's easy to fall into the HID trap because there is a lot of
information and code examples for HID, and because it is trivial to
use on Windows. (Those two are likely related.) In contrast, doing
almost anything else with USB on Windows is an absolute nightmare.

I suggest that you make your device use the vendor specific device
class 0xff instead of having it use the HID class.


> On a side note: Later on, the device will have to be usable from
> Windows as well.

No problem. There are two solutions at the moment, either you program
for the libusb-0.1 API, or you program for the libusb-1.0 API.

libusb-0.1 is no longer maintained, but might still be an option if
Windows support in the short term is neccessary.

In the former case you would install the libusb0.sys signed kernel
driver written by the libusb-win32 project (a fork from libusb-0.1,
providing the libusb-0.1 API with some extensions on Windows) to
handle your device on Windows, then everything works nicely.

In Linux and Mac OS you need only ensure that the user has access to
the vendor specific device. HID requires root access (reboot on Mac!).

You can still use the interrupt endpoints of course. But you can
completely cut away all the overhead introduced by the device
announcing that it's a HID class device, and then needing to work
with/around the kernel HID driver in every operating system.


> What would happen if I fail to read often enough apart from missing
> data? Would some fifo or so get full and would the lower level
> parts stop polling eventually? Suppose not a single program reads the 
> mouse but I keep on moving the mouse (rather useless, I know, but 
> theoretically speaking).

This is entirely device specific, or firmware specific if you will.

If no program on the host ever reads, then then host will never
initiate any communication with the device. The device is only given
opportunity to send data on the bus when an application wants to
read.

The device could of course have a FIFO that gets full and makes the
device go into a state where it will no longer respond to reads from
an application, but that would be one very broken device.


> The firmware "engineer" is myself as well ;-).

This is good. :)


> The device (an Amtel AVR mcu running LUFA) has some buttons that can be 
> pressed and a display
..
>> So the device has buttons - does it identify itself as a HID
>> keyboard?
>
> No, it doesn't. It is a vendor specific device.

HID and vendor specific are orthogonal and mutually exclusive.


> If I understand it correctly, if something is a keyboard device,
> it's keys are "parallel" to the keys on a normal keyboard. So if a
> button on the device were pressed and someone had his word
> processor on the foreground, something would happen in that program
> (e.g. an "a" was entered or so)(depending on the report descriptor
> in the device).

Yep, it is when this behavior is a feature that the USB HID class
should be used for a device.


> My project is for making an embedded device whiches keys have to be
> completely separate and are only relevant to one certain host side
> application.

Since it is a human interface, a case could be made to use the HID
class, but because you never want to deal with the OS HID driver I
would strongly recommend a vendor speciic device class instead.

>> remote resume is possible over USB, what is your question again?
..
> Now I have understood that this polling goes on because it still
> happens in the controller and that way an interrupt can be detected
> and wake up the pc again.

Almost right, there is no polling in suspend, wake-up signalling is
initiated by the device. This is a special case indeed.


>> It also depends on how the device wants to be read. 
>
> When something changes at the device side (button pressed or released) it 
> will put data (the current state of the buttons) in the IN EP that should 
> be read with a maximum latency of 50 ms. The rest of the time it will 
> return NAK.

Ok, that's perfectly fine, also using vendor specific.


> Then the data has to be put in a fifo (at least that is my plan at the 
> moment) and the application interested in it can read that using the
> select function.

Unfortunately it's not possible to program USB portably using
select(). The best you can get so far is libusb-1.0, which provides
both a synchronous and an asynchronous API for USB programming.
libusb-1.0 has known behavior (and one or two known bugs that are
being fixed) when used in threaded applications, while libusb-0.1
does not fit well into such an environment at all. Using libusb-1.0
in async mode you get callbacks on completed transfers.

In order to meet the 50ms system response time requirement I would
make sure to have multiple outstanding requests at all times, for
when many events follow each other.


> But that means that for the rest the application would come to a 
> halt (off course I can use the timeout of select).
>
> I think using a fork would be the simplest solution for the user
> space driver.

The only way to program USB portably is with libusb and threads,
which means that libusb-1.0 should really be your choice since 0.1
doesn't have very well defined behavior in threaded apps.


>> using libhid on top of libusb-compat-0.1 on top of libusb-1.0,
>
> I really don't know whether I am using this compatibility layer or not
> (I did read about it on the libusb website). I am using Xubuntu 9.04
> and when I look in the package manager, originally only libusb-0.1
> was installed. I then installed libusb-1.0 as well. And it works.
> However, how this works "under water", I don't know and I have no
> idea how to find it out.

libusb-0.1 and libusb-1.0 are not mutually exclusive. They are two
distinct APIs and ABIs, which can be said to solve the same problem
but in different ways. Thus it's fine to have both installed at the
same time. Apps using the 0.1 API will use the old library, apps
using the 1.0 API will use the new library.

libusb-compat-0.1 is a wrapper that provides the 0.1 API by using
the libusb-1.0 API. This has the benefit of increased performance and
deterministic threading behavior, without requiring app rewrite to
the new API, but really, the right thing to do is to use the new API
instead.


> Sorry for the confusion (like I said, many aspects from this
> project are new to me).

That's ok. I think you have a good understand of the important bits
already in a pretty short time. Well done!


> I hope the things I wrote above are sufficient.

I think so. I hope my advice is helpful.


> I really appreciate your help.

You're welcome! :)


//Peter



More information about the libhid-discuss mailing list