mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-30 15:34:33 +01:00
pub interface to logical2hw and hw2logical
This commit is contained in:
parent
a94de6bafc
commit
dad3a1f520
1 changed files with 57 additions and 93 deletions
150
src/lib.rs
150
src/lib.rs
|
@ -47,8 +47,7 @@ pub struct Resource<T, CEILING> {
|
||||||
impl<T, C> Resource<T, C> {
|
impl<T, C> Resource<T, C> {
|
||||||
/// Creates a new resource with ceiling `C`
|
/// Creates a new resource with ceiling `C`
|
||||||
pub const fn new(data: T) -> Self
|
pub const fn new(data: T) -> Self
|
||||||
where
|
where C: Ceiling
|
||||||
C: Ceiling,
|
|
||||||
{
|
{
|
||||||
Resource {
|
Resource {
|
||||||
_ceiling: PhantomData,
|
_ceiling: PhantomData,
|
||||||
|
@ -62,14 +61,12 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
|
||||||
/// section
|
/// section
|
||||||
///
|
///
|
||||||
/// This operation is zero cost and doesn't impose any additional blocking
|
/// This operation is zero cost and doesn't impose any additional blocking
|
||||||
pub fn borrow<'cs, PRIORITY, SCEILING>(
|
pub fn borrow<'cs, PRIORITY, SCEILING>(&'static self,
|
||||||
&'static self,
|
_priority: &P<PRIORITY>,
|
||||||
_priority: &P<PRIORITY>,
|
_system_ceiling: &'cs C<SCEILING>)
|
||||||
_system_ceiling: &'cs C<SCEILING>,
|
-> Ref<'cs, T>
|
||||||
) -> Ref<'cs, T>
|
where SCEILING: GreaterThanOrEqual<CEILING>,
|
||||||
where
|
CEILING: GreaterThanOrEqual<PRIORITY>
|
||||||
SCEILING: GreaterThanOrEqual<CEILING>,
|
|
||||||
CEILING: GreaterThanOrEqual<PRIORITY>,
|
|
||||||
{
|
{
|
||||||
unsafe { Ref::new(&*self.data.get()) }
|
unsafe { Ref::new(&*self.data.get()) }
|
||||||
}
|
}
|
||||||
|
@ -77,24 +74,18 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
|
||||||
/// Claims the resource at the task with highest priority
|
/// Claims the resource at the task with highest priority
|
||||||
///
|
///
|
||||||
/// This operation is zero cost and doesn't impose any additional blocking
|
/// This operation is zero cost and doesn't impose any additional blocking
|
||||||
pub fn claim<'task, PRIORITY>(
|
pub fn claim<'task, PRIORITY>(&'static self, _priority: &'task P<PRIORITY>) -> Ref<'task, T>
|
||||||
&'static self,
|
where CEILING: Cmp<PRIORITY, Output = Equal>
|
||||||
_priority: &'task P<PRIORITY>,
|
|
||||||
) -> Ref<'task, T>
|
|
||||||
where
|
|
||||||
CEILING: Cmp<PRIORITY, Output = Equal>,
|
|
||||||
{
|
{
|
||||||
unsafe { Ref::new(&*self.data.get()) }
|
unsafe { Ref::new(&*self.data.get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like [Resource.claim](struct.Resource.html#method.claim) but returns a
|
/// Like [Resource.claim](struct.Resource.html#method.claim) but returns a
|
||||||
/// `&mut-` reference
|
/// `&mut-` reference
|
||||||
pub fn claim_mut<'task, PRIORITY>(
|
pub fn claim_mut<'task, PRIORITY>(&'static self,
|
||||||
&'static self,
|
_priority: &'task mut P<PRIORITY>)
|
||||||
_priority: &'task mut P<PRIORITY>,
|
-> RefMut<'task, T>
|
||||||
) -> RefMut<'task, T>
|
where CEILING: Cmp<PRIORITY, Output = Equal>
|
||||||
where
|
|
||||||
CEILING: Cmp<PRIORITY, Output = Equal>,
|
|
||||||
{
|
{
|
||||||
unsafe { RefMut::new(&mut *self.data.get()) }
|
unsafe { RefMut::new(&mut *self.data.get()) }
|
||||||
}
|
}
|
||||||
|
@ -109,22 +100,15 @@ 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>(
|
pub fn lock<R, PRIORITY, F>(&'static self, _priority: &P<PRIORITY>, f: F) -> R
|
||||||
&'static self,
|
where F: FnOnce(Ref<T>, C<CEILING>) -> R,
|
||||||
_priority: &P<PRIORITY>,
|
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level
|
||||||
f: F,
|
|
||||||
) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(Ref<T>, C<CEILING>) -> R,
|
|
||||||
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less>
|
|
||||||
+ Level,
|
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let old_basepri = basepri::read();
|
let old_basepri = basepri::read();
|
||||||
basepri_max::write(<CEILING>::hw());
|
basepri_max::write(<CEILING>::hw());
|
||||||
barrier!();
|
barrier!();
|
||||||
let ret =
|
let ret = f(Ref::new(&*self.data.get()), C { _marker: PhantomData });
|
||||||
f(Ref::new(&*self.data.get()), C { _marker: PhantomData });
|
|
||||||
barrier!();
|
barrier!();
|
||||||
basepri::write(old_basepri);
|
basepri::write(old_basepri);
|
||||||
ret
|
ret
|
||||||
|
@ -138,15 +122,9 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
|
||||||
/// resource that has ceiling equal `CEILING`. This constraint is required
|
/// resource that has ceiling equal `CEILING`. This constraint is required
|
||||||
/// to preserve Rust aliasing rules.
|
/// to preserve Rust aliasing rules.
|
||||||
#[cfg(not(thumbv6m))]
|
#[cfg(not(thumbv6m))]
|
||||||
pub fn lock_mut<R, PRIORITY, F>(
|
pub fn lock_mut<R, PRIORITY, F>(&'static self, _priority: &mut P<PRIORITY>, f: F) -> R
|
||||||
&'static self,
|
where F: FnOnce(RefMut<T>) -> R,
|
||||||
_priority: &mut P<PRIORITY>,
|
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level
|
||||||
f: F,
|
|
||||||
) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(RefMut<T>) -> R,
|
|
||||||
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less>
|
|
||||||
+ Level,
|
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let old_basepri = basepri::read();
|
let old_basepri = basepri::read();
|
||||||
|
@ -160,32 +138,25 @@ impl<T, CEILING> Resource<T, C<CEILING>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T, C> Sync for Resource<T, C>
|
unsafe impl<T, C> Sync for Resource<T, C> where C: Ceiling {}
|
||||||
where
|
|
||||||
C: Ceiling,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A hardware peripheral as a resource
|
/// A hardware peripheral as a resource
|
||||||
pub struct Peripheral<P, CEILING>
|
pub struct Peripheral<P, CEILING>
|
||||||
where
|
where P: 'static
|
||||||
P: 'static,
|
|
||||||
{
|
{
|
||||||
peripheral: cortex_m::peripheral::Peripheral<P>,
|
peripheral: cortex_m::peripheral::Peripheral<P>,
|
||||||
_ceiling: PhantomData<CEILING>,
|
_ceiling: PhantomData<CEILING>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P, C> Peripheral<P, C>
|
impl<P, C> Peripheral<P, C>
|
||||||
where
|
where C: Ceiling
|
||||||
C: Ceiling,
|
|
||||||
{
|
{
|
||||||
/// Assigns a ceiling `C` to the `peripheral`
|
/// Assigns a ceiling `C` to the `peripheral`
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// You MUST not create two resources that point to the same peripheral
|
/// You MUST not create two resources that point to the same peripheral
|
||||||
pub const unsafe fn new(peripheral: cortex_m::peripheral::Peripheral<P>,)
|
pub const unsafe fn new(peripheral: cortex_m::peripheral::Peripheral<P>) -> Self {
|
||||||
-> Self {
|
|
||||||
Peripheral {
|
Peripheral {
|
||||||
_ceiling: PhantomData,
|
_ceiling: PhantomData,
|
||||||
peripheral: peripheral,
|
peripheral: peripheral,
|
||||||
|
@ -195,49 +166,37 @@ where
|
||||||
|
|
||||||
impl<Periph, CEILING> Peripheral<Periph, C<CEILING>> {
|
impl<Periph, CEILING> Peripheral<Periph, C<CEILING>> {
|
||||||
/// See [Resource.borrow](./struct.Resource.html#method.borrow)
|
/// See [Resource.borrow](./struct.Resource.html#method.borrow)
|
||||||
pub fn borrow<'cs, PRIORITY, SCEILING>(
|
pub fn borrow<'cs, PRIORITY, SCEILING>(&'static self,
|
||||||
&'static self,
|
_priority: &P<PRIORITY>,
|
||||||
_priority: &P<PRIORITY>,
|
_system_ceiling: &'cs C<SCEILING>)
|
||||||
_system_ceiling: &'cs C<SCEILING>,
|
-> Ref<'cs, Periph>
|
||||||
) -> Ref<'cs, Periph>
|
where SCEILING: GreaterThanOrEqual<CEILING>,
|
||||||
where
|
CEILING: GreaterThanOrEqual<PRIORITY>
|
||||||
SCEILING: GreaterThanOrEqual<CEILING>,
|
|
||||||
CEILING: GreaterThanOrEqual<PRIORITY>,
|
|
||||||
{
|
{
|
||||||
unsafe { Ref::new(&*self.peripheral.get()) }
|
unsafe { Ref::new(&*self.peripheral.get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [Resource.claim](./struct.Resource.html#method.claim)
|
/// See [Resource.claim](./struct.Resource.html#method.claim)
|
||||||
pub fn claim<'task, PRIORITY>(
|
pub fn claim<'task, PRIORITY>(&'static self,
|
||||||
&'static self,
|
_priority: &'task P<PRIORITY>)
|
||||||
_priority: &'task P<PRIORITY>,
|
-> Ref<'task, Periph>
|
||||||
) -> Ref<'task, Periph>
|
where CEILING: Cmp<PRIORITY, Output = Equal>
|
||||||
where
|
|
||||||
CEILING: Cmp<PRIORITY, Output = Equal>,
|
|
||||||
{
|
{
|
||||||
unsafe { Ref::new(&*self.peripheral.get()) }
|
unsafe { Ref::new(&*self.peripheral.get()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [Resource.lock](./struct.Resource.html#method.lock)
|
/// See [Resource.lock](./struct.Resource.html#method.lock)
|
||||||
#[cfg(not(thumbv6m))]
|
#[cfg(not(thumbv6m))]
|
||||||
pub fn lock<R, PRIORITY, F>(
|
pub fn lock<R, PRIORITY, F>(&'static self, _priority: &P<PRIORITY>, f: F) -> R
|
||||||
&'static self,
|
where F: FnOnce(Ref<Periph>, C<CEILING>) -> R,
|
||||||
_priority: &P<PRIORITY>,
|
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less> + Level
|
||||||
f: F,
|
|
||||||
) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(Ref<Periph>, C<CEILING>) -> R,
|
|
||||||
CEILING: Cmp<PRIORITY, Output = Greater> + Cmp<UMAX, Output = Less>
|
|
||||||
+ Level,
|
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let old_basepri = basepri::read();
|
let old_basepri = basepri::read();
|
||||||
basepri_max::write(<CEILING>::hw());
|
basepri_max::write(<CEILING>::hw());
|
||||||
barrier!();
|
barrier!();
|
||||||
let ret = f(
|
let ret = f(Ref::new(&*self.peripheral.get()),
|
||||||
Ref::new(&*self.peripheral.get()),
|
C { _marker: PhantomData });
|
||||||
C { _marker: PhantomData },
|
|
||||||
);
|
|
||||||
barrier!();
|
barrier!();
|
||||||
basepri::write(old_basepri);
|
basepri::write(old_basepri);
|
||||||
ret
|
ret
|
||||||
|
@ -245,18 +204,13 @@ impl<Periph, CEILING> Peripheral<Periph, C<CEILING>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T, C> Sync for Peripheral<T, C>
|
unsafe impl<T, C> Sync for Peripheral<T, C> where C: Ceiling {}
|
||||||
where
|
|
||||||
C: Ceiling,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A global critical section
|
/// A global critical section
|
||||||
///
|
///
|
||||||
/// No task can preempt this critical section
|
/// No task can preempt this critical section
|
||||||
pub fn critical<R, F>(f: F) -> R
|
pub fn critical<R, F>(f: F) -> R
|
||||||
where
|
where F: FnOnce(CMAX) -> R
|
||||||
F: FnOnce(CMAX) -> R,
|
|
||||||
{
|
{
|
||||||
let primask = ::cortex_m::register::primask::read();
|
let primask = ::cortex_m::register::primask::read();
|
||||||
::cortex_m::interrupt::disable();
|
::cortex_m::interrupt::disable();
|
||||||
|
@ -274,9 +228,8 @@ where
|
||||||
|
|
||||||
/// Requests the execution of a `task`
|
/// Requests the execution of a `task`
|
||||||
pub fn request<T, P>(_task: fn(T, P))
|
pub fn request<T, P>(_task: fn(T, P))
|
||||||
where
|
where T: Context + Nr,
|
||||||
T: Context + Nr,
|
P: Priority
|
||||||
P: Priority,
|
|
||||||
{
|
{
|
||||||
let nvic = unsafe { &*NVIC.get() };
|
let nvic = unsafe { &*NVIC.get() };
|
||||||
|
|
||||||
|
@ -310,8 +263,7 @@ pub struct P<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> P<T>
|
impl<T> P<T>
|
||||||
where
|
where T: Level
|
||||||
T: Level,
|
|
||||||
{
|
{
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn hw() -> u8 {
|
pub fn hw() -> u8 {
|
||||||
|
@ -342,10 +294,22 @@ pub unsafe trait Level {
|
||||||
/// DO NOT IMPLEMENT THIS TRAIT YOURSELF
|
/// DO NOT IMPLEMENT THIS TRAIT YOURSELF
|
||||||
pub unsafe trait Priority {}
|
pub unsafe trait Priority {}
|
||||||
|
|
||||||
fn logical2hw(logical: u8) -> u8 {
|
|
||||||
|
/// Convert a logical priority to a shifted hardware prio
|
||||||
|
/// as used by the NVIC and basepri registers
|
||||||
|
/// Notice, wrapping causes a panic due to u8
|
||||||
|
pub fn logical2hw(logical: u8) -> u8 {
|
||||||
((1 << PRIORITY_BITS) - logical) << (8 - PRIORITY_BITS)
|
((1 << PRIORITY_BITS) - logical) << (8 - PRIORITY_BITS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert a shifted hardware prio to a logical priority
|
||||||
|
/// as used by the NVIC and basepri registers
|
||||||
|
/// Notice, wrapping causes a panic due to u8
|
||||||
|
pub fn hw2logical(hw: u8) -> u8 {
|
||||||
|
(1 << PRIORITY_BITS) - (hw >> (8 - PRIORITY_BITS))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Priority 0, the lowest priority
|
/// Priority 0, the lowest priority
|
||||||
pub type P0 = P<::typenum::U0>;
|
pub type P0 = P<::typenum::U0>;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue