mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
wip tests do not pass
This commit is contained in:
parent
cbde2c7ef9
commit
20602bd77c
8 changed files with 90 additions and 6 deletions
|
@ -29,10 +29,10 @@ mod app {
|
|||
cx.shared.lock(|x| *x.shared += 1);
|
||||
}
|
||||
|
||||
#[task(binds = GPIOB, priority = 2, shared = [shared])]
|
||||
fn high(mut cx: high::Context) {
|
||||
cx.shared.lock(|x| *x.shared += 1);
|
||||
}
|
||||
// #[task(binds = GPIOB, priority = 2, shared = [shared])]
|
||||
// fn high(mut cx: high::Context) {
|
||||
// cx.shared.lock(|x| *x.shared += 1);
|
||||
// }
|
||||
}
|
||||
|
||||
// cargo objdump --example lockall_cost --target thumbv7m-none-eabi --release --features inline-asm -- --disassemble > lockall_cost.ojbdump
|
||||
|
|
|
@ -99,6 +99,7 @@ pub fn codegen(
|
|||
#[allow(non_snake_case)]
|
||||
fn #name(#context: #name::Context) {
|
||||
use rtic::Mutex as _;
|
||||
use rtic::MutexStruct as _;
|
||||
use rtic::mutex_prelude::*;
|
||||
|
||||
#(#stmts)*
|
||||
|
|
|
@ -73,6 +73,7 @@ pub fn codegen(
|
|||
#[allow(non_snake_case)]
|
||||
fn #name(#context: #name::Context) -> ! {
|
||||
use rtic::Mutex as _;
|
||||
use rtic::MutexStruct as _;
|
||||
use rtic::mutex_prelude::*;
|
||||
|
||||
#(#stmts)*
|
||||
|
|
|
@ -168,14 +168,14 @@ pub fn codegen(
|
|||
|
||||
let (lock_all, get_prio) = if let Some(name) = field_get_prio {
|
||||
(
|
||||
util::impl_mutex(
|
||||
util::impl_mutex_struct(
|
||||
extra,
|
||||
&vec![], // TODO: what cfg should go here?
|
||||
quote!(#ident),
|
||||
quote!(#ident_mut<#lt>),
|
||||
max_ceiling,
|
||||
quote!(self.priority()),
|
||||
quote!(|| { &mut #ident_mut::new() }),
|
||||
quote!(|| { #ident_mut::new() }),
|
||||
),
|
||||
quote!(
|
||||
// Used by the lock-all API
|
||||
|
|
|
@ -132,6 +132,7 @@ pub fn codegen(
|
|||
#[allow(non_snake_case)]
|
||||
fn #name(#context: #name::Context #(,#inputs)*) {
|
||||
use rtic::Mutex as _;
|
||||
use rtic::MutexStruct as _;
|
||||
use rtic::mutex_prelude::*;
|
||||
|
||||
#(#stmts)*
|
||||
|
|
|
@ -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)
|
||||
pub fn inputs_ident(task: &Ident) -> Ident {
|
||||
mark_internal_name(&format!("{}_INPUTS", task))
|
||||
|
|
|
@ -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
|
||||
/// and running the closure with interrupt::free
|
||||
///
|
||||
|
|
|
@ -104,3 +104,12 @@ impl<T> 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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue