diff options
Diffstat (limited to 'macros/src/codegen.rs')
-rw-r--r-- | macros/src/codegen.rs | 167 |
1 files changed, 92 insertions, 75 deletions
diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index 2433684c..f230d395 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -25,99 +25,105 @@ mod util; // TODO document the syntax here or in `rtic-syntax` pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { - let mut const_app = vec![]; + let mut mod_app = vec![]; + let mut mod_app_imports = vec![]; let mut mains = vec![]; let mut root = vec![]; let mut user = vec![]; + let mut imports = vec![]; - // generate a `main` function for each core - for core in 0..app.args.cores { - let assertion_stmts = assertions::codegen(core, analysis, extra); + // Generate the `main` function + let assertion_stmts = assertions::codegen(analysis); - let (const_app_pre_init, pre_init_stmts) = pre_init::codegen(core, &app, analysis, extra); + let pre_init_stmts = pre_init::codegen(&app, analysis, extra); - let (const_app_init, root_init, user_init, call_init) = - init::codegen(core, app, analysis, extra); + let (mod_app_init, root_init, user_init, user_init_imports, call_init) = + init::codegen(app, analysis, extra); - let (const_app_post_init, post_init_stmts) = - post_init::codegen(core, &app, analysis, extra); + let post_init_stmts = post_init::codegen(&app, analysis); - let (const_app_idle, root_idle, user_idle, call_idle) = - idle::codegen(core, app, analysis, extra); + let (mod_app_idle, root_idle, user_idle, user_idle_imports, call_idle) = + idle::codegen(app, analysis, extra); - user.push(quote!( - #user_init - - #user_idle - )); + if user_init.is_some() { + mod_app_imports.push(quote!( + use super::init; + )) + } + if user_idle.is_some() { + mod_app_imports.push(quote!( + use super::idle; + )) + } - root.push(quote!( - #(#root_init)* + user.push(quote!( + #user_init - #(#root_idle)* - )); + #user_idle + )); - const_app.push(quote!( - #(#const_app_pre_init)* + imports.push(quote!( + #(#user_init_imports)* + #(#user_idle_imports)* + )); - #const_app_init + root.push(quote!( + #(#root_init)* - #(#const_app_post_init)* + #(#root_idle)* + )); - #const_app_idle - )); + mod_app.push(quote!( + #mod_app_init - let cfg_core = util::cfg_core(core, app.args.cores); - let main = util::suffixed("main", core); - let section = util::link_section("text", core); - mains.push(quote!( - #[no_mangle] - #section - #cfg_core - unsafe extern "C" fn #main() -> ! { - let _TODO: () = (); + #mod_app_idle + )); - #(#assertion_stmts)* + let main = util::suffixed("main"); + mains.push(quote!( + #[no_mangle] + unsafe extern "C" fn #main() -> ! { + let _TODO: () = (); - #(#pre_init_stmts)* + #(#assertion_stmts)* - #call_init + #(#pre_init_stmts)* - #(#post_init_stmts)* + #call_init - #call_idle - } - )); - } + #(#post_init_stmts)* - let (const_app_resources, mod_resources) = resources::codegen(app, analysis, extra); + #call_idle + } + )); - let (const_app_hardware_tasks, root_hardware_tasks, user_hardware_tasks) = - hardware_tasks::codegen(app, analysis, extra); + let (mod_app_resources, mod_resources, mod_resources_imports) = + resources::codegen(app, analysis, extra); - let (const_app_software_tasks, root_software_tasks, user_software_tasks) = - software_tasks::codegen(app, analysis, extra); + let ( + mod_app_hardware_tasks, + root_hardware_tasks, + user_hardware_tasks, + user_hardware_tasks_imports, + ) = hardware_tasks::codegen(app, analysis, extra); - let const_app_dispatchers = dispatchers::codegen(app, analysis, extra); + let ( + mod_app_software_tasks, + root_software_tasks, + user_software_tasks, + user_software_tasks_imports, + ) = software_tasks::codegen(app, analysis, extra); - let const_app_spawn = spawn::codegen(app, analysis, extra); + let mod_app_dispatchers = dispatchers::codegen(app, analysis, extra); - let const_app_timer_queue = timer_queue::codegen(app, analysis, extra); + let mod_app_spawn = spawn::codegen(app, analysis, extra); - let const_app_schedule = schedule::codegen(app, extra); + let mod_app_timer_queue = timer_queue::codegen(app, analysis, extra); - 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); - ); + let mod_app_schedule = schedule::codegen(app, extra); + let user_imports = app.user_imports.clone(); + let user_code = app.user_code.clone(); let name = &app.name; let device = extra.device; quote!( @@ -136,30 +142,41 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #(#root_software_tasks)* /// Implementation details - // the user can't access the items within this `const` item - const #name: () = { + mod #name { /// Always include the device crate which contains the vector table use #device as _; + #(#imports)* + #(#user_imports)* + + /// User code from within the module + #(#user_code)* + /// User code end + + + #(#user_hardware_tasks_imports)* + + #(#user_software_tasks_imports)* - #check_excess_cores + #(#mod_resources_imports)* - #(#const_app)* + /// app module + #(#mod_app)* - #(#const_app_resources)* + #(#mod_app_resources)* - #(#const_app_hardware_tasks)* + #(#mod_app_hardware_tasks)* - #(#const_app_software_tasks)* + #(#mod_app_software_tasks)* - #(#const_app_dispatchers)* + #(#mod_app_dispatchers)* - #(#const_app_spawn)* + #(#mod_app_spawn)* - #(#const_app_timer_queue)* + #(#mod_app_timer_queue)* - #(#const_app_schedule)* + #(#mod_app_schedule)* #(#mains)* - }; + } ) } |