From f86dab5ff3e9c35e9e68b798b5c4faa08d390085 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Fri, 21 Jan 2022 21:49:45 +0100 Subject: Added support for SRP based scheduling for armv6m --- macros/src/codegen.rs | 2 +- macros/src/codegen/assertions.rs | 32 ++++++++++++++++++++++++++++++-- macros/src/codegen/shared_resources.rs | 33 +++++++++++++++++++++++++++++++++ macros/src/codegen/util.rs | 1 + 4 files changed, 65 insertions(+), 3 deletions(-) (limited to 'macros/src') diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index f5cae34a..01be1d57 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -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); diff --git a/macros/src/codegen/assertions.rs b/macros/src/codegen/assertions.rs index a8a4491b..36ab0364 100644 --- a/macros/src/codegen/assertions.rs +++ b/macros/src/codegen/assertions.rs @@ -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 { +pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec { let mut stmts = vec![]; for ty in &analysis.send_types { @@ -21,5 +21,33 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { 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 } diff --git a/macros/src/codegen/shared_resources.rs b/macros/src/codegen/shared_resources.rs index 9e45cff9..a016e453 100644 --- a/macros/src/codegen/shared_resources.rs +++ b/macros/src/codegen/shared_resources.rs @@ -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 = 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) } diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 6a07732c..4a29754b 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -52,6 +52,7 @@ pub fn impl_mutex( #priority, CEILING, #device::NVIC_PRIO_BITS, + &MASKS, f, ) } -- cgit v1.2.3