mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-27 14:04:56 +01:00
mock
This commit is contained in:
parent
70f573a6c4
commit
7072115573
1 changed files with 80 additions and 4 deletions
84
src/lib.rs
84
src/lib.rs
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
extern crate cortex_m;
|
extern crate cortex_m;
|
||||||
extern crate static_ref;
|
extern crate static_ref;
|
||||||
|
//#[macro_use]
|
||||||
extern crate typenum;
|
extern crate typenum;
|
||||||
|
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
|
@ -18,6 +19,7 @@ use cortex_m::interrupt::Nr;
|
||||||
#[cfg(not(thumbv6m))]
|
#[cfg(not(thumbv6m))]
|
||||||
use cortex_m::register::{basepri, basepri_max};
|
use cortex_m::register::{basepri, basepri_max};
|
||||||
use static_ref::{Ref, RefMut};
|
use static_ref::{Ref, RefMut};
|
||||||
|
|
||||||
use typenum::{Cmp, Equal, Unsigned};
|
use typenum::{Cmp, Equal, Unsigned};
|
||||||
#[cfg(not(thumbv6m))]
|
#[cfg(not(thumbv6m))]
|
||||||
use typenum::{Greater, Less};
|
use typenum::{Greater, Less};
|
||||||
|
@ -28,6 +30,7 @@ pub use cortex_m::asm::{bkpt, wfi};
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use cortex_m::peripheral::NVIC;
|
pub use cortex_m::peripheral::NVIC;
|
||||||
|
|
||||||
|
|
||||||
macro_rules! barrier {
|
macro_rules! barrier {
|
||||||
() => {
|
() => {
|
||||||
asm!(""
|
asm!(""
|
||||||
|
@ -57,6 +60,9 @@ impl<T, C> Resource<T, C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//unsafe impl Max<::typenum::U0> for ::typenum::U0 {}
|
||||||
|
use typenum::type_operators::*;
|
||||||
|
|
||||||
impl<T, CEILING> Resource<T, C<CEILING>> {
|
impl<T, CEILING> Resource<T, C<CEILING>> {
|
||||||
/// Borrows the resource for the duration of another resource's critical
|
/// Borrows the resource for the duration of another resource's critical
|
||||||
/// section
|
/// section
|
||||||
|
@ -109,9 +115,14 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
|
||||||
/// than `CEILING` can be borrowed at zero cost. See
|
/// than `CEILING` can be borrowed at zero cost. See
|
||||||
/// [Resource.borrow](struct.Resource.html#method.borrow).
|
/// [Resource.borrow](struct.Resource.html#method.borrow).
|
||||||
#[cfg(not(thumbv6m))]
|
#[cfg(not(thumbv6m))]
|
||||||
pub fn lock<R, PRIORITY, F>(&'static self, _priority: &P<PRIORITY>, f: F) -> R
|
pub fn lock<R, PRIORITY, F>(
|
||||||
where F: FnOnce(Ref<T>, C<CEILING>) -> R,
|
&'static self,
|
||||||
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level
|
_priority: &P<PRIORITY>,
|
||||||
|
f: F,
|
||||||
|
) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(Ref<T>, C<CEILING>) -> R,
|
||||||
|
CEILING: GreaterThanOrEqual<PRIORITY> + Level,
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let old_basepri = basepri::read();
|
let old_basepri = basepri::read();
|
||||||
|
@ -125,6 +136,43 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Locks the resource for the duration of the critical section `f`
|
||||||
|
///
|
||||||
|
/// For the duration of the critical section, tasks whose priority level is
|
||||||
|
/// smaller than or equal to the resource `CEILING` will be prevented from
|
||||||
|
/// preempting the current task.
|
||||||
|
///
|
||||||
|
/// Within this critical section, resources with ceiling equal to or smaller
|
||||||
|
/// than `CEILING` can be borrowed at zero cost. See
|
||||||
|
/// [Resource.borrow](struct.Resource.html#method.borrow).
|
||||||
|
#[cfg(not(thumbv6m))]
|
||||||
|
pub fn mock<R, PRIOTASK, CURRCEIL, F>(&'static self, _prio: &C<PRIOTASK>, _curr_ceil: &C<CURRCEIL>, f: F) -> R
|
||||||
|
where
|
||||||
|
F: FnOnce(Ref<T>, C<CEILING>) -> R,
|
||||||
|
PRIOTASK: Unsigned,
|
||||||
|
CURRCEIL: Unsigned,
|
||||||
|
CEILING: GreaterThanOrEqual<PRIOTASK> + Max<CURRCEIL> + Level + Unsigned,
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
let c1 = <CURRCEIL>::to_u8();
|
||||||
|
let c2 = <CEILING>::to_u8();
|
||||||
|
if c2 > c1 {
|
||||||
|
let old_basepri = basepri::read();
|
||||||
|
basepri_max::write(<CEILING>::hw());
|
||||||
|
barrier!();
|
||||||
|
let ret =
|
||||||
|
f(Ref::new(&*self.data.get()), C { _marker: PhantomData });
|
||||||
|
barrier!();
|
||||||
|
basepri::write(old_basepri);
|
||||||
|
ret
|
||||||
|
} else {
|
||||||
|
f(Ref::new(&*self.data.get()), C { _marker: PhantomData })
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Like [Resource.lock](struct.Resource.html#method.lock) but returns a
|
/// Like [Resource.lock](struct.Resource.html#method.lock) but returns a
|
||||||
/// `&mut-` reference
|
/// `&mut-` reference
|
||||||
///
|
///
|
||||||
|
@ -281,6 +329,35 @@ where
|
||||||
nvic.set_pending(task);
|
nvic.set_pending(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Requests the execution of a `task`
|
||||||
|
pub fn pend<T, C>(_task: fn(T, C))
|
||||||
|
where
|
||||||
|
T: Context + Nr,
|
||||||
|
C: ,
|
||||||
|
//C: Level,
|
||||||
|
{
|
||||||
|
let nvic = unsafe { &*NVIC.get() };
|
||||||
|
|
||||||
|
match () {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
() => {
|
||||||
|
// NOTE(safe) zero sized type
|
||||||
|
let task = unsafe { core::ptr::read(0x0 as *const T) };
|
||||||
|
// NOTE(safe) atomic read
|
||||||
|
assert!(!nvic.is_pending(task),
|
||||||
|
"Task is already in the pending state");
|
||||||
|
}
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
() => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(safe) zero sized type
|
||||||
|
let task = unsafe { core::ptr::read(0x0 as *const T) };
|
||||||
|
// NOTE(safe) atomic write
|
||||||
|
nvic.set_pending(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// A type-level ceiling
|
/// A type-level ceiling
|
||||||
pub struct C<T> {
|
pub struct C<T> {
|
||||||
_marker: PhantomData<T>,
|
_marker: PhantomData<T>,
|
||||||
|
@ -342,7 +419,6 @@ pub fn hw2logical(hw: u8) -> u8 {
|
||||||
|
|
||||||
/// Priority 0, the lowest priority
|
/// Priority 0, the lowest priority
|
||||||
pub type P0 = P<::typenum::U0>;
|
pub type P0 = P<::typenum::U0>;
|
||||||
|
|
||||||
/// Declares tasks
|
/// Declares tasks
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! tasks {
|
macro_rules! tasks {
|
||||||
|
|
Loading…
Reference in a new issue