rust-embedded-community / usb-device

Experimental device-side USB framework for microcontrollers in Rust.
MIT License
414 stars 77 forks source link

Callback on new data arrived #81

Closed vklachkov closed 2 years ago

vklachkov commented 2 years ago

Hello! How to handle an interrupt if new data received from USB? I need an alternative of CDC_Receive_FS in C world

mvirkkunen commented 2 years ago

Asynchronous callbacks are very annoying to use in Rust due to lifetime rules (even more so without a heap), so next to nothing in the embedded Rust world uses them.

The efficient way is to set up an interrupt handler for the USB interrupt(s) in your device, and then do the poll and read calls there. In this case the interrupt will be your "callback". I recommend RTIC for convenient interrupt handling.

vklachkov commented 2 years ago

It sounds difficult for the task of instant response to incoming data via usb cdc... Thanks

mvirkkunen commented 2 years ago

It's a bit more work, but using interrupts does give you the fastest response times if that's what you want. And yes, it'd be nice if you didn't have to jump through so many hoops to use interrupts nicely in Rust, but that's the way things are currently. I'm very hopeful async/await will allow for much nicer ways to handle everything.

vklachkov commented 2 years ago

@mvirkkunen sorry for the stupid question, but how do I handle a USB interrupt in Rust? Where to look at the implementation or what to read

mvirkkunen commented 2 years ago

The closest example I have at hand is this, but it's for an old version of RTIC (RTFM) and also for a different chip. You'd have to change it a bit to work with the newest version of RTIC and on your chip.

https://github.com/stm32-rs/stm32-usbd-examples/blob/master/example-stm32f103c8/examples/serial_rtfm.rs

There's some basic information on interrupt handling in the Rust embedded book, it's really the same for any peripheral including USB:

https://docs.rust-embedded.org/book/start/interrupts.html

My favorite option currently is RTIC (allows you to avoid most of the unsafe code, and avoids resource conflicts etc). It takes some learning to get used to, but once you do, it's really nice:

https://rtic.rs/