Skip to content

solution to fix usbtmc frame partitioning issues on Linux. #468

@jyfrau

Description

@jyfrau

Hello,

I am sharing with you a solution to fix the usbtmc frame partitioning issues that are not handled properly under Linux.

I am using pyvisa and pyvisa-py to communicate with Siglent devices (SSA3032X and SVA1032X). On Linux it does not work. I get the message "Unexpected MsgID format. Consider updating the device's firmware. See #20".

The problem comes from the fact that usbtmc frames are split into 64-byte packets. A problem that does not appear under Windows, nor on a Linux virtual machine on a Windows host (which therefore goes through the Windows driver...).

Although this partitioning management problem does not come from pyvisa-py, I found a solution to add a processing of these packets in the file "…/site-packages/pyvisa/usbtmc.c", in the read() function of the USBTMC class :
when receiving the usbtmc frame (resp = raw_read(…)), I read the data length field directly in the usbtmc header and I receive the missing packets (resp += raw_read(…)) as long as the usbtmc frame is not the expected length.

It takes just 3 lines of code (between "### DEB PATCH" and "### END PATCH"):

try:
resp = raw_read(recv_chunk + header_size + max_padding)

### DEB PATCH                                                             # processing if partitioned frame :
usbtmc_size = header_size + int.from_bytes(resp[4:8], byteorder='little') # calculating the number of bytes expected
while len(resp) < usbtmc_size:                                            # as long as the frame is incomplete...
    resp += raw_read(recv_chunk + header_size + max_padding)              # ...we get a packet
### END PATCH

response = BulkInMessage.from_bytes(resp)

except (usb.core.USBError, ValueError):
# Abort failed Bulk-IN operation.
self._abort_bulk_in(self._btag)
raise

received.extend(response.data)

This partitioned frame handling in usbtmc.c works very well. I tested it with the Siglent SSA3032X and SVA1032X, as well as with a Keysight EDUX1002A (which does not partition its frames). I did this under Linux and under Windows, it works fine.

These 3 additional lines of code remain transparent if they are not needed but provide a great service in the event of partitioning poorly managed by the lower layers.

Although it is not the role of pyvisa-py to do this processing, do you think it is possible to integrate it into a future update of the pyvisa-py module?

Best regard

The modified read method of the USBTMC class:
USBTMC read

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions