Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pyusb test suite #235

Open
jayvdb opened this issue Apr 13, 2019 · 34 comments
Open

pyusb test suite #235

jayvdb opened this issue Apr 13, 2019 · 34 comments

Comments

@jayvdb
Copy link

jayvdb commented Apr 13, 2019

Is there no test suite for this package?

Seems strange not to have one as the project has been around so long.

@ixjlyons
Copy link
Contributor

The most common problems with using this library seem to mostly be hardware or environment/OS issues, which are pretty hard to catch with automated tests. I could see some utility in writing tests that exercise the API, but those are most effective when they're written before or during development and pyusb is fairly inactive/stable at this point. They could help detect regressions though. Did you have example test cases in mind?

@jayvdb
Copy link
Author

jayvdb commented Apr 14, 2019

I was mostly looking for smoke test type tests, in order to validate that the openSUSE package is working correctly. We need to validate that it is compatible with Python 3.7. Also need to check it works with the system dsos, and some integration problem hasnt occurred.

@ixjlyons
Copy link
Contributor

Well, I totally forgot that there are actually are tests, they just don't run in a CI environment. It seems to me after a quick glance that most of the tests depend on some kind of hardware device to be present (see tests/devinfo.py). Tests that rely on hardware could be skipped and remaining tests or new tests could be run to check compatibility across Python versions, backend versions, etc.

I think @SimplicityGuy is the person with the keys to the repo and would be the person to talk to about getting tests running automatically if it makes sense to try and do so. Unfortunately the original author appears to be unable to contribute to the project these days, so this will probably take quite a bit of effort.

@jayvdb
Copy link
Author

jayvdb commented Apr 15, 2019

Wow, I dont know how I missed that. A good way to get more visibility for the tests is to include them in the sdist, and add a note about that at the top of the changelog. That should get some distros attempting to run them, reporting problems, etc and hopefully providing patches.

I'll see if I can get some of them working.

@jayvdb
Copy link
Author

jayvdb commented Apr 15, 2019

I have the utils and find components tested at https://build.opensuse.org/package/show/home:jayvdb:branches:devel:languages:python/python-usb. I'll tidy it up a bit and submit it.

The rest does require a device, and I couldnt quickly see how to emulate that.

Some interesting projects doing that in https://github.com/search?l=Python&q=usbip&type=Repositories , and https://github.com/smulikHakipod/USB-Emulation/blob/master/USBIP.py

Very likely more of the codebase can be tested using some mocking.

https://github.com/vpelletier/python-libusb1/blob/master/usb1/testUSB1.py has some example tests which get a bit deeper into the codebase, and they have logic to skip certain tests when there is no device to test.

@jayvdb
Copy link
Author

jayvdb commented Apr 15, 2019

I found etc/pyusb.rules contains the same vendor/product id (04d8 fa2e) as in tests/devinfo.py, and the same device is referenced in https://github.com/me21/usb-travis/blob/master/libusbK/examples/open-device/open-device.c . 04d8 is Microchip Technology, Inc. Not sure about the device ID, but some places mentioning fa2e also mention a benchmark device.

@mcuee
Copy link
Member

mcuee commented Nov 29, 2019

The test is for a Microchip FW based device, but you can use other device and adapt the test codes.

@mcuee
Copy link
Member

mcuee commented Nov 29, 2019

FW codes are here.
https://github.com/walac/bmfw

It is based on the FW codes written by Travis, the author of libusbK.
https://github.com/mcuee/libusbk/tree/master/BmFW

@mcuee mcuee added the doc label Nov 29, 2019
@jonasmalacofilho
Copy link
Member

jonasmalacofilho commented Jan 5, 2020

@mcuee

I definitively need to build/get a test device for myself... could you suggest a device and setup that's easy to configure for this?

@mcuee
Copy link
Member

mcuee commented Jan 6, 2020

Any Arm Cortex M0/M3/M4 device should be good if you want to port to the more popular MCU platform.

If you want to use PIC, then I think the following board is low cost and very powerful.
https://www.microchipdirect.com/product/search/all/dm320107?_ga=2.138139893.473561004.1578276435-901967630.1553597350

@mcuee
Copy link
Member

mcuee commented Jan 6, 2020

I myself use an old PIC18F87J50 USB PIM.
https://www.microchip.com/Developmenttools/ProductDetails/MA180021#additional-summary

I also have Explorer 16 with PIC32 and USB Pictail board. But I have not touched it for a while.

@mcuee
Copy link
Member

mcuee commented Jan 6, 2020

For STM32, I think this is a good start.
https://github.com/dmitrystu/libusb_stm32

Travis has created a WinUSB demo here.
https://github.com/TravisRo/libusb_stm32

You can get it work on cheap STM32 discovery boards or Nucleo boards.
Or even the dirt cheap Blue Pill board.
https://stm32-base.org/boards/STM32F103C8T6-Blue-Pill

@jonasmalacofilho
Copy link
Member

Thanks @mcuee , I'll look into these.

@eblot
Copy link

eblot commented Apr 1, 2020

FWIW, I have the same issue with PyFtdi: how to run CI, for example with GitHub Actions...

I looked at various HW solutions: STM32, MSP430, even small FPGAs.

The problem here is that it requires a LOT of work to make a configurable remote device to simulate and/or catch errors, and be versatile enough to be reconfigured for each kind of tests. It would be definitely great, but it is nearly the same work effort than the project I want to test... I have not enough spare time to deal with both. For now, I kept this idea in mind as it would definitely be a interesting solution. Moreover to test PyUSB you would need a HS capable device to validate real use cases, which brings its own challenges.

Another issue is that it reduces the count of people that can run the tests, as they need the test HW, and the tools to program it. It is not something you can download and easily get up and running whenever you want to troubleshoot an issue, unfortunately.

I ended up writing a virtual backend so that it is possible to describe virtual USB devices using simple Yaml config files and test several APIs.

Obviously, it is not possible to test everything this way, but it gives much more confidence in the changes as it enables to catch many errors nonetheless.

This virtual backend is added on demand to the list of PyUSB backend candidates. This means that it is not possible to exercise the code of the existing backends, only the core and util modules of PyUSB - but I guess a similar solution could be implemented to test a backend by faking ctypes...

Yaml files describe the USB device hierarchy (device, configurations, interfaces, endpoints) and support multiple devices. The virtual backend then handles the control and bulk requests.

Vendor calls are redirected to the second emulation level which handles the FTDI HW API, so it can emulate the HW behavior. At this point the test code may access this virtual HW to check what’s going on and handle the virtualized IOs.

It’s still a work in progress but I already found several issues that have been silently hiding in PyFtdi for years, and I’ve been able to develop new features and test them first with the virtual HW then check how it behaves with the real one. The most challenging part will be to simulate the real time behavior of an actual HW.

A similar solution might be useful for PyUSB, at least to check some parts of its base code.

I’m interested in whatever solution is implemented to test PyUSB (HW, virtual, any other idea) as I think I have the same needs.

HTH,
Manu

@mcuee
Copy link
Member

mcuee commented Sep 9, 2020

For Linux, look at gadget driver.
https://www.kernel.org/doc/html/v4.17/driver-api/usb/gadget.html

@mcuee
Copy link
Member

mcuee commented Sep 9, 2020

https://raspberrypi.stackexchange.com/questions/71613/how-to-use-raspberry-pi-3-as-a-usb-gadget

Take note the following from the above answer:
You cannot use the Raspberry Pi 3 as a USB gadget. At the time of writing this is only possible on the Raspberry Pi 0, 0W, A, A+, and 4. The Pi B, B+, 2, 3, 3A+, and 3B+ lack the required pin for OTG.

@mcuee
Copy link
Member

mcuee commented Sep 9, 2020

The above link to an example on RASPBERRY PI ZERO.
https://www.isticktoit.net/?p=1383

@mcuee
Copy link
Member

mcuee commented Sep 9, 2020

@jonasmalacofilho
https://www.kernel.org/doc/html/latest/usb/gadget-testing.html

The following is of particular interests as it supports isoc transfer and bulk transfer.
SOURCESINK function


pattern | 0 (all zeros), 1 (mod63), 2 (none)
-- | --
isoc_interval | 1..16
isoc_maxpacket | 0 - 1023 (fs), 0 - 1024 (hs/ss)
isoc_mult | 0..2 (hs/ss only)
isoc_maxburst | 0..15 (ss only)
bulk_buflen | buffer length
bulk_qlen | depth of queue for bulk
iso_qlen | depth of queue for iso


But you can start with the loopback first as it is simpler (only bulk transfer).

@jayvdb
Copy link
Author

jayvdb commented Sep 9, 2020

It looks like https://github.com/eblot/pyftdi/blob/master/pyftdi/tests/mockusb.py is what @eblot was referring to.

@eblot
Copy link

eblot commented Sep 9, 2020

It looks like https://github.com/eblot/pyftdi/blob/master/pyftdi/tests/mockusb.py is what @eblot was referring to.

👍

@mcuee
Copy link
Member

mcuee commented Jun 26, 2021

As mentioned in #373, I can rebuild the test FW by Wander under Windows 10.
https://github.com/walac/bmfw

Legacy Microchip MCU SW tools used:

  1. MPLAB 8.92 (you can download C32 compiler here as well)
    https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-ecosystem-downloads-archive

  2. MPLAB C18 3.47 Lite version
    https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/SW006011

HW used: PIC18F87J50 USB PIM
https://www.microchip.com/Developmenttools/ProductDetails/MA180021

But you can use other HW tools mentioned here as well, for example, you can use PICkit 2. There are quite some cheap PICkit 2 clones online.
https://github.com/walac/bmfw/tree/master/USB_Device_Benchmark/Firmware

It should be possible to port the FW to new MPLAB X IDE and XC8/XC16/XC32 based compilers and new USB PIC based boards.

On the other hand, I understand USB PICs are not that popular. I think it is probably not that difficult to port this to USB ARM based MCUs.

@mcuee
Copy link
Member

mcuee commented Jun 26, 2021

Just dig out my Orange Pi Zero board and it seems to me OTG is working as I can see g_serial driver is working (I can log in to the system using serial connection from my Mac Mini M1 using Cool Term). I will need to know how to get the SourceSink loopback gadget to work (usb_f_ss_lb.ko), modprobe seems to work but I can not see the device from the host side.
https://www.kernel.org/doc/html/latest/usb/gadget-testing.html

OrangePi Zero
http://www.orangepi.org/orangepizero/
https://www.armbian.com/orange-pi-zero/

But Raspberry Pi Zero should be easier.

@mcuee
Copy link
Member

mcuee commented Jun 27, 2021

First progress.

From orange pi zero (the first two commands are just to play safe).

mcuee@orangepizero:~$ sudo rmmod g_serial
mcuee@orangepizero:~$ sudo rmmod usb_f_acm
mcuee@orangepizero:~$ sudo modprobe usb_f_ss_lb
mcuee@orangepizero:~$ sudo modprobe g_zero

From macOS (you can use Linux as well).


~ ❯ lsusb1 -vvv -d 0525:a4a0

Bus 002 Device 017: ID 0525:a4a0  
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass          255 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x0525 
  idProduct          0xa4a0 
  bcdDevice            4.14
  iManufacturer           1 
  iProduct                2 
  iSerial                 3 
  bNumConfigurations      2
OTG Descriptor:
  bLength                 3
  bDescriptorType         9
  bmAttributes         0x03
    SRP (Session Request Protocol)
    HNP (Host Negotiation Protocol)
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0023
    bNumInterfaces          1
    bConfigurationValue     3
    iConfiguration          4 source and sink data
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                2mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0023
    bNumInterfaces          1
    bConfigurationValue     2
    iConfiguration          5 loop input to output
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower                2mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              6 loop input to output
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass          255 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  bNumConfigurations      2
can't get debug descriptor: No such file or directory
Device Status:     0x0001
  Self Powered

@mcuee
Copy link
Member

mcuee commented Jun 27, 2021

Now someone needs to port the following tool to libusb and pyusb.
https://github.com/torvalds/linux/blob/master/tools/usb/testusb.c

Device side (Orange Pi Zero)

[ 2626.275126] zero gadget: Gadget Zero, version: Cinco de Mayo 2008
[ 2626.275140] zero gadget: zero ready
[ 2626.785670] zero gadget: high-speed config #3: source/sink

Host side (Raspberry Pi 400)

[ 2578.150176] usb 1-1.2.1.3: new high-speed USB device number 14 using xhci_hcd
[ 2578.250951] usb 1-1.2.1.3: New USB device found, idVendor=0525, idProduct=a4a0, bcdDevice= 4.14
[ 2578.250973] usb 1-1.2.1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2578.250979] usb 1-1.2.1.3: Product: Gadget Zero
[ 2578.250983] usb 1-1.2.1.3: Manufacturer: Linux 4.14.70-sunxi with musb-hdrc
[ 2578.250988] usb 1-1.2.1.3: SerialNumber: 0123456789.0123456789.0123456789
[ 2578.338905] usbtest 1-1.2.1.3:3.0: Linux gadget zero
[ 2578.338925] usbtest 1-1.2.1.3:3.0: high-speed {control in/out bulk-in bulk-out} tests (+alt)

build/libusb/testusb ❯ gcc testusb.c -o testusb -lpthread

build/libusb/testusb ❯ ./testusb 
must specify '-a' or '-D dev', or DEVICE=/dev/bus/usb/BBB/DDD in env
usage: ./testusb [options]
Options:
	-D dev		only test specific device
	-A usb-dir
	-a		test all recognized devices
	-l		loop forever(for stress test)
	-t testnum	only run specified case
	-n		no test running, show devices to be tested
Case arguments:
	-c iterations		default 1000
	-s transfer length	default 1024
	-g sglen		default 32
	-v vary			default 1024

build/libusb/testusb took 57s ❯ sudo ./testusb -v 512 -D /dev/bus/usb/001/014
unknown speed	/dev/bus/usb/001/014	0
/dev/bus/usb/001/014 test 0,    0.000044 secs
/dev/bus/usb/001/014 test 1,    0.156936 secs
/dev/bus/usb/001/014 test 2,    0.094374 secs
/dev/bus/usb/001/014 test 3,    0.090598 secs
/dev/bus/usb/001/014 test 4,    0.063349 secs
/dev/bus/usb/001/014 test 5,    2.006133 secs
/dev/bus/usb/001/014 test 6,    1.196170 secs
/dev/bus/usb/001/014 test 7,    3.040815 secs
/dev/bus/usb/001/014 test 8,    6.078812 secs
/dev/bus/usb/001/014 test 9,    1.783042 secs
/dev/bus/usb/001/014 test 10,    2.467652 secs
/dev/bus/usb/001/014 test 11,   16.482459 secs
/dev/bus/usb/001/014 test 12,   17.303233 secs
/dev/bus/usb/001/014 test 13,    2.962595 secs
/dev/bus/usb/001/014 test 14,    0.221378 secs
/dev/bus/usb/001/014 test 17,    0.127209 secs
/dev/bus/usb/001/014 test 18,    0.066474 secs
/dev/bus/usb/001/014 test 19,    0.126169 secs
/dev/bus/usb/001/014 test 20,    0.097838 secs
/dev/bus/usb/001/014 test 21,    0.223985 secs
/dev/bus/usb/001/014 test 24,    2.199070 secs
/dev/bus/usb/001/014 test 27,    2.001612 secs
/dev/bus/usb/001/014 test 28,    1.179446 secs
/dev/bus/usb/001/014 test 29,    0.436017 secs


@mcuee
Copy link
Member

mcuee commented Jun 28, 2021

For people who want to try SuperSpeed USB, then the following Cypress kit may be a good value buy at US$49 (ARM9 CPU Core with 512KB RAM).
https://www.cypress.com/documentation/development-kitsboards/cyusb3kit-003-ez-usb-fx3-superspeed-explorer-kit

@mcuee
Copy link
Member

mcuee commented Jun 29, 2021

Some interesting articles: you can use simple scripts to create USB Gadgets

  1. Tested successful using my Orange Pi Zero (eq to g_zero)
    https://wiki.tizen.org/USB/Linux_USB_Layers/Configfs_Composite_Gadget/Usage_eq._to_g_zero.ko

  2. Not tested but looks good
    https://www.collabora.com/news-and-blog/blog/2019/02/18/modern-usb-gadget-on-linux-and-how-to-integrate-it-with-systemd-part-1/

@mcuee
Copy link
Member

mcuee commented Jul 16, 2021

I just got the Cypress 3 demo board and it is very good.

I just mock up a quick pyusb codes from the example here (make it to be usable with Python3)
https://github.com/danielkucera/cyusb3014-breakout/blob/master/software/loopback-test.py

#!/usr/bin/python

import usb.core
import usb.util
import time
import _thread

# find our device
dev = usb.core.find(idVendor=0x04b4, idProduct=0x00f0 )

# was it found?
if dev is None:
    raise ValueError('Device not found')

# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()

# get an endpoint instance
cfg = dev.get_active_configuration()

#intf = cfg[(0,1)]

#dev.set_interface_altsetting(interface = 0, alternate_setting = 0)
intf = cfg[(0,0)]

#print intf

ep = usb.util.find_descriptor(
    intf,
    # match the first OUT endpoint
    custom_match = \
    lambda e: \
        e.bEndpointAddress == 1)

ep2 = usb.util.find_descriptor(
    intf,
    # match the first OUT endpoint
    custom_match = \
    lambda e: \
        e.bEndpointAddress == 0x81)

assert ep is not None
assert ep2 is not None

print ('ep:',ep)
print ('ep2:',ep2)

chunkr = 2**16
chunkw = 2**22

print ("Starting CYUSB3014 python loopback test")

def read_loop():
    start = time.time()
    trans = 0
    while True:
        data = dev.read(0x81, chunkw, 1000)
        trans = trans + len(data)
        if time.time() > start + 1:
            bps = trans/(time.time() - start)
            print ("Transfered %d kB/s" % (bps/(1024)) )
            trans = 0
            start = time.time()

def write_loop():
    dat = "A"*chunkw
    while True:
        try:
            ep.write(dat)
        except:
            pass

_thread.start_new_thread( write_loop, () )

read_loop()

And here is the test results under Windows 10 and libusb-0.1 backend (with libusbk driver) using the Cypress default bulk loopback firmware ( cyfxbulklpautoenum.img).
https://github.com/hantianjz/cy_fx3_sdk/tree/master/cyusb_linux_1.0.5/fx3_images

C:\work\cyusb\cyusb3014-breakout\software [master ≡ +1 ~1 -0 !]> C:\Python39\python.exe .\loopback-test.py
ep:       ENDPOINT 0x1: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x1 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x400 (1024 bytes)
       bInterval        :    0x0
ep2:       ENDPOINT 0x81: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x400 (1024 bytes)
       bInterval        :    0x0
Starting CYUSB3014 python loopback test
Transfered 79918 kB/s
Transfered 73125 kB/s
Transfered 70744 kB/s
Transfered 73111 kB/s
Transfered 72270 kB/s
Transfered 76391 kB/s
Transfered 69592 kB/s
Transfered 71945 kB/s
Transfered 77444 kB/s
Transfered 71453 kB/s
Transfered 85137 kB/s
Transfered 69856 kB/s
Transfered 68236 kB/s
Transfered 74049 kB/s
Transfered 76535 kB/s
Transfered 78738 kB/s
Transfered 74406 kB/s
Transfered 82533 kB/s
Transfered 71939 kB/s
Transfered 73249 kB/s
Transfered 79609 kB/s
Transfered 72313 kB/s
Transfered 93656 kB/s
Transfered 75502 kB/s

@mcuee
Copy link
Member

mcuee commented Jul 16, 2021

And here is the test results under Windows 10 and libusb-0.1 backend (with libusbk.sys driver and libusb-0.1.dll from libusb-win32 project) using the Cypress default bulk source sink firmware ( cyfxbulksrcsink.img).
https://github.com/hantianjz/cy_fx3_sdk/tree/master/cyusb_linux_1.0.5/fx3_images

Quick mod of pyusb codes

#!/usr/bin/python

import usb.core
import usb.util
import time
import _thread

# find our device
dev = usb.core.find(idVendor=0x04b4, idProduct=0x00f1 )

# was it found?
if dev is None:
    raise ValueError('Device not found')

# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()

# get an endpoint instance
cfg = dev.get_active_configuration()

#intf = cfg[(0,1)]

#dev.set_interface_altsetting(interface = 0, alternate_setting = 0)
intf = cfg[(0,0)]

#print intf

ep = usb.util.find_descriptor(
    intf,
    # match the first OUT endpoint
    custom_match = \
    lambda e: \
        e.bEndpointAddress == 1)

ep2 = usb.util.find_descriptor(
    intf,
    # match the first OUT endpoint
    custom_match = \
    lambda e: \
        e.bEndpointAddress == 0x81)

assert ep is not None
assert ep2 is not None

print ('ep:',ep)
print ('ep2:',ep2)

chunkr = 2**16
chunkw = 2**16

print ("Starting CYUSB3014 python bulk sourcesink test")

def read_loop():
    start = time.time()
    trans = 0
    while True:
        data = dev.read(0x81, chunkw, 1000)
        trans = trans + len(data)
        if time.time() > start + 1:
            bps = trans/(time.time() - start)
            print ("Read: transfered %d kB/s" % (bps/(1024)) )
            trans = 0
            start = time.time()

def write_loop():
    start1 = time.time()
    trans1 = 0
    dat = "A"*chunkw
    while True:
        ep.write(dat)
        trans1 = trans1 + len(dat)
        if time.time() > start1 + 1:
            bps1 = trans1/(time.time() - start1)
            print ("Write: transfered %d kB/s" % (bps1/(1024)) )
            trans1 = 0
            start1 = time.time()

_thread.start_new_thread( write_loop, () )

read_loop()


C:\work\cyusb\cyusb3014-breakout\software [master ≡ +3 ~1 -0 !]> C:\Python39\python.exe .\sourcesink_python3.py
ep:       ENDPOINT 0x1: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x1 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x400 (1024 bytes)
       bInterval        :    0x0
ep2:       ENDPOINT 0x81: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x400 (1024 bytes)
       bInterval        :    0x0
Starting CYUSB3014 python bulk sourcesink test
Read: transfered 254788 kB/s
Write: transfered 239949 kB/s
Read: transfered 256516 kB/s
Write: transfered 237127 kB/s
Write: transfered 239851 kB/s
Read: transfered 257513 kB/s
Write: transfered 246194 kB/s
Read: transfered 254514 kB/s
Write: transfered 243847 kB/s
Read: transfered 257347 kB/s
Write: transfered 248995 kB/s
Read: transfered 253793 kB/s
Write: transfered 246223 kB/s
Read: transfered 255750 kB/s
Write: transfered 244703 kB/s
Read: transfered 254942 kB/s
Read: transfered 260570 kB/s
Write: transfered 241867 kB/s
Write: transfered 247435 kB/s
Read: transfered 255497 kB/s
Write: transfered 246942 kB/s
Read: transfered 256157 kB/s
Write: transfered 246276 kB/s
Read: transfered 256769 kB/s
Write: transfered 249399 kB/s
Read: transfered 256892 kB/s
Write: transfered 249238 kB/s
Read: transfered 255354 kB/s
Write: transfered 247957 kB/s
Read: transfered 255627 kB/s
Write: transfered 245715 kB/s
Read: transfered 255074 kB/s
Write: transfered 245474 kB/s
Read: transfered 256934 kB/s
Write: transfered 244311 kB/s
Read: transfered 255716 kB/s
Write: transfered 245908 kB/s
Read: transfered 254292 kB/s
Write: transfered 250961 kB/s
Read: transfered 255390 kB/s
Write: transfered 246998 kB/s
Read: transfered 252284 kB/s

@mcuee
Copy link
Member

mcuee commented Jul 16, 2021

Using libusb-1.0.24 release and WinUSB driver, I got a bit worse result than the above but still very decent.


(py39venv) C:\work\cyusb\cyusb3014-breakout\software [master ≡ +3 ~1 -0 !]> python .\sourcesink_python3.py
ep:       ENDPOINT 0x1: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x1 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x400 (1024 bytes)
       bInterval        :    0x0
ep2:       ENDPOINT 0x81: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x400 (1024 bytes)
       bInterval        :    0x0
Starting CYUSB3014 python bulk sourcesink test
Write: transfered 230158 kB/s
Read: transfered 231950 kB/s
Write: transfered 228750 kB/s
Read: transfered 230030 kB/s
Write: transfered 231019 kB/s
Read: transfered 233387 kB/s
Write: transfered 227717 kB/s
Read: transfered 228741 kB/s
Write: transfered 229477 kB/s
Read: transfered 231397 kB/s
Write: transfered 231185 kB/s
Read: transfered 232336 kB/s
Write: transfered 229526 kB/s
Read: transfered 231062 kB/s
Write: transfered 229421 kB/s
Read: transfered 230701 kB/s
Write: transfered 228526 kB/s
Read: transfered 230126 kB/s
Write: transfered 230364 kB/s
Read: transfered 232156 kB/s

@mcuee
Copy link
Member

mcuee commented Jul 16, 2021

Native libusbk Windows API is very fast (similar to Cypress Cyusb API under Windows), it can nearly reach 5Gbps (max speed for Cypress FX3).


C:\work\libusb\libusbk\libusbK\bin\kBench\x64\Release [master ≡ +19 ~0 -0 !]> .\kBench.exe list notestselect loop buffercount=4 buffersize=32768 mode=async
device-count=1
1. FX3 (USB\VID_04B4&PID_00F1\5&E9F3E45&0&17) [WinUSB]
Select device (1-1) :1

opened FX3 (USB\VID_04B4&PID_00F1\5&E9F3E45&0&17)..
Loop Test Information
        Driver          : WinUSB
        Vid / Pid       : 04B4h / 00F1h
        DevicePath      : \\?\usb#vid_04b4&pid_00f1#5&e9f3e45&0&17#{2bd89cab-e993-bf2c-5d31-9fc66ae52d58}
        Device Speed    : High
        Interface #     : 00h
        Alt Interface # : 00h
        Num Endpoints   : 2
        Priority        : 0
        Read Size       : 32768
        Write Size      : 32768
        Buffer Count    : 4
        Display Refresh : 1000 (ms)
        Transfer Timeout: 5000 (ms)
        Retry Count     : 0
        Verify Data     : Off

Bulk Read (Ep81h) Maximum Packet Size:1024
Bulk Write (Ep01h) Maximum Packet Size:1024

While the test is running:
Press 'Q' to quit
Press 'T' for test details
Press 'I' for status information
Press 'R' to reset averages

Press 'Q' to exit, any other key to begin..
Avg. Bytes/s: 617426600.99 Transfers: 19125 Bytes/s: 617426600.99
Avg. Bytes/s: 621827684.37 Transfers: 38238 Bytes/s: 626294784.00
Avg. Bytes/s: 620473053.12 Transfers: 57393 Bytes/s: 617786456.69
Avg. Bytes/s: 620673043.74 Transfers: 76656 Bytes/s: 621269669.29
Avg. Bytes/s: 620468747.53 Transfers: 95850 Bytes/s: 619654179.31
Avg. Bytes/s: 621473066.31 Transfers: 114971 Bytes/s: 626556928.00
Avg. Bytes/s: 621557269.90 Transfers: 133955 Bytes/s: 622067712.00
Avg. Bytes/s: 620880178.26 Transfers: 153060 Bytes/s: 616173858.27
Avg. Bytes/s: 621144548.14 Transfers: 172081 Bytes/s: 623280128.00
Avg. Bytes/s: 620838832.46 Transfers: 191227 Bytes/s: 618104559.61
Avg. Bytes/s: 621008690.89 Transfers: 210231 Bytes/s: 622723072.00
Avg. Bytes/s: 620903402.10 Transfers: 229447 Bytes/s: 619753826.77
Avg. Bytes/s: 621347170.95 Transfers: 248573 Bytes/s: 626720768.00
Avg. Bytes/s: 620998257.27 Transfers: 267688 Bytes/s: 616496377.95
Avg. Bytes/s: 621398269.88 Transfers: 286824 Bytes/s: 627048448.00
Avg. Bytes/s: 621406342.50 Transfers: 306076 Bytes/s: 621526636.45
waiting for Ep81h thread..
stopped Ep81h thread.   ExitCode=0
stopped Ep01h thread.   ExitCode=0
Loop Test Information
        Driver          : WinUSB
        Vid / Pid       : 04B4h / 00F1h
        DevicePath      : \\?\usb#vid_04b4&pid_00f1#5&e9f3e45&0&17#{2bd89cab-e993-bf2c-5d31-9fc66ae52d58}
        Device Speed    : High
        Interface #     : 00h
        Alt Interface # : 00h
        Num Endpoints   : 2
        Priority        : 0
        Read Size       : 32768
        Write Size      : 32768
        Buffer Count    : 4
        Display Refresh : 1000 (ms)
        Transfer Timeout: 5000 (ms)
        Retry Count     : 0
        Verify Data     : Off

Bulk Read (Ep81h) Maximum Packet Size:1024
        Total Bytes     : 5038833664
        Total Transfers : 153773
        Avg. Bytes/sec  : 312195394.30
        Elapsed Time    : 16.14 seconds

Bulk Write (Ep01h) Maximum Packet Size:1024
        Total Bytes     : 4990697472
        Total Transfers : 152304
        Avg. Bytes/sec  : 309212978.44
        Elapsed Time    : 16.14 seconds

Press any key to exit..

@mcuee
Copy link
Member

mcuee commented Aug 24, 2021

It looks like https://github.com/eblot/pyftdi/blob/master/pyftdi/tests/mockusb.py is what @eblot was referring to.

Maybe this is the way to go as it is more generic and not depending on hardware.

Hardware specific things can be added as examples if needed.

@mcuee
Copy link
Member

mcuee commented Sep 13, 2021

For those who wat to look at using python for creating Linux USB gadgets using functionfs, you can look at this: vpelletier/python-functionfs#20

Other ways:

  1. Using shell scripts with configfs: https://wiki.tizen.org/USB/Linux_USB_Layers/Configfs_Composite_Gadget
  2. using gt with configfs: https://github.com/linux-usb-gadgets/gt

@mcuee
Copy link
Member

mcuee commented Sep 16, 2021

With dummy_hcd, I think python-functionfs can be a powerful tool to create test device on Linux machine (even without the dedicated usb device controller) as dummy_hcd is emulated and you can use your normal Linux PC.

Ref: https://www.collabora.com/news-and-blog/blog/2019/06/24/using-dummy-hcd/

@mcuee mcuee changed the title Tests pyusb test suite Jan 30, 2022
@mcuee
Copy link
Member

mcuee commented May 8, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants