Skip to content

Commit 4134f02

Browse files
bors[bot]japaric
andcommitted
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 <[email protected]>
2 parents d394540 + 92f269f commit 4134f02

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/peripheral/nvic.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,12 @@ pub struct RegisterBlock {
6969

7070
impl NVIC {
7171
/// Clears `interrupt`'s pending state
72+
#[deprecated(since = "0.5.8", note = "Use `NVIC::unpend`")]
7273
pub fn clear_pending<I>(&mut self, interrupt: I)
7374
where
7475
I: Nr,
7576
{
76-
let nr = interrupt.nr();
77-
78-
unsafe { self.icpr[usize::from(nr / 32)].write(1 << (nr % 32)) }
77+
Self::unpend(interrupt)
7978
}
8079

8180
/// Disables `interrupt`
@@ -161,13 +160,23 @@ impl NVIC {
161160
}
162161

163162
/// Forces `interrupt` into pending state
164-
pub fn set_pending<I>(&mut self, interrupt: I)
163+
pub fn pend<I>(interrupt: I)
165164
where
166165
I: Nr,
167166
{
168167
let nr = interrupt.nr();
169168

170-
unsafe { self.ispr[usize::from(nr / 32)].write(1 << (nr % 32)) }
169+
// NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
170+
unsafe { (*Self::ptr()).ispr[usize::from(nr / 32)].write(1 << (nr % 32)) }
171+
}
172+
173+
/// Forces `interrupt` into pending state
174+
#[deprecated(since = "0.5.8", note = "Use `NVIC::pend`")]
175+
pub fn set_pending<I>(&mut self, interrupt: I)
176+
where
177+
I: Nr,
178+
{
179+
Self::pend(interrupt)
171180
}
172181

173182
/// Sets the "priority" of `interrupt` to `prio`
@@ -203,6 +212,17 @@ impl NVIC {
203212
}
204213
}
205214

215+
/// Clears `interrupt`'s pending state
216+
pub fn unpend<I>(interrupt: I)
217+
where
218+
I: Nr,
219+
{
220+
let nr = interrupt.nr();
221+
222+
// NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
223+
unsafe { (*Self::ptr()).icpr[usize::from(nr / 32)].write(1 << (nr % 32)) }
224+
}
225+
206226
#[cfg(armv6m)]
207227
fn ipr_index<I>(interrupt: &I) -> usize
208228
where

0 commit comments

Comments
 (0)