-
Notifications
You must be signed in to change notification settings - Fork 29
Description
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.