stm32-usbd icon indicating copy to clipboard operation
stm32-usbd copied to clipboard

Allow single-threaded use without critical sections?

Open dlaw opened this issue 2 years ago • 1 comments

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.

dlaw avatar Sep 02 '23 12:09 dlaw

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).

FeldrinH avatar Jul 07 '25 00:07 FeldrinH