aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Per Lindgren <per.lindgren@ltu.se> 2021-11-03 16:10:10 +0100
committerGravatar Per Lindgren <per.lindgren@ltu.se> 2021-11-03 16:10:10 +0100
commit20602bd77c59bd752fabb05713bbbeab1c0ad7cc (patch)
tree11d98de5c161139d0f51ae4d46c24269c32603e5
parentcbde2c7ef95de5767b830b963dc122a661d65efa (diff)
downloadrtic-20602bd77c59bd752fabb05713bbbeab1c0ad7cc.tar.gz
rtic-20602bd77c59bd752fabb05713bbbeab1c0ad7cc.tar.zst
rtic-20602bd77c59bd752fabb05713bbbeab1c0ad7cc.zip
wip tests do not pass
-rw-r--r--examples/lockall_cost.rs8
-rw-r--r--macros/src/codegen/hardware_tasks.rs1
-rw-r--r--macros/src/codegen/idle.rs1
-rw-r--r--macros/src/codegen/shared_resources_struct.rs4
-rw-r--r--macros/src/codegen/software_tasks.rs1
-rw-r--r--macros/src/codegen/util.rs35
-rw-r--r--src/export.rs37
-rw-r--r--src/lib.rs9
8 files changed, 90 insertions, 6 deletions
diff --git a/examples/lockall_cost.rs b/examples/lockall_cost.rs
index ba87e8e4..a0cd5201 100644
--- a/examples/lockall_cost.rs
+++ b/examples/lockall_cost.rs
@@ -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
diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs
index 8532176e..da0d6441 100644
--- a/macros/src/codegen/hardware_tasks.rs
+++ b/macros/src/codegen/hardware_tasks.rs
@@ -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)*
diff --git a/macros/src/codegen/idle.rs b/macros/src/codegen/idle.rs
index 09a95598..718ed261 100644
--- a/macros/src/codegen/idle.rs
+++ b/macros/src/codegen/idle.rs
@@ -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)*
diff --git a/macros/src/codegen/shared_resources_struct.rs b/macros/src/codegen/shared_resources_struct.rs
index 21a1f991..6ca9710b 100644
--- a/macros/src/codegen/shared_resources_struct.rs
+++ b/macros/src/codegen/shared_resources_struct.rs
@@ -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
diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs
index c8ea3059..56779c7b 100644
--- a/macros/src/codegen/software_tasks.rs
+++ b/macros/src/codegen/software_tasks.rs
@@ -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)*
diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs
index 9f84359c..671f839a 100644
--- a/macros/src/codegen/util.rs
+++ b/macros/src/codegen/util.rs
@@ -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))
diff --git a/src/export.rs b/src/export.rs
index 74b1d2ff..c10b340e 100644
--- a/src/export.rs
+++ b/src/export.rs
@@ -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
///
diff --git a/src/lib.rs b/src/lib.rs
index 8463442a..a78114b1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;
+}