mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-24 04:32:52 +01:00
aad8f81991
469: Goodbye static mut r=AfoHT a=korken89
Squashed and updated version of @perlindgren branch.
In release there are 0 bytes difference for all examples 🎉
For debug we see a bloat of ~1-2% worst case, commonly less.
Complete diff of sizes for all examples (first is goodbye static mut, second is master):
```
< 27220 0 28 27248 6a70 spawn
---
> 27092 0 28 27120 69f0 spawn
< 16916 0 44 16960 4240 late
---
> 16836 0 44 16880 41f0 late
< 15952 0 12 15964 3e5c type-usage
---
> 15872 0 12 15884 3e0c type-usage
< 22068 0 44 22112 5660 cfg
---
> 21812 0 44 21856 5560 cfg
< 34784 0 40 34824 8808 periodic
---
> 34496 0 40 34536 86e8 periodic
< 22308 0 32 22340 5744 task
---
> 21972 0 32 22004 55f4 task
< 15076 8 24 15108 3b04 task-local
---
> 14980 8 24 15012 3aa4 task-local
< 12884 0 24 12908 326c destructure
---
> 12820 0 24 12844 322c destructure
< 10128 0 16 10144 27a0 init
---
> 10112 0 16 10128 2790 init
< 19044 0 20 19064 4a78 task_named_main
---
> 18916 0 20 18936 49f8 task_named_main
< 27252 0 28 27280 6a90 extern_spawn
---
> 27124 0 28 27152 6a10 extern_spawn
< 10176 0 16 10192 27d0 idle
---
> 10160 0 16 10176 27c0 idle
< 13972 0 16 13988 36a4 resource
---
> 13940 0 16 13956 3684 resource
< 16228 0 24 16252 3f7c multilock
---
> 16116 0 24 16140 3f0c multilock
< 14660 0 16 14676 3954 lock
---
> 14628 0 16 14644 3934 lock
< 10416 0 16 10432 28c0 task-local-minimal
---
> 10400 0 16 10416 28b0 task-local-minimal
< 14164 0 24 14188 376c generics
---
> 14148 0 24 14172 375c generics
< 30644 0 48 30692 77e4 message
---
> 30308 0 48 30356 7694 message
< 28964 0 36 29000 7148 spawn2
---
> 28724 0 36 28760 7058 spawn2
< 15952 0 8 15960 3e58 t-schedule-core-stable
---
> 15872 0 8 15880 3e08 t-schedule-core-stable
< 17408 0 20 17428 4414 t-cfg
---
> 17248 0 20 17268 4374 t-cfg
< 12948 0 16 12964 32a4 hardware
---
> 12932 0 16 12948 3294 hardware
< 54640 0 104 54744 d5d8 t-schedule
---
> 53696 0 104 53800 d228 t-schedule
< 26132 0 548 26680 6838 pool
---
> 25876 0 548 26424 6738 pool
< 22372 0 56 22428 579c cfg-whole-task
---
> 22100 0 56 22156 568c cfg-whole-task
< 38292 0 76 38368 95e0 schedule
---
> 37828 0 76 37904 9410 schedule
< 21216 0 32 21248 5300 t-spawn
---
> 20880 0 32 20912 51b0 t-spawn
< 22820 0 56 22876 595c capacity
---
> 22580 0 56 22636 586c capacity
< 17060 0 48 17108 42d4 static
---
> 16980 0 48 17028 4284 static
< 20288 0 24 20312 4f58 ramfunc
---
> 20096 0 24 20120 4e98 ramfunc
< 11760 0 20 11780 2e04 t-resource
---
> 11664 0 20 11684 2da4 t-resource
< 13028 0 16 13044 32f4 only-shared-access
---
> 13012 0 16 13028 32e4 only-shared-access
< 16576 0 16 16592 40d0 not-sync
---
> 16432 0 16 16448 4040 not-sync
< 13892 0 16 13908 3654 resource-user-struct
---
> 13860 0 16 13876 3634 resource-user-struct
< 37472 0 64 37536 92a0 double_schedule
---
> 36960 0 64 37024 90a0 double_schedule
< 17648 0 8 17656 44f8 t-stask-main
---
> 17520 0 8 17528 4478 t-stask-main
< 8816 0 4 8820 2274 t-late-not-send
---
> 8800 0 4 8804 2264 t-late-not-send
< 23280 0 32 23312 5b10 types
---
> 23120 0 32 23152 5a70 types
```
Co-authored-by: Emil Fresk <emil.fresk@gmail.com>
223 lines
5.9 KiB
Rust
223 lines
5.9 KiB
Rust
use proc_macro2::TokenStream as TokenStream2;
|
|
use quote::quote;
|
|
use rtic_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 software_tasks;
|
|
mod timer_queue;
|
|
mod util;
|
|
|
|
// TODO document the syntax here or in `rtic-syntax`
|
|
pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|
let mut mod_app = vec![];
|
|
let mut mains = vec![];
|
|
let mut root = vec![];
|
|
let mut user = vec![];
|
|
|
|
// Generate the `main` function
|
|
let assertion_stmts = assertions::codegen(app, analysis);
|
|
|
|
let pre_init_stmts = pre_init::codegen(app, analysis, extra);
|
|
|
|
let (mod_app_init, root_init, user_init, call_init) = init::codegen(app, analysis, extra);
|
|
|
|
let post_init_stmts = post_init::codegen(app, analysis);
|
|
|
|
let (mod_app_idle, root_idle, user_idle, call_idle) = idle::codegen(app, analysis, extra);
|
|
|
|
user.push(quote!(
|
|
#user_init
|
|
|
|
#user_idle
|
|
));
|
|
|
|
root.push(quote!(
|
|
#(#root_init)*
|
|
|
|
#(#root_idle)*
|
|
));
|
|
|
|
mod_app.push(quote!(
|
|
#mod_app_init
|
|
|
|
#mod_app_idle
|
|
));
|
|
|
|
let main = util::suffixed("main");
|
|
mains.push(quote!(
|
|
#[doc(hidden)]
|
|
mod rtic_ext {
|
|
use super::*;
|
|
#[no_mangle]
|
|
unsafe extern "C" fn #main() -> ! {
|
|
#(#assertion_stmts)*
|
|
|
|
#(#pre_init_stmts)*
|
|
|
|
#[inline(never)]
|
|
fn __rtic_init_resources<F>(f: F) where F: FnOnce() {
|
|
f();
|
|
}
|
|
|
|
// Wrap late_init_stmts in a function to ensure that stack space is reclaimed.
|
|
__rtic_init_resources(||{
|
|
#call_init
|
|
|
|
#(#post_init_stmts)*
|
|
});
|
|
|
|
#call_idle
|
|
}
|
|
}
|
|
));
|
|
|
|
let (mod_app_resources, mod_resources) = resources::codegen(app, analysis, extra);
|
|
|
|
let (mod_app_hardware_tasks, root_hardware_tasks, user_hardware_tasks) =
|
|
hardware_tasks::codegen(app, analysis, extra);
|
|
|
|
let (mod_app_software_tasks, root_software_tasks, user_software_tasks) =
|
|
software_tasks::codegen(app, analysis, extra);
|
|
|
|
let mod_app_dispatchers = dispatchers::codegen(app, analysis, extra);
|
|
let mod_app_timer_queue = timer_queue::codegen(app, analysis, extra);
|
|
let user_imports = &app.user_imports;
|
|
let user_code = &app.user_code;
|
|
let name = &app.name;
|
|
let device = &extra.device;
|
|
let app_name = &app.name;
|
|
let app_path = quote! {crate::#app_name};
|
|
|
|
let monotonic_parts: Vec<_> = app
|
|
.monotonics
|
|
.iter()
|
|
.map(|(_, monotonic)| {
|
|
let name = &monotonic.ident;
|
|
let name_str = &name.to_string();
|
|
let ty = &monotonic.ty;
|
|
let ident = util::monotonic_ident(&name_str);
|
|
let ident = util::mark_internal_ident(&ident);
|
|
let panic_str = &format!(
|
|
"Use of monotonic '{}' before it was passed to the runtime",
|
|
name_str
|
|
);
|
|
let doc = &format!(
|
|
"This module holds the static implementation for `{}::now()`",
|
|
name_str
|
|
);
|
|
let user_imports = &app.user_imports;
|
|
|
|
let default_monotonic = if monotonic.args.default {
|
|
quote!(pub use #name::now;)
|
|
} else {
|
|
quote!()
|
|
};
|
|
|
|
quote! {
|
|
#default_monotonic
|
|
|
|
#[doc = #doc]
|
|
#[allow(non_snake_case)]
|
|
pub mod #name {
|
|
#(
|
|
#[allow(unused_imports)]
|
|
#user_imports
|
|
)*
|
|
|
|
/// Read the current time from this monotonic
|
|
pub fn now() -> rtic::time::Instant<#ty> {
|
|
rtic::export::interrupt::free(|_| {
|
|
use rtic::Monotonic as _;
|
|
use rtic::time::Clock as _;
|
|
if let Some(m) = unsafe{ #app_path::#ident.get_mut_unchecked() } {
|
|
if let Ok(v) = m.try_now() {
|
|
v
|
|
} else {
|
|
unreachable!("Your monotonic is not infallible!")
|
|
}
|
|
} else {
|
|
panic!(#panic_str);
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
let monotonics = if !monotonic_parts.is_empty() {
|
|
quote!(
|
|
pub use rtic::Monotonic as _;
|
|
|
|
/// Holds static methods for each monotonic.
|
|
pub mod monotonics {
|
|
#(
|
|
#[allow(unused_imports)]
|
|
#user_imports
|
|
)*
|
|
|
|
#(#monotonic_parts)*
|
|
}
|
|
)
|
|
} else {
|
|
quote!()
|
|
};
|
|
let rt_err = util::rt_err_ident();
|
|
|
|
quote!(
|
|
/// The RTIC application module
|
|
pub mod #name {
|
|
/// Always include the device crate which contains the vector table
|
|
use #device as #rt_err;
|
|
|
|
#monotonics
|
|
|
|
#(#user_imports)*
|
|
|
|
/// User code from within the module
|
|
#(#user_code)*
|
|
/// User code end
|
|
|
|
#(#user)*
|
|
|
|
#(#user_hardware_tasks)*
|
|
|
|
#(#user_software_tasks)*
|
|
|
|
#(#root)*
|
|
|
|
#mod_resources
|
|
|
|
#(#root_hardware_tasks)*
|
|
|
|
#(#root_software_tasks)*
|
|
|
|
/// app module
|
|
#(#mod_app)*
|
|
|
|
#(#mod_app_resources)*
|
|
|
|
#(#mod_app_hardware_tasks)*
|
|
|
|
#(#mod_app_software_tasks)*
|
|
|
|
#(#mod_app_dispatchers)*
|
|
|
|
#(#mod_app_timer_queue)*
|
|
|
|
#(#mains)*
|
|
}
|
|
)
|
|
}
|