mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-01 16:04:33 +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);
|
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
|
||||||
|
|
|
@ -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)*
|
||||||
|
|
|
@ -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)*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)*
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
///
|
///
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue