You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First a little context. I wasted a lot of time diagnosing why I couldn't create a usbd_serial::SerialPort. The reason is because I was creating the SerialPortafter the UsbDevice. The device builder will freeze the UsbBusAllocator, disallowing any future uses. This causes SerialPort::new() to panic. I don't have a debugger setup for my target at the moment, so runtime panics are hard to debug!
What do I expect to happen? The following code should not compile:
letmut usb_dev = UsbDeviceBuilder::new(&usb_bus,UsbVidPid(0x16c0,0x27dd)).product("Serial port").device_class(USB_CLASS_CDC).build();// ERROR: `usb_bus` is frozen by the call to `build()`.letmut serial = SerialPort::new(&usb_bus);
An easy way to prevent this UX issue is for UsbDeviceBuilder::new() to take ownership of the UsbBusAllocator:
// Notice `usb_bus` is moved here.letmut usb_dev = UsbDeviceBuilder::new(usb_bus,UsbVidPid(0x16c0,0x27dd)).product("Serial port").device_class(USB_CLASS_CDC).build();// Compile error: attempt to access moved value `usb_bus`.letmut serial = SerialPort::new(&usb_bus);
Perhaps there are valid use cases for the device builder to borrow the bus allocator. "Flexibility" is often cited in similar situations, and it always leads to extra complexity such as interior mutability and the kind of invalid states and runtime panics shown here.
I'm also aware this is a breaking change and could potentially end up being a great deal of work. I believe that it will provide a less error-prone interface and may even afford you a way to clean up some of the library internals. For these reasons, I think it is worth considering.
The text was updated successfully, but these errors were encountered:
I am thinking this suggestion won't work because the allocator needs to outlive the SerialPort.
The suggestions in #9 are tangentially related. The borrowing means that these types cannot easily be moved to a struct because it would create self-references.
First a little context. I wasted a lot of time diagnosing why I couldn't create a
usbd_serial::SerialPort
. The reason is because I was creating theSerialPort
after theUsbDevice
. The device builder will freeze theUsbBusAllocator
, disallowing any future uses. This causesSerialPort::new()
to panic. I don't have a debugger setup for my target at the moment, so runtime panics are hard to debug!What do I expect to happen? The following code should not compile:
An easy way to prevent this UX issue is for
UsbDeviceBuilder::new()
to take ownership of theUsbBusAllocator
:Perhaps there are valid use cases for the device builder to borrow the bus allocator. "Flexibility" is often cited in similar situations, and it always leads to extra complexity such as interior mutability and the kind of invalid states and runtime panics shown here.
I'm also aware this is a breaking change and could potentially end up being a great deal of work. I believe that it will provide a less error-prone interface and may even afford you a way to clean up some of the library internals. For these reasons, I think it is worth considering.
The text was updated successfully, but these errors were encountered: