wip tests do not pass

This commit is contained in:
Per Lindgren 2021-11-03 16:10:10 +01:00
parent cbde2c7ef9
commit 20602bd77c
8 changed files with 90 additions and 6 deletions

View file

@ -29,10 +29,10 @@ mod app {
cx.shared.lock(|x| *x.shared += 1); cx.shared.lock(|x| *x.shared += 1);
} }
#[task(binds = GPIOB, priority = 2, shared = [shared])] // #[task(binds = GPIOB, priority = 2, shared = [shared])]
fn high(mut cx: high::Context) { // fn high(mut cx: high::Context) {
cx.shared.lock(|x| *x.shared += 1); // cx.shared.lock(|x| *x.shared += 1);
} // }
} }
// cargo objdump --example lockall_cost --target thumbv7m-none-eabi --release --features inline-asm -- --disassemble > lockall_cost.ojbdump // cargo objdump --example lockall_cost --target thumbv7m-none-eabi --release --features inline-asm -- --disassemble > lockall_cost.ojbdump

View file

@ -99,6 +99,7 @@ pub fn codegen(
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn #name(#context: #name::Context) { fn #name(#context: #name::Context) {
use rtic::Mutex as _; use rtic::Mutex as _;
use rtic::MutexStruct as _;
use rtic::mutex_prelude::*; use rtic::mutex_prelude::*;
#(#stmts)* #(#stmts)*

View file

@ -73,6 +73,7 @@ pub fn codegen(
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn #name(#context: #name::Context) -> ! { fn #name(#context: #name::Context) -> ! {
use rtic::Mutex as _; use rtic::Mutex as _;
use rtic::MutexStruct as _;
use rtic::mutex_prelude::*; use rtic::mutex_prelude::*;
#(#stmts)* #(#stmts)*

View file

@ -168,14 +168,14 @@ pub fn codegen(
let (lock_all, get_prio) = if let Some(name) = field_get_prio { let (lock_all, get_prio) = if let Some(name) = field_get_prio {
( (
util::impl_mutex( util::impl_mutex_struct(
extra, extra,
&vec![], // TODO: what cfg should go here? &vec![], // TODO: what cfg should go here?
quote!(#ident), quote!(#ident),
quote!(#ident_mut<#lt>), quote!(#ident_mut<#lt>),
max_ceiling, max_ceiling,
quote!(self.priority()), quote!(self.priority()),
quote!(|| { &mut #ident_mut::new() }), quote!(|| { #ident_mut::new() }),
), ),
quote!( quote!(
// Used by the lock-all API // Used by the lock-all API

View file

@ -132,6 +132,7 @@ pub fn codegen(
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn #name(#context: #name::Context #(,#inputs)*) { fn #name(#context: #name::Context #(,#inputs)*) {
use rtic::Mutex as _; use rtic::Mutex as _;
use rtic::MutexStruct as _;
use rtic::mutex_prelude::*; use rtic::mutex_prelude::*;
#(#stmts)* #(#stmts)*

View file

@ -54,6 +54,41 @@ pub fn impl_mutex(
) )
} }
/// Generates a `MutexStruct` implementation
pub fn impl_mutex_struct(
extra: &Extra,
cfgs: &[Attribute],
path: TokenStream2,
ty: TokenStream2,
ceiling: u8,
priority: TokenStream2,
ptr: TokenStream2,
) -> TokenStream2 {
let device = &extra.device;
quote!(
#(#cfgs)*
impl<'a> rtic::MutexStruct for #path<'a> {
type T = #ty;
#[inline(always)]
fn lock<RTIC_INTERNAL_R>(&mut self, f: impl FnOnce(#ty) -> RTIC_INTERNAL_R) -> RTIC_INTERNAL_R {
/// Priority ceiling
const CEILING: u8 = #ceiling;
unsafe {
rtic::export::lock_struct(
#ptr,
#priority,
CEILING,
#device::NVIC_PRIO_BITS,
f,
)
}
}
}
)
}
/// Generates an identifier for the `INPUTS` buffer (`spawn` & `schedule` API) /// Generates an identifier for the `INPUTS` buffer (`spawn` & `schedule` API)
pub fn inputs_ident(task: &Ident) -> Ident { pub fn inputs_ident(task: &Ident) -> Ident {
mark_internal_name(&format!("{}_INPUTS", task)) mark_internal_name(&format!("{}_INPUTS", task))

View file

@ -161,6 +161,43 @@ pub unsafe fn lock<T, R>(
} }
} }
/// Lock the resource proxy by setting the BASEPRI
/// and running the closure with interrupt::free
///
/// # Safety
///
/// Writing to the BASEPRI
/// Dereferencing a raw pointer
#[cfg(armv7m)]
#[inline(always)]
pub unsafe fn lock_struct<T, R>(
ptr: impl Fn() -> T,
priority: &Priority,
ceiling: u8,
nvic_prio_bits: u8,
f: impl FnOnce(T) -> R,
) -> R {
let current = priority.get();
if current < ceiling {
if ceiling == (1 << nvic_prio_bits) {
priority.set(u8::max_value());
let r = interrupt::free(|_| f(ptr()));
priority.set(current);
r
} else {
priority.set(ceiling);
basepri::write(logical2hw(ceiling, nvic_prio_bits));
let r = f(ptr()); // inside of lock
basepri::write(logical2hw(current, nvic_prio_bits));
priority.set(current);
r
}
} else {
f(ptr())
}
}
/// Lock the resource proxy by setting the PRIMASK /// Lock the resource proxy by setting the PRIMASK
/// and running the closure with interrupt::free /// and running the closure with interrupt::free
/// ///

View file

@ -104,3 +104,12 @@ impl<T> RacyCell<T> {
} }
unsafe impl<T> Sync for RacyCell<T> {} unsafe impl<T> Sync for RacyCell<T> {}
/// Should be moved to `rtic-core`
pub trait MutexStruct {
/// Data protected by the mutex
type T;
/// Creates a critical section and grants temporary access to the protected data
fn lock<R>(&mut self, f: impl FnOnce(Self::T) -> R) -> R;
}