diff options
author | 2018-10-27 11:14:53 +0000 | |
---|---|---|
committer | 2018-10-27 11:14:53 +0000 | |
commit | 4134f02d65982e18784e87b046a11dab287f74c3 (patch) | |
tree | c1865a7703f13ef9a4f2bd96c877fc7ab0a3f221 /src | |
parent | d394540ca3583d0fdc959538f1f9201a5e132c5a (diff) | |
parent | 92f269f74181d7079650c669b37b5671f0379a7e (diff) | |
download | cortex-m-4134f02d65982e18784e87b046a11dab287f74c3.tar.gz cortex-m-4134f02d65982e18784e87b046a11dab287f74c3.tar.zst cortex-m-4134f02d65982e18784e87b046a11dab287f74c3.zip |
Merge #120
120: deprecate NVIC.{clear,set}_pending in favor of NVIC::{un,}pend r=therealprof a=japaric
NVIC::{un,}pend are static methods that don't require an instance of NVIC to be
invoked.
Rationale: These operations perform writes to stateless registers so they can
*not* result in data races.
More tricky is the question of whether letting the user call these from any
execution context without any critical section or other means of synchronization
can result in memory unsafety when used in conjunction with methods like
NVIC.{get,set}_priority that do require an instance of NVIC. I can't foresee any
trouble given that these methods (e.g. pend and set_priority) operate on
different registers.
Co-authored-by: Jorge Aparicio <jorge@japaric.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/peripheral/nvic.rs | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/src/peripheral/nvic.rs b/src/peripheral/nvic.rs index 1005799..c59c2c8 100644 --- a/src/peripheral/nvic.rs +++ b/src/peripheral/nvic.rs @@ -69,13 +69,12 @@ pub struct RegisterBlock { impl NVIC { /// Clears `interrupt`'s pending state + #[deprecated(since = "0.5.8", note = "Use `NVIC::unpend`")] pub fn clear_pending<I>(&mut self, interrupt: I) where I: Nr, { - let nr = interrupt.nr(); - - unsafe { self.icpr[usize::from(nr / 32)].write(1 << (nr % 32)) } + Self::unpend(interrupt) } /// Disables `interrupt` @@ -161,13 +160,23 @@ impl NVIC { } /// Forces `interrupt` into pending state - pub fn set_pending<I>(&mut self, interrupt: I) + pub fn pend<I>(interrupt: I) where I: Nr, { let nr = interrupt.nr(); - unsafe { self.ispr[usize::from(nr / 32)].write(1 << (nr % 32)) } + // NOTE(unsafe) atomic stateless write; ICPR doesn't store any state + unsafe { (*Self::ptr()).ispr[usize::from(nr / 32)].write(1 << (nr % 32)) } + } + + /// Forces `interrupt` into pending state + #[deprecated(since = "0.5.8", note = "Use `NVIC::pend`")] + pub fn set_pending<I>(&mut self, interrupt: I) + where + I: Nr, + { + Self::pend(interrupt) } /// Sets the "priority" of `interrupt` to `prio` @@ -203,6 +212,17 @@ impl NVIC { } } + /// Clears `interrupt`'s pending state + pub fn unpend<I>(interrupt: I) + where + I: Nr, + { + let nr = interrupt.nr(); + + // NOTE(unsafe) atomic stateless write; ICPR doesn't store any state + unsafe { (*Self::ptr()).icpr[usize::from(nr / 32)].write(1 << (nr % 32)) } + } + #[cfg(armv6m)] fn ipr_index<I>(interrupt: &I) -> usize where |