Bug 573 - FX2-based USB analyzers do not work on their full speed
Summary: FX2-based USB analyzers do not work on their full speed
Status: RESOLVED FIXED
Alias: None
Product: libsigrok
Classification: Unclassified
Component: Common: USB handling code (show other bugs)
Version: unreleased development snapshot
Hardware: All All
: Normal minor
Target Milestone: ---
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-03 20:02 CEST by Vlad Ivanov
Modified: 2016-02-17 11:01 CET (History)
7 users (show)



Attachments
Call WinUsb_SetPipePolicy with RAW_IO flag from fx2lafw driver (4.34 KB, patch)
2015-09-06 19:20 CEST, Vlad Ivanov
Details
Set RAW_IO WinUsb pipe flag (4.86 KB, patch)
2015-09-07 21:00 CEST, Vlad Ivanov
Details
Output log from Linux. (299.95 KB, text/plain)
2015-10-15 09:42 CEST, jry
Details
Artifact showing the problem (27.45 KB, text/plain)
2015-11-13 17:14 CET, fteller
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vlad Ivanov 2015-04-03 20:02:40 CEST
This issue is related to devices that stream capruted data in a realtime mode, such as FX2-based analyzers. The highest samplerate achieved with PulseView (Windows x64) is 6M. However, a capture using sigrok-cli works quite stable with 16M samplerate (out of 24M hardware limit).
Comment 1 Petteri Aimonen 2015-04-03 20:31:40 CEST
Just a note on my experiences with a FX2-based LA:

1) Asus Zenbook UX32VD, Ubuntu Linux 14.04 x64: works at up to 24MSps both with sigrok-cli and pulseview.

2) HP EliteBook 8541W, Windows 7 x64: works at up to 12MSps with Saleae software. Captures less than 1M samples with sigrok-cli, no matter what samplerate, ends with libusb timeout. Same problem with Ubuntu inside VirtualBox, but capture ends even sooner.
Comment 2 Vlad Ivanov 2015-04-03 20:42:18 CEST
(I should also mention that Saleae software works at 24 MSPS on the same computer — Core i3-2100, Windows 7 X64)

Regarding 1M samples limit on Windows: have you tried updating PulseView to the latest nightly build? There was a handle leak a while ago and it was fixed recently (see #343)
Comment 3 Felix 2015-04-24 10:07:14 CEST
It seems like a Windows only Problem:
- Up to 24 MHz (8 Ch) and 12 MHz (16 Ch) on Archlinux
- Same Machine, using Windows 7: Errors on more than 2 MHz

my assumption:
WinUSB can be set to different Pipe-Policies, to control thorughput. For Bulk-Read-Transfers, the Flag RAW_IO has to be set, otherwise WinUSB would wait for received Data before requesting the next packet. In RAW_IO mode, multiple Requests can be queued and done in parralel.
(see https://msdn.microsoft.com/en-us/library/windows/hardware/ff728833%28v=vs.85%29.aspx)

Problem here: libsigrok doesn't use WinUSB directly, but through cross-platform-wrapper libusb.

To confirm this assumption, a quick fix would be to patch libusb (set RAW_IO at libusb/os/windows_usb.c:2394 in winusb_configure_endpoints() ).
If this helps, a final fix would be only possible in libusb, or by implementing WinUSB directly in libsigrok.

If I got enough time, I will try to set up the toolchain and give this a shot.
Comment 4 Vlad Ivanov 2015-09-05 14:27:08 CEST
(In reply to comment #3)
> It seems like a Windows only Problem:
> - Up to 24 MHz (8 Ch) and 12 MHz (16 Ch) on Archlinux
> - Same Machine, using Windows 7: Errors on more than 2 MHz
> 
> my assumption:
> WinUSB can be set to different Pipe-Policies, to control thorughput. For
> Bulk-Read-Transfers, the Flag RAW_IO has to be set, otherwise WinUSB would
> wait for received Data before requesting the next packet. In RAW_IO mode,
> multiple Requests can be queued and done in parralel.
> (see
> https://msdn.microsoft.com/en-us/library/windows/hardware/ff728833%28v=vs.
> 85%29.aspx)
> 
> Problem here: libsigrok doesn't use WinUSB directly, but through
> cross-platform-wrapper libusb.
> 
> To confirm this assumption, a quick fix would be to patch libusb (set RAW_IO
> at libusb/os/windows_usb.c:2394 in winusb_configure_endpoints() ).
> If this helps, a final fix would be only possible in libusb, or by
> implementing WinUSB directly in libsigrok.
> 
> If I got enough time, I will try to set up the toolchain and give this a
> shot.

Have you by chance tried to patch libusb?
Comment 5 Vlad Ivanov 2015-09-05 19:12:33 CEST
Just tried with patched libusb and it worked, stable 24M capture on Windows with FX2 analyzer! Thanks to Felix for the suggestion, I'll try to figure out a solution without patching libusb.
Comment 6 Vlad Ivanov 2015-09-06 19:20:33 CEST
Created attachment 154 [details]
Call WinUsb_SetPipePolicy with RAW_IO flag from fx2lafw driver

So here are some of the available solutions:
1) Use a patched version of libusb, download and compile using sigrok-cross-mingw script. Possible problems: I don't know if it's ok to use RAW_IO for all USB devices handled by libsigrok
2) Extend libusb API to allow managing pipe policies, use patched version, compile as in (1). Harder to maintain.
3) Mess around with libusb OS private structures as in the attached patch. It's a very “dirty” solution, but it doesn't require patching libusb. Although the patch seems to obtain a winusb handle and the endpoint id correctly, Pulseview crashes due a memory access violation in winusb.dll — I haven't figured it out, but it could be a calling convention violation. libusb calls WinUsb functions using LoadLibrary and GetProcAddress.
Comment 7 Vlad Ivanov 2015-09-07 21:00:50 CEST
Created attachment 155 [details]
Set RAW_IO WinUsb pipe flag
Comment 8 Martin Ling 2015-09-07 22:14:42 CEST
We are actually about to start using a patched libusb for Windows builds anyway, although for other reasons, and the patch series in question is one that's likely to be merged in the near future anyway - it's the one implementing libusb_get_pollfds() on Windows.

This libsigrok patch as is is waay too hacky to merge, but it's great to have - it shows what needs to be done and gives us something working to check/benchmark a cleaner solution against.
Comment 9 Martin Ling 2015-09-07 23:42:05 CEST
There is some relevant discussion about RAW_IO here:

http://comments.gmane.org/gmane.comp.lib.libusb.devel.general/20756
Comment 10 Daniel Elstner 2015-09-25 18:05:45 CEST
(In reply to comment #8)
> We are actually about to start using a patched libusb for Windows builds
> anyway, although for other reasons, and the patch series in question is one
> that's likely to be merged in the near future anyway - it's the one
> implementing libusb_get_pollfds() on Windows.

Just to note, this is done now, and current libsigrok in fact requires the patched libusb for USB support on Windows.
Comment 11 jry 2015-10-15 09:42:47 CEST
Created attachment 167 [details]
Output log from Linux.
Comment 12 jry 2015-10-15 09:46:15 CEST
I want to confirm this problem but in my case I can reproduce it even on Linux Mint 17.2 x86 running inside VMware (on Windows 7 x64). Please see previously attached output log from this command:

sigrok-cli -d fx2lafw -c samplerate=24M --time 10000 --loglevel 5 -o out.sr 2>log.txt
Comment 13 jry 2015-10-15 10:06:33 CEST
With Saleae software installed on Linux (inside VMware) I'm able to capture up to 16MHz for one minute or longer.
For 24MHz I'm getting error message "device was not able to keep up with this sample rate" and 16MHz sample rate is set.

With sigrok-cli even 8MHz doesn't work, I'm getting LIBUSB_TRANSFER_TIMED_OUT.
Comment 14 fteller 2015-11-13 17:14:48 CET
Created attachment 185 [details]
Artifact showing the problem

Hello,
I encountered the similar problem on Beaglebone black ARM linux. I am not sure if this is exactly the same problem but looks like yes.
Setup is: Beaglebone black with Buildroot-based Linux and Saleae "ebay-clone".
Log from my run provided in attachments.
Comment 15 Vlad Ivanov 2016-01-19 14:41:06 CET
>> We are actually about to start using a patched libusb for Windows builds
>> anyway, although for other reasons, and the patch series in question is one
>> that's likely to be merged in the near future anyway - it's the one
>> implementing libusb_get_pollfds() on Windows.

> Just to note, this is done now, and current libsigrok in fact requires 
> the patched libusb for USB support on Windows.

It looks like libusb_get_pollfds() returns a handle to the event (assigned here: https://github.com/dickens/libusb/blob/event-abstraction-v4/libusb/io.c#L2443 and here: https://github.com/dickens/libusb/blob/event-abstraction-v4/libusb/os/windows_usb.c#L713) which doesn't seem related to the winusb handle required for WinUsb_SetPipePolicy.
Comment 16 Martin Ling 2016-01-19 14:53:41 CET
I wasn't suggesting that the patches we're already applying to libusb would help. Just that since we're already using a patched libusb, it would be straightforward to add additional patches to change pipe policy.
Comment 17 Vlad Ivanov 2016-01-19 19:08:20 CET
>it would be straightforward to add additional patches to change pipe policy.

In your opinion, what would be the correct way to implement such functionality? Provide an API function to retrieve a native interface handle?  

Could you please describe the optimal way so I (or somebody else) could implement a patch? Thank you.
Comment 18 Martin Ling 2016-01-19 19:49:13 CET
(In reply to comment #17)
> In your opinion, what would be the correct way to implement such
> functionality? Provide an API function to retrieve a native interface
> handle?  
> 
> Could you please describe the optimal way so I (or somebody else) could
> implement a patch? Thank you.

I think ideally it would be something that could eventually go upstream into libusb - we don't want to be patching it ourselves indefinitely.

I don't know if there's any existing mechanism for adjusting OS-specific details in libusb that you could add this onto. If not, I guess it would take the form of a new libusb API call, either to allow configuring the pipe policy, or to get a pointer to the relevant WinUSB data structure to do it yourself.

For sigrok purposes I'd be happy just to have something that works and is relatively clean - we can debate API details with the libusb guys later. But if you want to get some input f
Comment 19 Martin Ling 2016-01-19 19:51:05 CET
...from them, discuss on the libusb mailing list first I guess.
Comment 20 Vlad Ivanov 2016-02-02 06:58:42 CET
I have posted a question to libusb mailing list. It appears that the easiest solution is to enable RAW_IO unconditionally since libusb does the buffer management itself. Is https://github.com/dickens/libusb/ owned by libsigrok developers (so a PR should be sent there) or should we patch libusb in sigrok-cross-mingw script?
Comment 21 Martin Ling 2016-02-02 10:47:09 CET
(In reply to comment #20)
> I have posted a question to libusb mailing list. It appears that the easiest
> solution is to enable RAW_IO unconditionally since libusb does the buffer
> management itself.

Link to libusb-devel thread for others following this:

http://sourceforge.net/p/libusb/mailman/message/34809509/

> Is https://github.com/dickens/libusb/ owned by libsigrok developers (so a PR
> should be sent there) or should we patch libusb in sigrok-cross-mingw script?

That repository belongs to Chris Dickens who is working on the event abstraction branch for libusb - i.e. supporting libusb_get_pollfds() on Windows. He's not a sigrok developer.

The RAW_IO change would be unrelated to that work, so a PR there would not be appropriate. We should come up with a patch, apply it in sigrok-cross-mingw, and submit it to libusb. Could be done via your own github or other public repo.
Comment 22 Uwe Hermann 2016-02-17 11:01:20 CET
Fixed in 38599f9c9116df8bd0f3012c003b5d92af705089, thanks a lot to Vlad Ivanov for the final patch and everyone else who helped debug and fix this!

As far as I can see the FX2 devices are pretty usable on Windows now with the above patch. The patch will hopefully be upstreamed eventually (as well as the special libsub branch we're using currently) so we can switch back to using release tarballs of libusb later on.

I've tested a bunch of non-FX2 devices as well, couldn't see any regressions there either after the patch, so this bug can be closed I think.

If there's anything else missing related to this specific issue on Windows, please reopen though.

For other, unrelated and/or non-Windows fx2lafw issues, please open separate bugs (if any).