High-speed USB3 camera low frame rate

Hi,

I have a 800fps USB3 camera. It sends out individual frames with usb bulk transfers. It has been confirmed the maximum fps rate of 814 fps can be archived on the desktop Linux system. However, when I move to FreeBSD aarch64, the frame rate goes down to about 70fps. No sign of operational error is present - the camera just becomes slow. I'm wondering what OS-driven clock rates could possibly be insufficiently high for providing enough USB3 throughput? For example, I tried to look at and all uses of xfer_set_interval() and USB_MS_TO_TICKS(). What else would you recommend?

Thanks!
 
It's RK3328 based Neo3. It has a fully functional USB3 A port with DWC function connected directly to the SoC, without any hubs.
 
Meanwhile, I've successfully got the expected full 815fps in FreeBSD on x86_64.

Maybe I need some quirks?
 
Might I suggest we callup our resident USB Expert hselasky@

He may be able to offer some insight.

For my curiosity what are the details on the camera if you don't mind. Off the shelf or custom? Frame size?
 
Code:
> sudo usbconfig -d 0.4 dump_all_desc
ugen0.4: <Machine Vision MV-A5031MU815> at usbus0, cfg=0 md=HOST spd=SUPER (5.0Gbps) pwr=ON (224mA)

  bLength = 0x0012
  bDescriptorType = 0x0001
  bcdUSB = 0x0300
  bDeviceClass = 0x00ef  <Miscellaneous device>
  bDeviceSubClass = 0x0002
  bDeviceProtocol = 0x0001
  bMaxPacketSize0 = 0x0009
  idVendor = 0x2e03
  idProduct = 0x0001
  bcdDevice = 0x1106
  iManufacturer = 0x0001  <Machine Vision>
  iProduct = 0x0002  <MV-A5031MU815>
  iSerialNumber = 0x0003  <BF03407AAK00011>
  bNumConfigurations = 0x0001

 Configuration index 0

    bLength = 0x0009
    bDescriptorType = 0x0002
    wTotalLength = 0x0074
    bNumInterfaces = 0x0003
    bConfigurationValue = 0x0001
    iConfiguration = 0x0000  <no string>
    bmAttributes = 0x00c0
    bMaxPower = 0x0070

    Additional Descriptor

    bLength = 0x08
    bDescriptorType = 0x0b
    bDescriptorSubType = 0x00
     RAW dump:
     0x00 | 0x08, 0x0b, 0x00, 0x03, 0xef, 0x05, 0x00, 0x04


    Interface 0
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0000
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0002
      bInterfaceClass = 0x00ef  <Miscellaneous device>
      bInterfaceSubClass = 0x0005
      bInterfaceProtocol = 0x0000
      iInterface = 0x0005  <Machine Vision>

      Additional Descriptor

      bLength = 0x14
      bDescriptorType = 0x24
      bDescriptorSubType = 0x01
       RAW dump:
       0x00 | 0x14, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
       0x08 | 0x00, 0x01, 0x00, 0x06, 0x01, 0x02, 0x07, 0x08,
       0x10 | 0x09, 0x0b, 0x0a, 0x0c


     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0001  <OUT>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0400
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000

      Additional Descriptor

      bLength = 0x06
      bDescriptorType = 0x30
      bDescriptorSubType = 0x00
       RAW dump:
       0x00 | 0x06, 0x30, 0x00, 0x00, 0x00, 0x00


     Endpoint 1
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0081  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0400
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000

      Additional Descriptor

      bLength = 0x06
      bDescriptorType = 0x30
      bDescriptorSubType = 0x00
       RAW dump:
       0x00 | 0x06, 0x30, 0x00, 0x00, 0x00, 0x00



    Interface 1
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0001
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0001
      bInterfaceClass = 0x00ef  <Miscellaneous device>
      bInterfaceSubClass = 0x0005
      bInterfaceProtocol = 0x0001
      iInterface = 0x000b  <BF03407AAK00011>

     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0082  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0400
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000

      Additional Descriptor

      bLength = 0x06
      bDescriptorType = 0x30
      bDescriptorSubType = 0x00
       RAW dump:
       0x00 | 0x06, 0x30, 0x00, 0x00, 0x00, 0x00



    Interface 2
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0002
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0001
      bInterfaceClass = 0x00ef  <Miscellaneous device>
      bInterfaceSubClass = 0x0005
      bInterfaceProtocol = 0x0002
      iInterface = 0x000c  <7X3>

     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0083  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0400
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000

      Additional Descriptor

      bLength = 0x06
      bDescriptorType = 0x30
      bDescriptorSubType = 0x0f
       RAW dump:
       0x00 | 0x06, 0x30, 0x0f, 0x00, 0x00, 0x00
 
It's an industrial cube camera, 640x480 GRAY8. The protocol is called GenICam. The camera config is kept somewhere in an XML file. Protocol uses raw libusb to perform data I/O, there is no readable capabilities or UVC in the USB descriptors.

Support is provided by software called Aravis, it works well on FreeBSD. I attach a debug-enabled log of a benchmarking test program.

On NanoPi Neo3 embedded board, the same test program either fails early, or can make only 70 Hz at best.

Code:
sudo ./genicam_test -d all
Looking for the first available camera
Found 1 USB3Vision device (among 4 USB devices)
[UvDevice::new] Vendor  = Machine Vision
[UvDevice::new] Product = MV-A5031MU815
[UvDevice::new] Using control endpoint 1, interface 0
[UvDevice::new] Using data endpoint 3, interface 2
Get genicam
MANUFACTURER_NAME =        'Machine Vision'
MAX_DEVICE_RESPONSE_TIME = 0x0000012c
DEVICE_CAPABILITY        = 0x0000000000000b0d
SRBM_ADDRESS =             0x0000000010010000
MANIFEST_TABLE_ADDRESS =   0x0000000010000000
U3VCP_CAPABILITY =         0x00000003
MAX_CMD_TRANSFER =         0x00000400
MAX_ACK_TRANSFER =         0x00000400
SIRM_OFFSET =              0x0000000010020000
SI_INFO =                  0x00000000
SI_CONTROL =               0x00000000
SI_REQ_PAYLOAD_SIZE =      0x000000000004b000
SI_REQ_LEADER_SIZE =       0x00000034
SI_REQ_TRAILER_SIZE =      0x00000020
SI_MAX_LEADER_SIZE =       0x00000034
SI_PAYLOAD_SIZE =          0x00344000
SI_PAYLOAD_COUNT =         0x00000000
SI_TRANSFER1_SIZE =        0x0004b000
SI_TRANSFER2_SIZE =        0x0004b000
SI_MAX_TRAILER_SIZE =      0x00000020
MANIFEST_N_ENTRIES =       0x0000000000000001
MANIFEST ENTRY
00000000 01 00 00 00 00 04 01 01 00 00 05 00 00 00 00 00  ................
00000010 63 6c 00 00 00 00 00 00 37 65 65 39 39 35 63 37  cl......7ee995c7
00000020 35 66 66 31 65 38 66 31 37 33 31 61 00 00 00 00  5ff1e8f1731a....
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

genicam address =          0x0000000000050000
genicam size    =          0x0000000000006c63
zip file =                 general_132832_20200927091905.xml
[GcFeature::set_attribute] Unknown attribute 'ToolTip'
[GcFeature::set_attribute] Unknown attribute 'StandardNameSpace'
[GcFeature::set_attribute] Unknown attribute 'ProductGuid'
[GcFeature::set_attribute] Unknown attribute 'VersionGuid'
[GcFeature::set_attribute] Unknown attribute 'xmlns'
[GcFeature::set_attribute] Unknown attribute 'xmlns:xsi'
[GcFeature::set_attribute] Unknown attribute 'xsi:schemaLocation'
[ArvDevice::get_integer_feature_value] Node 'BinningHorizontal' is not an integer
[ArvDevice::get_integer_feature_value] Node 'BinningVertical' is not an integer
[ArvDevice::get_integer_feature_value] Node 'GainRaw' is not an integer
vendor name           = Machine Vision
model name            = MV-A5031MU815
[ArvDevice::get_string_feature_value] Node 'DeviceID' is not a string
device id             = (null)
image width           = 640
image height          = 480
horizontal binning    = 0
vertical binning      = 0
payload               = 307200 bytes
exposure              = 1000 µs
gain                  = 0 dB
SI_INFO            =       0x00000000
SI_REQ_PAYLOAD_SIZE =      0x000000000004b000
SI_REQ_LEADER_SIZE =       0x00000034
SI_REQ_TRAILER_SIZE =      0x00000020
Required alignment =       1
SI_PAYLOAD_SIZE =          0x00100000
SI_PAYLOAD_COUNT =         0x00000000
SI_TRANSFER1_SIZE =        0x0004b000
SI_TRANSFER2_SIZE =        0x00000000
SI_MAX_LEADER_SIZE =       0x00000034
SI_MAX_TRAILER_SIZE =      0x00000020
Frame rate = 1185 Hz
Frame rate = 844 Hz
Frame rate = 787 Hz
Frame rate = 812 Hz
Frame rate = 825 Hz
Frame rate = 807 Hz
Frame rate = 816 Hz
Frame rate = 815 Hz
Frame rate = 816 Hz
Frame rate = 816 Hz
Frame rate = 816 Hz
Frame rate = 816 Hz
Frame rate = 815 Hz
Frame rate = 816 Hz
Frame rate = 816 Hz
Frame rate = 816 Hz
Frame rate = 816 Hz

(Here I press Ctrl^C)

Completed buffers = 14234
Failures          = 0
Underruns         = 0
USB transfer error: LIBUSB_ERROR_TIMEOUT
[UvStream::finalize] n_completed_buffers    = 14237
[UvStream::finalize] n_failures             = 0
[UvStream::finalize] n_underruns            = 0
[Stream::finalize] Flush 50 buffer[s] in input queue
[Stream::finalize] Flush 0 buffer[s] in output queue
 
Thanks for the details. 640x480 greyscale camera for machine vision.
That was what I was wondering.
Many of the high speed cameras use displaylink. I wasn't aware USB3 had that reach..

The best place for the question is maybe FreeBSD mailing list for arm since amd64 works to spec.

For rapid response see bsd.mips on IRC efnet
 
Technically, this is CYUSB3014 serving as a USB3 peripheral on the other end. Given that camera is also independently ran by this chip, there could be some issue in negotiation between the USB driver on host and the firmware used by this SoC.
 
You may want to install usbutils from ports, and run lsusb -vvv, which should dump the USB video class descriptors, and what frame rates are supported. Seems like you've got something working.

There is also a v4l-utils package, and some tools to do stuff with webcams, set parameters, and so on.
 
Back
Top