aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/local-cfg.rs127
-rw-r--r--examples/static.rs15
-rw-r--r--examples/task-local-minimal.rs (renamed from examples/local_minimal.rs)13
-rw-r--r--examples/task-local.rs (renamed from examples/local.rs)17
-rw-r--r--macros/Cargo.toml8
-rw-r--r--macros/src/custom_local.rs165
-rw-r--r--macros/src/lib.rs15
-rw-r--r--ui/single/local-cfg-task-local-err.rs (renamed from examples/local-cfg-task-local.rs)15
-rw-r--r--ui/single/local-cfg-task-local-err.stderr37
-rw-r--r--ui/single/local-err.rs (renamed from examples/local_err.rs)11
-rw-r--r--ui/single/local-err.stderr60
11 files changed, 141 insertions, 342 deletions
diff --git a/examples/local-cfg.rs b/examples/local-cfg.rs
deleted file mode 100644
index b9165508..00000000
--- a/examples/local-cfg.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-//! examples/local.rs
-
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![no_main]
-#![no_std]
-
-#[cfg(
- any(
- feature = "feature_s",
- feature = "feature_e1",
- feature = "feature_e2",
- feature = "feature_l1",
- feature = "feature_l2"
- )
- )
-]
-use cortex_m_semihosting::hprintln;
-use cortex_m_semihosting::debug;
-use lm3s6965::Interrupt;
-use panic_semihosting as _;
-
-#[rtfm::app(device = lm3s6965)]
-const APP: () = {
- struct Resources {
- // An early resource
- #[cfg(feature = "feature_s")]
- #[init(0)]
- shared: u32,
-
- // A local (move), early resource
- #[cfg(feature = "feature_l1")]
- #[task_local]
- #[init(1)]
- l1: u32,
-
- // An exclusive, early resource
- #[cfg(feature = "feature_e1")]
- #[lock_free]
- #[init(1)]
- e1: u32,
-
- // A local (move), late resource
- #[task_local]
- #[cfg(feature = "feature_l2")]
- l2: u32,
-
- // An exclusive, late resource
- #[cfg(feature = "feature_e2")]
- #[lock_free]
- e2: u32,
- }
-
- #[init]
- fn init(_: init::Context) -> init::LateResources {
- rtfm::pend(Interrupt::UART0);
- rtfm::pend(Interrupt::UART1);
- init::LateResources {
- #[cfg(feature = "feature_e2")]
- e2: 2,
- #[cfg(feature = "feature_l2")]
- l2: 2
- }
- }
-
- // `shared` cannot be accessed from this context
- // l1 ok (task_local)
- // e2 ok (lock_free)
- #[idle(resources =[#[cfg(feature = "feature_l1")]l1, e2])]
- fn idle(_cx: idle::Context) -> ! {
- #[cfg(feature = "feature_l1")]
- hprintln!("IDLE:l1 = {}", _cx.resources.l1).unwrap();
- #[cfg(feature = "feature_e2")]
- hprintln!("IDLE:e2 = {}", _cx.resources.e2).unwrap();
- debug::exit(debug::EXIT_SUCCESS);
- loop {}
- }
-
- // `shared` can be accessed from this context
- // l2 ok (task_local)
- // e1 ok (lock_free)
- #[task(priority = 1, binds = UART0, resources = [shared, #[cfg(feature = "feature_l2")]l2, #[cfg(feature = "feature_e1")]e1])]
- fn uart0(_cx: uart0::Context) {
- #[cfg(feature = "feature_s")]
- let shared: &mut u32 = _cx.resources.shared;
-
- #[cfg(feature = "feature_s")]
- {
- *shared += 1;
- }
-
- #[cfg(feature = "feature_e1")]
- {
- // Unless put in a closure, the following error:
- // error[E0658]: attributes on expressions are experimental
- // --> examples/local-cfg.rs:69:9
- // 69 | #[cfg(feature = "feature_x")]
- // | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // = note: see issue #15701
- // <https://github.com/rust-lang/rust/issues/15701> for more information
- *_cx.resources.e1 += 10;
- }
- #[cfg(feature = "feature_s")]
- hprintln!("UART0: shared = {}", shared).unwrap();
- #[cfg(feature = "feature_l2")]
- hprintln!("UART0:l2 = {}", _cx.resources.l2).unwrap();
- #[cfg(feature = "feature_e1")]
- hprintln!("UART0:e1 = {}", _cx.resources.e1).unwrap();
- }
-
- // `shared` can be accessed from this context
- // e1 ok (lock_free)
- #[task(priority = 1, binds = UART1, resources = [#[cfg(feature = "feature_s")]shared, #[cfg(feature = "feature_e1")]e1])]
- fn uart1(_cx: uart1::Context) {
- #[cfg(feature = "feature_s")]
- let shared: &mut u32 = _cx.resources.shared;
- #[cfg(feature = "feature_s")]
- {
- *shared += 1;
- }
-
- #[cfg(feature = "feature_s")]
- hprintln!("UART1: shared = {}", shared).unwrap();
- #[cfg(feature = "feature_e1")]
- hprintln!("UART1:e1 = {}", _cx.resources.e1).unwrap();
- }
-};
diff --git a/examples/static.rs b/examples/static.rs
index ddcb11e6..9c3110c0 100644
--- a/examples/static.rs
+++ b/examples/static.rs
@@ -1,4 +1,4 @@
-//! examples/late.rs
+//! examples/static.rs
#![deny(unsafe_code)]
#![deny(warnings)]
@@ -14,9 +14,14 @@ use heapless::{
use lm3s6965::Interrupt;
use panic_semihosting as _;
-#[rtfm::app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
+
+ use crate::U4;
+ use crate::{Consumer, Producer};
+
// Late resources
+ #[resources]
struct Resources {
p: Producer<'static, u32, U4>,
c: Consumer<'static, u32, U4>,
@@ -40,7 +45,7 @@ const APP: () = {
debug::exit(debug::EXIT_SUCCESS);
} else {
- rtfm::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART0);
}
}
}
@@ -51,4 +56,4 @@ const APP: () = {
*KALLE += 1;
c.resources.p.enqueue(42).unwrap();
}
-};
+}
diff --git a/examples/local_minimal.rs b/examples/task-local-minimal.rs
index 13531c5e..fd5ac68a 100644
--- a/examples/local_minimal.rs
+++ b/examples/task-local-minimal.rs
@@ -1,4 +1,4 @@
-//! examples/local_minimal.rs
+//! examples/task-local_minimal.rs
#![deny(unsafe_code)]
#![deny(warnings)]
#![no_main]
@@ -7,8 +7,9 @@
use cortex_m_semihosting::{debug, hprintln};
use panic_semihosting as _;
-#[rtfm::app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
struct Resources {
// A local (move), late resource
#[task_local]
@@ -25,6 +26,8 @@ const APP: () = {
fn idle(cx: idle::Context) -> ! {
hprintln!("IDLE:l = {}", cx.resources.l).unwrap();
debug::exit(debug::EXIT_SUCCESS);
- loop {}
+ loop {
+ cortex_m::asm::nop();
+ }
}
-};
+}
diff --git a/examples/local.rs b/examples/task-local.rs
index 802ab20f..8f0dfc79 100644
--- a/examples/local.rs
+++ b/examples/task-local.rs
@@ -1,4 +1,4 @@
-//! examples/local.rs
+//! examples/task-local.rs
#![deny(unsafe_code)]
#![deny(warnings)]
@@ -9,8 +9,9 @@ use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
use panic_semihosting as _;
-#[rtfm::app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
struct Resources {
// An early resource
#[init(0)]
@@ -37,8 +38,8 @@ const APP: () = {
#[init]
fn init(_: init::Context) -> init::LateResources {
- rtfm::pend(Interrupt::UART0);
- rtfm::pend(Interrupt::UART1);
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
init::LateResources { e2: 2, l2: 2 }
}
@@ -50,7 +51,9 @@ const APP: () = {
hprintln!("IDLE:l1 = {}", cx.resources.l1).unwrap();
hprintln!("IDLE:e2 = {}", cx.resources.e2).unwrap();
debug::exit(debug::EXIT_SUCCESS);
- loop {}
+ loop {
+ cortex_m::asm::nop();
+ }
}
// `shared` can be accessed from this context
@@ -76,4 +79,4 @@ const APP: () = {
hprintln!("UART1: shared = {}", shared).unwrap();
hprintln!("UART1:e1 = {}", cx.resources.e1).unwrap();
}
-};
+}
diff --git a/macros/Cargo.toml b/macros/Cargo.toml
index 74f54433..4fac48fe 100644
--- a/macros/Cargo.toml
+++ b/macros/Cargo.toml
@@ -21,10 +21,6 @@ proc-macro = true
proc-macro2 = "1"
quote = "1"
syn = "1"
-#rtic-syntax = { git = "https://github.com/rtic-rs/rtic-syntax", branch = "master", version = "0.4.0" }
-
-[dependencies.rtic-syntax]
-git = "https://github.com/rtic-rs/rtic-syntax.git"
-branch = "task_local_experiment"
-version = "0.4.1"
+#rtic-syntax = { git = "https://github.com/rtic-rs/rtic-syntax", branch = "task_local_experiment", version = "0.4.1" }
+rtic-syntax = { git = "https://github.com/AfoHT/rtic-syntax", branch = "task_local_experiment", version = "0.4.1" }
diff --git a/macros/src/custom_local.rs b/macros/src/custom_local.rs
deleted file mode 100644
index f220c3d8..00000000
--- a/macros/src/custom_local.rs
+++ /dev/null
@@ -1,165 +0,0 @@
-use syn::parse;
-use std::collections::HashMap;
-use proc_macro2::Ident;
-use rtfm_syntax::{
- analyze::Analysis,
- ast::App,
-};
-use syn::Error;
-
-type Idents<'a> = Vec<&'a Ident>;
-
-// Assign an `extern` interrupt to each priority level
-pub fn app(app: &App, _analysis: &Analysis) -> parse::Result<()> {
- // collect task local resources
- let task_local: Idents = app
- .resources
- .iter()
- .filter(|(_, r)| r.properties.task_local)
- .map(|(i, _)| i)
- .chain(
- app.late_resources
- .iter()
- .filter(|(_, r)| r.properties.task_local)
- .map(|(i, _)| i),
- )
- .collect();
-
- let lock_free: Idents = app
- .resources
- .iter()
- .filter(|(_, r)| r.properties.lock_free)
- .map(|(i, _)| i)
- .chain(
- app.late_resources
- .iter()
- .filter(|(_, r)| r.properties.lock_free)
- .map(|(i, _)| i),
- )
- .collect();
-
- // collect all tasks into a vector
- type Task = String;
- type Priority = u8;
-
- let all_tasks: Vec<(Task, Idents, Priority)> = app
- .idles
- .iter()
- .map(|(core, ht)| {
- (
- format!("Idle (core {})", core),
- ht.args.resources.iter().map(|(v, _)| v).collect::<Vec<_>>(),
- 0
-
- )
- })
- .chain(app.software_tasks.iter().map(|(name, ht)| {
- (
- name.to_string(),
- ht.args.resources.iter().map(|(v, _)| v).collect::<Vec<_>>(),
- ht.args.priority
- )
- }))
- .chain(app.hardware_tasks.iter().map(|(name, ht)| {
- (
- name.to_string(),
- ht.args.resources.iter().map(|(v, _)| v).collect::<Vec<_>>(),
- ht.args.priority
- )
- }))
- .collect();
-
- // check that task_local resources is only used once
- let mut error = vec![];
- for task_local_id in task_local.iter() {
- let mut used = vec![];
- for (task, tr, priority) in all_tasks.iter() {
- for r in tr {
- if task_local_id == r {
- used.push((task, r, priority));
- }
- }
- }
- if used.len() > 1 {
- error.push(Error::new(
- task_local_id.span(),
- format!(
- "task local resource {:?} is used by multiple tasks",
- task_local_id.to_string()
- ),
- ));
-
- used.iter().for_each(|(task, resource, priority)| {
- error.push(Error::new(
- resource.span(),
- format!(
- "task local resource {:?} is used by task {:?} with priority {:?}",
- resource.to_string(),
- task,
- priority
- ),
- ))
- });
- }
- }
-
- let mut lf_res_with_error = vec![];
- let mut lf_hash = HashMap::new();
-
- for lf_res in lock_free.iter() {
- for (task, tr, priority) in all_tasks.iter() {
- for r in tr {
- // Get all uses of resources annotated lock_free
- if lf_res == r {
- // HashMap returns the previous existing object if old.key == new.key
- if let Some(lf_res) = lf_hash.insert(r.to_string(), (task, r, priority)) {
- // Check if priority differ, if it does, append to
- // list of resources which will be annotated with errors
- if priority != lf_res.2 {
- lf_res_with_error.push(lf_res.1);
- lf_res_with_error.push(r);
- }
- // If the resource already violates lock free properties
- if lf_res_with_error.contains(&r) {
- lf_res_with_error.push(lf_res.1);
- lf_res_with_error.push(r);
- }
- }
- }
- }
- }
- }
-
- // Add error message in the resource struct
- for r in lock_free {
- if lf_res_with_error.contains(&&r) {
- error.push(Error::new(
- r.span(),
- format!(
- "Lock free resource {:?} is used by tasks at different priorities",
- r.to_string(),
- ),
- ));
- }
- }
-
- // Add error message for each use of the resource
- for resource in lf_res_with_error.clone() {
- error.push(Error::new(
- resource.span(),
- format!(
- "Resource {:?} is declared lock free but used by tasks at different priorities",
- resource.to_string(),
- ),
- ));
- }
-
- // collect errors
- if error.is_empty() {
- Ok(())
- } else {
- let mut err = error.iter().next().unwrap().clone();
- error.iter().for_each(|e| err.combine(e.clone()));
- Err(err)
- }
-} \ No newline at end of file
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index 2c81ede0..e659559e 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -10,7 +10,6 @@ use rtic_syntax::Settings;
mod analyze;
mod check;
mod codegen;
-mod custom_local;
#[cfg(test)]
mod tests;
@@ -215,27 +214,13 @@ pub fn app(args: TokenStream, input: TokenStream) -> TokenStream {
Ok(x) => x,
};
- match custom_local::app(&app, &analysis) {
- Err(e) => return e.to_compile_error().into(),
- Ok(_) => {}
- }
-
let extra = match check::app(&app, &analysis) {
Err(e) => return e.to_compile_error().into(),
Ok(x) => x,
};
- // println!("extra {:?}", extra);
-
let analysis = analyze::app(analysis, &app);
- // println!("after analysis, extra {:?}", extra);
-
- // match custom_local::app(&app, &analysis) {
- // Err(e) => return e.to_compile_error().into(),
- // Ok(_) => {}
- // }
-
let ts = codegen::app(&app, &analysis, &extra);
// Try to write the expanded code to disk
diff --git a/examples/local-cfg-task-local.rs b/ui/single/local-cfg-task-local-err.rs
index 49069113..412f6142 100644
--- a/examples/local-cfg-task-local.rs
+++ b/ui/single/local-cfg-task-local-err.rs
@@ -5,13 +5,14 @@
#![no_main]
#![no_std]
-use cortex_m_semihosting::hprintln;
use cortex_m_semihosting::debug;
+use cortex_m_semihosting::hprintln;
use lm3s6965::Interrupt;
use panic_semihosting as _;
-#[rtfm::app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
struct Resources {
// A local (move), early resource
#[cfg(feature = "feature_l1")]
@@ -26,13 +27,13 @@ const APP: () = {
#[init]
fn init(_: init::Context) -> init::LateResources {
- rtfm::pend(Interrupt::UART0);
- rtfm::pend(Interrupt::UART1);
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
init::LateResources {
#[cfg(feature = "feature_l2")]
l2: 2,
#[cfg(not(feature = "feature_l2"))]
- l2: 5
+ l2: 5,
}
}
@@ -62,4 +63,4 @@ const APP: () = {
#[cfg(not(feature = "feature_l2"))]
hprintln!("UART0:l2 = {}", _cx.resources.l2).unwrap();
}
-};
+}
diff --git a/ui/single/local-cfg-task-local-err.stderr b/ui/single/local-cfg-task-local-err.stderr
new file mode 100644
index 00000000..9a84ead4
--- /dev/null
+++ b/ui/single/local-cfg-task-local-err.stderr
@@ -0,0 +1,37 @@
+error: task local resource "l2" is used by multiple tasks
+ --> $DIR/local-cfg-task-local-err.rs:25:9
+ |
+25 | l2: u32,
+ | ^^
+
+error: task local resource "l2" is used by task "uart0" with priority 1
+ --> $DIR/local-cfg-task-local-err.rs:51:39
+ |
+51 | #[cfg(feature = "feature_l2")]l2,
+ | ^^
+
+error: task local resource "l2" is used by task "uart1" with priority 1
+ --> $DIR/local-cfg-task-local-err.rs:60:44
+ |
+60 | #[cfg(not(feature = "feature_l2"))]l2
+ | ^^
+
+warning: unused import: `cortex_m_semihosting::debug`
+ --> $DIR/local-cfg-task-local-err.rs:8:5
+ |
+8 | use cortex_m_semihosting::debug;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(unused_imports)]` on by default
+
+warning: unused import: `cortex_m_semihosting::hprintln`
+ --> $DIR/local-cfg-task-local-err.rs:9:5
+ |
+9 | use cortex_m_semihosting::hprintln;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused import: `lm3s6965::Interrupt`
+ --> $DIR/local-cfg-task-local-err.rs:10:5
+ |
+10 | use lm3s6965::Interrupt;
+ | ^^^^^^^^^^^^^^^^^^^
diff --git a/examples/local_err.rs b/ui/single/local-err.rs
index 3be593a8..0fe98a4b 100644
--- a/examples/local_err.rs
+++ b/ui/single/local-err.rs
@@ -11,8 +11,9 @@ use cortex_m_semihosting::{debug, hprintln};
use lm3s6965::Interrupt;
use panic_semihosting as _;
-#[rtfm::app(device = lm3s6965)]
-const APP: () = {
+#[rtic::app(device = lm3s6965)]
+mod app {
+ #[resources]
struct Resources {
// An early resource
#[init(0)]
@@ -39,8 +40,8 @@ const APP: () = {
#[init]
fn init(_: init::Context) -> init::LateResources {
- rtfm::pend(Interrupt::UART0);
- rtfm::pend(Interrupt::UART1);
+ rtic::pend(Interrupt::UART0);
+ rtic::pend(Interrupt::UART1);
init::LateResources { e2: 2, l2: 2 }
}
@@ -79,4 +80,4 @@ const APP: () = {
hprintln!("UART1:l2 = {}", cx.resources.l2).unwrap();
hprintln!("UART1:e1 = {}", cx.resources.e1).unwrap();
}
-};
+}
diff --git a/ui/single/local-err.stderr b/ui/single/local-err.stderr
new file mode 100644
index 00000000..88369d8e
--- /dev/null
+++ b/ui/single/local-err.stderr
@@ -0,0 +1,60 @@
+error: task local resource "l2" is used by multiple tasks
+ --> $DIR/local-err.rs:34:9
+ |
+34 | l2: u32,
+ | ^^
+
+error: task local resource "l2" is used by task "idle" with priority 0
+ --> $DIR/local-err.rs:52:28
+ |
+52 | #[idle(resources =[l1, l2, e2])]
+ | ^^
+
+error: task local resource "l2" is used by task "uart0" with priority 1
+ --> $DIR/local-err.rs:63:62
+ |
+63 | #[task(priority = 1, binds = UART0, resources = [shared, l2, e1])]
+ | ^^
+
+error: task local resource "l2" is used by task "uart1" with priority 2
+ --> $DIR/local-err.rs:74:62
+ |
+74 | #[task(priority = 2, binds = UART1, resources = [shared, l2, e1])]
+ | ^^
+
+error: Lock free resource "e1" is used by tasks at different priorities
+ --> $DIR/local-err.rs:30:9
+ |
+30 | e1: u32,
+ | ^^
+
+error: Resource "e1" is declared lock free but used by tasks at different priorities
+ --> $DIR/local-err.rs:63:66
+ |
+63 | #[task(priority = 1, binds = UART0, resources = [shared, l2, e1])]
+ | ^^
+
+error: Resource "e1" is declared lock free but used by tasks at different priorities
+ --> $DIR/local-err.rs:74:66
+ |
+74 | #[task(priority = 2, binds = UART1, resources = [shared, l2, e1])]
+ | ^^
+
+error: unused imports: `debug`, `hprintln`
+ --> $DIR/local-err.rs:10:28
+ |
+10 | use cortex_m_semihosting::{debug, hprintln};
+ | ^^^^^ ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/local-err.rs:4:9
+ |
+4 | #![deny(warnings)]
+ | ^^^^^^^^
+ = note: `#[deny(unused_imports)]` implied by `#[deny(warnings)]`
+
+error: unused import: `lm3s6965::Interrupt`
+ --> $DIR/local-err.rs:11:5
+ |
+11 | use lm3s6965::Interrupt;
+ | ^^^^^^^^^^^^^^^^^^^