From 81275bfa4f41e2066770087f3a33cad4227eab41 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 13 Jun 2019 23:56:59 +0200 Subject: rtfm-syntax refactor + heterogeneous multi-core support --- examples/shared-with-init.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'examples/shared-with-init.rs') diff --git a/examples/shared-with-init.rs b/examples/shared-with-init.rs index 0fb9191c..1640ca9b 100644 --- a/examples/shared-with-init.rs +++ b/examples/shared-with-init.rs @@ -5,10 +5,9 @@ #![no_main] #![no_std] -extern crate panic_halt; - use cortex_m_semihosting::debug; use lm3s6965::Interrupt; +use panic_halt as _; use rtfm::app; pub struct MustBeSend; -- cgit v1.2.3 From 4e51bb68b976c6bb6a9a989dc560d2a8123a84ca Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 20 Jun 2019 06:19:59 +0200 Subject: RFC #207 --- examples/baseline.rs | 4 ++-- examples/binds.rs | 2 +- examples/capacity.rs | 4 ++-- examples/generics.rs | 8 ++++---- examples/interrupt.rs | 4 ++-- examples/late.rs | 4 ++-- examples/lock.rs | 12 +++++------ examples/pool.rs | 4 ++-- examples/resource.rs | 8 ++++---- examples/shared-with-init.rs | 4 ++-- examples/static.rs | 8 ++++---- examples/t-binds.rs | 6 ++++-- examples/t-resource.rs | 8 ++++---- examples/t-schedule.rs | 8 ++++---- examples/t-spawn.rs | 8 ++++---- examples/types.rs | 16 +++++++-------- macros/src/check.rs | 19 ++++++----------- macros/src/codegen/hardware_tasks.rs | 4 ++-- macros/src/codegen/pre_init.rs | 14 ++++++------- macros/src/codegen/util.rs | 12 +++++++++++ macros/src/lib.rs | 21 ++++++++----------- macros/src/tests/multi.rs | 12 +++++------ macros/src/tests/single.rs | 7 +++---- ui/single/exception-invalid.rs | 4 ++-- ui/single/exception-invalid.stderr | 4 ++-- ui/single/exception-systick-used.rs | 4 ++-- ui/single/exception-systick-used.stderr | 4 ++-- ui/single/extern-interrupt-used.rs | 2 +- ui/single/extern-interrupt-used.stderr | 6 +++--- ui/single/locals-cfg.rs | 8 ++++---- ui/single/resources-cfg.rs | 8 ++++---- ui/single/resources-cfg.stderr | 12 +++++------ ui/single/task-priority-too-high.rs | 36 ++++++++++++++++----------------- 33 files changed, 143 insertions(+), 142 deletions(-) (limited to 'examples/shared-with-init.rs') diff --git a/examples/baseline.rs b/examples/baseline.rs index cc9b412c..3a8ab0e4 100644 --- a/examples/baseline.rs +++ b/examples/baseline.rs @@ -35,8 +35,8 @@ const APP: () = { } } - #[interrupt(spawn = [foo])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, spawn = [foo])] + fn uart0(c: uart0::Context) { hprintln!("UART0(baseline = {:?})", c.start).unwrap(); // `foo` inherits the baseline of `UART0`: its `start` time diff --git a/examples/binds.rs b/examples/binds.rs index 1959d759..b10cb434 100644 --- a/examples/binds.rs +++ b/examples/binds.rs @@ -30,7 +30,7 @@ const APP: () = { loop {} } - #[interrupt(binds = UART0)] + #[task(binds = UART0)] fn foo(_: foo::Context) { static mut TIMES: u32 = 0; diff --git a/examples/capacity.rs b/examples/capacity.rs index e1a835ca..ebc86b80 100644 --- a/examples/capacity.rs +++ b/examples/capacity.rs @@ -16,8 +16,8 @@ const APP: () = { rtfm::pend(Interrupt::UART0); } - #[interrupt(spawn = [foo, bar])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, spawn = [foo, bar])] + fn uart0(c: uart0::Context) { c.spawn.foo(0).unwrap(); c.spawn.foo(1).unwrap(); c.spawn.foo(2).unwrap(); diff --git a/examples/generics.rs b/examples/generics.rs index a35ba237..562470d4 100644 --- a/examples/generics.rs +++ b/examples/generics.rs @@ -20,8 +20,8 @@ const APP: () = { rtfm::pend(Interrupt::UART1); } - #[interrupt(resources = [SHARED])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [SHARED])] + fn uart0(c: uart0::Context) { static mut STATE: u32 = 0; hprintln!("UART0(STATE = {})", *STATE).unwrap(); @@ -33,8 +33,8 @@ const APP: () = { debug::exit(debug::EXIT_SUCCESS); } - #[interrupt(priority = 2, resources = [SHARED])] - fn UART1(c: UART1::Context) { + #[task(binds = UART1, priority = 2, resources = [SHARED])] + fn uart1(c: uart1::Context) { static mut STATE: u32 = 0; hprintln!("UART1(STATE = {})", *STATE).unwrap(); diff --git a/examples/interrupt.rs b/examples/interrupt.rs index 3fe8ff35..f0069b83 100644 --- a/examples/interrupt.rs +++ b/examples/interrupt.rs @@ -33,8 +33,8 @@ const APP: () = { loop {} } - #[interrupt] - fn UART0(_: UART0::Context) { + #[task(binds = UART0)] + fn uart0(_: uart0::Context) { static mut TIMES: u32 = 0; // Safe access to local `static mut` variable diff --git a/examples/late.rs b/examples/late.rs index 4d48a6a2..19807ff7 100644 --- a/examples/late.rs +++ b/examples/late.rs @@ -47,8 +47,8 @@ const APP: () = { } } - #[interrupt(resources = [P])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [P])] + fn uart0(c: uart0::Context) { c.resources.P.enqueue(42).unwrap(); } }; diff --git a/examples/lock.rs b/examples/lock.rs index b7d36b41..17b6a58b 100644 --- a/examples/lock.rs +++ b/examples/lock.rs @@ -19,8 +19,8 @@ const APP: () = { } // when omitted priority is assumed to be `1` - #[interrupt(resources = [SHARED])] - fn GPIOA(mut c: GPIOA::Context) { + #[task(binds = GPIOA, resources = [SHARED])] + fn gpioa(mut c: gpioa::Context) { hprintln!("A").unwrap(); // the lower priority task requires a critical section to access the data @@ -44,16 +44,16 @@ const APP: () = { debug::exit(debug::EXIT_SUCCESS); } - #[interrupt(priority = 2, resources = [SHARED])] - fn GPIOB(c: GPIOB::Context) { + #[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(); } - #[interrupt(priority = 3)] - fn GPIOC(_: GPIOC::Context) { + #[task(binds = GPIOC, priority = 3)] + fn gpioc(_: gpioc::Context) { hprintln!("C").unwrap(); } }; diff --git a/examples/pool.rs b/examples/pool.rs index db321b53..8c44cb17 100644 --- a/examples/pool.rs +++ b/examples/pool.rs @@ -29,8 +29,8 @@ const APP: () = { rtfm::pend(Interrupt::I2C0); } - #[interrupt(priority = 2, spawn = [foo, bar])] - fn I2C0(c: I2C0::Context) { + #[task(binds = I2C0, priority = 2, spawn = [foo, bar])] + fn i2c0(c: i2c0::Context) { // claim a memory block, leave it uninitialized and .. let x = P::alloc().unwrap().freeze(); diff --git a/examples/resource.rs b/examples/resource.rs index 82689504..661f8c35 100644 --- a/examples/resource.rs +++ b/examples/resource.rs @@ -31,16 +31,16 @@ const APP: () = { } // `SHARED` can be access from this context - #[interrupt(resources = [SHARED])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [SHARED])] + fn uart0(c: uart0::Context) { *c.resources.SHARED += 1; hprintln!("UART0: SHARED = {}", c.resources.SHARED).unwrap(); } // `SHARED` can be access from this context - #[interrupt(resources = [SHARED])] - fn UART1(c: UART1::Context) { + #[task(binds = UART1, resources = [SHARED])] + fn uart1(c: uart1::Context) { *c.resources.SHARED += 1; hprintln!("UART1: SHARED = {}", c.resources.SHARED).unwrap(); diff --git a/examples/shared-with-init.rs b/examples/shared-with-init.rs index 1640ca9b..ed73c8ba 100644 --- a/examples/shared-with-init.rs +++ b/examples/shared-with-init.rs @@ -25,8 +25,8 @@ const APP: () = { rtfm::pend(Interrupt::UART0); } - #[interrupt(resources = [SHARED])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [SHARED])] + fn uart0(c: uart0::Context) { if let Some(message) = c.resources.SHARED.take() { // `message` has been received drop(message); diff --git a/examples/static.rs b/examples/static.rs index eeb522f5..5eb7b197 100644 --- a/examples/static.rs +++ b/examples/static.rs @@ -23,15 +23,15 @@ const APP: () = { init::LateResources { KEY: 0xdeadbeef } } - #[interrupt(resources = [KEY])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [KEY])] + fn uart0(c: uart0::Context) { hprintln!("UART0(KEY = {:#x})", c.resources.KEY).unwrap(); debug::exit(debug::EXIT_SUCCESS); } - #[interrupt(priority = 2, resources = [KEY])] - fn UART1(c: UART1::Context) { + #[task(binds = UART1, priority = 2, resources = [KEY])] + fn uart1(c: uart1::Context) { hprintln!("UART1(KEY = {:#x})", c.resources.KEY).unwrap(); } }; diff --git a/examples/t-binds.rs b/examples/t-binds.rs index b4693a47..dda8e201 100644 --- a/examples/t-binds.rs +++ b/examples/t-binds.rs @@ -12,12 +12,14 @@ const APP: () = { #[init] fn init(_: init::Context) {} - #[exception(binds = SVCall)] + // Cortex-M exception + #[task(binds = SVCall)] fn foo(c: foo::Context) { foo_trampoline(c) } - #[interrupt(binds = UART0)] + // LM3S6965 interrupt + #[task(binds = UART0)] fn bar(c: bar::Context) { bar_trampoline(c) } diff --git a/examples/t-resource.rs b/examples/t-resource.rs index 40dc2a65..adcc04b3 100644 --- a/examples/t-resource.rs +++ b/examples/t-resource.rs @@ -51,8 +51,8 @@ const APP: () = { loop {} } - #[interrupt(resources = [O3, S1, S2, S3])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [O3, S1, S2, S3])] + fn uart0(c: uart0::Context) { // owned by interrupt == `&mut` let _: &mut u32 = c.resources.O3; @@ -66,8 +66,8 @@ const APP: () = { let _: &u32 = c.resources.S3; } - #[interrupt(resources = [S2, O5])] - fn UART1(c: UART1::Context) { + #[task(binds = UART1, resources = [S2, O5])] + fn uart1(c: uart1::Context) { // owned by interrupt == `&` if read-only let _: &u32 = c.resources.O5; diff --git a/examples/t-schedule.rs b/examples/t-schedule.rs index 67ff358b..e6035b3f 100644 --- a/examples/t-schedule.rs +++ b/examples/t-schedule.rs @@ -26,15 +26,15 @@ const APP: () = { loop {} } - #[exception(schedule = [foo, bar, baz])] - fn SVCall(c: SVCall::Context) { + #[task(binds = SVCall, schedule = [foo, bar, baz])] + fn svcall(c: svcall::Context) { let _: Result<(), ()> = c.schedule.foo(c.start + 70.cycles()); let _: Result<(), u32> = c.schedule.bar(c.start + 80.cycles(), 0); let _: Result<(), (u32, u32)> = c.schedule.baz(c.start + 90.cycles(), 0, 1); } - #[interrupt(schedule = [foo, bar, baz])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, schedule = [foo, bar, baz])] + fn uart0(c: uart0::Context) { let _: Result<(), ()> = c.schedule.foo(c.start + 100.cycles()); let _: Result<(), u32> = c.schedule.bar(c.start + 110.cycles(), 0); let _: Result<(), (u32, u32)> = c.schedule.baz(c.start + 120.cycles(), 0, 1); diff --git a/examples/t-spawn.rs b/examples/t-spawn.rs index 6bb9b31f..682b9b89 100644 --- a/examples/t-spawn.rs +++ b/examples/t-spawn.rs @@ -25,15 +25,15 @@ const APP: () = { loop {} } - #[exception(spawn = [foo, bar, baz])] - fn SVCall(c: SVCall::Context) { + #[task(binds = SVCall, spawn = [foo, bar, baz])] + fn svcall(c: svcall::Context) { let _: Result<(), ()> = c.spawn.foo(); let _: Result<(), u32> = c.spawn.bar(0); let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1); } - #[interrupt(spawn = [foo, bar, baz])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, spawn = [foo, bar, baz])] + fn uart0(c: uart0::Context) { let _: Result<(), ()> = c.spawn.foo(); let _: Result<(), u32> = c.spawn.bar(0); let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1); diff --git a/examples/types.rs b/examples/types.rs index 2e72f0a0..3e9c7ea5 100644 --- a/examples/types.rs +++ b/examples/types.rs @@ -24,19 +24,19 @@ const APP: () = { debug::exit(debug::EXIT_SUCCESS); } - #[exception(schedule = [foo], spawn = [foo])] - fn SVCall(c: SVCall::Context) { + #[task(binds = SVCall, schedule = [foo], spawn = [foo])] + fn svcall(c: svcall::Context) { let _: Instant = c.start; - let _: SVCall::Schedule = c.schedule; - let _: SVCall::Spawn = c.spawn; + let _: svcall::Schedule = c.schedule; + let _: svcall::Spawn = c.spawn; } - #[interrupt(resources = [SHARED], schedule = [foo], spawn = [foo])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [SHARED], schedule = [foo], spawn = [foo])] + fn uart0(c: uart0::Context) { let _: Instant = c.start; let _: resources::SHARED = c.resources.SHARED; - let _: UART0::Schedule = c.schedule; - let _: UART0::Spawn = c.spawn; + let _: uart0::Schedule = c.schedule; + let _: uart0::Spawn = c.spawn; } #[task(priority = 2, resources = [SHARED], schedule = [foo], spawn = [foo])] diff --git a/macros/src/check.rs b/macros/src/check.rs index 619ec8fb..85fda75b 100644 --- a/macros/src/check.rs +++ b/macros/src/check.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use proc_macro2::Span; use rtfm_syntax::{ analyze::Analysis, - ast::{App, CustomArg, HardwareTaskKind}, + ast::{App, CustomArg}, }; use syn::{parse, Path}; @@ -44,18 +44,9 @@ pub fn app<'a>(app: &'a App, analysis: &Analysis) -> parse::Result> { // check that all exceptions are valid; only exceptions with configurable priorities are // accepted - for (name, task) in app - .hardware_tasks - .iter() - .filter(|(_, task)| task.kind == HardwareTaskKind::Exception) - { - let name_s = task.args.binds(name).to_string(); + for (name, task) in &app.hardware_tasks { + let name_s = task.args.binds.to_string(); match &*name_s { - // NOTE that some of these don't exist on ARMv6-M but we don't check that here -- the - // code we generate will check that the exception actually exists on ARMv6-M - "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" | "SVCall" - | "DebugMonitor" | "PendSV" => {} // OK - "SysTick" => { if analysis.timer_queues.get(&task.args.core).is_some() { return Err(parse::Error::new( @@ -67,12 +58,14 @@ pub fn app<'a>(app: &'a App, analysis: &Analysis) -> parse::Result> { } } - _ => { + "NonMaskableInt" | "HardFault" => { return Err(parse::Error::new( name.span(), "only exceptions with configurable priority can be used as hardware tasks", )); } + + _ => {} } } diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs index e7f053d3..a7af510a 100644 --- a/macros/src/codegen/hardware_tasks.rs +++ b/macros/src/codegen/hardware_tasks.rs @@ -50,9 +50,9 @@ pub fn codegen( }; let symbol = if cfg!(feature = "homogeneous") { - util::suffixed(&task.args.binds(name).to_string(), core) + util::suffixed(&task.args.binds.to_string(), core) } else { - task.args.binds(name).clone() + task.args.binds.clone() }; let priority = task.args.priority; diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index 19fc6461..948dae54 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -1,6 +1,6 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; -use rtfm_syntax::ast::{App, HardwareTaskKind}; +use rtfm_syntax::ast::App; use crate::{analyze::Analysis, check::Extra, codegen::util}; @@ -52,9 +52,9 @@ pub fn codegen( .get(&core) .iter() .flat_map(|interrupts| *interrupts) - .chain(app.hardware_tasks.iter().flat_map(|(name, task)| { - if task.kind == HardwareTaskKind::Interrupt { - Some((&task.args.priority, task.args.binds(name))) + .chain(app.hardware_tasks.values().flat_map(|task| { + if !util::is_exception(&task.args.binds) { + Some((&task.args.priority, &task.args.binds)) } else { // we do exceptions in another pass None @@ -102,9 +102,9 @@ pub fn codegen( } // set exception priorities - for (name, priority) in app.hardware_tasks.iter().filter_map(|(name, task)| { - if task.kind == HardwareTaskKind::Exception { - Some((task.args.binds(name), task.args.priority)) + for (name, priority) in app.hardware_tasks.values().filter_map(|task| { + if util::is_exception(&task.args.binds) { + Some((&task.args.binds, task.args.priority)) } else { None } diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 8c43b350..cd01264d 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -113,6 +113,18 @@ pub fn interrupt_ident(core: Core, cores: u8) -> Ident { } } +/// Whether `name` is an exception with configurable priority +pub fn is_exception(name: &Ident) -> bool { + let s = name.to_string(); + + match &*s { + "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" | "SVCall" + | "DebugMonitor" | "PendSV" | "SysTick" => true, + + _ => false, + } +} + /// Generates a pre-reexport identifier for the "late resources" struct pub fn late_resources_ident(init: &Ident) -> Ident { Ident::new( diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 6502d9ca..ed55095d 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -16,19 +16,14 @@ mod tests; #[proc_macro_attribute] pub fn app(args: TokenStream, input: TokenStream) -> TokenStream { - let (app, analysis) = match rtfm_syntax::parse( - args, - input, - Settings { - parse_cores: cfg!(feature = "heterogeneous") || cfg!(feature = "homogeneous"), - parse_exception: true, - parse_extern_interrupt: true, - parse_interrupt: true, - parse_schedule: true, - optimize_priorities: true, - ..Settings::default() - }, - ) { + let mut settings = Settings::default(); + settings.optimize_priorities = true; + settings.parse_binds = true; + settings.parse_cores = cfg!(feature = "heterogeneous") || cfg!(feature = "homogeneous"); + settings.parse_extern_interrupt = true; + settings.parse_schedule = true; + + let (app, analysis) = match rtfm_syntax::parse(args, input, settings) { Err(e) => return e.to_compile_error().into(), Ok(x) => x, }; diff --git a/macros/src/tests/multi.rs b/macros/src/tests/multi.rs index 37fef53f..b55c451f 100644 --- a/macros/src/tests/multi.rs +++ b/macros/src/tests/multi.rs @@ -3,6 +3,10 @@ use rtfm_syntax::Settings; #[test] fn analyze() { + let mut settings = Settings::default(); + settings.parse_cores = true; + settings.parse_extern_interrupt = true; + let (app, analysis) = rtfm_syntax::parse2( quote!(device = pac, cores = 2), quote!( @@ -35,13 +39,9 @@ fn analyze() { } }; ), - Settings { - parse_cores: true, - parse_extern_interrupt: true, - ..Settings::default() - }, + settings, ) - .unwrap(); + .unwrap(); let analysis = crate::analyze::app(analysis, &app); diff --git a/macros/src/tests/single.rs b/macros/src/tests/single.rs index fb2d430f..5d7a8a9d 100644 --- a/macros/src/tests/single.rs +++ b/macros/src/tests/single.rs @@ -3,6 +3,8 @@ use rtfm_syntax::Settings; #[test] fn analyze() { + let mut settings = Settings::default(); + settings.parse_extern_interrupt = true; let (app, analysis) = rtfm_syntax::parse2( quote!(device = pac), quote!( @@ -20,10 +22,7 @@ fn analyze() { } }; ), - Settings { - parse_extern_interrupt: true, - ..Settings::default() - }, + settings, ) .unwrap(); diff --git a/ui/single/exception-invalid.rs b/ui/single/exception-invalid.rs index 426cb673..54f59928 100644 --- a/ui/single/exception-invalid.rs +++ b/ui/single/exception-invalid.rs @@ -2,6 +2,6 @@ #[rtfm::app(device = lm3s6965)] const APP: () = { - #[exception] - fn NonMaskableInt(_: NonMaskableInt::Context) {} + #[task(binds = NonMaskableInt)] + fn nmi(_: nmi::Context) {} }; diff --git a/ui/single/exception-invalid.stderr b/ui/single/exception-invalid.stderr index f7fc2922..306074b0 100644 --- a/ui/single/exception-invalid.stderr +++ b/ui/single/exception-invalid.stderr @@ -1,8 +1,8 @@ error: only exceptions with configurable priority can be used as hardware tasks --> $DIR/exception-invalid.rs:6:8 | -6 | fn NonMaskableInt(_: NonMaskableInt::Context) {} - | ^^^^^^^^^^^^^^ +6 | fn nmi(_: nmi::Context) {} + | ^^^ error: aborting due to previous error diff --git a/ui/single/exception-systick-used.rs b/ui/single/exception-systick-used.rs index d30da1bd..1155834f 100644 --- a/ui/single/exception-systick-used.rs +++ b/ui/single/exception-systick-used.rs @@ -2,8 +2,8 @@ #[rtfm::app(device = lm3s6965)] const APP: () = { - #[exception] - fn SysTick(_: SysTick::Context) {} + #[task(binds = SysTick)] + fn sys_tick(_: sys_tick::Context) {} #[task(schedule = [foo])] fn foo(_: foo::Context) {} diff --git a/ui/single/exception-systick-used.stderr b/ui/single/exception-systick-used.stderr index 47786c6c..e2ccbd3b 100644 --- a/ui/single/exception-systick-used.stderr +++ b/ui/single/exception-systick-used.stderr @@ -1,8 +1,8 @@ error: this exception can't be used because it's being used by the runtime --> $DIR/exception-systick-used.rs:6:8 | -6 | fn SysTick(_: SysTick::Context) {} - | ^^^^^^^ +6 | fn sys_tick(_: sys_tick::Context) {} + | ^^^^^^^^ error: aborting due to previous error diff --git a/ui/single/extern-interrupt-used.rs b/ui/single/extern-interrupt-used.rs index 25f34b36..59f38068 100644 --- a/ui/single/extern-interrupt-used.rs +++ b/ui/single/extern-interrupt-used.rs @@ -2,7 +2,7 @@ #[rtfm::app(device = lm3s6965)] const APP: () = { - #[interrupt(binds = UART0)] + #[task(binds = UART0)] fn a(_: a::Context) {} extern "C" { diff --git a/ui/single/extern-interrupt-used.stderr b/ui/single/extern-interrupt-used.stderr index 8707b1d2..2e084caf 100644 --- a/ui/single/extern-interrupt-used.stderr +++ b/ui/single/extern-interrupt-used.stderr @@ -1,8 +1,8 @@ error: `extern` interrupts can't be used as hardware tasks - --> $DIR/extern-interrupt-used.rs:5:25 + --> $DIR/extern-interrupt-used.rs:5:20 | -5 | #[interrupt(binds = UART0)] - | ^^^^^ +5 | #[task(binds = UART0)] + | ^^^^^ error: aborting due to previous error diff --git a/ui/single/locals-cfg.rs b/ui/single/locals-cfg.rs index bcce5ca9..8761f72e 100644 --- a/ui/single/locals-cfg.rs +++ b/ui/single/locals-cfg.rs @@ -20,16 +20,16 @@ const APP: () = { loop {} } - #[exception] - fn SVCall(_: SVCall::Context) { + #[task(binds = SVCall)] + fn svcall(_: svcall::Context) { #[cfg(never)] static mut FOO: u32 = 0; FOO; } - #[interrupt] - fn UART0(_: UART0::Context) { + #[task(binds = UART0)] + fn uart0(_: uart0::Context) { #[cfg(never)] static mut FOO: u32 = 0; diff --git a/ui/single/resources-cfg.rs b/ui/single/resources-cfg.rs index f8c36729..6f608fa4 100644 --- a/ui/single/resources-cfg.rs +++ b/ui/single/resources-cfg.rs @@ -41,16 +41,16 @@ const APP: () = { loop {} } - #[interrupt(resources = [O3, S1, S2, S3])] - fn UART0(c: UART0::Context) { + #[task(binds = UART0, resources = [O3, S1, S2, S3])] + fn uart0(c: uart0::Context) { c.resources.O3; c.resources.S1; c.resources.S2; c.resources.S3; } - #[interrupt(resources = [S2, O5])] - fn UART1(c: UART1::Context) { + #[task(binds = UART1, resources = [S2, O5])] + fn uart1(c: uart1::Context) { c.resources.S2; c.resources.O5; } diff --git a/ui/single/resources-cfg.stderr b/ui/single/resources-cfg.stderr index 88c34d20..55e7ee0e 100644 --- a/ui/single/resources-cfg.stderr +++ b/ui/single/resources-cfg.stderr @@ -70,7 +70,7 @@ error[E0609]: no field `S3` on type `idleResources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `O3` on type `UART0Resources<'_>` +error[E0609]: no field `O3` on type `uart0Resources<'_>` --> $DIR/resources-cfg.rs:46:21 | 46 | c.resources.O3; @@ -78,7 +78,7 @@ error[E0609]: no field `O3` on type `UART0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `S1` on type `UART0Resources<'_>` +error[E0609]: no field `S1` on type `uart0Resources<'_>` --> $DIR/resources-cfg.rs:47:21 | 47 | c.resources.S1; @@ -86,7 +86,7 @@ error[E0609]: no field `S1` on type `UART0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `S2` on type `UART0Resources<'_>` +error[E0609]: no field `S2` on type `uart0Resources<'_>` --> $DIR/resources-cfg.rs:48:21 | 48 | c.resources.S2; @@ -94,7 +94,7 @@ error[E0609]: no field `S2` on type `UART0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `S3` on type `UART0Resources<'_>` +error[E0609]: no field `S3` on type `uart0Resources<'_>` --> $DIR/resources-cfg.rs:49:21 | 49 | c.resources.S3; @@ -102,7 +102,7 @@ error[E0609]: no field `S3` on type `UART0Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `S2` on type `UART1Resources<'_>` +error[E0609]: no field `S2` on type `uart1Resources<'_>` --> $DIR/resources-cfg.rs:54:21 | 54 | c.resources.S2; @@ -110,7 +110,7 @@ error[E0609]: no field `S2` on type `UART1Resources<'_>` | = note: available fields are: `__marker__` -error[E0609]: no field `O5` on type `UART1Resources<'_>` +error[E0609]: no field `O5` on type `uart1Resources<'_>` --> $DIR/resources-cfg.rs:55:21 | 55 | c.resources.O5; diff --git a/ui/single/task-priority-too-high.rs b/ui/single/task-priority-too-high.rs index c7c9dc9b..24cb11e5 100644 --- a/ui/single/task-priority-too-high.rs +++ b/ui/single/task-priority-too-high.rs @@ -7,32 +7,32 @@ const APP: () = { #[init] fn init(_: init::Context) {} - #[interrupt(priority = 1)] - fn GPIOA(_: GPIOA::Context) {} + #[task(binds = GPIOA, priority = 1)] + fn gpioa(_: gpioa::Context) {} - #[interrupt(priority = 2)] - fn GPIOB(_: GPIOB::Context) {} + #[task(binds = GPIOB, priority = 2)] + fn gpiob(_: gpiob::Context) {} - #[interrupt(priority = 3)] - fn GPIOC(_: GPIOC::Context) {} + #[task(binds = GPIOC, priority = 3)] + fn gpioc(_: gpioc::Context) {} - #[interrupt(priority = 4)] - fn GPIOD(_: GPIOD::Context) {} + #[task(binds = GPIOD, priority = 4)] + fn gpiod(_: gpiod::Context) {} - #[interrupt(priority = 5)] - fn GPIOE(_: GPIOE::Context) {} + #[task(binds = GPIOE, priority = 5)] + fn gpioe(_: gpioe::Context) {} - #[interrupt(priority = 6)] - fn UART0(_: UART0::Context) {} + #[task(binds = UART0, priority = 6)] + fn uart0(_: uart0::Context) {} - #[interrupt(priority = 7)] - fn UART1(_: UART1::Context) {} + #[task(binds = UART1, priority = 7)] + fn uart1(_: uart1::Context) {} // OK, this is the maximum priority supported by the device - #[interrupt(priority = 8)] - fn SSI0(_: SSI0::Context) {} + #[task(binds = SSI0, priority = 8)] + fn ssi0(_: ssi0::Context) {} // this value is too high! - #[interrupt(priority = 9)] - fn I2C0(_: I2C0::Context) {} + #[task(binds = I2C0, priority = 9)] + fn i2c0(_: i2c0::Context) {} }; -- cgit v1.2.3 From 9195038c87703fc94b6e99f6de593886d51c2b19 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 10 Jul 2019 22:42:44 +0200 Subject: implement RFC #212 --- ci/expected/generics.run | 6 +-- ci/expected/lock.run | 4 +- ci/expected/resource.run | 4 +- ci/expected/static.run | 4 +- examples/cfg.rs | 15 +++--- examples/generics.rs | 19 ++++--- examples/late.rs | 16 +++--- examples/lock.rs | 19 ++++--- examples/not-send.rs | 13 +++-- examples/not-sync.rs | 13 +++-- examples/resource.rs | 27 +++++----- examples/shared-with-init.rs | 13 +++-- examples/static.rs | 14 ++--- examples/t-cfg.rs | 11 ++-- examples/t-late-not-send.rs | 16 +++--- examples/t-resource.rs | 70 ++++++++++++++----------- examples/types.rs | 13 +++-- heterogeneous/examples/x-init-2.rs | 16 +++--- heterogeneous/examples/x-init.rs | 12 ++--- homogeneous/examples/x-init-2.rs | 16 +++--- homogeneous/examples/x-init.rs | 12 ++--- macros/src/codegen/resources.rs | 79 ++++++++++++++-------------- macros/src/codegen/resources_struct.rs | 8 ++- ui/single/resources-cfg.rs | 96 ++++++++++++++++++++-------------- ui/single/resources-cfg.stderr | 90 +++++++++++++++---------------- 25 files changed, 332 insertions(+), 274 deletions(-) (limited to 'examples/shared-with-init.rs') diff --git a/ci/expected/generics.run b/ci/expected/generics.run index 7fa97758..fb31731e 100644 --- a/ci/expected/generics.run +++ b/ci/expected/generics.run @@ -1,6 +1,6 @@ UART1(STATE = 0) -SHARED: 0 -> 1 +shared: 0 -> 1 UART0(STATE = 0) -SHARED: 1 -> 2 +shared: 1 -> 2 UART1(STATE = 1) -SHARED: 2 -> 4 +shared: 2 -> 4 diff --git a/ci/expected/lock.run b/ci/expected/lock.run index 156ac222..a987b372 100644 --- a/ci/expected/lock.run +++ b/ci/expected/lock.run @@ -1,5 +1,5 @@ A -B - SHARED = 1 +B - shared = 1 C -D - SHARED = 2 +D - shared = 2 E diff --git a/ci/expected/resource.run b/ci/expected/resource.run index 9c70856a..a587a942 100644 --- a/ci/expected/resource.run +++ b/ci/expected/resource.run @@ -1,2 +1,2 @@ -UART0: SHARED = 1 -UART1: SHARED = 2 +UART0: shared = 1 +UART1: shared = 2 diff --git a/ci/expected/static.run b/ci/expected/static.run index 2c295c99..1d4eed00 100644 --- a/ci/expected/static.run +++ b/ci/expected/static.run @@ -1,2 +1,2 @@ -UART1(KEY = 0xdeadbeef) -UART0(KEY = 0xdeadbeef) +UART1(key = 0xdeadbeef) +UART0(key = 0xdeadbeef) diff --git a/examples/cfg.rs b/examples/cfg.rs index b1f65cfd..fb812cb0 100644 --- a/examples/cfg.rs +++ b/examples/cfg.rs @@ -11,25 +11,28 @@ use panic_semihosting as _; #[rtfm::app(device = lm3s6965)] const APP: () = { - #[cfg(debug_assertions)] // <- `true` when using the `dev` profile - static mut COUNT: u32 = 0; + struct Resources { + #[cfg(debug_assertions)] // <- `true` when using the `dev` profile + #[init(0)] + count: u32, + } #[init] fn init(_: init::Context) { // .. } - #[task(priority = 3, resources = [COUNT], spawn = [log])] + #[task(priority = 3, resources = [count], spawn = [log])] fn foo(_c: foo::Context) { #[cfg(debug_assertions)] { - *_c.resources.COUNT += 1; + *_c.resources.count += 1; - _c.spawn.log(*_c.resources.COUNT).ok(); + _c.spawn.log(*_c.resources.count).ok(); } // this wouldn't compile in `release` mode - // *resources.COUNT += 1; + // *resources.count += 1; // .. } diff --git a/examples/generics.rs b/examples/generics.rs index 562470d4..f0632d9a 100644 --- a/examples/generics.rs +++ b/examples/generics.rs @@ -12,7 +12,10 @@ use rtfm::{Exclusive, Mutex}; #[rtfm::app(device = lm3s6965)] const APP: () = { - static mut SHARED: u32 = 0; + struct Resources { + #[init(0)] + shared: u32, + } #[init] fn init(_: init::Context) { @@ -20,29 +23,29 @@ const APP: () = { rtfm::pend(Interrupt::UART1); } - #[task(binds = UART0, resources = [SHARED])] + #[task(binds = UART0, resources = [shared])] fn uart0(c: uart0::Context) { static mut STATE: u32 = 0; hprintln!("UART0(STATE = {})", *STATE).unwrap(); - advance(STATE, c.resources.SHARED); + advance(STATE, c.resources.shared); rtfm::pend(Interrupt::UART1); debug::exit(debug::EXIT_SUCCESS); } - #[task(binds = UART1, priority = 2, resources = [SHARED])] + #[task(binds = UART1, priority = 2, resources = [shared])] fn uart1(c: uart1::Context) { static mut STATE: u32 = 0; hprintln!("UART1(STATE = {})", *STATE).unwrap(); - // just to show that `SHARED` can be accessed directly - *c.resources.SHARED += 0; + // just to show that `shared` can be accessed directly + *c.resources.shared += 0; - advance(STATE, Exclusive(c.resources.SHARED)); + advance(STATE, Exclusive(c.resources.shared)); } }; @@ -55,5 +58,5 @@ fn advance(state: &mut u32, mut shared: impl Mutex) { (old, *shared) }); - hprintln!("SHARED: {} -> {}", old, new).unwrap(); + hprintln!("shared: {} -> {}", old, new).unwrap(); } diff --git a/examples/late.rs b/examples/late.rs index 19807ff7..536d71aa 100644 --- a/examples/late.rs +++ b/examples/late.rs @@ -16,9 +16,9 @@ use panic_semihosting as _; #[rtfm::app(device = lm3s6965)] const APP: () = { // Late resources - extern "C" { - static mut P: Producer<'static, u32, U4>; - static mut C: Consumer<'static, u32, U4>; + struct Resources { + p: Producer<'static, u32, U4>, + c: Consumer<'static, u32, U4>, } #[init] @@ -31,13 +31,13 @@ const APP: () = { let (p, c) = Q.as_mut().unwrap().split(); // Initialization of late resources - init::LateResources { P: p, C: c } + init::LateResources { p, c } } - #[idle(resources = [C])] + #[idle(resources = [c])] fn idle(c: idle::Context) -> ! { loop { - if let Some(byte) = c.resources.C.dequeue() { + if let Some(byte) = c.resources.c.dequeue() { hprintln!("received message: {}", byte).unwrap(); debug::exit(debug::EXIT_SUCCESS); @@ -47,8 +47,8 @@ const APP: () = { } } - #[task(binds = UART0, resources = [P])] + #[task(binds = UART0, resources = [p])] fn uart0(c: uart0::Context) { - c.resources.P.enqueue(42).unwrap(); + c.resources.p.enqueue(42).unwrap(); } }; diff --git a/examples/lock.rs b/examples/lock.rs index 17b6a58b..f33a60a4 100644 --- a/examples/lock.rs +++ b/examples/lock.rs @@ -11,7 +11,10 @@ use panic_semihosting as _; #[rtfm::app(device = lm3s6965)] const APP: () = { - static mut SHARED: u32 = 0; + struct Resources { + #[init(0)] + shared: u32, + } #[init] fn init(_: init::Context) { @@ -19,21 +22,21 @@ const APP: () = { } // when omitted priority is assumed to be `1` - #[task(binds = GPIOA, resources = [SHARED])] + #[task(binds = GPIOA, resources = [shared])] fn gpioa(mut c: gpioa::Context) { hprintln!("A").unwrap(); // the lower priority task requires a critical section to access the data - c.resources.SHARED.lock(|shared| { + 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 rtfm::pend(Interrupt::GPIOB); - hprintln!("B - SHARED = {}", *shared).unwrap(); + hprintln!("B - shared = {}", *shared).unwrap(); - // GPIOC does not contend for `SHARED` so it's allowed to run now + // GPIOC does not contend for `shared` so it's allowed to run now rtfm::pend(Interrupt::GPIOC); }); @@ -44,12 +47,12 @@ const APP: () = { debug::exit(debug::EXIT_SUCCESS); } - #[task(binds = GPIOB, priority = 2, resources = [SHARED])] + #[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; + *c.resources.shared += 1; - hprintln!("D - SHARED = {}", *c.resources.SHARED).unwrap(); + hprintln!("D - shared = {}", *c.resources.shared).unwrap(); } #[task(binds = GPIOC, priority = 3)] diff --git a/examples/not-send.rs b/examples/not-send.rs index f240e511..d27cc82f 100644 --- a/examples/not-send.rs +++ b/examples/not-send.rs @@ -17,7 +17,10 @@ pub struct NotSend { #[app(device = lm3s6965)] const APP: () = { - static mut SHARED: Option = None; + struct Resources { + #[init(None)] + shared: Option, + } #[init(spawn = [baz, quux])] fn init(c: init::Context) { @@ -36,16 +39,16 @@ const APP: () = { // scenario 1 } - #[task(priority = 2, resources = [SHARED])] + #[task(priority = 2, resources = [shared])] fn baz(c: baz::Context) { // scenario 2: resource shared between tasks that run at the same priority - *c.resources.SHARED = Some(NotSend { _0: PhantomData }); + *c.resources.shared = Some(NotSend { _0: PhantomData }); } - #[task(priority = 2, resources = [SHARED])] + #[task(priority = 2, resources = [shared])] fn quux(c: quux::Context) { // scenario 2 - let _not_send = c.resources.SHARED.take().unwrap(); + let _not_send = c.resources.shared.take().unwrap(); debug::exit(debug::EXIT_SUCCESS); } diff --git a/examples/not-sync.rs b/examples/not-sync.rs index 6b499111..f0f6075e 100644 --- a/examples/not-sync.rs +++ b/examples/not-sync.rs @@ -16,21 +16,24 @@ pub struct NotSync { #[rtfm::app(device = lm3s6965)] const APP: () = { - static SHARED: NotSync = NotSync { _0: PhantomData }; + struct Resources { + #[init(NotSync { _0: PhantomData })] + shared: NotSync, + } #[init] fn init(_: init::Context) { debug::exit(debug::EXIT_SUCCESS); } - #[task(resources = [SHARED])] + #[task(resources = [shared])] fn foo(c: foo::Context) { - let _: &NotSync = c.resources.SHARED; + let _: &NotSync = c.resources.shared; } - #[task(resources = [SHARED])] + #[task(resources = [shared])] fn bar(c: bar::Context) { - let _: &NotSync = c.resources.SHARED; + let _: &NotSync = c.resources.shared; } extern "C" { diff --git a/examples/resource.rs b/examples/resource.rs index 661f8c35..2506a2cb 100644 --- a/examples/resource.rs +++ b/examples/resource.rs @@ -11,8 +11,11 @@ use panic_semihosting as _; #[rtfm::app(device = lm3s6965)] const APP: () = { - // A resource - static mut SHARED: u32 = 0; + struct Resources { + // A resource + #[init(0)] + shared: u32, + } #[init] fn init(_: init::Context) { @@ -24,25 +27,25 @@ const APP: () = { fn idle(_: idle::Context) -> ! { debug::exit(debug::EXIT_SUCCESS); - // error: `SHARED` can't be accessed from this context - // SHARED += 1; + // error: `shared` can't be accessed from this context + // shared += 1; loop {} } - // `SHARED` can be access from this context - #[task(binds = UART0, resources = [SHARED])] + // `shared` can be access from this context + #[task(binds = UART0, resources = [shared])] fn uart0(c: uart0::Context) { - *c.resources.SHARED += 1; + *c.resources.shared += 1; - hprintln!("UART0: SHARED = {}", c.resources.SHARED).unwrap(); + hprintln!("UART0: shared = {}", c.resources.shared).unwrap(); } - // `SHARED` can be access from this context - #[task(binds = UART1, resources = [SHARED])] + // `shared` can be access from this context + #[task(binds = UART1, resources = [shared])] fn uart1(c: uart1::Context) { - *c.resources.SHARED += 1; + *c.resources.shared += 1; - hprintln!("UART1: SHARED = {}", c.resources.SHARED).unwrap(); + hprintln!("UART1: shared = {}", c.resources.shared).unwrap(); } }; diff --git a/examples/shared-with-init.rs b/examples/shared-with-init.rs index ed73c8ba..14fa54b7 100644 --- a/examples/shared-with-init.rs +++ b/examples/shared-with-init.rs @@ -14,20 +14,23 @@ pub struct MustBeSend; #[app(device = lm3s6965)] const APP: () = { - static mut SHARED: Option = None; + struct Resources { + #[init(None)] + shared: Option, + } - #[init(resources = [SHARED])] + #[init(resources = [shared])] fn init(c: init::Context) { // this `message` will be sent to task `UART0` let message = MustBeSend; - *c.resources.SHARED = Some(message); + *c.resources.shared = Some(message); rtfm::pend(Interrupt::UART0); } - #[task(binds = UART0, resources = [SHARED])] + #[task(binds = UART0, resources = [shared])] fn uart0(c: uart0::Context) { - if let Some(message) = c.resources.SHARED.take() { + if let Some(message) = c.resources.shared.take() { // `message` has been received drop(message); diff --git a/examples/static.rs b/examples/static.rs index 5eb7b197..4af7ee67 100644 --- a/examples/static.rs +++ b/examples/static.rs @@ -11,8 +11,8 @@ use panic_semihosting as _; #[rtfm::app(device = lm3s6965)] const APP: () = { - extern "C" { - static KEY: u32; + struct Resources { + key: u32, } #[init] @@ -20,18 +20,18 @@ const APP: () = { rtfm::pend(Interrupt::UART0); rtfm::pend(Interrupt::UART1); - init::LateResources { KEY: 0xdeadbeef } + init::LateResources { key: 0xdeadbeef } } - #[task(binds = UART0, resources = [KEY])] + #[task(binds = UART0, resources = [&key])] fn uart0(c: uart0::Context) { - hprintln!("UART0(KEY = {:#x})", c.resources.KEY).unwrap(); + hprintln!("UART0(key = {:#x})", c.resources.key).unwrap(); debug::exit(debug::EXIT_SUCCESS); } - #[task(binds = UART1, priority = 2, resources = [KEY])] + #[task(binds = UART1, priority = 2, resources = [&key])] fn uart1(c: uart1::Context) { - hprintln!("UART1(KEY = {:#x})", c.resources.KEY).unwrap(); + hprintln!("UART1(key = {:#x})", c.resources.key).unwrap(); } }; diff --git a/examples/t-cfg.rs b/examples/t-cfg.rs index 158eef55..e61ec795 100644 --- a/examples/t-cfg.rs +++ b/examples/t-cfg.rs @@ -7,8 +7,11 @@ use panic_halt as _; #[rtfm::app(device = lm3s6965, monotonic = rtfm::cyccnt::CYCCNT)] const APP: () = { - #[cfg(never)] - static mut FOO: u32 = 0; + struct Resources { + #[cfg(never)] + #[init(0)] + foo: u32, + } #[init] fn init(_: init::Context) { @@ -24,13 +27,13 @@ const APP: () = { loop {} } - #[task(resources = [FOO], schedule = [quux], spawn = [quux])] + #[task(resources = [foo], schedule = [quux], spawn = [quux])] fn foo(_: foo::Context) { #[cfg(never)] static mut BAR: u32 = 0; } - #[task(priority = 3, resources = [FOO], schedule = [quux], spawn = [quux])] + #[task(priority = 3, resources = [foo], schedule = [quux], spawn = [quux])] fn bar(_: bar::Context) { #[cfg(never)] static mut BAR: u32 = 0; diff --git a/examples/t-late-not-send.rs b/examples/t-late-not-send.rs index 55a053df..4fd3504e 100644 --- a/examples/t-late-not-send.rs +++ b/examples/t-late-not-send.rs @@ -13,23 +13,23 @@ pub struct NotSend { #[rtfm::app(device = lm3s6965)] const APP: () = { - extern "C" { - static mut X: NotSend; + struct Resources { + x: NotSend, + #[init(None)] + y: Option, } - static mut Y: Option = None; - - #[init(resources = [Y])] + #[init(resources = [y])] fn init(c: init::Context) -> init::LateResources { // equivalent to late resource initialization - *c.resources.Y = Some(NotSend { _0: PhantomData }); + *c.resources.y = Some(NotSend { _0: PhantomData }); init::LateResources { - X: NotSend { _0: PhantomData }, + x: NotSend { _0: PhantomData }, } } - #[idle(resources = [X, Y])] + #[idle(resources = [x, y])] fn idle(_: idle::Context) -> ! { loop {} } diff --git a/examples/t-resource.rs b/examples/t-resource.rs index adcc04b3..303340ed 100644 --- a/examples/t-resource.rs +++ b/examples/t-resource.rs @@ -9,69 +9,79 @@ use panic_halt as _; #[rtfm::app(device = lm3s6965)] const APP: () = { - static mut O1: u32 = 0; // init - static mut O2: u32 = 0; // idle - static mut O3: u32 = 0; // EXTI0 - static O4: u32 = 0; // idle - static O5: u32 = 0; // EXTI1 - static O6: u32 = 0; // init - - static mut S1: u32 = 0; // idle & EXTI0 - static mut S2: u32 = 0; // EXTI0 & EXTI1 - static S3: u32 = 0; - - #[init(resources = [O1, O4, O5, O6, S3])] + struct Resources { + #[init(0)] + o1: u32, // init + #[init(0)] + o2: u32, // idle + #[init(0)] + o3: u32, // EXTI0 + #[init(0)] + o4: u32, // idle + #[init(0)] + o5: u32, // EXTI1 + #[init(0)] + o6: u32, // init + #[init(0)] + s1: u32, // idle & uart0 + #[init(0)] + s2: u32, // uart0 & uart1 + #[init(0)] + s3: u32, // idle & uart0 + } + + #[init(resources = [o1, o4, o5, o6, s3])] fn init(c: init::Context) { // owned by `init` == `&'static mut` - let _: &'static mut u32 = c.resources.O1; + let _: &'static mut u32 = c.resources.o1; // owned by `init` == `&'static` if read-only - let _: &'static u32 = c.resources.O6; + let _: &'static u32 = c.resources.o6; // `init` has exclusive access to all resources - let _: &mut u32 = c.resources.O4; - let _: &mut u32 = c.resources.O5; - let _: &mut u32 = c.resources.S3; + let _: &mut u32 = c.resources.o4; + let _: &mut u32 = c.resources.o5; + let _: &mut u32 = c.resources.s3; } - #[idle(resources = [O2, O4, S1, S3])] + #[idle(resources = [o2, &o4, s1, &s3])] fn idle(mut c: idle::Context) -> ! { // owned by `idle` == `&'static mut` - let _: &'static mut u32 = c.resources.O2; + let _: &'static mut u32 = c.resources.o2; // owned by `idle` == `&'static` if read-only - let _: &'static u32 = c.resources.O4; + let _: &'static u32 = c.resources.o4; // shared with `idle` == `Mutex` - c.resources.S1.lock(|_| {}); + c.resources.s1.lock(|_| {}); // `&` if read-only - let _: &u32 = c.resources.S3; + let _: &u32 = c.resources.s3; loop {} } - #[task(binds = UART0, resources = [O3, S1, S2, S3])] + #[task(binds = UART0, resources = [o3, s1, s2, &s3])] fn uart0(c: uart0::Context) { // owned by interrupt == `&mut` - let _: &mut u32 = c.resources.O3; + let _: &mut u32 = c.resources.o3; // no `Mutex` proxy when access from highest priority task - let _: &mut u32 = c.resources.S1; + let _: &mut u32 = c.resources.s1; // no `Mutex` proxy when co-owned by cooperative (same priority) tasks - let _: &mut u32 = c.resources.S2; + let _: &mut u32 = c.resources.s2; // `&` if read-only - let _: &u32 = c.resources.S3; + let _: &u32 = c.resources.s3; } - #[task(binds = UART1, resources = [S2, O5])] + #[task(binds = UART1, resources = [s2, &o5])] fn uart1(c: uart1::Context) { // owned by interrupt == `&` if read-only - let _: &u32 = c.resources.O5; + let _: &u32 = c.resources.o5; // no `Mutex` proxy when co-owned by cooperative (same priority) tasks - let _: &mut u32 = c.resources.S2; + let _: &mut u32 = c.resources.s2; } }; diff --git a/examples/types.rs b/examples/types.rs index 3e9c7ea5..0c8097f3 100644 --- a/examples/types.rs +++ b/examples/types.rs @@ -11,7 +11,10 @@ use rtfm::cyccnt::Instant; #[rtfm::app(device = lm3s6965, peripherals = true, monotonic = rtfm::cyccnt::CYCCNT)] const APP: () = { - static mut SHARED: u32 = 0; + struct Resources { + #[init(0)] + shared: u32, + } #[init(schedule = [foo], spawn = [foo])] fn init(c: init::Context) { @@ -31,18 +34,18 @@ const APP: () = { let _: svcall::Spawn = c.spawn; } - #[task(binds = UART0, resources = [SHARED], schedule = [foo], spawn = [foo])] + #[task(binds = UART0, resources = [shared], schedule = [foo], spawn = [foo])] fn uart0(c: uart0::Context) { let _: Instant = c.start; - let _: resources::SHARED = c.resources.SHARED; + let _: resources::shared = c.resources.shared; let _: uart0::Schedule = c.schedule; let _: uart0::Spawn = c.spawn; } - #[task(priority = 2, resources = [SHARED], schedule = [foo], spawn = [foo])] + #[task(priority = 2, resources = [shared], schedule = [foo], spawn = [foo])] fn foo(c: foo::Context) { let _: Instant = c.scheduled; - let _: &mut u32 = c.resources.SHARED; + let _: &mut u32 = c.resources.shared; let _: foo::Resources = c.resources; let _: foo::Schedule = c.schedule; let _: foo::Spawn = c.spawn; diff --git a/heterogeneous/examples/x-init-2.rs b/heterogeneous/examples/x-init-2.rs index b9c39197..033753c2 100644 --- a/heterogeneous/examples/x-init-2.rs +++ b/heterogeneous/examples/x-init-2.rs @@ -9,30 +9,30 @@ use panic_halt as _; #[rtfm::app(cores = 2, device = heterogeneous)] const APP: () = { - extern "C" { + struct Resources { // owned by core #1 but initialized by core #0 - static mut X: u32; + x: u32, // owned by core #0 but initialized by core #1 - static mut Y: u32; + y: u32, } - #[init(core = 0, late = [X])] + #[init(core = 0, late = [x])] fn a(_: a::Context) -> a::LateResources { - a::LateResources { X: 0 } + a::LateResources { x: 0 } } - #[idle(core = 0, resources = [Y])] + #[idle(core = 0, resources = [y])] fn b(_: b::Context) -> ! { loop {} } #[init(core = 1)] fn c(_: c::Context) -> c::LateResources { - c::LateResources { Y: 0 } + c::LateResources { y: 0 } } - #[idle(core = 1, resources = [X])] + #[idle(core = 1, resources = [x])] fn d(_: d::Context) -> ! { loop {} } diff --git a/heterogeneous/examples/x-init.rs b/heterogeneous/examples/x-init.rs index 53e73805..41837134 100644 --- a/heterogeneous/examples/x-init.rs +++ b/heterogeneous/examples/x-init.rs @@ -9,18 +9,18 @@ use panic_halt as _; #[rtfm::app(cores = 2, device = heterogeneous)] const APP: () = { - extern "C" { - static mut X: u32; - static mut Y: u32; + struct Resources { + x: u32, + y: u32, } - #[init(core = 0, late = [X])] + #[init(core = 0, late = [x])] fn a(_: a::Context) -> a::LateResources { - a::LateResources { X: 0 } + a::LateResources { x: 0 } } #[init(core = 1)] fn b(_: b::Context) -> b::LateResources { - b::LateResources { Y: 0 } + b::LateResources { y: 0 } } }; diff --git a/homogeneous/examples/x-init-2.rs b/homogeneous/examples/x-init-2.rs index f51e2f6e..de35cf6f 100644 --- a/homogeneous/examples/x-init-2.rs +++ b/homogeneous/examples/x-init-2.rs @@ -9,30 +9,30 @@ use panic_halt as _; #[rtfm::app(cores = 2, device = homogeneous)] const APP: () = { - extern "C" { + struct Resources { // owned by core #1 but initialized by core #0 - static mut X: u32; + x: u32, // owned by core #0 but initialized by core #1 - static mut Y: u32; + y: u32, } - #[init(core = 0, late = [X])] + #[init(core = 0, late = [x])] fn a(_: a::Context) -> a::LateResources { - a::LateResources { X: 0 } + a::LateResources { x: 0 } } - #[idle(core = 0, resources = [Y])] + #[idle(core = 0, resources = [y])] fn b(_: b::Context) -> ! { loop {} } #[init(core = 1)] fn c(_: c::Context) -> c::LateResources { - c::LateResources { Y: 0 } + c::LateResources { y: 0 } } - #[idle(core = 1, resources = [X])] + #[idle(core = 1, resources = [x])] fn d(_: d::Context) -> ! { loop {} } diff --git a/homogeneous/examples/x-init.rs b/homogeneous/examples/x-init.rs index 5089e385..c359901c 100644 --- a/homogeneous/examples/x-init.rs +++ b/homogeneous/examples/x-init.rs @@ -9,18 +9,18 @@ use panic_halt as _; #[rtfm::app(cores = 2, device = homogeneous)] const APP: () = { - extern "C" { - static mut X: u32; - static mut Y: u32; + struct Resources { + x: u32, + y: u32, } - #[init(core = 0, late = [X])] + #[init(core = 0, late = [x])] fn a(_: a::Context) -> a::LateResources { - a::LateResources { X: 0 } + a::LateResources { x: 0 } } #[init(core = 1)] fn b(_: b::Context) -> b::LateResources { - b::LateResources { Y: 0 } + b::LateResources { y: 0 } } }; diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs index 1161a7a5..bec46020 100644 --- a/macros/src/codegen/resources.rs +++ b/macros/src/codegen/resources.rs @@ -57,6 +57,7 @@ pub fn codegen( let attrs = &res.attrs; const_app.push(quote!( + #[allow(non_upper_case_globals)] #(#attrs)* #(#cfgs)* #loc_attr @@ -65,50 +66,48 @@ pub fn codegen( )); } - // generate a resource proxy if needed - if res.mutability.is_some() { - if let Some(Ownership::Shared { ceiling }) = analysis.ownerships.get(name) { - let cfg_core = util::cfg_core(loc.core().expect("UNREACHABLE"), app.args.cores); + if let Some(Ownership::Contended { ceiling }) = analysis.ownerships.get(name) { + let cfg_core = util::cfg_core(loc.core().expect("UNREACHABLE"), app.args.cores); - mod_resources.push(quote!( - #(#cfgs)* - #cfg_core - pub struct #name<'a> { - priority: &'a Priority, + mod_resources.push(quote!( + #[allow(non_camel_case_types)] + #(#cfgs)* + #cfg_core + pub struct #name<'a> { + priority: &'a Priority, + } + + #(#cfgs)* + #cfg_core + impl<'a> #name<'a> { + #[inline(always)] + pub unsafe fn new(priority: &'a Priority) -> Self { + #name { priority } } - #(#cfgs)* - #cfg_core - impl<'a> #name<'a> { - #[inline(always)] - pub unsafe fn new(priority: &'a Priority) -> Self { - #name { priority } - } - - #[inline(always)] - pub unsafe fn priority(&self) -> &Priority { - self.priority - } + #[inline(always)] + pub unsafe fn priority(&self) -> &Priority { + self.priority } - )); - - let ptr = if expr.is_none() { - quote!(#name.as_mut_ptr()) - } else { - quote!(&mut #name) - }; - - const_app.push(util::impl_mutex( - extra, - cfgs, - cfg_core.as_ref(), - true, - name, - quote!(#ty), - *ceiling, - ptr, - )); - } + } + )); + + let ptr = if expr.is_none() { + quote!(#name.as_mut_ptr()) + } else { + quote!(&mut #name) + }; + + const_app.push(util::impl_mutex( + extra, + cfgs, + cfg_core.as_ref(), + true, + name, + quote!(#ty), + *ceiling, + ptr, + )); } } diff --git a/macros/src/codegen/resources_struct.rs b/macros/src/codegen/resources_struct.rs index 0248f199..07a60616 100644 --- a/macros/src/codegen/resources_struct.rs +++ b/macros/src/codegen/resources_struct.rs @@ -24,13 +24,17 @@ pub fn codegen( let mut values = vec![]; let mut has_cfgs = false; - for name in resources { + for (name, access) in resources { let (res, expr) = app.resource(name).expect("UNREACHABLE"); let cfgs = &res.cfgs; has_cfgs |= !cfgs.is_empty(); - let mut_ = res.mutability; + let mut_ = if access.is_exclusive() { + Some(quote!(mut)) + } else { + None + }; let ty = &res.ty; if ctxt.is_init() { diff --git a/ui/single/resources-cfg.rs b/ui/single/resources-cfg.rs index 6f608fa4..906b3e25 100644 --- a/ui/single/resources-cfg.rs +++ b/ui/single/resources-cfg.rs @@ -2,56 +2,74 @@ #[rtfm::app(device = lm3s6965)] const APP: () = { - #[cfg(never)] - static mut O1: u32 = 0; // init - #[cfg(never)] - static mut O2: u32 = 0; // idle - #[cfg(never)] - static mut O3: u32 = 0; // EXTI0 - #[cfg(never)] - static O4: u32 = 0; // idle - #[cfg(never)] - static O5: u32 = 0; // EXTI1 - #[cfg(never)] - static O6: u32 = 0; // init - - #[cfg(never)] - static mut S1: u32 = 0; // idle & EXTI0 - #[cfg(never)] - static mut S2: u32 = 0; // EXTI0 & EXTI1 - #[cfg(never)] - static S3: u32 = 0; - - #[init(resources = [O1, O4, O5, O6, S3])] + struct Resources { + #[cfg(never)] + #[init(0)] + o1: u32, // init + + #[cfg(never)] + #[init(0)] + o2: u32, // idle + + #[cfg(never)] + #[init(0)] + o3: u32, // EXTI0 + + #[cfg(never)] + #[init(0)] + o4: u32, // idle + + #[cfg(never)] + #[init(0)] + o5: u32, // EXTI1 + + #[cfg(never)] + #[init(0)] + o6: u32, // init + + #[cfg(never)] + #[init(0)] + s1: u32, // idle & EXTI0 + + #[cfg(never)] + #[init(0)] + s2: u32, // EXTI0 & EXTI1 + + #[cfg(never)] + #[init(0)] + s3: u32, + } + + #[init(resources = [o1, o4, o5, o6, s3])] fn init(c: init::Context) { - c.resources.O1; - c.resources.O4; - c.resources.O5; - c.resources.O6; - c.resources.S3; + c.resources.o1; + c.resources.o4; + c.resources.o5; + c.resources.o6; + c.resources.s3; } - #[idle(resources = [O2, O4, S1, S3])] + #[idle(resources = [o2, &o4, s1, &s3])] fn idle(c: idle::Context) -> ! { - c.resources.O2; - c.resources.O4; - c.resources.S1; - c.resources.S3; + c.resources.o2; + c.resources.o4; + c.resources.s1; + c.resources.s3; loop {} } - #[task(binds = UART0, resources = [O3, S1, S2, S3])] + #[task(binds = UART0, resources = [o3, s1, s2, &s3])] fn uart0(c: uart0::Context) { - c.resources.O3; - c.resources.S1; - c.resources.S2; - c.resources.S3; + c.resources.o3; + c.resources.s1; + c.resources.s2; + c.resources.s3; } - #[task(binds = UART1, resources = [S2, O5])] + #[task(binds = UART1, resources = [s2, &o5])] fn uart1(c: uart1::Context) { - c.resources.S2; - c.resources.O5; + c.resources.s2; + c.resources.o5; } }; diff --git a/ui/single/resources-cfg.stderr b/ui/single/resources-cfg.stderr index 55e7ee0e..a745e6e2 100644 --- a/ui/single/resources-cfg.stderr +++ b/ui/single/resources-cfg.stderr @@ -1,119 +1,119 @@ -error[E0609]: no field `O1` on type `initResources<'_>` - --> $DIR/resources-cfg.rs:27:21 +error[E0609]: no field `o1` on type `initResources<'_>` + --> $DIR/resources-cfg.rs:45:21 | -27 | c.resources.O1; +45 | c.resources.o1; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `O4` on type `initResources<'_>` - --> $DIR/resources-cfg.rs:28:21 +error[E0609]: no field `o4` on type `initResources<'_>` + --> $DIR/resources-cfg.rs:46:21 | -28 | c.resources.O4; +46 | c.resources.o4; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `O5` on type `initResources<'_>` - --> $DIR/resources-cfg.rs:29:21 +error[E0609]: no field `o5` on type `initResources<'_>` + --> $DIR/resources-cfg.rs:47:21 | -29 | c.resources.O5; +47 | c.resources.o5; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `O6` on type `initResources<'_>` - --> $DIR/resources-cfg.rs:30:21 +error[E0609]: no field `o6` on type `initResources<'_>` + --> $DIR/resources-cfg.rs:48:21 | -30 | c.resources.O6; +48 | c.resources.o6; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `S3` on type `initResources<'_>` - --> $DIR/resources-cfg.rs:31:21 +error[E0609]: no field `s3` on type `initResources<'_>` + --> $DIR/resources-cfg.rs:49:21 | -31 | c.resources.S3; +49 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `O2` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:36:21 +error[E0609]: no field `o2` on type `idleResources<'_>` + --> $DIR/resources-cfg.rs:54:21 | -36 | c.resources.O2; +54 | c.resources.o2; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `O4` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:37:21 +error[E0609]: no field `o4` on type `idleResources<'_>` + --> $DIR/resources-cfg.rs:55:21 | -37 | c.resources.O4; +55 | c.resources.o4; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `S1` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:38:21 +error[E0609]: no field `s1` on type `idleResources<'_>` + --> $DIR/resources-cfg.rs:56:21 | -38 | c.resources.S1; +56 | c.resources.s1; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `S3` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:39:21 +error[E0609]: no field `s3` on type `idleResources<'_>` + --> $DIR/resources-cfg.rs:57:21 | -39 | c.resources.S3; +57 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `O3` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:46:21 +error[E0609]: no field `o3` on type `uart0Resources<'_>` + --> $DIR/resources-cfg.rs:64:21 | -46 | c.resources.O3; +64 | c.resources.o3; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `S1` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:47:21 +error[E0609]: no field `s1` on type `uart0Resources<'_>` + --> $DIR/resources-cfg.rs:65:21 | -47 | c.resources.S1; +65 | c.resources.s1; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `S2` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:48:21 +error[E0609]: no field `s2` on type `uart0Resources<'_>` + --> $DIR/resources-cfg.rs:66:21 | -48 | c.resources.S2; +66 | c.resources.s2; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `S3` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:49:21 +error[E0609]: no field `s3` on type `uart0Resources<'_>` + --> $DIR/resources-cfg.rs:67:21 | -49 | c.resources.S3; +67 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `S2` on type `uart1Resources<'_>` - --> $DIR/resources-cfg.rs:54:21 +error[E0609]: no field `s2` on type `uart1Resources<'_>` + --> $DIR/resources-cfg.rs:72:21 | -54 | c.resources.S2; +72 | c.resources.s2; | ^^ unknown field | = note: available fields are: `__marker__` -error[E0609]: no field `O5` on type `uart1Resources<'_>` - --> $DIR/resources-cfg.rs:55:21 +error[E0609]: no field `o5` on type `uart1Resources<'_>` + --> $DIR/resources-cfg.rs:73:21 | -55 | c.resources.O5; +73 | c.resources.o5; | ^^ unknown field | = note: available fields are: `__marker__` -- cgit v1.2.3