Discussion:
[libhid-discuss] Polling interrupt endpoint
Rene
2010-07-02 16:57:19 UTC
Permalink
Hi to all of You!

I (who am a total newbie to usb and libusb/libhid) am using libhid to
both read and write from an IN and OUT interrupt endpoint in a hid. This
goes OK with hid_interrupt_read() and hid_interrupt_write(). I have been
doing a lot of reading about usb and have among many other things that
an interrupt ep has a polling time. AFAI understand it, this is used for
calculating the required bandwidth (along with the ep size, this is done
by driver code that is on a lower level in the usb stack) and off course
for setting the polling time. However, when I "steal" the device from
the kernel hid driver, do I have to see to it that this polling time is
respected? I guess I do because I can't find another possibility. Esp.
for reading this is important. For writing (updating the readings on a
display) I can just send a package whenever there is something to be
sent, being carefull to respect the polling time.

Another question is how pressing a button on the usb device might wake
up the pc if it is suspended. AFAI can see, this is not possible.

Are my own answers to my questions correct? Or am I overlooking something?

My last question is about the fact that there are two things taking
place. The display part (the display is on the device) of my program is
reading from a fifo, I could do that with a blocking read or with select
with a time-out, the last option allows me to poll the in ep at a
regular interval where the first one doesn't. The in ep needs to be read
every 50 ms and then something has to be put into another fifo. What
would be the most elegant solution to achieve this?

The thought occured to me that I could fork the program and have child
and parent do their own parts.

Another option would be to have a select with just a timeout, when it
times out (10ms) it polls the in ep every fifth time (polling time for
the out ep is 10 ms, for in ep 50 ms) and it checks the fifo that in
this case would have been opened as non-blocking to see if there is
anything to send to the out ep.

I am not only new to usb and libhid but also rather new to Linux and
would very much like to hear Your opinions about this or perhaps You
have a completely different idea about how I would best design this.

Thank You very much in advance!

Yours sincerely,
Rene

P.S. And for the readers who have build libhid: A big thank You for that
fact as well!
Peter Stuge
2010-07-04 10:12:30 UTC
Permalink
Hi Rene,
Post by Rene
an interrupt ep has a polling time. AFAI understand it, this is used
for calculating the required bandwidth (along with the ep size, this
is done by driver code that is on a lower level in the usb stack)
and off course for setting the polling time. However, 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.)

The poll time is not so much a requirement for the USB driver (your
program) but for the USB host controller chip and the USB system
software (the kernel USB stack, always used, even if you detach the
HID kernel driver).

If the device has data available for you with this interval, and if
you do not want to lose any data, *then* you need to make sure to
read from the device using libhid frequently enough that the lower
level USB software and hardware will consistently perform a transfer
on every opportunity.
Post by Rene
Esp. for reading this is important.
I hope it's clearer from the above. Basically we can't say if it is
important or not, that depends on your particular device and the
assumptions made by the firmware engineers.
Post by Rene
For writing (updating the readings on a display) I can just send
a package whenever there is something to be sent, being carefull to
respect the polling time.
You can send any time. The lower level USB software and hardware will
handle scheduling for you.
Post by Rene
Another question is how pressing a button on the usb device might
wake up the pc if it is suspended. AFAI can see, this is not possible.
So the device has buttons - does it identify itself as a HID
keyboard? If so, then I would strongly recommend interfacing with the
kernel input layer instead of trying to speak directly with the USB
device.

That said - remote resume is possible over USB, what is your question
again? While the PC is suspended, USB still has power. Not a lot, but
some.
Post by Rene
My last question is about the fact that there are two things taking place.
The display part (the display is on the device) of my program is reading
from a fifo, I could do that with a blocking read or with select with a
time-out, the last option allows me to poll the in ep at a regular interval
where the first one doesn't. The in ep needs to be read every 50 ms and
then something has to be put into another fifo. What would be the most
elegant solution to achieve this?
It also depends on how the device wants to be read. If you were using
libusb then one option would be to have two threads, or to use async
USB transfers. I'm not sure you can, with libhid. (Though, if you're
using libhid on top of libusb-compat-0.1 on top of libusb-1.0, then
it would probably be fine anyway.)
Post by Rene
Another option would be to have a select with just a timeout, when it times
out (10ms) it polls the in ep every fifth time (polling time for the out ep
is 10 ms, for in ep 50 ms)
Please don't mix these timings. Any timeout involved in userspace
calls into the kernel have no guaranteed latency and can always be
longer than the specified time, while the polling time is an
absolutely strict upper limit for the hardware. The polling is done
in the host controller hardware.
Post by Rene
I am not only new to usb and libhid but also rather new to Linux and
would very much like to hear Your opinions about this or perhaps You
have a completely different idea about how I would best design this.
Please say more about the process of reading data from the device.


//Peter
Rene
2010-07-07 12:10:03 UTC
Permalink
Post by Peter Stuge
Hi Rene,
Hi Peter,

First of all, thank you very much for replying! Second, sorry that I did
not reply sooner, this was most certainly not due to a lack of interest.

You have already given me quite some enlightment. I am very new to all
of this and usb is not an easy matter, it is not just the protocol one
has to learn but also the practical aspects of implenting stuff both on
device and host side. There is a lot of theoretical information on the
web, and there is a lot of stuff that can be helpfull when it comes to
implementation but how exactly to use all of this is sometimes difficult.
Post by Peter Stuge
Post by Rene
an interrupt ep has a polling time. AFAI understand it, this is used
for calculating the required bandwidth (along with the ep size, this
is done by driver code that is on a lower level in the usb stack)
and off course for setting the polling time. However, 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).

On a side note: Later on, the device will have to be usable from Windows
as well.
Post by Peter Stuge
The poll time is not so much a requirement for the USB driver (your
program) but for the USB host controller chip and the USB system
software (the kernel USB stack, always used, even if you detach the
HID kernel driver).
If the device has data available for you with this interval, and if
you do not want to lose any data, *then* you need to make sure to
read from the device using libhid frequently enough that the lower
level USB software and hardware will consistently perform a transfer
on every opportunity.
Aha, that is very clear. 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).
Post by Peter Stuge
Post by Rene
Esp. for reading this is important.
I hope it's clearer from the above.
Yes, it most certainly is, thanks.
Post by Peter Stuge
Basically we can't say if it is
important or not, that depends on your particular device and the
assumptions made by the firmware engineers.
The firmware "engineer" is myself as well ;-). I should have given more
detail in my first post.

The device (an Amtel AVR mcu running LUFA) has some buttons that can be
pressed and a display (but in a future edition it might have values from
a rotary encoder or from the ADC as well), the host side application
should and will (because I will write it) know how to interpret the
data. The device sends data only if something has changed. The display
does not need constant refreshing. When I want it to display something
else, 1 KB of raw data has to be send to it as quickly as possible (in 8
byte chunks which is the maximum the ep of the mcu can handle)(and I
made a mistake about the polling time: the OUT EP polling time will be 1
ms).
Post by Peter Stuge
Post by Rene
For writing (updating the readings on a display) I can just send
a package whenever there is something to be sent, being carefull to
respect the polling time.
You can send any time. The lower level USB software and hardware will
handle scheduling for you.
I understand that now, I was very confused about that and obviously my
hypothesis was wrong.
Post by Peter Stuge
Post by Rene
Another question is how pressing a button on the usb device might
wake up the pc if it is suspended. AFAI can see, this is not possible.
So the device has buttons - does it identify itself as a HID
keyboard?
No, it doesn't. It is a vendor specific device. 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). 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.
Post by Peter Stuge
If so, then I would strongly recommend interfacing with the
kernel input layer instead of trying to speak directly with the USB
device.
That said - remote resume is possible over USB, what is your question
again? While the PC is suspended, USB still has power. Not a lot, but
some.
I know, my problem was that I thought that the user space program would
be responsible for the polling once the device was "stolen" from the
kernel. In that case, when the pc would put itself to sleep, there would
be no more polling (because my user space program would be sleeping) and
so the system would never know that there was an interrupt from the usb
device. 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.
Post by Peter Stuge
Post by Rene
My last question is about the fact that there are two things taking place.
The display part (the display is on the device) of my program is reading
from a fifo, I could do that with a blocking read or with select with a
time-out, the last option allows me to poll the in ep at a regular interval
where the first one doesn't. The in ep needs to be read every 50 ms and
then something has to be put into another fifo. What would be the most
elegant solution to achieve this?
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.

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. 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.
Post by Peter Stuge
If you were using
libusb then one option would be to have two threads, or to use async
USB transfers. I'm not sure you can, with libhid. (Though, if you're
using libhid on top of libusb-compat-0.1 on top of libusb-1.0, then
it would probably be fine anyway.)
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.
Post by Peter Stuge
Post by Rene
Another option would be to have a select with just a timeout, when it times
out (10ms) it polls the in ep every fifth time (polling time for the out ep
is 10 ms, for in ep 50 ms)
Please don't mix these timings. Any timeout involved in userspace
calls into the kernel have no guaranteed latency and can always be
longer than the specified time, while the polling time is an
absolutely strict upper limit for the hardware. The polling is done
in the host controller hardware.
I mixed things up a bit. I was thinking about minimum latency so the
device would not be asked for data too quickly but off course we're
talking about _maximum_ latency. I know that can't be guaranteed in user
space. Sorry for the confusion (like I said, many aspects from this
project are new to me).
Post by Peter Stuge
Post by Rene
I am not only new to usb and libhid but also rather new to Linux and
would very much like to hear Your opinions about this or perhaps You
have a completely different idea about how I would best design this.
Please say more about the process of reading data from the device.
I hope the things I wrote above are sufficient.

I really appreciate your help.

Yours sincerely,
Rene
Peter Stuge
2010-07-09 20:01:55 UTC
Permalink
Hi Rene,
Post by Rene
First of all, thank you very much for replying!
You're welcome.
Post by Rene
Post by Peter Stuge
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.
Post by Rene
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.
Post by Rene
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.
Post by Rene
The firmware "engineer" is myself as well ;-).
This is good. :)
Post by Rene
The device (an Amtel AVR mcu running LUFA) has some buttons that can be
pressed and a display
..
Post by Rene
Post by Peter Stuge
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.
Post by Rene
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.
Post by Rene
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.
Post by Rene
Post by Peter Stuge
remote resume is possible over USB, what is your question again?
..
Post by Rene
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.
Post by Rene
Post by Peter Stuge
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.
Post by Rene
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.
Post by Rene
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.
Post by Rene
Post by Peter Stuge
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.
Post by Rene
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!
Post by Rene
I hope the things I wrote above are sufficient.
I think so. I hope my advice is helpful.
Post by Rene
I really appreciate your help.
You're welcome! :)


//Peter
Rene
2010-07-12 15:10:59 UTC
Permalink
Hi Peter,

Thanks again for your help and patience...
Post by Peter Stuge
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.
Yes, I am going to try that. At the moment, the device is working the
way I want it to (well, the display part is working, the i/o not yet),
now I am going to try to rework both firmware and host software to get
out the HID stuff and replace it with non-HID code.

I nosed around in libhid and saw that e.g. an interrupt ep there just
calls the interrupt read from usblib. I don't expect much troubles. I am
starting to get used a bit to the way libs are documented. For a
beginner, what is generated in these doxygenpages is not always
sufficient to get started with...
Post by Peter Stuge
Post by Rene
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.
I am confident that I'll be able to work things out that way. But first
I am going to concentrate on Linux.

By the way, I think for Windows I might use "windows backend", I saw
that it should be working quite well by now.
Post by Peter Stuge
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.
Yes, I understand that that is much better. There is no advantage in
using my device as a HID. It was just the easiest way to get it going at
the moment I was looking around at the web. And almost all of the
examples and tutorials concentrate on creating usb devices from a
certain defined class, hid or audio or so. But there is not much to be
found that shows one how to build a vendor defined class usb device and
driver on the pc.
Post by Peter Stuge
Post by Rene
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.
That was a misunderstanding as well, I thought that polling was taking
place all the time. That if one set a polling interval of say 10 ms,
every 10 ms, the device would be read, no matter what. In that case
somewhere in the host something would get full at some moment. But now
that you wrote that a device is only being read when a program wants to
read from that device, it all makes much more sense. After all, it would
be rather useless to be polling a device if nothing is being done with
the data.
Post by Peter Stuge
Post by Rene
The firmware "engineer" is myself as well ;-).
This is good. :)
Well, in fact it is only as good as I am as a usb-programmer, which at
the moment is not that good yet ;-) (no, I am not fishing for a
compliment, you already gave me one but what I wrote here is just the
way it is - I don't feel bad about it). But I am very happy that my
device is already working, that gives a lot of confidence. Learning usb
is quite frustrating, all the time one wants to start coding but really
a lot of reading, re-reading and re-re-reading is required, as well as
processing in the brain before one really gets a grasp. At least, that
is how it worked for me. Fortunately I am now in the phase where I can
do active experimenting, and I appreciate it very much that you
corrected several misunderstandings I had in my head.
Post by Peter Stuge
HID and vendor specific are orthogonal and mutually exclusive.
You are right. What I meant was vendor specific usage, so not one of the
standard HIDs like a keyboard or a mouse where the report items have
some meaning to the os.
Post by Peter Stuge
Post by Rene
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.
And it is not the behaviour I am looking for so a HID is obviously not
the right choice, I understand now why.
Post by Peter Stuge
Post by Rene
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.
Yes, I am going to take that road from now.
Post by Peter Stuge
Post by Rene
Post by Peter Stuge
remote resume is possible over USB, what is your question again?
..
Post by Rene
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.
I looked it up after reading this. I did not know that yet. But it turns
out that LUFA even supports that. Quite a guy who wrote that framework!
Post by Peter Stuge
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.
I already had been reading a bit in the api documentation and had found
the descriptions of those two.

But the select part of my driver would not be about usb but it would be
the other side of the driver, the fifo. I might use a message queue for
it as well, am not sure yet. Anyway in Linux I want there to be a fifo
somewhere or a message queue in which the program that should write
something on the display can just write some special sort of bitmap
structure (which I will provide in a header file) by means of calling a
fuction which does the actual writing for the programmer, and I want the
driver to read this fifo or queue with select. In Windows I'll take
another road, but in Linux this driver would be a process that is
running and monitoring its input and sending the data, after some
processing (simple protocol to the device) to the endpoint.
Post by Peter Stuge
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.
Suppose I would not use async mode but sync. Is it correct if I would
implement it this way:

(pseudocode)

while (1)
{
usb_interrupt_read(timeout parameter = 1 second or so, more than 50
ms I mean);
do something with received data;
}

Am I correct that this piece of code will automatically only take place
every 50 ms if that value is in the endpoint descriptor?

I know that this way I can not achieve what I want, after all I need to
write to another endpoint as well, but this is just theoreticaclly
speaking.
Post by Peter Stuge
Post by Rene
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.
Post by Rene
Post by Peter Stuge
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.
I see, and this all functions without me having to do anything? I mean,
if one has a system with only libusb-1.0 on it and one runs a program
written for libusb-0.1, I don't have to do anything, this layer will do
the translation automatically? It is also integrated in libusb-1.0 and
not something that has to be installed seperately?
Post by Peter Stuge
Post by Rene
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!
That sounds very encouraging, thanks!
Post by Peter Stuge
Post by Rene
I hope the things I wrote above are sufficient.
I think so. I hope my advice is helpful.
It most certainly is. Not only have you given me some precious tips, you
have also pointed me at several things I thought I understood but where
my understanding was wrong. Many things make more sense to me now.

Yours sincerely,
Rene

Loading...