aboutsummaryrefslogtreecommitdiff
path: root/macros/src
diff options
context:
space:
mode:
authorGravatar Emil Fresk <emil.fresk@gmail.com> 2022-08-05 08:59:16 +0200
committerGravatar Emil Fresk <emil.fresk@gmail.com> 2022-08-05 09:00:46 +0200
commitb48a95e87930fa51ef6fb47ad08a95d3159d9bac (patch)
treeb2475335911408e0b59751980823bd11db742308 /macros/src
parent4488ac0421b53ffa5b97e6dddd396cbdb52c6283 (diff)
downloadrtic-b48a95e87930fa51ef6fb47ad08a95d3159d9bac.tar.gz
rtic-b48a95e87930fa51ef6fb47ad08a95d3159d9bac.tar.zst
rtic-b48a95e87930fa51ef6fb47ad08a95d3159d9bac.zip
Fix codegen when having executor at multiple priorities
The codegen generated code for all executors in all dispatchers, which caused some weird bugs. Also the definition of an executor was not generated globally, this caused use after free errors when having multiple priority levels.
Diffstat (limited to 'macros/src')
-rw-r--r--macros/src/check.rs6
-rw-r--r--macros/src/codegen/dispatchers.rs47
-rw-r--r--macros/src/codegen/idle.rs3
3 files changed, 36 insertions, 20 deletions
diff --git a/macros/src/check.rs b/macros/src/check.rs
index 374fcedd..4b360738 100644
--- a/macros/src/check.rs
+++ b/macros/src/check.rs
@@ -40,7 +40,11 @@ pub fn app(app: &App, _analysis: &Analysis) -> parse::Result<Extra> {
})
.collect::<HashSet<_>>();
- let need = priorities.len();
+ let need = priorities
+ .iter()
+ // Only count if not 0
+ .filter_map(|prio| if *prio > 0 { Some(prio) } else { None })
+ .count();
let given = app.args.extern_interrupts.len();
if need > given {
let s = {
diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs
index 9552451c..cc994402 100644
--- a/macros/src/codegen/dispatchers.rs
+++ b/macros/src/codegen/dispatchers.rs
@@ -10,6 +10,21 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
let interrupts = &analysis.interrupts;
+ // Generate executor definition in global scope
+ for (name, task) in app.software_tasks.iter() {
+ if task.is_async {
+ let type_name = util::internal_task_ident(name, "F");
+ let exec_name = util::internal_task_ident(name, "EXEC");
+
+ items.push(quote!(
+ type #type_name = impl core::future::Future + 'static;
+ static #exec_name:
+ rtic::RacyCell<rtic::export::executor::AsyncTaskExecutor<#type_name>> =
+ rtic::RacyCell::new(rtic::export::executor::AsyncTaskExecutor::new());
+ ));
+ }
+ }
+
for (&level, channel) in &analysis.channels {
let mut stmts = vec![];
@@ -123,24 +138,17 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
})
.collect::<Vec<_>>();
- for (name, task) in app.software_tasks.iter() {
- if task.is_async {
- let type_name = util::internal_task_ident(name, "F");
- let exec_name = util::internal_task_ident(name, "EXEC");
-
- stmts.push(quote!(
- type #type_name = impl core::future::Future + 'static;
- static #exec_name:
- rtic::RacyCell<rtic::export::executor::AsyncTaskExecutor<#type_name>> =
- rtic::RacyCell::new(rtic::export::executor::AsyncTaskExecutor::new());
- ));
- }
- }
-
- let n_executors = app
- .software_tasks
+ let n_executors = channel
+ .tasks
.iter()
- .map(|(_, task)| if task.is_async { 1 } else { 0 })
+ .map(|name| {
+ let task = &app.software_tasks[name];
+ if task.is_async {
+ 1
+ } else {
+ 0
+ }
+ })
.sum::<usize>()
.max(1);
@@ -165,9 +173,10 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
}
));
- for (name, _task) in app.software_tasks.iter().filter_map(|(name, task)| {
+ for name in channel.tasks.iter().filter_map(|name| {
+ let task = &app.software_tasks[name];
if task.is_async {
- Some((name, task))
+ Some(name)
} else {
None
}
diff --git a/macros/src/codegen/idle.rs b/macros/src/codegen/idle.rs
index 83b85d7b..ea23f814 100644
--- a/macros/src/codegen/idle.rs
+++ b/macros/src/codegen/idle.rs
@@ -80,6 +80,9 @@ pub fn codegen(
(mod_app, root_idle, user_idle, call_idle)
} else {
+ // TODO: No idle defined, check for 0-priority tasks and generate an executor if needed
+
+ //
(
vec![],
vec![],