Quantcast

interrupt transfers

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

interrupt transfers

John Stirling

Hi,

 

I'm having an issue with occasional lost interrupt transfers. On a USB analyser I can see the problem occurs when two interrupt transfers come in fairly close to each other (approx 1ms gap).

 

Currently I am stacking up several (10) interrupt transfer requests at initialisation and then just resubmitting them every time I get a callback.

 

Setup -

 

#define HID_RX_BUFFER_SIZE 512

 

static void vRequestHIDData(int iIndex)

{

  libusb_device_handle *ptDeviceHandle = [poUSBDevice ptGetDeviceHandle];

  unsigned int uiHIDEndpoint = [poUSBDevice uiGetHIDEndpoint];

 

  struct libusb_transfer *ptTransfer = g_atHIDRxTransfers[iIndex].ptTransfer;

  u8 *pu8Buffer = g_atHIDRxTransfers[iIndex].pu8Data;

 

  // Reload the transfer

  libusb_fill_interrupt_transfer(ptTransfer,        // transfer

                                 ptDeviceHandle,         // dev_handle

                                 uiHIDEndpoint,        // endpoint

                                 pu8Buffer,           // buffer

                                 HID_RX_BUFFER_SIZE,     // length

                                 vHIDRxCallback,   // callback

                                 (void *)iIndex,        // user_data

                                 500                    // timeout

                                );

 

  libusb_submit_transfer(ptTransfer);

}

 

Resubmission:

static void vHIDRxCallback(struct libusb_transfer *ptTransfer)
{
  int iLength = ptTransfer->actual_length;
  int iIndex = (int)ptTransfer->user_data;

  if (ptTransfer->status != LIBUSB_TRANSFER_TIMED_OUT)
  {
    vLOG_STATIC_FUNC_VA("### HID RX (%d) l=%d s=%d ###", iIndex, iLength, ptTransfer->status);
    if (bLOG_IsLoggingEnabledHere())
      vUTL_DumpHex(ptTransfer->buffer, iLength);
  }

  // Send it on to main app thread
  write(iWriteFD, ptTransfer->buffer, iLength);

  // and set up to receive more HID data
  libusb_submit_transfer(ptTransfer);
}

If I set different timeouts for each transfer i can see the previously missing transfers. eg

static void vRequestHIDData(int iIndex)

{

  libusb_device_handle *ptDeviceHandle = [poUSBDevice ptGetDeviceHandle];

  unsigned int uiHIDEndpoint = [poUSBDevice uiGetHIDEndpoint];

 

  struct libusb_transfer *ptTransfer = g_atHIDRxTransfers[iIndex].ptTransfer;

  u8 *pu8Buffer = g_atHIDRxTransfers[iIndex].pu8Data;

 

  // Reload the transfer

  libusb_fill_interrupt_transfer(ptTransfer,        // transfer

                                 ptDeviceHandle,         // dev_handle

                                 uiHIDEndpoint,        // endpoint

                                 pu8Buffer,           // buffer

                                 HID_RX_BUFFER_SIZE,     // length

                                 vHIDRxCallback,   // callback

                                 (void *)iIndex,        // user_data

                                 (100*iIndex)                    // timeout

                                );

 

  libusb_submit_transfer(ptTransfer);

}

I suspect my initial attempty was failing due to all 10 transfers timing out at approx the same time and not being resubmitted quick enough ?

Is there an example somewhere showing interrupt transfers stacked up and resubmitted ? Although setting different timeouts is getting me past this problem I suspect I might need to recalculate the timeout on each resubmission to ensure there are a certain number outstanding at all times ?

Thanks,
John

 

 

 

 

 

 

 



Audio Partnership PLC, Gallery Court, Hankey Place, London SE1 4BB, UK Reg No. 2953313 This e-mail is confidential and for the addressee only. Please refer to Disclaimer for important notices.
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: interrupt transfers

Tim Roberts
John Stirling wrote:

>
>  
>
> I'm having an issue with occasional lost interrupt transfers. On a USB
> analyser I can see the problem occurs when two interrupt transfers
> come in fairly close to each other (approx 1ms gap).
> ...
>
> I suspect my initial attempty was failing due to all 10 transfers
> timing out at approx the same time and not being resubmitted quick
> enough ?
>

That's quite possible.

> Is there an example somewhere showing interrupt transfers stacked up
> and resubmitted ? Although setting different timeouts is getting me
> past this problem I suspect I might need to recalculate the timeout on
> each resubmission to ensure there are a certain number outstanding at
> all times ?
>

Do you really need the timeout?  Usually, a timeout on an interrupt pipe
is just an escape hatch, in case something goes horribly wrong.  In that
case, you could set it to a very long interval that was unlikely to
occur in real life.

--
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: interrupt transfers

Peter Stuge
Tim Roberts wrote:
> > I suspect I might need to recalculate the timeout on each
> > resubmission to ensure there are a certain number outstanding
> > at all times ?
>
> Do you really need the timeout?  Usually, a timeout on an interrupt pipe
> is just an escape hatch, in case something goes horribly wrong.  In that
> case, you could set it to a very long interval that was unlikely to
> occur in real life.

I'd recommend using a minimum of 10+bInterval ms timeout for
interrupt transfers if you want to make sure that they will
not time out under normal circumstances.


//Peter

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: interrupt transfers

Akos Vandra
Also if your app might be used from within a virtual machine, the
latency can skyrocket. I could get my app working only if my timeout
were in the 500ms range. Usually they completed around 100ms, but
sometimes it got as high as 500ms.

Regards,
  Ákos

On 21 May 2012 20:23, Peter Stuge <[hidden email]> wrote:

> Tim Roberts wrote:
>> > I suspect I might need to recalculate the timeout on each
>> > resubmission to ensure there are a certain number outstanding
>> > at all times ?
>>
>> Do you really need the timeout?  Usually, a timeout on an interrupt pipe
>> is just an escape hatch, in case something goes horribly wrong.  In that
>> case, you could set it to a very long interval that was unlikely to
>> occur in real life.
>
> I'd recommend using a minimum of 10+bInterval ms timeout for
> interrupt transfers if you want to make sure that they will
> not time out under normal circumstances.
>
>
> //Peter
>
> ------------------------------------------------------------------------------
> Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and
> threat landscape has changed and how IT managers can respond. Discussions
> will include endpoint security, mobile security and the latest in malware
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> libusb-devel mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/libusb-devel

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: interrupt transfers

Alan Stern
In reply to this post by Peter Stuge
On Mon, 21 May 2012, Peter Stuge wrote:

> Tim Roberts wrote:
> > > I suspect I might need to recalculate the timeout on each
> > > resubmission to ensure there are a certain number outstanding
> > > at all times ?
> >
> > Do you really need the timeout?  Usually, a timeout on an interrupt pipe
> > is just an escape hatch, in case something goes horribly wrong.  In that
> > case, you could set it to a very long interval that was unlikely to
> > occur in real life.
>
> I'd recommend using a minimum of 10+bInterval ms timeout for
> interrupt transfers if you want to make sure that they will
> not time out under normal circumstances.

I don't understand why this is a problem in the first place.

Why does there have to be an outstanding transfer at all times?  If the
device wants to send or receive some data on an interrupt endpoint but
the host isn't ready, the device should simply wait until the host _is_
ready.  It shouldn't throw away the data.

If there _are_ going to be several transfers outstanding then why isn't
the async API being used?  The idea with multiple transfers is that
each time one of them completes, you submit a new one.  That can't be
done with synchronous transfers (unless you use a separate thread for
each one, which seems like overkill).  The async API doesn't include
timeouts -- you just cancel a transfer whenever you want.

Alan Stern


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: interrupt transfers

John Stirling
In reply to this post by Tim Roberts

> Is there an example somewhere showing interrupt transfers stacked up
> and resubmitted ? Although setting different timeouts is getting me
> past this problem I suspect I might need to recalculate the timeout on
> each resubmission to ensure there are a certain number outstanding at
> all times ?
>

Do you really need the timeout?  Usually, a timeout on an interrupt pipe
is just an escape hatch, in case something goes horribly wrong.  In that
case, you could set it to a very long interval that was unlikely to
occur in real life.

[John Stirling]

Setting the timeout to eg 15 seconds results works ok for a few
transfers but then seems to occasionally stick (for about 15 seconds)
and then delivers the data via the interrupt callback 15 seconds later
than it is actually observed on the USB trace.

I initially tried with timeout=0. That seems to result in a few
successful transfers followed by nothing. Possibly this is the same
problem as above.

I'm guessing above is not expected behaviour.

Going back to my original example with 10 transfers stacked up I have
double checked that they have not timed out at the point where the
problem occurs. The USB analyser shows two packets successfully
transferred on HID report 1. There is a 1ms gap between the two. I'm
only seeing data from the 2nd packet appear in the callback. The index
of the transfer is as expected (ie one greater than the last rx
transfer). It's like the 2nd packet has just overwritten the 1st.

If I repeat the test several times I am occasionally seeing the first
packet. I can't see any pattern to this yet.

Any suggestions ?

Audio Partnership PLC, Gallery Court, Hankey Place, London SE1 4BB, UK
Reg No. 2953313
This e-mail is confidential and for the addressee only.
Please refer to <a href="http://www.audiopartnership.com/AP-disclaimer.html">Disclaimer</a>  for important notices.


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: interrupt transfers

Peter Stuge
John Stirling wrote:

> Setting the timeout to eg 15 seconds results works ok for a few
> transfers but then seems to occasionally stick (for about 15 seconds)
> and then delivers the data via the interrupt callback 15 seconds later
> than it is actually observed on the USB trace.
>
> I initially tried with timeout=0. That seems to result in a few
> successful transfers followed by nothing. Possibly this is the same
> problem as above.
>
> I'm guessing above is not expected behaviour.

>From your description it sounds almost like a firmware problem..

Can you give more details about your environment? Which operating
system, what have you considered with regard to kernel drivers, and
so on? Also if you use libusb-1.0 directly or HIDAPI, and if libusb
then a note about why would be good.

libusb is not really suited for HID class communication. HIDAPI is
significantly better.


//Peter

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: interrupt transfers

John Stirling
In reply to this post by Alan Stern

On Mon, 21 May 2012, Peter Stuge wrote:

> Tim Roberts wrote:
> > > I suspect I might need to recalculate the timeout on each
> > > resubmission to ensure there are a certain number outstanding
> > > at all times ?
> >
> > Do you really need the timeout?  Usually, a timeout on an interrupt
pipe
> > is just an escape hatch, in case something goes horribly wrong.  In
that
> > case, you could set it to a very long interval that was unlikely to
> > occur in real life.
>
> I'd recommend using a minimum of 10+bInterval ms timeout for
> interrupt transfers if you want to make sure that they will
> not time out under normal circumstances.

I don't understand why this is a problem in the first place.

Why does there have to be an outstanding transfer at all times?  If the
device wants to send or receive some data on an interrupt endpoint but
the host isn't ready, the device should simply wait until the host _is_
ready.  It shouldn't throw away the data.

[John Stirling]
If I stack up the transfers the tx/rx sequence is a lot quicker than if
i just have one transfer. It's not essential, just seemed better.

The data is being sent across the bus correctly. It's just not appearing
in the rx callback. The 2nd packet is appearing. It's as if it has
overwritten the first packet. I haven't dug any further than that.


If there _are_ going to be several transfers outstanding then why isn't
the async API being used?  The idea with multiple transfers is that
each time one of them completes, you submit a new one.  That can't be
done with synchronous transfers (unless you use a separate thread for
each one, which seems like overkill).  The async API doesn't include
timeouts -- you just cancel a transfer whenever you want.

[John Stirling]
I am using the async API. There are timeouts included in that as far as
I'm aware. Or am I missing something ?

Audio Partnership PLC, Gallery Court, Hankey Place, London SE1 4BB, UK
Reg No. 2953313
This e-mail is confidential and for the addressee only.
Please refer to <a href="http://www.audiopartnership.com/AP-disclaimer.html">Disclaimer</a>  for important notices.


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: interrupt transfers

Alan Stern
On Tue, 22 May 2012, John Stirling wrote:

> If I stack up the transfers the tx/rx sequence is a lot quicker than if
> i just have one transfer. It's not essential, just seemed better.
>
> The data is being sent across the bus correctly. It's just not appearing
> in the rx callback. The 2nd packet is appearing. It's as if it has
> overwritten the first packet. I haven't dug any further than that.

Ah, okay.  If you know that both packets are getting sent on the
bus, have you checked that the data toggle values are set correctly?  
An incorrect data toggle will cause a packet to be ignored by the host
controller.

If you're running under Linux, you can get further information by using
usbmon (see Documentation/usb/usbmon.txt in the kernel source) and by
turning on the usbfs_snoop module parameter for usbcore.  The first
will show whether the kernel receives the second packet correctly, and
the second will show whether the information is getting sent back to
libusb.

> I am using the async API. There are timeouts included in that as far as
> I'm aware. Or am I missing something ?

Oh, you're right.  Sorry, my mistake -- I didn't look very carefully.

Alan Stern


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: interrupt transfers

John Stirling
On Tue, 22 May 2012, John Stirling wrote:

> If I stack up the transfers the tx/rx sequence is a lot quicker than
if
> i just have one transfer. It's not essential, just seemed better.
>
> The data is being sent across the bus correctly. It's just not
appearing
> in the rx callback. The 2nd packet is appearing. It's as if it has
> overwritten the first packet. I haven't dug any further than that.

Ah, okay.  If you know that both packets are getting sent on the
bus, have you checked that the data toggle values are set correctly?  
An incorrect data toggle will cause a packet to be ignored by the host
controller.

If you're running under Linux, you can get further information by using
usbmon (see Documentation/usb/usbmon.txt in the kernel source) and by
turning on the usbfs_snoop module parameter for usbcore.  The first
will show whether the kernel receives the second packet correctly, and
the second will show whether the information is getting sent back to
libusb.


[John Stirling]
Yes, I'm running linux. 2.6.21, on a Samsung s3c2412 (arm based)

I haven't checked the toggle values. I'll have a look. Thanks for the
suggestion.

Audio Partnership PLC, Gallery Court, Hankey Place, London SE1 4BB, UK
Reg No. 2953313
This e-mail is confidential and for the addressee only.
Please refer to <a href="http://www.audiopartnership.com/AP-disclaimer.html">Disclaimer</a>  for important notices.


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: interrupt transfers

Xiaofan Chen
On Wed, May 23, 2012 at 12:15 AM, John Stirling
<[hidden email]> wrote:
> On Tue, 22 May 2012, John Stirling wrote:
> [John Stirling]
> Yes, I'm running linux. 2.6.21, on a Samsung s3c2412 (arm based)

That kernel version is really very old. You may want to try
a newer version to see if that helps.

> I haven't checked the toggle values. I'll have a look. Thanks for the
> suggestion.
>

--
Xiaofan

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
libusb-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Loading...