aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Per Lindgren <per.lindgren@ltu.se> 2020-10-24 19:38:49 +0200
committerGravatar Per Lindgren <per.lindgren@ltu.se> 2020-10-29 19:29:46 +0100
commit96cd625223404a3b32a62384055ccd4765f92312 (patch)
treee1190b395650334f834c218ff33583b783f81054
parentd11b2ddd3559b29480b9bbcf9d5b7836de190f77 (diff)
downloadrtic-96cd625223404a3b32a62384055ccd4765f92312.tar.gz
rtic-96cd625223404a3b32a62384055ccd4765f92312.tar.zst
rtic-96cd625223404a3b32a62384055ccd4765f92312.zip
extern task
-rw-r--r--CHANGELOG.md2
-rw-r--r--book/en/src/migration/migration_v5.md11
-rw-r--r--examples/extern_binds.rs48
-rw-r--r--examples/extern_spawn.rs35
-rw-r--r--macros/src/codegen/hardware_tasks.rs28
-rw-r--r--macros/src/codegen/software_tasks.rs32
-rw-r--r--ui/single/extern-interrupt-used.rs4
7 files changed, 127 insertions, 33 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec19bd16..22018ebe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- `#[task_local]`, there must be only one task, similar to a task local
resource, but (optionally) set-up by init. This is similar to move.
+- Improved ergonomics allowing separation of task signatures to actual implementation in extern block `extern "Rust" { #[task(..)] fn t(..); }`.
+
### Changed
- [breaking-change] [PR 400] Move dispatchers from extern block to app argument.
diff --git a/book/en/src/migration/migration_v5.md b/book/en/src/migration/migration_v5.md
index 5cf818c5..44af15e2 100644
--- a/book/en/src/migration/migration_v5.md
+++ b/book/en/src/migration/migration_v5.md
@@ -36,7 +36,6 @@ mod app {
This works also for ram functions, see examples/ramfunc.rs
-
## Module instead of Const
With the support of attributes on modules the `const APP` workaround is not needed.
@@ -125,3 +124,13 @@ struct whateveryouwant {
```
would work equally well.
+
+---
+
+## Additions
+
+### Extern tasks
+
+Both software and hardware tasks can now be defined external to the `mod app`. Previously this was possible only by implementing a trampoline calling out the task implementation.
+
+See examples `examples/extern_binds.rs` and `examples/extern_spawn.rs`. \ No newline at end of file
diff --git a/examples/extern_binds.rs b/examples/extern_binds.rs
new file mode 100644
index 00000000..632f4ca0
--- /dev/null
+++ b/examples/extern_binds.rs
@@ -0,0 +1,48 @@
+//! examples/extern_binds.rs
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::hprintln;
+use panic_semihosting as _;
+
+// Free function implementing the interrupt bound task `foo`.
+fn foo(_: app::foo::Context) {
+ hprintln!("foo called").ok();
+}
+
+#[rtic::app(device = lm3s6965)]
+mod app {
+ use crate::foo;
+ use cortex_m_semihosting::{debug, hprintln};
+ use lm3s6965::Interrupt;
+
+ #[init]
+ fn init(_: init::Context) -> init::LateResources {
+ rtic::pend(Interrupt::UART0);
+
+ hprintln!("init").unwrap();
+
+ init::LateResources {}
+ }
+
+ #[idle]
+ fn idle(_: idle::Context) -> ! {
+ hprintln!("idle").unwrap();
+
+ rtic::pend(Interrupt::UART0);
+
+ debug::exit(debug::EXIT_SUCCESS);
+
+ loop {
+ cortex_m::asm::nop();
+ }
+ }
+
+ extern "Rust" {
+ #[task(binds = UART0)]
+ fn foo(_: foo::Context);
+ }
+}
diff --git a/examples/extern_spawn.rs b/examples/extern_spawn.rs
new file mode 100644
index 00000000..1be3d512
--- /dev/null
+++ b/examples/extern_spawn.rs
@@ -0,0 +1,35 @@
+//! examples/extern_spawn.rs
+
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![no_main]
+#![no_std]
+
+use cortex_m_semihosting::{debug, hprintln};
+use panic_semihosting as _;
+
+// Free function implementing the spawnable task `foo`.
+fn foo(_c: app::foo::Context, x: i32, y: u32) {
+ hprintln!("foo {}, {}", x, y).unwrap();
+ if x == 2 {
+ debug::exit(debug::EXIT_SUCCESS);
+ }
+ app::foo::spawn(2, 3).unwrap();
+}
+
+#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
+mod app {
+ use crate::foo;
+
+ #[init]
+ fn init(_c: init::Context) -> init::LateResources {
+ foo::spawn(1, 2).unwrap();
+
+ init::LateResources {}
+ }
+
+ extern "Rust" {
+ #[task()]
+ fn foo(_c: foo::Context, _x: i32, _y: u32);
+ }
+}
diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs
index e5a8deb9..c9d0297e 100644
--- a/macros/src/codegen/hardware_tasks.rs
+++ b/macros/src/codegen/hardware_tasks.rs
@@ -95,19 +95,21 @@ pub fn codegen(
locals_pat = Some(pat);
}
- let attrs = &task.attrs;
- let context = &task.context;
- let stmts = &task.stmts;
- let locals_pat = locals_pat.iter();
- user_tasks.push(quote!(
- #(#attrs)*
- #[allow(non_snake_case)]
- fn #name(#(#locals_pat,)* #context: #name::Context) {
- use rtic::Mutex as _;
-
- #(#stmts)*
- }
- ));
+ if !&task.is_extern {
+ let attrs = &task.attrs;
+ let context = &task.context;
+ let stmts = &task.stmts;
+ let locals_pat = locals_pat.iter();
+ user_tasks.push(quote!(
+ #(#attrs)*
+ #[allow(non_snake_case)]
+ fn #name(#(#locals_pat,)* #context: #name::Context) {
+ use rtic::Mutex as _;
+
+ #(#stmts)*
+ }
+ ));
+ }
}
(mod_app, root, user_tasks)
diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs
index dfba193b..833e338d 100644
--- a/macros/src/codegen/software_tasks.rs
+++ b/macros/src/codegen/software_tasks.rs
@@ -99,21 +99,23 @@ pub fn codegen(
root.push(struct_);
}
- let context = &task.context;
- let attrs = &task.attrs;
- let cfgs = &task.cfgs;
- let stmts = &task.stmts;
- let locals_pat = locals_pat.iter();
- user_tasks.push(quote!(
- #(#attrs)*
- #(#cfgs)*
- #[allow(non_snake_case)]
- fn #name(#(#locals_pat,)* #context: #name::Context #(,#inputs)*) {
- use rtic::Mutex as _;
-
- #(#stmts)*
- }
- ));
+ if !&task.is_extern {
+ let context = &task.context;
+ let attrs = &task.attrs;
+ let cfgs = &task.cfgs;
+ let stmts = &task.stmts;
+ let locals_pat = locals_pat.iter();
+ user_tasks.push(quote!(
+ #(#attrs)*
+ #(#cfgs)*
+ #[allow(non_snake_case)]
+ fn #name(#(#locals_pat,)* #context: #name::Context #(,#inputs)*) {
+ use rtic::Mutex as _;
+
+ #(#stmts)*
+ }
+ ));
+ }
root.push(module::codegen(
Context::SoftwareTask(name),
diff --git a/ui/single/extern-interrupt-used.rs b/ui/single/extern-interrupt-used.rs
index 2ba31682..240e7363 100644
--- a/ui/single/extern-interrupt-used.rs
+++ b/ui/single/extern-interrupt-used.rs
@@ -4,8 +4,4 @@
mod app {
#[task(binds = UART0)]
fn a(_: a::Context) {}
-
- extern "C" {
- fn UART0();
- }
}