diff options
author | 2022-08-05 08:59:16 +0200 | |
---|---|---|
committer | 2022-08-05 09:00:46 +0200 | |
commit | b48a95e87930fa51ef6fb47ad08a95d3159d9bac (patch) | |
tree | b2475335911408e0b59751980823bd11db742308 /macros/src | |
parent | 4488ac0421b53ffa5b97e6dddd396cbdb52c6283 (diff) | |
download | rtic-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.rs | 6 | ||||
-rw-r--r-- | macros/src/codegen/dispatchers.rs | 47 | ||||
-rw-r--r-- | macros/src/codegen/idle.rs | 3 |
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![], |