-
Notifications
You must be signed in to change notification settings - Fork 83
Description
Currently every UsbBus
implementation that I am aware of is Sync
and it synchronizes access by wrapping most UsbBus
methods in a critical section. This can cause latency issues, because it means that during USB reads, writes and polling any higher priority interrupt handlers will be delayed. This has been a problem in practice (see stm32-rs/stm32-usbd#32, stm32-rs/synopsys-usb-otg#27).
In theory a UsbBus
could be implemented which is not Sync
, as the Sync
bound was removed in #149. Unfortunately, in practice such a UsbBus
ends up being extremely restrictive. This is because UsbDevice
and UsbClass
-es contain a reference to UsbBus
and if UsbBus
isn't Sync
then &UsbBus
isn't send and therefore UsbDevice
and UsbClass
-es using the bus aren't Send
. This means that there is no safe way to move them into interrupt handlers or elsewhere, even with mutexes and other synchronization. This rules out practically any architecture except for using UsbDevice
and UsbClass
-es in the main loop.
Given all this, there is a practical need for a way to implement UsbBus
without critical sections everywhere while still allowing you to move UsbDevice
and UsbClass
-es to other threads.
My main claim is this:
I believe it isn't possible for individual UsbBus
implementations to fix this problem on their own. There is a need to adjust the usb-device API to resolve this.
I don't have a specific proposal, but I have two high-level solution outlines:
-
Split
UsbBus
into components which can be owned exclusively byUsbDevice
andUsbClass
-es. E.g. theUsbDevice
would have exclusive ownership of the core USB registers (interrupts, statuses and whatnot) and eachUsbClass
would have exclusive ownership of its own endpoints. Since all endpoints are allocated ahead of time there should be minimal interaction between these components at runtime and thus minimal need for synchronization using critical sections. -
Make
UsbDevice
exclusively own theUsbClass
-es. This would allowUsbDevice
to exclusively own the entireUsbBus
, thus requiring no synchronization. (This is compatible with solution 2 from this semi-related issue: Figure out a better way to keep track of the list of classes #9.)
I would love to have some feedback on what people think of this. Can this be done? Should this be done? Is anyone using workarounds for this in practice and if so what are these workarounds?