Appearance
Using USB Serial Tools
A Rockface USB serial tool allows communication with a USB target device that provides a serial interface (e.g. USB CDC-ACM).
In the rockface
python library, USB serial tools are represented using the rockface.tools.usb_serial.USBSerial
type:
py
from rockface import Rig
from rockface.tools.usb_serial import USBSerial
rig = Rig.find_by_name("my-rig")
serial = rig.tools["usb"]
assert isinstance(serial, USBSerial)
Examples continue from the above
For brevity, the rest of the examples on this page will continue on from the above example, with the serial
variable set to a USBSerial
instance.
Availability
A USB device must enumerate with its host before it can be used. The USB serial tool communicates whether a device is currently available through its is_available
property:
py
import time
print("Waiting for USB serial device to become available")
while not serial.is_available:
time.sleep(1)
Reading
While the target device is available, the USB serial tool will continuously read data from the target device into a "read buffer" within the tool. Data can be retrieved and removed from this buffer using the read
method, which takes the maximum number of bytes to retrieve as an argument:
py
data = serial.read(1000)
print(f"len(data) bytes received")
If the buffer reaches maximum capacity (usually 1 MiB), then the oldest data in the buffer will be discarded.
read
does not block
When read
is called, it will provide up to the number of requested bytes from the read buffer. It will not wait until the requested number of bytes have been received from the target device.
For example, if the read buffer contained 3 bytes and read
requests 10 bytes, only 3 bytes will be returned. If there is no data available, then an empty bytestring will be returned.
Writing
Data can be written to the USB serial target using the write
method:
py
serial.write(b"Hello World!")
write
will append the provided data to the tool's "write buffer", and then return almost instantly. The tool will continuously take data from this buffer and write it to the target device until there is no more data in the buffer.
Write Buffer Capacity Limit
write
will put as much of the provided data in the buffer as possible. If the buffer reaches maximum capacity (usually 1 MiB), then not all of the provided data will be appended to the buffer. The number of bytes that were successfully added to the buffer is returned:
py
written = serial.write(b"Hello World!")
print(f"{written} bytes were written")
Buffer Clearing
The read and write buffers are both emptied when the tool is reset. The buffers will also be cleared when the device availability changes as follows:
- The read buffer is emptied when the device becomes available.
- The write buffer is emptied when the device becomes unavailable.
Interacting with transiently available target devices
Sometimes the target device may not be available for very long. It might power up, send some data over USB, and then power down. The read buffer is not cleared when the device becomes unavailable, so any data it sent while it was available can still be read from the tool.
Data can be enqueued in the write buffer before the target device becomes available. The tool will start writing data to the target device as soon as it becomes available.
Reading USB Descriptors
The standard USB device string descriptors provided by the target device can be accessed using the descriptors
property of the tool:
py
print("Manufacturer:", serial.descriptors["manufacturer"])
print("Serial number:", serial.descriptors["serial_number"])
print("Product:", serial.descriptors["product"])