2019-06-13 23:56:59 +02:00
|
|
|
use proc_macro2::TokenStream as TokenStream2;
|
2018-11-03 17:02:41 +01:00
|
|
|
use quote::quote;
|
2019-06-13 23:56:59 +02:00
|
|
|
use rtfm_syntax::ast::App;
|
|
|
|
|
|
|
|
use crate::{analyze::Analysis, check::Extra};
|
|
|
|
|
|
|
|
mod assertions;
|
|
|
|
mod dispatchers;
|
|
|
|
mod hardware_tasks;
|
|
|
|
mod idle;
|
|
|
|
mod init;
|
|
|
|
mod locals;
|
|
|
|
mod module;
|
|
|
|
mod post_init;
|
|
|
|
mod pre_init;
|
|
|
|
mod resources;
|
|
|
|
mod resources_struct;
|
|
|
|
mod schedule;
|
|
|
|
mod schedule_body;
|
|
|
|
mod software_tasks;
|
|
|
|
mod spawn;
|
|
|
|
mod spawn_body;
|
|
|
|
mod timer_queue;
|
|
|
|
mod util;
|
|
|
|
|
|
|
|
// TODO document the syntax here or in `rtfm-syntax`
|
|
|
|
pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|
|
|
let mut const_app = vec![];
|
|
|
|
let mut mains = vec![];
|
|
|
|
let mut root = vec![];
|
|
|
|
let mut user = vec![];
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
// generate a `main` function for each core
|
|
|
|
for core in 0..app.args.cores {
|
2019-06-24 14:09:12 +02:00
|
|
|
let assertion_stmts = assertions::codegen(core, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let (const_app_pre_init, pre_init_stmts) = pre_init::codegen(core, &app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let (const_app_init, root_init, user_init, call_init) =
|
|
|
|
init::codegen(core, app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let (const_app_post_init, post_init_stmts) = post_init::codegen(core, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let (const_app_idle, root_idle, user_idle, call_idle) =
|
|
|
|
idle::codegen(core, app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
user.push(quote!(
|
|
|
|
#user_init
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#user_idle
|
|
|
|
));
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
root.push(quote!(
|
|
|
|
#(#root_init)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#root_idle)*
|
|
|
|
));
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
const_app.push(quote!(
|
|
|
|
#(#const_app_pre_init)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-04-21 20:02:59 +02:00
|
|
|
#const_app_init
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_post_init)*
|
2019-04-21 20:02:59 +02:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#const_app_idle
|
|
|
|
));
|
2019-04-21 20:02:59 +02:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let cfg_core = util::cfg_core(core, app.args.cores);
|
2019-06-18 10:31:31 +02:00
|
|
|
let main = util::suffixed("main", core);
|
2019-06-13 23:56:59 +02:00
|
|
|
mains.push(quote!(
|
2019-04-21 20:02:59 +02:00
|
|
|
#[no_mangle]
|
2019-06-13 23:56:59 +02:00
|
|
|
#cfg_core
|
2019-06-18 10:31:31 +02:00
|
|
|
unsafe extern "C" fn #main() -> ! {
|
2019-04-21 20:02:59 +02:00
|
|
|
#(#assertion_stmts)*
|
|
|
|
|
|
|
|
#(#pre_init_stmts)*
|
|
|
|
|
|
|
|
#call_init
|
|
|
|
|
|
|
|
#(#post_init_stmts)*
|
|
|
|
|
|
|
|
#call_idle
|
|
|
|
}
|
2019-02-12 14:53:49 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let (const_app_resources, mod_resources) = resources::codegen(app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let (const_app_hardware_tasks, root_hardware_tasks, user_hardware_tasks) =
|
|
|
|
hardware_tasks::codegen(app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let (const_app_software_tasks, root_software_tasks, user_software_tasks) =
|
|
|
|
software_tasks::codegen(app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let const_app_dispatchers = dispatchers::codegen(app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let const_app_spawn = spawn::codegen(app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let const_app_timer_queue = timer_queue::codegen(app, analysis, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let const_app_schedule = schedule::codegen(app, extra);
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-24 14:15:00 +02:00
|
|
|
let cores = app.args.cores.to_string();
|
|
|
|
let cfg_core = quote!(#[cfg(core = #cores)]);
|
|
|
|
let msg = format!(
|
|
|
|
"specified {} core{} but tried to compile for more than {0} core{1}",
|
|
|
|
app.args.cores,
|
|
|
|
if app.args.cores > 1 { "s" } else { "" }
|
|
|
|
);
|
|
|
|
let check_excess_cores = quote!(
|
|
|
|
#cfg_core
|
|
|
|
compile_error!(#msg);
|
|
|
|
);
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
let name = &app.name;
|
|
|
|
let device = extra.device;
|
2019-04-21 20:02:59 +02:00
|
|
|
quote!(
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#user)*
|
2018-12-15 19:07:09 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#user_hardware_tasks)*
|
2019-02-16 00:22:00 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#user_software_tasks)*
|
2018-12-15 19:07:09 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#root)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#mod_resources)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#root_hardware_tasks)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#root_software_tasks)*
|
2018-12-16 19:10:36 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Implementation details
|
|
|
|
// the user can't access the items within this `const` item
|
|
|
|
const #name: () = {
|
|
|
|
/// Always include the device crate which contains the vector table
|
|
|
|
use #device as _;
|
2019-02-15 19:52:25 +01:00
|
|
|
|
2019-06-24 14:15:00 +02:00
|
|
|
#check_excess_cores
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_resources)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_hardware_tasks)*
|
2018-12-16 18:37:36 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_software_tasks)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_dispatchers)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_spawn)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_timer_queue)*
|
2019-04-21 20:02:59 +02:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#const_app_schedule)*
|
2018-11-03 17:02:41 +01:00
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
#(#mains)*
|
2019-02-15 19:52:25 +01:00
|
|
|
};
|
2018-11-03 17:02:41 +01:00
|
|
|
)
|
|
|
|
}
|