Skip to content

Conversation

kyp44
Copy link
Contributor

@kyp44 kyp44 commented Oct 3, 2025

Summary

NOTE: Marking as draft because this depends on a merge of PR #935.

A number of Tier 1 BSP examples that use USB as a serial device emit compiler warnings related to the necessary use of static mut. Additionally, some are not used in a safe way.

This updates these examples to suppress the warnings and make things safe by accessing the USB device in the main program (i.e. not in the USB polling interrupt) only in crticial sections that disable applicable USB interrupts.

The usability issue with USB in embedded applications is a known issue, and the best solution for these examples was discussed in Matrix.

See the commit log for details about which BSP examples were changed, and not that each BSP crate was changed in a separate commit per the guideline.

Checklist

  • All new or modified code is well documented, especially public items
  • No new warnings or clippy suggestions have been introduced - CI will deny clippy warnings by default! You may #[allow] certain lints where reasonable, but ideally justify those with a short comment.

kyp44 and others added 10 commits September 30, 2025 07:57
…HAL to support refactoring the `feather_m0/adalogger` example.
* For the `adalogger` example, fixes a compiler error by upgrading the `embedded-sdmmc` dependency and migrating to the new API.
* Fixes a minor compiler error in the `adc` example when the `use_semihosting` feature is enabled.
* Fixes a minor compiler warning in the `async_adc` example.
* Fixes a minor compiler warning in the `adc` example.
* Fixes a minor compiler warning in the `async_adc` example.
* Renames `usb_echo` to `usb_echo_basic` and suppresses the `static mut` warnings.
* Adds the `usb_echo_rtic` example showing how using USB is easier with RTIC.
…atics to use `OnceCell` and suppressing the `static mut` warnings:

* `nvm_dsu`
* `pukcc_test`
* `smart_eeprom`
* `usb_echo`
…mut` warnings:

* `adalogger`
* `clock`
* `usb_echo`
@rnd-ash
Copy link
Contributor

rnd-ash commented Oct 3, 2025

I had a look at this, overall quite happy with things,

However, I think the usb_get and usb_free methods that are used are a little bit over complex for an example (Especially making the user have to manually create a critical section).

In some other projects I have done with USB, I have gotten around the static mut like so

Incomplete example:

pub static USB_BUS_ALLOC: StaticCell<UsbBusAllocator<UsbBus>> = StaticCell::new();

// Data to be accessed whenever an ISR occurs on USB
pub struct UsbIsrInfo<'a> {
    pub dev: UsbDevice<'a, UsbBus>,
    pub class: SomeClassLikeSerial<'a, UsbBus>,
}

pub static USB: Mutex<RefCell<Option<UsbIsrInfo<'static>>>> = Mutex::new(RefCell::new(None));

#[inline(always)]
pub fn with_cs_mutex<R, T, F: FnOnce(&CriticalSection, &mut T) -> R>(
    m: &Mutex<RefCell<Option<T>>>,
    f: F,
) -> Option<R> {
    free(|cs| m.borrow(cs).borrow_mut().as_mut().map(|x| f(cs, x)))
}

/// Example usage for ISR:

#[interrupt]
fn USB_OTHER() {
    poll_usb();
}

#[interrupt]
fn USB_TRCPT0() {
    poll_usb();
}

#[interrupt]
fn USB_TRCPT1() {
    poll_usb();
}

fn poll_usb() {
    free(|cs| {
        if let Some(inf) = USB.borrow(cs).borrow_mut().as_mut() {
            if inf.dev.poll(&mut [&mut inf.can_usb]) {
                inf.class.poll(cs);
            }
        }
    });
}

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

Successfully merging this pull request may close these issues.

2 participants