work around Cortex-M7 BASEPRI erratum

This commit is contained in:
Jorge Aparicio 2017-12-23 20:33:40 +01:00
parent 8a396c51f2
commit ca395922e6
2 changed files with 21 additions and 2 deletions

View file

@ -181,6 +181,7 @@ fn idle(app: &App, ownerships: &Ownerships, main: &mut Vec<Tokens>, root: &mut V
&#_static, &#_static,
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
#device::CPU,
t, t,
f, f,
) )
@ -196,6 +197,7 @@ fn idle(app: &App, ownerships: &Ownerships, main: &mut Vec<Tokens>, root: &mut V
&mut #_static, &mut #_static,
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
#device::CPU,
t, t,
f, f,
) )
@ -499,6 +501,7 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
&#_static, &#_static,
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
#device::CPU,
t, t,
f, f,
) )
@ -514,6 +517,7 @@ fn tasks(app: &App, ownerships: &Ownerships, root: &mut Vec<Tokens>) {
&mut #_static, &mut #_static,
#ceiling, #ceiling,
#device::NVIC_PRIO_BITS, #device::NVIC_PRIO_BITS,
#device::CPU,
t, t,
f, f,
) )

View file

@ -74,6 +74,7 @@
//! [rtfm]: http://www.diva-portal.org/smash/get/diva2:1005680/FULLTEXT01.pdf //! [rtfm]: http://www.diva-portal.org/smash/get/diva2:1005680/FULLTEXT01.pdf
#![deny(missing_docs)] #![deny(missing_docs)]
#![deny(warnings)] #![deny(warnings)]
#![feature(asm)]
#![feature(proc_macro)] #![feature(proc_macro)]
#![no_std] #![no_std]
@ -119,6 +120,7 @@ pub unsafe fn claim<T, R, F>(
data: T, data: T,
ceiling: u8, ceiling: u8,
_nvic_prio_bits: u8, _nvic_prio_bits: u8,
_cpu: &str,
t: &mut Threshold, t: &mut Threshold,
f: F, f: F,
) -> R ) -> R
@ -132,6 +134,7 @@ where
#[cfg(not(armv6m))] #[cfg(not(armv6m))]
() => { () => {
let is_cm7 = _cpu == "CM7";
let max_priority = 1 << _nvic_prio_bits; let max_priority = 1 << _nvic_prio_bits;
if ceiling == max_priority { if ceiling == max_priority {
@ -139,9 +142,21 @@ where
} else { } else {
let old = basepri::read(); let old = basepri::read();
let hw = (max_priority - ceiling) << (8 - _nvic_prio_bits); let hw = (max_priority - ceiling) << (8 - _nvic_prio_bits);
basepri::write(hw); if is_cm7 {
asm!("cpsid i
msr BASEPRI, $0
cpsie i" :: "r"(hw) : "memory" : "volatile");
} else {
basepri::write(hw);
}
let ret = f(data, &mut Threshold::new(ceiling)); let ret = f(data, &mut Threshold::new(ceiling));
basepri::write(old); if is_cm7 {
asm!("cpsid i
msr BASEPRI, $0
cpsie i" :: "r"(old) : "memory" : "volatile");
} else {
basepri::write(old);
}
ret ret
} }
} }