diff options
-rw-r--r-- | CHANGELOG.md | 23 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | macros/Cargo.toml | 4 | ||||
-rw-r--r-- | macros/src/codegen/shared_resources.rs | 70 | ||||
-rw-r--r-- | macros/src/codegen/util.rs | 7 | ||||
-rw-r--r-- | src/export.rs | 34 |
6 files changed, 119 insertions, 23 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f05aeeaf..b9bd7f53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,26 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top! ### Added +### Fixed + +- Generation of masks for the source masking scheduling for thumbv6 + +### Changed + +## [v1.1.1] - 2022-04-13 + +### Added + +### Fixed + +- Fixed `marcro` version + +### Changed + +## [v1.1.0] - 2022-04-13 + +### Added + - Improve how CHANGELOG.md merges are handled - If current $stable and master version matches, dev-book redirects to $stable book - During deploy stage, merge master branch into current stable IFF cargo package version matches @@ -485,7 +505,8 @@ Yanked due to a soundness issue in `init`; the issue has been mostly fixed in v0 - Initial release -[Unreleased]: https://github.com/rtic-rs/cortex-m-rtic/compare/v1.0.0...HEAD +[Unreleased]: https://github.com/rtic-rs/cortex-m-rtic/compare/v1.1.0...HEAD +[v1.1.0]: https://github.com/rtic-rs/cortex-m-rtic/compare/v1.0.0...v1.1.0 [v1.0.0]: https://github.com/rtic-rs/cortex-m-rtic/compare/v0.6.0-rc.4...v1.0.0 [v0.6.0-rc.4]: https://github.com/rtic-rs/cortex-m-rtic/compare/v0.6.0-rc.3...v0.6.0-rc.4 [v0.6.0-rc.3]: https://github.com/rtic-rs/cortex-m-rtic/compare/v0.6.0-rc.2...v0.6.0-rc.3 @@ -14,14 +14,14 @@ name = "cortex-m-rtic" readme = "README.md" repository = "https://github.com/rtic-rs/cortex-m-rtic" -version = "1.0.0" +version = "1.1.1" [lib] name = "rtic" [dependencies] cortex-m = "0.7.0" -cortex-m-rtic-macros = { path = "macros", version = "1.0.0" } +cortex-m-rtic-macros = { path = "macros", version = "1.1.0" } rtic-monotonic = "1.0.0" rtic-core = "1.0.0" heapless = "0.7.7" diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 0c008c88..350db900 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0" name = "cortex-m-rtic-macros" readme = "../README.md" repository = "https://github.com/rtic-rs/cortex-m-rtic" -version = "1.0.0" +version = "1.1.0" [lib] proc-macro = true @@ -22,7 +22,7 @@ proc-macro2 = "1" proc-macro-error = "1" quote = "1" syn = "1" -rtic-syntax = "1.0.0" +rtic-syntax = "1.0.1" [features] debugprint = [] diff --git a/macros/src/codegen/shared_resources.rs b/macros/src/codegen/shared_resources.rs index a016e453..f944e3e5 100644 --- a/macros/src/codegen/shared_resources.rs +++ b/macros/src/codegen/shared_resources.rs @@ -1,8 +1,8 @@ +use crate::{analyze::Analysis, check::Extra, codegen::util}; use proc_macro2::TokenStream as TokenStream2; use quote::quote; use rtic_syntax::{analyze::Ownership, ast::App}; - -use crate::{analyze::Analysis, check::Extra, codegen::util}; +use std::collections::HashMap; /// Generates `static` variables and shared resource proxies pub fn codegen( @@ -108,35 +108,71 @@ 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 mut prio_to_masks = HashMap::new(); let device = &extra.device; - - for p in 0..3 { - masks.insert(p, quote!(0)); - } + let mut uses_exceptions_with_resources = false; 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 + // If any resource to the exception uses non-lock-free or non-local resources this is + // not allwed on thumbv6. + uses_exceptions_with_resources = uses_exceptions_with_resources + || task + .args + .shared_resources + .iter() + .map(|(ident, access)| { + if access.is_exclusive() { + if let Some(r) = app.shared_resources.get(ident) { + !r.properties.lock_free + } else { + false + } + } else { + false + } + }) + .any(|v| v); + None } })) { - let name = quote!(#device::Interrupt::#name as u32); - if let Some(v) = masks.get_mut(&(priority - 1)) { - *v = quote!(#v | 1 << #name); - }; + let v = prio_to_masks.entry(priority - 1).or_insert(Vec::new()); + v.push(quote!(#device::Interrupt::#name as u32)); } - 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(); + // Call rtic::export::create_mask([u32; N]), where the array is the list of shifts + + let mut mask_arr = Vec::new(); + // NOTE: 0..3 assumes max 4 priority levels according to M0 spec + for i in 0..3 { + let v = if let Some(v) = prio_to_masks.get(&i) { + v.clone() + } else { + Vec::new() + }; + mask_arr.push(quote!( + rtic::export::create_mask([#(#v),*]) + )); + } + + let masks_name = util::priority_masks_ident(); mod_app.push(quote!( - const MASKS: [u32; 3] = [#(#mask_arr),*]; + #[doc(hidden)] + #[allow(non_camel_case_types)] + const #masks_name: [u32; 3] = [#(#mask_arr),*]; )); + if uses_exceptions_with_resources { + mod_app.push(quote!( + #[doc(hidden)] + #[allow(non_camel_case_types)] + const __rtic_internal_V6_ERROR: () = rtic::export::v6_panic(); + )); + } + (mod_app, mod_resources) } diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs index 4a29754b..0f3dca7c 100644 --- a/macros/src/codegen/util.rs +++ b/macros/src/codegen/util.rs @@ -36,6 +36,7 @@ pub fn impl_mutex( }; let device = &extra.device; + let masks_name = priority_masks_ident(); quote!( #(#cfgs)* impl<'a> rtic::Mutex for #path<'a> { @@ -52,7 +53,7 @@ pub fn impl_mutex( #priority, CEILING, #device::NVIC_PRIO_BITS, - &MASKS, + &#masks_name, f, ) } @@ -252,6 +253,10 @@ pub fn static_shared_resource_ident(name: &Ident) -> Ident { mark_internal_name(&format!("shared_resource_{}", name)) } +pub fn priority_masks_ident() -> Ident { + mark_internal_name("MASKS") +} + pub fn static_local_resource_ident(name: &Ident) -> Ident { mark_internal_name(&format!("local_resource_{}", name)) } diff --git a/src/export.rs b/src/export.rs index ed51a9e9..42f3fe2e 100644 --- a/src/export.rs +++ b/src/export.rs @@ -315,3 +315,37 @@ unsafe fn clear_enable_mask(mask: u32) { pub fn logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 { ((1 << nvic_prio_bits) - logical) << (8 - nvic_prio_bits) } + +#[cfg(not(armv6m))] +pub const fn create_mask<const N: usize>(_: [u32; N]) -> u32 { + 0 +} + +#[cfg(armv6m)] +pub const fn create_mask<const N: usize>(list_of_shifts: [u32; N]) -> u32 { + let mut mask = 0; + let mut i = 0; + + while i < N { + let shift = list_of_shifts[i]; + i += 1; + + if shift > 31 { + panic!("Generating masks for thumbv6 failed! Are you compiling for thumbv6 on an thumbv7 MCU?"); + } + + mask |= 1 << shift; + } + + mask +} + +#[cfg(not(armv6m))] +pub const fn v6_panic() { + // For non-v6 all is fine +} + +#[cfg(armv6m)] +pub const fn v6_panic() { + panic!("Exceptions with shared resources are not allowed when compiling for thumbv6. Use local resources or `#[lock_free]` shared resources"); +} |