Conversation
0d40861 to
12368e7
Compare
There was a problem hiding this comment.
Pull request overview
This PR rewrites the NVIC peripheral implementation to use derive-mmio so MMIO access doesn’t rely on creating shared references (as with VolatileCell / volatile-register).
Changes:
- Introduces
derive-mmioand converts the NVICRegisterBlockto a#[derive(derive_mmio::Mmio)]MMIO model. - Refactors
crate::peripheral::NVICinto an owning wrapper aroundnvic::MmioRegisterBlock<'static>and updates NVIC methods accordingly. - Updates peripheral address layout tests to use
derive-mmiopointer helpers instead of taking&*NVIC::PTR.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| cortex-m/src/peripheral/nvic.rs | Replaces volatile-register register block with derive-mmio and rewrites NVIC operations to use generated MMIO accessors / raw volatile byte access for IPR on non-armv6m. |
| cortex-m/src/peripheral/mod.rs | Changes NVIC from a ZST marker with PTR to a wrapper holding MmioRegisterBlock<'static>, and updates Peripherals::steal() construction. |
| cortex-m/src/peripheral/test.rs | Updates NVIC address assertions to use derive-mmio pointer accessors and NVIC::steal(). |
| cortex-m/Cargo.toml | Adds derive-mmio = "0.6" dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| impl NVIC { | ||
| /// Pointer to the register block | ||
| pub const PTR: *const nvic::RegisterBlock = 0xE000_E100 as *const _; | ||
|
|
||
| /// Returns a pointer to the register block | ||
| #[inline(always)] | ||
| #[deprecated(since = "0.7.5", note = "Use the associated constant `PTR` instead")] | ||
| pub const fn ptr() -> *const nvic::RegisterBlock { | ||
| Self::PTR | ||
| /// Unsafely steal an instance of the NVIC. | ||
| /// | ||
| /// # Safety | ||
| /// | ||
| /// This potentially allows to create multiple instances of the NVIC register block, which | ||
| /// might only be valid in certain multi-core environments. | ||
| #[inline] | ||
| pub unsafe fn steal() -> Self { | ||
| NVIC(unsafe { nvic::RegisterBlock::new_mmio_fixed() }) | ||
| } |
There was a problem hiding this comment.
This change removes the long-standing NVIC::PTR / NVIC::ptr() raw-pointer API and changes NVIC from a ZST marker to an owning wrapper. That’s a breaking public API change (and is inconsistent with the other peripherals in this module that still expose PTR). Consider keeping PTR (as a raw pointer/usize base address) and the deprecated ptr() for compatibility, even if you steer users to steal()/derive-mmio accessors.
There was a problem hiding this comment.
It is a breaking change anyway. Not sure how useful it would be to keep the old PTR API for the new type.
| // SAFETY: | ||
| // - atomic stateless write; IPR doesn't store any state | ||
| // - InterruptNumber is an unsafe trait, we can assume correct implementation. | ||
| unsafe { core::ptr::write_volatile(ipr_ptr.offset(nr as isize), prio) } |
There was a problem hiding this comment.
NVIC::set_priority (non-armv6m path) uses ptr.offset(...) on an MMIO pointer. As with get_priority, this can be UB under strict provenance because offset requires staying within a single allocated object. Prefer wrapping_add/wrapping_offset (or address arithmetic from BASE_ADDRESS) before calling write_volatile.
| unsafe { core::ptr::write_volatile(ipr_ptr.offset(nr as isize), prio) } | |
| unsafe { core::ptr::write_volatile(ipr_ptr.wrapping_add(usize::from(nr)), prio) } |
There was a problem hiding this comment.
this should be fine I think? The pointer is related to the IPR allocation and we assume the interrupt number is valid.
12368e7 to
3539584
Compare
|
I tested this PR with #655 with https://github.com/ferrous-systems/rust-training/tree/main/example-code/qemu-thumbv7em. Async and interrupt using examples were running fine. I'll probably add some tests to verify priority setting/reading as well because pointer magic was used there.. |
3539584 to
2570853
Compare
b797433 to
624d62f
Compare
The primary advantage is that
derive-mmiodoes not create shared references to MMIO likeVolatileCell/volatile_registerdoes.