stm32-usbd
stm32-usbd copied to clipboard
Allow single-threaded use without critical sections?
I have a hard-real-time firmware application that is implemented with RTIC on an STM32F303. I am using the USB interface to provide secondary (non-real-time) diagnostic capabilities. I poll the UsbDevice in my idle task (i.e. the main loop), which results in entirely adequate performance. I do not use USB interrupts and I never access the UsbDevice from an interrupt context. It looks something like this:
#[idle]
fn idle(_: idle::Context) -> ! {
let mut usb_dev = UsbDeviceBuilder::new(...);
loop {
usb_dev.poll(...);
// read & write from the endpoints
}
}
#[task(binds = EXTI1)]
fn hard_real_time(_: hard_real_time::Context) {
very_fast_thing();
}
Unfortunately, my hard-real-time interrupt handlers (which are only a few microseconds long) experience hundreds of microseconds of timing jitter due to the interrupts-disabled critical sections (cortex_m::interrupt::free) which are found throughout stm32-usbd.
For my project, I patched in my own version of stm32-usbd which removes all of the critical sections:
https://github.com/dlaw/stm32-usbd-no-cs
I have confirmed that it works for me and solves my problem.
I am wondering if there is a safe way to make this functionality available from the stm32-usbd crate, as an official feature which could be selected via Cargo. I could contribute a patch if given some pointers about the best way to implement this. (e.g. is it a feature to remove critical sections, or a feature to add critical sections?)
Unfortunately, the UsbBus trait bound requires Sync, which means I had to provide a bogus impl Sync for Endpoint. I would much prefer to end up with a non-Sync UsbBus when critical sections are not used, as otherwise the safety guarantees of the Rust language are violated. But it seems this would require a change to https://github.com/rust-embedded-community/usb-device as well.
It seems that the change to remove Sync requirement from UsbBus trait got merged. Is there any chance of support for disabling critical sections in stm32-usbd?
EDIT: In fact, I would suggest to go even further and remove critical sections from stm32-usbd alltogether. I think it would be cleaner and more flexible to remove Sync from UsbBus and make it the user's responsibility to use a Mutex or whatnot if they need UsbBus to be Sync. AFAIK it is possible to safely access UsbBus from a single interrupt handler even if UsbBus is not Sync, as long as you don't access it anywhere else (correct me if I'm wrong).