mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-19 06:15:45 +01:00
rtfm-syntax refactor + heterogeneous multi-core support
This commit is contained in:
parent
fafeeb2727
commit
81275bfa4f
127 changed files with 4072 additions and 5848 deletions
121
macros/src/codegen/hardware_tasks.rs
Normal file
121
macros/src/codegen/hardware_tasks.rs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use rtfm_syntax::{ast::App, Context};
|
||||
|
||||
use crate::{
|
||||
analyze::Analysis,
|
||||
check::Extra,
|
||||
codegen::{locals, module, resources_struct, util},
|
||||
};
|
||||
|
||||
/// Generate support code for hardware tasks (`#[exception]`s and `#[interrupt]`s)
|
||||
pub fn codegen(
|
||||
app: &App,
|
||||
analysis: &Analysis,
|
||||
extra: &Extra,
|
||||
) -> (
|
||||
// const_app_hardware_tasks -- interrupt handlers and `${task}Resources` constructors
|
||||
Vec<TokenStream2>,
|
||||
// root_hardware_tasks -- items that must be placed in the root of the crate:
|
||||
// - `${task}Locals` structs
|
||||
// - `${task}Resources` structs
|
||||
// - `${task}` modules
|
||||
Vec<TokenStream2>,
|
||||
// user_hardware_tasks -- the `#[task]` functions written by the user
|
||||
Vec<TokenStream2>,
|
||||
) {
|
||||
let mut const_app = vec![];
|
||||
let mut root = vec![];
|
||||
let mut user_tasks = vec![];
|
||||
|
||||
for (name, task) in &app.hardware_tasks {
|
||||
let core = task.args.core;
|
||||
let cfg_core = util::cfg_core(core, app.args.cores);
|
||||
|
||||
let (let_instant, instant) = if app.uses_schedule(core) {
|
||||
let m = extra.monotonic();
|
||||
|
||||
(
|
||||
Some(quote!(let instant = <#m as rtfm::Monotonic>::now();)),
|
||||
Some(quote!(, instant)),
|
||||
)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let locals_new = if task.locals.is_empty() {
|
||||
quote!()
|
||||
} else {
|
||||
quote!(#name::Locals::new(),)
|
||||
};
|
||||
|
||||
let symbol = task.args.binds(name);
|
||||
let priority = task.args.priority;
|
||||
|
||||
const_app.push(quote!(
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#cfg_core
|
||||
unsafe fn #symbol() {
|
||||
const PRIORITY: u8 = #priority;
|
||||
|
||||
#let_instant
|
||||
|
||||
rtfm::export::run(PRIORITY, || {
|
||||
crate::#name(
|
||||
#locals_new
|
||||
#name::Context::new(&rtfm::export::Priority::new(PRIORITY) #instant)
|
||||
)
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
let mut needs_lt = false;
|
||||
|
||||
// `${task}Resources`
|
||||
if !task.args.resources.is_empty() {
|
||||
let (item, constructor) = resources_struct::codegen(
|
||||
Context::HardwareTask(name),
|
||||
priority,
|
||||
&mut needs_lt,
|
||||
app,
|
||||
analysis,
|
||||
);
|
||||
|
||||
root.push(item);
|
||||
|
||||
const_app.push(constructor);
|
||||
}
|
||||
|
||||
root.push(module::codegen(
|
||||
Context::HardwareTask(name),
|
||||
needs_lt,
|
||||
app,
|
||||
extra,
|
||||
));
|
||||
|
||||
// `${task}Locals`
|
||||
let mut locals_pat = None;
|
||||
if !task.locals.is_empty() {
|
||||
let (struct_, pat) = locals::codegen(Context::HardwareTask(name), &task.locals, app);
|
||||
|
||||
root.push(struct_);
|
||||
locals_pat = Some(pat);
|
||||
}
|
||||
|
||||
let attrs = &task.attrs;
|
||||
let context = &task.context;
|
||||
let stmts = &task.stmts;
|
||||
user_tasks.push(quote!(
|
||||
#(#attrs)*
|
||||
#[allow(non_snake_case)]
|
||||
fn #name(#(#locals_pat,)* #context: #name::Context) {
|
||||
use rtfm::Mutex as _;
|
||||
|
||||
#(#stmts)*
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
(const_app, root, user_tasks)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue