mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-29 06:54:33 +01:00
wip3, examples lock3 and lock4 now express intended use, relation to Exclusive still not resolved
This commit is contained in:
parent
c360ffaad8
commit
7c504668da
5 changed files with 263 additions and 87 deletions
176
Cargo.toml
176
Cargo.toml
|
@ -1,111 +1,121 @@
|
|||
[[example]]
|
||||
name = 'baseline'
|
||||
required-features = ['__v7']
|
||||
|
||||
[[example]]
|
||||
name = 'periodic'
|
||||
required-features = ['__v7']
|
||||
|
||||
[[example]]
|
||||
name = 'pool'
|
||||
required-features = ['__v7']
|
||||
|
||||
[[example]]
|
||||
name = 'schedule'
|
||||
required-features = ['__v7']
|
||||
|
||||
[[example]]
|
||||
name = 't-cfg'
|
||||
required-features = ['__v7']
|
||||
|
||||
[[example]]
|
||||
name = 't-cfg-resources'
|
||||
required-features = ['__min_r1_43']
|
||||
|
||||
[[example]]
|
||||
name = 't-schedule'
|
||||
required-features = ['__v7']
|
||||
|
||||
[[example]]
|
||||
name = 'types'
|
||||
required-features = ['__v7']
|
||||
|
||||
[package]
|
||||
authors = [
|
||||
"The Real-Time Interrupt-driven Concurrency developers",
|
||||
"Jorge Aparicio <jorge@japaric.io>",
|
||||
"Per Lindgren <per.lindgren@ltu.se>",
|
||||
'The Real-Time Interrupt-driven Concurrency developers',
|
||||
'Jorge Aparicio <jorge@japaric.io>',
|
||||
'Per Lindgren <per.lindgren@ltu.se>',
|
||||
]
|
||||
categories = ["concurrency", "embedded", "no-std"]
|
||||
description = "Real-Time Interrupt-driven Concurrency (RTIC): a concurrency framework for building real time systems"
|
||||
documentation = "https://rtic.rs/"
|
||||
edition = "2018"
|
||||
keywords = ["arm", "cortex-m"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
name = "cortex-m-rtic"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/rtic-rs/cortex-m-rtic"
|
||||
version = "0.5.3"
|
||||
categories = [
|
||||
'concurrency',
|
||||
'embedded',
|
||||
'no-std',
|
||||
]
|
||||
description = 'Real-Time Interrupt-driven Concurrency (RTIC): a concurrency framework for building real time systems'
|
||||
documentation = 'https://rtic.rs/'
|
||||
edition = '2018'
|
||||
keywords = [
|
||||
'arm',
|
||||
'cortex-m',
|
||||
]
|
||||
license = 'MIT OR Apache-2.0'
|
||||
name = 'cortex-m-rtic'
|
||||
readme = 'README.md'
|
||||
repository = 'https://github.com/rtic-rs/cortex-m-rtic'
|
||||
version = '0.5.3'
|
||||
|
||||
[lib]
|
||||
name = "rtic"
|
||||
|
||||
[[example]]
|
||||
name = "baseline"
|
||||
required-features = ["__v7"]
|
||||
|
||||
[[example]]
|
||||
name = "periodic"
|
||||
required-features = ["__v7"]
|
||||
|
||||
[[example]]
|
||||
name = "pool"
|
||||
required-features = ["__v7"]
|
||||
|
||||
[[example]]
|
||||
name = "schedule"
|
||||
required-features = ["__v7"]
|
||||
|
||||
[[example]]
|
||||
name = "t-cfg"
|
||||
required-features = ["__v7"]
|
||||
|
||||
[[example]]
|
||||
name = "t-cfg-resources"
|
||||
required-features = ["__min_r1_43"]
|
||||
|
||||
[[example]]
|
||||
name = "t-schedule"
|
||||
required-features = ["__v7"]
|
||||
|
||||
[[example]]
|
||||
name = "types"
|
||||
required-features = ["__v7"]
|
||||
name = 'rtic'
|
||||
[patch.crates-io.rtic-core]
|
||||
git = 'https://github.com/rtic-rs/rtic-core.git'
|
||||
branch = 'immutable_resource_proxies'
|
||||
|
||||
[dependencies]
|
||||
cortex-m = "0.6.2"
|
||||
cortex-m-rtic-macros = { path = "macros", version = "0.5.0" }
|
||||
rtic-core = "0.3.0"
|
||||
cortex-m-rt = "0.6.9"
|
||||
heapless = "0.5.0"
|
||||
cortex-m = '0.6.2'
|
||||
rtic-core = '0.3.0'
|
||||
cortex-m-rt = '0.6.9'
|
||||
heapless = '0.5.0'
|
||||
|
||||
[build-dependencies]
|
||||
version_check = "0.9"
|
||||
[dependencies.cortex-m-rtic-macros]
|
||||
path = 'macros'
|
||||
version = '0.5.0'
|
||||
|
||||
[dependencies.microamp]
|
||||
optional = true
|
||||
version = "0.1.0-alpha.2"
|
||||
version = '0.1.0-alpha.2'
|
||||
|
||||
[build-dependencies]
|
||||
version_check = '0.9'
|
||||
|
||||
[dev-dependencies]
|
||||
lm3s6965 = "0.1.3"
|
||||
panic-halt = "0.2.0"
|
||||
cortex-m-semihosting = "0.3.3"
|
||||
lm3s6965 = '0.1.3'
|
||||
panic-halt = '0.2.0'
|
||||
cortex-m-semihosting = '0.3.3'
|
||||
|
||||
[dev-dependencies.panic-semihosting]
|
||||
features = ["exit"]
|
||||
version = "0.5.2"
|
||||
|
||||
features = ['exit']
|
||||
version = '0.5.2'
|
||||
[target.x86_64-unknown-linux-gnu.dev-dependencies]
|
||||
trybuild = "1"
|
||||
trybuild = '1'
|
||||
|
||||
[features]
|
||||
heterogeneous = ["cortex-m-rtic-macros/heterogeneous", "microamp"]
|
||||
homogeneous = ["cortex-m-rtic-macros/homogeneous"]
|
||||
# used for testing this crate; do not use in applications
|
||||
__v7 =[]
|
||||
__min_r1_43 =[]
|
||||
|
||||
heterogeneous = [
|
||||
'cortex-m-rtic-macros/heterogeneous',
|
||||
'microamp',
|
||||
]
|
||||
homogeneous = ['cortex-m-rtic-macros/homogeneous']
|
||||
__v7 = []
|
||||
__min_r1_43 = []
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"heterogeneous",
|
||||
"homogeneous",
|
||||
"macros",
|
||||
]
|
||||
|
||||
# do not optimize proc-macro deps or build scripts
|
||||
[profile.dev.build-override]
|
||||
codegen-units = 16
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
opt-level = 0
|
||||
overflow-checks = false
|
||||
|
||||
|
||||
[profile.release.build-override]
|
||||
codegen-units = 16
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
opt-level = 0
|
||||
overflow-checks = false
|
||||
[profile.dev.build-override]
|
||||
codegen-units = 16
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
opt-level = 0
|
||||
overflow-checks = false
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
'heterogeneous',
|
||||
'homogeneous',
|
||||
'macros',
|
||||
]
|
||||
|
|
63
examples/lock4.rs
Normal file
63
examples/lock4.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
//! examples/lock.rs
|
||||
|
||||
#![deny(unsafe_code)]
|
||||
#![deny(warnings)]
|
||||
#![no_main]
|
||||
#![no_std]
|
||||
|
||||
use cortex_m_semihosting::{debug, hprintln};
|
||||
use lm3s6965::Interrupt;
|
||||
use panic_semihosting as _;
|
||||
|
||||
#[rtic::app(device = lm3s6965)]
|
||||
const APP: () = {
|
||||
struct Resources {
|
||||
#[init(0)]
|
||||
shared: u32,
|
||||
}
|
||||
|
||||
#[init]
|
||||
fn init(_: init::Context) {
|
||||
rtic::pend(Interrupt::GPIOA);
|
||||
}
|
||||
|
||||
// when omitted priority is assumed to be `1`
|
||||
#[task(binds = GPIOA, resources = [shared])]
|
||||
fn gpioa(c: gpioa::Context) {
|
||||
hprintln!("A").unwrap();
|
||||
|
||||
// the lower priority task requires a critical section to access the data
|
||||
c.resources.shared.lock(|shared| {
|
||||
// data can only be modified within this critical section (closure)
|
||||
*shared += 1;
|
||||
|
||||
// GPIOB will *not* run right now due to the critical section
|
||||
rtic::pend(Interrupt::GPIOB);
|
||||
|
||||
hprintln!("B - shared = {}", *shared).unwrap();
|
||||
|
||||
c.resources.shared.lock(|_shared| {});
|
||||
// GPIOC does not contend for `shared` so it's allowed to run now
|
||||
rtic::pend(Interrupt::GPIOC);
|
||||
});
|
||||
|
||||
// critical section is over: GPIOB can now start
|
||||
|
||||
hprintln!("E").unwrap();
|
||||
|
||||
debug::exit(debug::EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#[task(binds = GPIOB, priority = 2, resources = [shared])]
|
||||
fn gpiob(c: gpiob::Context) {
|
||||
// the higher priority task does *not* need a critical section
|
||||
*c.resources.shared += 1;
|
||||
|
||||
hprintln!("D - shared = {}", *c.resources.shared).unwrap();
|
||||
}
|
||||
|
||||
#[task(binds = GPIOC, priority = 3)]
|
||||
fn gpioc(_: gpioc::Context) {
|
||||
hprintln!("C").unwrap();
|
||||
}
|
||||
};
|
107
expand_lock.rs
107
expand_lock.rs
|
@ -75,8 +75,8 @@ pub mod init {
|
|||
}
|
||||
}
|
||||
mod resources {
|
||||
use rtic::export::Priority;
|
||||
use core::cell::Cell;
|
||||
use rtic::export::Priority;
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct shared<'a> {
|
||||
priority: &'a Priority,
|
||||
|
@ -163,5 +163,108 @@ pub mod gpioc {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation details
|
||||
const APP: () = { # [ doc = r" Always include the device crate which contains the vector table" ] use lm3s6965 as _ ; # [ allow ( non_upper_case_globals ) ] static mut shared : u32 = 0 ; impl < 'a > rtic :: Mutex for resources :: shared < 'a > { type T = u32 ; # [ inline ( always ) ] fn lock < R > ( & mut self , f : impl FnOnce ( & mut u32 ) -> R ) -> R { # [ doc = r" Priority ceiling" ] const CEILING : u8 = 2u8 ; if self . get_locked ( ) { :: core :: panicking :: panic ( "Resource locked in sequential context" ) ; } ; self . set_locked ( true ) ; let r = unsafe { rtic :: export :: lock ( & mut shared , self . priority ( ) , CEILING , lm3s6965 :: NVIC_PRIO_BITS , f ) } ; self . set_locked ( false ) ; r } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOA ( ) { const PRIORITY : u8 = 1u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpioa ( gpioa :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpioaResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpioaResources { shared : resources :: shared :: new ( priority ) , } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOB ( ) { const PRIORITY : u8 = 2u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpiob ( gpiob :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } impl < 'a > gpiobResources < 'a > { # [ inline ( always ) ] unsafe fn new ( priority : & 'a rtic :: export :: Priority ) -> Self { gpiobResources { shared : & mut shared , } } } # [ allow ( non_snake_case ) ] # [ no_mangle ] unsafe fn GPIOC ( ) { const PRIORITY : u8 = 3u8 ; rtic :: export :: run ( PRIORITY , | | { crate :: gpioc ( gpioc :: Context :: new ( & rtic :: export :: Priority :: new ( PRIORITY ) ) ) } ) ; } # [ no_mangle ] unsafe extern "C" fn main ( ) -> ! { let _TODO : ( ) = ( ) ; rtic :: export :: interrupt :: disable ( ) ; let mut core : rtic :: export :: Peripherals = core :: mem :: transmute ( ( ) ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 1u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOA , rtic :: export :: logical2hw ( 1u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOA ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 2u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOB , rtic :: export :: logical2hw ( 2u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOB ) ; let _ = [ ( ) ; ( ( 1 << lm3s6965 :: NVIC_PRIO_BITS ) - 3u8 as usize ) ] ; core . NVIC . set_priority ( lm3s6965 :: Interrupt :: GPIOC , rtic :: export :: logical2hw ( 3u8 , lm3s6965 :: NVIC_PRIO_BITS ) ) ; rtic :: export :: NVIC :: unmask ( lm3s6965 :: Interrupt :: GPIOC ) ; core . SCB . scr . modify ( | r | r | 1 << 1 ) ; let late = crate :: init ( init :: Context :: new ( core . into ( ) ) ) ; rtic :: export :: interrupt :: enable ( ) ; loop { rtic :: export :: wfi ( ) } } };
|
||||
const APP: () = {
|
||||
#[doc = r" Always include the device crate which contains the vector table"]
|
||||
use lm3s6965 as _;
|
||||
#[allow(non_upper_case_globals)]
|
||||
static mut shared: u32 = 0;
|
||||
impl<'a> rtic::Mutex for resources::shared<'a> {
|
||||
type T = u32;
|
||||
#[inline(always)]
|
||||
fn lock<R>(&self, f: impl FnOnce(&mut u32) -> R) -> R {
|
||||
#[doc = r" Priority ceiling"]
|
||||
const CEILING: u8 = 2u8;
|
||||
if unsafe { self.get_locked() } {
|
||||
::core::panicking::panic("Resource locked in sequential context");
|
||||
};
|
||||
unsafe {
|
||||
self.set_locked(true);
|
||||
}
|
||||
let r = unsafe {
|
||||
rtic::export::lock(
|
||||
&mut shared,
|
||||
self.priority(),
|
||||
CEILING,
|
||||
lm3s6965::NVIC_PRIO_BITS,
|
||||
f,
|
||||
)
|
||||
};
|
||||
unsafe {
|
||||
self.set_locked(false);
|
||||
}
|
||||
r
|
||||
}
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
unsafe fn GPIOA() {
|
||||
const PRIORITY: u8 = 1u8;
|
||||
rtic::export::run(PRIORITY, || {
|
||||
crate::gpioa(gpioa::Context::new(&rtic::export::Priority::new(PRIORITY)))
|
||||
});
|
||||
}
|
||||
impl<'a> gpioaResources<'a> {
|
||||
#[inline(always)]
|
||||
unsafe fn new(priority: &'a rtic::export::Priority) -> Self {
|
||||
gpioaResources {
|
||||
shared: resources::shared::new(priority),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
unsafe fn GPIOB() {
|
||||
const PRIORITY: u8 = 2u8;
|
||||
rtic::export::run(PRIORITY, || {
|
||||
crate::gpiob(gpiob::Context::new(&rtic::export::Priority::new(PRIORITY)))
|
||||
});
|
||||
}
|
||||
impl<'a> gpiobResources<'a> {
|
||||
#[inline(always)]
|
||||
unsafe fn new(priority: &'a rtic::export::Priority) -> Self {
|
||||
gpiobResources {
|
||||
shared: &mut shared,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
unsafe fn GPIOC() {
|
||||
const PRIORITY: u8 = 3u8;
|
||||
rtic::export::run(PRIORITY, || {
|
||||
crate::gpioc(gpioc::Context::new(&rtic::export::Priority::new(PRIORITY)))
|
||||
});
|
||||
}
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn main() -> ! {
|
||||
let _TODO: () = ();
|
||||
rtic::export::interrupt::disable();
|
||||
let mut core: rtic::export::Peripherals = core::mem::transmute(());
|
||||
let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 1u8 as usize)];
|
||||
core.NVIC.set_priority(
|
||||
lm3s6965::Interrupt::GPIOA,
|
||||
rtic::export::logical2hw(1u8, lm3s6965::NVIC_PRIO_BITS),
|
||||
);
|
||||
rtic::export::NVIC::unmask(lm3s6965::Interrupt::GPIOA);
|
||||
let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 2u8 as usize)];
|
||||
core.NVIC.set_priority(
|
||||
lm3s6965::Interrupt::GPIOB,
|
||||
rtic::export::logical2hw(2u8, lm3s6965::NVIC_PRIO_BITS),
|
||||
);
|
||||
rtic::export::NVIC::unmask(lm3s6965::Interrupt::GPIOB);
|
||||
let _ = [(); ((1 << lm3s6965::NVIC_PRIO_BITS) - 3u8 as usize)];
|
||||
core.NVIC.set_priority(
|
||||
lm3s6965::Interrupt::GPIOC,
|
||||
rtic::export::logical2hw(3u8, lm3s6965::NVIC_PRIO_BITS),
|
||||
);
|
||||
rtic::export::NVIC::unmask(lm3s6965::Interrupt::GPIOC);
|
||||
core.SCB.scr.modify(|r| r | 1 << 1);
|
||||
let late = crate::init(init::Context::new(core.into()));
|
||||
rtic::export::interrupt::enable();
|
||||
loop {
|
||||
rtic::export::wfi()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -72,7 +72,7 @@ pub fn impl_mutex(
|
|||
impl<'a> rtic::Mutex for #path<'a> {
|
||||
type T = #ty;
|
||||
#[inline(always)]
|
||||
fn lock<R>(&mut self, f: impl FnOnce(&mut #ty) -> R) -> R {
|
||||
fn lock<R>(&self, f: impl FnOnce(&mut #ty) -> R) -> R {
|
||||
/// Priority ceiling
|
||||
const CEILING: u8 = #ceiling;
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ use cortex_m::{
|
|||
#[cfg(all(not(feature = "heterogeneous"), not(feature = "homogeneous")))]
|
||||
use cortex_m_rt as _; // vector table
|
||||
pub use cortex_m_rtic_macros::app;
|
||||
pub use rtic_core::{Exclusive, Mutex};
|
||||
pub use rtic_core::Mutex;
|
||||
|
||||
#[cfg(armv7m)]
|
||||
pub mod cyccnt;
|
||||
|
|
Loading…
Reference in a new issue