api test (mostly hard coded)

This commit is contained in:
Per Lindgren 2021-10-18 16:00:34 +02:00
parent 7155b55ac8
commit cde82dea30
3 changed files with 132 additions and 0 deletions

73
examples/lockall.rs Normal file
View file

@ -0,0 +1,73 @@
//! examples/lock.rs
// #![deny(unsafe_code)]
// #![deny(warnings)]
#![no_main]
#![no_std]
use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])]
mod app {
use cortex_m_semihosting::{debug, hprintln};
#[shared]
struct Shared {
a: u32,
b: i64,
}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
foo::spawn().unwrap();
(Shared { a: 1, b: 2 }, Local {}, init::Monotonics())
}
// when omitted priority is assumed to be `1`
#[task(shared = [a, b])]
fn foo(mut c: foo::Context) {
static mut X: Option<&'static mut u32> = None;
static mut Y: u32 = 0;
let _ = hprintln!("before lock");
c.shared.lock(|s| {
let _ = hprintln!("in lock");
let _ = hprintln!("here {}, {}", s.a, s.b);
*s.a += 1;
// soundness check
// c.shared.lock(|s| {}); // borrow error
// c.shared.a.lock(|s| {}); // borrow error
unsafe {
X = Some(&mut Y);
// X = Some(s.a); // lifetime issue
// X = Some(&mut *s.a); // lifetime issue
// X = Some(&'static mut *s.a); // not rust
}
let _ = hprintln!("here {}, {}", s.a, s.b);
});
// the lower priority task requires a critical section to access the data
// c.shared.shared.lock(|shared| {
// // data can only be modified within this critical section (closure)
// *shared += 1;
// // bar will *not* run right now due to the critical section
// bar::spawn().unwrap();
// hprintln!("B - shared = {}", *shared).unwrap();
// // baz does not contend for `shared` so it's allowed to run now
// baz::spawn().unwrap();
// });
// // critical section is over: bar can now start
// hprintln!("E").unwrap();
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
}
}

View file

@ -104,5 +104,62 @@ pub fn codegen(
})
};
let manual = "Manual Codegen".to_string();
let to_gen = quote! {
pub struct __rtic_internal_fooShared {
a: &'static mut u32,
b: &'static mut i64,
}
impl __rtic_internal_fooShared {
#[inline(always)]
pub unsafe fn new() -> Self {
__rtic_internal_fooShared {
a: &mut *__rtic_internal_shared_resource_a
.get_mut_unchecked()
.as_mut_ptr(),
b: &mut *__rtic_internal_shared_resource_b
.get_mut_unchecked()
.as_mut_ptr(),
}
}
}
#[doc = #manual]
impl<'a> __rtic_internal_fooSharedResources<'a> {
#[inline(always)]
pub unsafe fn priority(&self) -> &rtic::export::Priority {
self.priority
}
}
#[doc = #manual]
impl<'a> rtic::Mutex for __rtic_internal_fooSharedResources<'a> {
type T = __rtic_internal_fooShared;
#[inline(always)]
fn lock<RTIC_INTERNAL_R>(
&mut self,
f: impl FnOnce(&mut __rtic_internal_fooShared) -> RTIC_INTERNAL_R,
) -> RTIC_INTERNAL_R {
/// Priority ceiling
const CEILING: u8 = 1u8;
unsafe {
rtic::export::lock(
&mut __rtic_internal_fooShared::new(),
self.priority(),
CEILING,
lm3s6965::NVIC_PRIO_BITS,
f,
)
}
}
}
};
mod_app.push(to_gen);
(mod_app, mod_resources)
}

View file

@ -108,6 +108,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
#[doc = #doc]
pub struct #ident<#lt> {
#(#fields,)*
priority: &'a rtic::export::Priority,
}
);
@ -122,6 +123,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
pub unsafe fn new(#arg) -> Self {
#ident {
#(#values,)*
priority
}
}
}