summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bors[bot] <26634292+bors[bot]@users.noreply.github.com> 2021-04-08 08:15:05 +0000
committerGravatar GitHub <noreply@github.com> 2021-04-08 08:15:05 +0000
commit83cdf00eecb0f14857b5e0f28e884b2120eabb18 (patch)
tree17f732cbb06dd480bd0881d0ec627cc173ba5bfc
parent6c8257bb73de0f68072467447692a1f7dff555f9 (diff)
parent51500a1d7096395be9162599fae647ec121db91d (diff)
downloadrtic-83cdf00eecb0f14857b5e0f28e884b2120eabb18.tar.gz
rtic-83cdf00eecb0f14857b5e0f28e884b2120eabb18.tar.zst
rtic-83cdf00eecb0f14857b5e0f28e884b2120eabb18.zip
Merge #466
466: Fix for type aliases in `mod app`, UB in `spawn_at`, and `#[cfg]` in hardware tasks r=AfoHT a=korken89 Type aliases such as the following did not work in `0.6-alpha`: ```rust use rtic::app; #[app(device = lm3s6965, dispatchers = [SSI0])] mod app { type Test = u32; #[task] fn t1(_: t1::Context, _val: Test) {} } ``` Plus that accessing associated constants of monotonic timers was not working as it should dues to the syntax and codegen transforming: ```rust #[monotonic(binds = SysTick, default = true)] type MyMono = DwtSystick<8_000_000>; // 8 MHz ``` into ```rust mod MyMono { // ... } ``` causing the original `type MyMono` to not exist anymore. This PR fixes this and adds test to check for this by doing the following expansion instead: ```rust #[monotonic(binds = SysTick, default = true)] type MyMono = DwtSystick<8_000_000>; // 8 MHz ``` into ```rust type MyMono = DwtSystick<8_000_000>; mod monotonics { mod MyMono { // ... } // And other monotonics go here as well } ``` **Breaking change** This causes a breaking change in accessing the `MyMono::now()` method which now exists under `monotonics::MyMono::now()`. --- Moreover a UB issue was found and fixed in `spawn_at` and hardware tasks properly propagate `#[cfg]`s. Closes #460 Closes #462 Closes #463 Co-authored-by: Emil Fresk <emil.fresk@gmail.com>
-rw-r--r--examples/t-schedule.rs33
-rw-r--r--examples/type-usage.rs15
-rw-r--r--macros/Cargo.toml3
-rw-r--r--macros/src/codegen.rs16
-rw-r--r--macros/src/codegen/hardware_tasks.rs4
-rw-r--r--macros/src/codegen/module.rs37
-rw-r--r--src/tq.rs6
7 files changed, 75 insertions, 39 deletions
diff --git a/examples/t-schedule.rs b/examples/t-schedule.rs
index ef04c451..5e38dbaf 100644
--- a/examples/t-schedule.rs
+++ b/examples/t-schedule.rs
@@ -26,24 +26,27 @@ mod app {
// Task without message passing
// Not default
- let _: Result<foo::MyMono::SpawnHandle, ()> = foo::MyMono::spawn_at(MyMono::now());
+ let _: Result<foo::MyMono::SpawnHandle, ()> =
+ foo::MyMono::spawn_at(monotonics::MyMono::now());
let handle: Result<foo::MyMono::SpawnHandle, ()> = foo::MyMono::spawn_after(Seconds(1_u32));
let _: Result<foo::MyMono::SpawnHandle, ()> =
handle.unwrap().reschedule_after(Seconds(1_u32));
let handle: Result<foo::MyMono::SpawnHandle, ()> = foo::MyMono::spawn_after(Seconds(1_u32));
- let _: Result<foo::MyMono::SpawnHandle, ()> = handle.unwrap().reschedule_at(MyMono::now());
+ let _: Result<foo::MyMono::SpawnHandle, ()> =
+ handle.unwrap().reschedule_at(monotonics::MyMono::now());
let handle: Result<foo::MyMono::SpawnHandle, ()> = foo::MyMono::spawn_after(Seconds(1_u32));
let _: Result<(), ()> = handle.unwrap().cancel();
// Using default
- let _: Result<foo::SpawnHandle, ()> = foo::spawn_at(MyMono::now());
+ let _: Result<foo::SpawnHandle, ()> = foo::spawn_at(monotonics::MyMono::now());
let handle: Result<foo::SpawnHandle, ()> = foo::spawn_after(Seconds(1_u32));
let _: Result<foo::SpawnHandle, ()> = handle.unwrap().reschedule_after(Seconds(1_u32));
let handle: Result<foo::SpawnHandle, ()> = foo::spawn_after(Seconds(1_u32));
- let _: Result<foo::SpawnHandle, ()> = handle.unwrap().reschedule_at(MyMono::now());
+ let _: Result<foo::SpawnHandle, ()> =
+ handle.unwrap().reschedule_at(monotonics::MyMono::now());
let handle: Result<foo::SpawnHandle, ()> = foo::spawn_after(Seconds(1_u32));
let _: Result<(), ()> = handle.unwrap().cancel();
@@ -51,7 +54,8 @@ mod app {
// Task with single message passing
// Not default
- let _: Result<bar::MyMono::SpawnHandle, u32> = bar::MyMono::spawn_at(MyMono::now(), 0);
+ let _: Result<bar::MyMono::SpawnHandle, u32> =
+ bar::MyMono::spawn_at(monotonics::MyMono::now(), 0);
let handle: Result<bar::MyMono::SpawnHandle, u32> =
bar::MyMono::spawn_after(Seconds(1_u32), 0);
let _: Result<bar::MyMono::SpawnHandle, ()> =
@@ -59,19 +63,21 @@ mod app {
let handle: Result<bar::MyMono::SpawnHandle, u32> =
bar::MyMono::spawn_after(Seconds(1_u32), 0);
- let _: Result<bar::MyMono::SpawnHandle, ()> = handle.unwrap().reschedule_at(MyMono::now());
+ let _: Result<bar::MyMono::SpawnHandle, ()> =
+ handle.unwrap().reschedule_at(monotonics::MyMono::now());
let handle: Result<bar::MyMono::SpawnHandle, u32> =
bar::MyMono::spawn_after(Seconds(1_u32), 0);
let _: Result<u32, ()> = handle.unwrap().cancel();
// Using default
- let _: Result<bar::SpawnHandle, u32> = bar::spawn_at(MyMono::now(), 0);
+ let _: Result<bar::SpawnHandle, u32> = bar::spawn_at(monotonics::MyMono::now(), 0);
let handle: Result<bar::SpawnHandle, u32> = bar::spawn_after(Seconds(1_u32), 0);
let _: Result<bar::SpawnHandle, ()> = handle.unwrap().reschedule_after(Seconds(1_u32));
let handle: Result<bar::SpawnHandle, u32> = bar::spawn_after(Seconds(1_u32), 0);
- let _: Result<bar::SpawnHandle, ()> = handle.unwrap().reschedule_at(MyMono::now());
+ let _: Result<bar::SpawnHandle, ()> =
+ handle.unwrap().reschedule_at(monotonics::MyMono::now());
let handle: Result<bar::SpawnHandle, u32> = bar::spawn_after(Seconds(1_u32), 0);
let _: Result<u32, ()> = handle.unwrap().cancel();
@@ -80,7 +86,7 @@ mod app {
// Not default
let _: Result<baz::MyMono::SpawnHandle, (u32, u32)> =
- baz::MyMono::spawn_at(MyMono::now(), 0, 1);
+ baz::MyMono::spawn_at(monotonics::MyMono::now(), 0, 1);
let handle: Result<baz::MyMono::SpawnHandle, (u32, u32)> =
baz::MyMono::spawn_after(Seconds(1_u32), 0, 1);
let _: Result<baz::MyMono::SpawnHandle, ()> =
@@ -88,19 +94,22 @@ mod app {
let handle: Result<baz::MyMono::SpawnHandle, (u32, u32)> =
baz::MyMono::spawn_after(Seconds(1_u32), 0, 1);
- let _: Result<baz::MyMono::SpawnHandle, ()> = handle.unwrap().reschedule_at(MyMono::now());
+ let _: Result<baz::MyMono::SpawnHandle, ()> =
+ handle.unwrap().reschedule_at(monotonics::MyMono::now());
let handle: Result<baz::MyMono::SpawnHandle, (u32, u32)> =
baz::MyMono::spawn_after(Seconds(1_u32), 0, 1);
let _: Result<(u32, u32), ()> = handle.unwrap().cancel();
// Using default
- let _: Result<baz::SpawnHandle, (u32, u32)> = baz::spawn_at(MyMono::now(), 0, 1);
+ let _: Result<baz::SpawnHandle, (u32, u32)> =
+ baz::spawn_at(monotonics::MyMono::now(), 0, 1);
let handle: Result<baz::SpawnHandle, (u32, u32)> = baz::spawn_after(Seconds(1_u32), 0, 1);
let _: Result<baz::SpawnHandle, ()> = handle.unwrap().reschedule_after(Seconds(1_u32));
let handle: Result<baz::SpawnHandle, (u32, u32)> = baz::spawn_after(Seconds(1_u32), 0, 1);
- let _: Result<baz::SpawnHandle, ()> = handle.unwrap().reschedule_at(MyMono::now());
+ let _: Result<baz::SpawnHandle, ()> =
+ handle.unwrap().reschedule_at(monotonics::MyMono::now());
let handle: Result<baz::SpawnHandle, (u32, u32)> = baz::spawn_after(Seconds(1_u32), 0, 1);
let _: Result<(u32, u32), ()> = handle.unwrap().cancel();
diff --git a/examples/type-usage.rs b/examples/type-usage.rs
new file mode 100644
index 00000000..9bb7eb8d
--- /dev/null
+++ b/examples/type-usage.rs
@@ -0,0 +1,15 @@
+//! examples/type-usage.rs
+
+#![no_main]
+#![no_std]
+
+use panic_semihosting as _; // panic handler
+use rtic::app;
+
+#[app(device = lm3s6965, dispatchers = [SSI0])]
+mod app {
+ type Test = u32;
+
+ #[task]
+ fn t1(_: t1::Context, _val: Test) {}
+}
diff --git a/macros/Cargo.toml b/macros/Cargo.toml
index f14b1046..203a2bb1 100644
--- a/macros/Cargo.toml
+++ b/macros/Cargo.toml
@@ -22,5 +22,4 @@ proc-macro2 = "1"
proc-macro-error = "1"
quote = "1"
syn = "1"
-rtic-syntax = "0.5.0-alpha.1"
-
+rtic-syntax = "0.5.0-alpha.2"
diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs
index c5d95687..cf728a7d 100644
--- a/macros/src/codegen.rs
+++ b/macros/src/codegen.rs
@@ -112,8 +112,6 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
let user_imports = &app.user_imports;
quote! {
- pub use rtic::Monotonic as _;
-
#[doc = #doc]
#[allow(non_snake_case)]
pub mod #name {
@@ -143,6 +141,18 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
})
.collect();
+ let monotonics = if !monotonic_parts.is_empty() {
+ quote!(
+ pub use rtic::Monotonic as _;
+
+ /// Holds static methods for each monotonic.
+ pub mod monotonics {
+ #(#monotonic_parts)*
+ }
+ )
+ } else {
+ quote!()
+ };
let rt_err = util::rt_err_ident();
quote!(
@@ -151,7 +161,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
/// Always include the device crate which contains the vector table
use #device as #rt_err;
- #(#monotonic_parts)*
+ #monotonics
#(#user_imports)*
diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs
index 4a1d7492..540b95e5 100644
--- a/macros/src/codegen/hardware_tasks.rs
+++ b/macros/src/codegen/hardware_tasks.rs
@@ -37,12 +37,16 @@ pub fn codegen(
let symbol = task.args.binds.clone();
let priority = task.args.priority;
+ let cfgs = &task.cfgs;
+ let attrs = &task.attrs;
let app_name = &app.name;
let app_path = quote! {crate::#app_name};
mod_app.push(quote!(
#[allow(non_snake_case)]
#[no_mangle]
+ #(#attrs)*
+ #(#cfgs)*
unsafe fn #symbol() {
const PRIORITY: u8 = #priority;
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index e15aab1c..50146c02 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -21,7 +21,7 @@ pub fn codegen(
let app_name = &app.name;
let app_path = quote! {crate::#app_name};
- let all_task_names: Vec<_> = app
+ let all_task_imports: Vec<_> = app
.software_tasks
.iter()
.map(|(name, st)| {
@@ -46,6 +46,13 @@ pub fn codegen(
quote!()
}
}))
+ .chain(app.user_types.iter().map(|ty| {
+ let t = &ty.ident;
+ quote! {
+ #[allow(unused_imports)]
+ use super::#t;
+ }
+ }))
.collect();
let mut lt = None;
@@ -230,7 +237,7 @@ pub fn codegen(
// Spawn caller
items.push(quote!(
- #(#all_task_names)*
+ #(#all_task_imports)*
#(#cfgs)*
/// Spawns the task directly
@@ -268,7 +275,7 @@ pub fn codegen(
let tq = util::mark_internal_ident(&tq);
let t = util::schedule_t_ident();
let m = &monotonic.ident;
- let mono_type = &monotonic.ty;
+ let mono_type = &monotonic.ident;
let m_ident = util::monotonic_ident(&monotonic_name);
let m_ident = util::mark_internal_ident(&m_ident);
let m_isr = &monotonic.args.binds;
@@ -300,10 +307,6 @@ pub fn codegen(
items.push(quote!(
/// Holds methods related to this monotonic
pub mod #m {
- // #(
- // #[allow(unused_imports)]
- // use #app_path::#all_task_names as #all_task_names;
- // )*
use super::*;
#[allow(unused_imports)]
use #app_path::#tq_marker;
@@ -341,7 +344,7 @@ pub fn codegen(
where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint,
D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>,
{
- self.reschedule_at(#app_path::#m::now() + duration)
+ self.reschedule_at(#app_path::monotonics::#m::now() + duration)
}
pub fn reschedule_at(self, instant: rtic::time::Instant<#app_path::#mono_type>) -> Result<Self, ()>
@@ -373,7 +376,7 @@ pub fn codegen(
let instant = if rtic::export::interrupt::free(|_| unsafe { #app_path::#m_ident.is_none() }) {
rtic::time::Instant::new(0)
} else {
- #app_path::#m::now()
+ #app_path::monotonics::#m::now()
};
spawn_at(instant + duration #(,#untupled)*)
@@ -411,17 +414,11 @@ pub fn codegen(
let tq = unsafe { &mut *#app_path::#tq.as_mut_ptr() };
- if let Some(mono) = #app_path::#m_ident.as_mut() {
- tq.enqueue_unchecked(
- nr,
- || #enable_interrupt,
- || #pend,
- mono)
- } else {
- // We can only use the timer queue if `init` has returned, and it
- // writes the `Some(monotonic)` we are accessing here.
- core::hint::unreachable_unchecked()
- }
+ tq.enqueue_unchecked(
+ nr,
+ || #enable_interrupt,
+ || #pend,
+ #app_path::#m_ident.as_mut());
Ok(SpawnHandle { marker })
})
diff --git a/src/tq.rs b/src/tq.rs
index 38640259..985e0f88 100644
--- a/src/tq.rs
+++ b/src/tq.rs
@@ -42,7 +42,7 @@ where
nr: NotReady<Mono, Task>,
enable_interrupt: F1,
pend_handler: F2,
- mono: &mut Mono,
+ mono: Option<&mut Mono>,
) where
F1: FnOnce(),
F2: FnOnce(),
@@ -57,7 +57,9 @@ where
if if_heap_max_greater_than_nr {
if Mono::DISABLE_INTERRUPT_ON_EMPTY_QUEUE && self.0.is_empty() {
- mono.enable_timer();
+ if let Some(mono) = mono {
+ mono.enable_timer();
+ }
enable_interrupt();
}