Use of AFIT in Embaassy

The following are rough notes on the usage of Async Function in Traits from the Embassy runtime. They are derived from a conversation between dirbaio and nikomatsakis.

Links to uses of async functions in traits within Embassy:

most of these are "abstract over hardware", and when you build a firmware for some product/board you know which actual hardware you have, so you use static generics, no need for dyn

the few instances I've wished for dyn is:

  • with embedded-io it does sometimes happen. For example, running the same terminal ui over a physical serial port and over telnet at the same time. Without dyn that code gets monomorphized two times, which is somewhat wasteful.
  • this trait https://github.com/embassy-rs/embassy/blob/master/embassy-usb/src/lib.rs#L89 . That one MUST use dyn because you want to register multiple handlers that might be different types. Sometimes it'd have been handy to be able to do async things within these callbacks. Workaround is to fire off a notification to some other async task, it's not been that bad.
    • niko: how is this used?
    • handlers are added here, passed into UsbDevice here, and then called when handling some bus-related stuff, for example here.
    • the tldr of what it's used for is you might have a "composite" usb device, which can have multiple "classes" at the same time (say, an Ethernet adapter and a serial port). Each class gets its own "endpoints" for data, so each launches its own independent async tasks reading/writing to these endpoints.
    • But there's also a "control pipe" endpoint that carries "control" requests that can be for any class for example for ethernet there's control requests for "bring the ethernet interface up/down", so each class registers a handler with callbacks to handle their own control requests, there's a "control pipe" task that dispatches them.
    • Sometimes when handling them, you want to do async stuff. For example for "bring the ethernet interface up" you might want to do some async SPI transfer to the ethernet chip, but currently you can't.
    • niko: would all methods be async if you could?
    • not sure if all methods, but probably control_in/control_out yes. and about where to store the future for the dyn... not sure. That crate is no-alloc so Box is out it'd probably be inline in the stack, like with StackFuture. Would need configuring the max size, probably some compile-time setting, or a const-generic in UsbDevice.