Added support for SRP based scheduling for armv6m

This commit is contained in:
Per Lindgren 2022-01-21 21:49:45 +01:00 committed by Emil Fresk
parent 790b074e18
commit f86dab5ff3
9 changed files with 434 additions and 16 deletions

View file

@ -28,7 +28,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
let mut user = vec![];
// Generate the `main` function
let assertion_stmts = assertions::codegen(app, analysis);
let assertion_stmts = assertions::codegen(app, analysis, extra);
let pre_init_stmts = pre_init::codegen(app, analysis, extra);

View file

@ -1,11 +1,11 @@
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use crate::analyze::Analysis;
use crate::{analyze::Analysis, check::Extra, codegen::util};
use rtic_syntax::ast::App;
/// Generates compile-time assertions that check that types implement the `Send` / `Sync` traits
pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
let mut stmts = vec![];
for ty in &analysis.send_types {
@ -21,5 +21,33 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
stmts.push(quote!(rtic::export::assert_monotonic::<#ty>();));
}
let device = &extra.device;
let arm_v6_checks: Vec<_> = app
.hardware_tasks
.iter()
.filter_map(|(_, task)| {
if !util::is_exception(&task.args.binds) {
let interrupt_name = &task.args.binds;
Some(quote!(assert!((#device::Interrupt::#interrupt_name as u32) < 32);))
} else {
None
}
})
.collect();
let const_check = quote! {
const _CONST_CHECK: () = {
if rtic::export::is_armv6() {
#(#arm_v6_checks)*
} else {
// TODO: Add armv7 checks here
}
};
let _ = _CONST_CHECK;
};
stmts.push(const_check);
stmts
}

View file

@ -105,5 +105,38 @@ pub fn codegen(
})
};
// Computing mapping of used interrupts to masks
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
use std::collections::HashMap;
let mut masks: HashMap<u8, _> = std::collections::HashMap::new();
let device = &extra.device;
for p in 0..3 {
masks.insert(p, quote!(0));
}
for (&priority, name) in interrupt_ids.chain(app.hardware_tasks.values().flat_map(|task| {
if !util::is_exception(&task.args.binds) {
Some((&task.args.priority, &task.args.binds))
} else {
// TODO: exceptions not implemented
None
}
})) {
let name = quote!(#device::Interrupt::#name as u32);
if let Some(v) = masks.get_mut(&(priority - 1)) {
*v = quote!(#v | 1 << #name);
};
}
let mut mask_arr: Vec<(_, _)> = masks.iter().collect();
mask_arr.sort_by_key(|(k, _v)| *k);
let mask_arr: Vec<_> = mask_arr.iter().map(|(_, v)| v).collect();
mod_app.push(quote!(
const MASKS: [u32; 3] = [#(#mask_arr),*];
));
(mod_app, mod_resources)
}

View file

@ -52,6 +52,7 @@ pub fn impl_mutex(
#priority,
CEILING,
#device::NVIC_PRIO_BITS,
&MASKS,
f,
)
}