Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow single-threaded use without critical sections? #32

Open
dlaw opened this issue Sep 2, 2023 · 0 comments
Open

Allow single-threaded use without critical sections? #32

dlaw opened this issue Sep 2, 2023 · 0 comments

Comments

@dlaw
Copy link

dlaw commented Sep 2, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant