Add feature flags

This commit is contained in:
Emil Fresk 2023-02-19 14:30:49 +01:00 committed by Henrik Tjäder
parent 60f0342b69
commit b9e0f36aff
12 changed files with 88 additions and 73 deletions

View file

@ -26,10 +26,13 @@ default = []
debugprint = [] debugprint = []
# list of supported codegen backends # list of supported codegen backends
thumbv6 = [] cortex_m_source_masking = []
thumbv7 = [] cortex_m_basepri = []
# riscv-clic = [] # riscv_clic = []
# riscv-ch32 = [] # riscv_ch32 = []
# backend API test
test_template = []
[dependencies] [dependencies]
indexmap = "1.9.2" indexmap = "1.9.2"

View file

@ -1,5 +1,18 @@
// TODO: Feature gate #[cfg(not(any(
feature = "cortex_m_source_masking",
feature = "cortex_m_basepri",
feaute = "test_template"
)))]
compile_error!("No backend selected");
#[cfg(any(feature = "cortex_m_source_masking", feature = "cortex_m_basepri"))]
pub use cortex::*;
#[cfg(feature = "test_template")]
pub use cortex::*;
#[cfg(any(feature = "cortex_m_source_masking", feature = "cortex_m_basepri"))]
mod cortex; mod cortex;
// TODO: Feature gate #[cfg(feature = "test_template")]
pub use cortex::*; mod template;

View file

@ -8,8 +8,9 @@ use quote::quote;
use std::collections::HashSet; use std::collections::HashSet;
use syn::{parse, Attribute, Ident}; use syn::{parse, Attribute, Ident};
// TODO: This should be feature gated #[cfg(feature = "cortex_m_basepri")]
// pub use basepri::*; pub use basepri::*;
#[cfg(feature = "cortex_m_source_masking")]
pub use source_masking::*; pub use source_masking::*;
/// Whether `name` is an exception with configurable priority /// Whether `name` is an exception with configurable priority
@ -29,7 +30,8 @@ fn is_exception(name: &Ident) -> bool {
) )
} }
pub mod source_masking { #[cfg(feature = "cortex_m_source_masking")]
mod source_masking {
use super::*; use super::*;
use std::collections::HashMap; use std::collections::HashMap;
@ -87,14 +89,6 @@ pub mod source_masking {
)); ));
} }
// if uses_exceptions_with_resources {
// mod_app.push(quote!(
// #[doc(hidden)]
// #[allow(non_upper_case_globals)]
// const __rtic_internal_V6_ERROR: () = rtic::export::no_basepri_panic();
// ));
// }
quote!( quote!(
#(#cfgs)* #(#cfgs)*
impl<'a> rtic::Mutex for #path<'a> { impl<'a> rtic::Mutex for #path<'a> {
@ -121,38 +115,12 @@ pub mod source_masking {
} }
pub fn extra_assertions(_: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> { pub fn extra_assertions(_: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> {
// let device = &app.args.device;
// let no_basepri_checks: Vec<_> = app
// .hardware_tasks
// .iter()
// .filter_map(|(_, task)| {
// if !is_exception(&task.args.binds) {
// let interrupt_name = &task.args.binds;
// Some(quote!(
// if (#device::Interrupt::#interrupt_name as usize) >= (#chunks_name * 32) {
// ::core::panic!("An interrupt out of range is used while in armv6 or armv8m.base");
// }
// ))
// } else {
// None
// }
// })
// .collect();
// let const_check = quote! {
// const _CONST_CHECK: () = {
// #(#no_basepri_checks)*
// };
// let _ = _CONST_CHECK;
// };
// vec![const_check]
vec![] vec![]
} }
} }
pub mod basepri { #[cfg(feature = "cortex_m_basepri")]
mod basepri {
use super::*; use super::*;
/// Generates a `Mutex` implementation /// Generates a `Mutex` implementation
@ -245,7 +213,7 @@ pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<
stmts.push(quote!( stmts.push(quote!(
core.NVIC.set_priority( core.NVIC.set_priority(
#rt_err::#interrupt::#name, #rt_err::#interrupt::#name,
rtic::export::logical2hw(#priority, #nvic_prio_bits), rtic::export::cortex_logical2hw(#priority, #nvic_prio_bits),
); );
)); ));
@ -272,7 +240,7 @@ pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<
stmts.push(quote!(core.SCB.set_priority( stmts.push(quote!(core.SCB.set_priority(
rtic::export::SystemHandler::#name, rtic::export::SystemHandler::#name,
rtic::export::logical2hw(#priority, #nvic_prio_bits), rtic::export::cortex_logical2hw(#priority, #nvic_prio_bits),
);)); );));
} }

View file

@ -2,7 +2,7 @@ use crate::syntax::{ast::App, Context};
use core::sync::atomic::{AtomicUsize, Ordering}; use core::sync::atomic::{AtomicUsize, Ordering};
use proc_macro2::{Span, TokenStream as TokenStream2}; use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::quote; use quote::quote;
use syn::{Attribute, Ident, PatType}; use syn::{Ident, PatType};
const RTIC_INTERNAL: &str = "__rtic_internal"; const RTIC_INTERNAL: &str = "__rtic_internal";

View file

@ -157,7 +157,7 @@ macro_rules! make_systick_handler {
#[no_mangle] #[no_mangle]
#[allow(non_snake_case)] #[allow(non_snake_case)]
unsafe extern "C" fn SysTick() { unsafe extern "C" fn SysTick() {
Systick::__tq().on_monotonic_interrupt(); rtic_monotonics::systick::Systick::__tq().on_monotonic_interrupt();
} }
}; };
} }

View file

@ -40,10 +40,7 @@ bare-metal = "1.0.0"
atomic-polyfill = "1" atomic-polyfill = "1"
rtic-macros = { path = "../rtic-macros", version = "2.0.0-alpha.0" } rtic-macros = { path = "../rtic-macros", version = "2.0.0-alpha.0" }
rtic-core = "1" rtic-core = "1"
critical-section = "1"
[build-dependencies]
version_check = "0.9"
[dev-dependencies] [dev-dependencies]
heapless = "0.7.7" heapless = "0.7.7"
@ -66,6 +63,17 @@ version = "0.6.0"
trybuild = "1" trybuild = "1"
[features] [features]
default = []
thumbv6 = ["rtic-macros/cortex_m_source_masking"]
thumbv7 = ["rtic-macros/cortex_m_basepri"]
thumbv8_base = ["rtic-macros/cortex_m_source_masking"]
thumbv8_main = ["rtic-macros/cortex_m_basepri"]
# riscv_clic = ["rtic-macros/riscv_clic"]
# riscv_ch32 = ["rtic-macros/riscv_ch32"]
# riscv_esp32c3 = ["rtic-macros/riscv_esp32c3"]
# needed for testing
test-critical-section = ["cortex-m/critical-section-single-core", "rtic-monotonics/systick_100hz"] test-critical-section = ["cortex-m/critical-section-single-core", "rtic-monotonics/systick_100hz"]
# [[example]] # [[example]]

View file

@ -3,22 +3,21 @@ use std::env;
fn main() { fn main() {
let target = env::var("TARGET").unwrap(); let target = env::var("TARGET").unwrap();
if version_check::Channel::read().unwrap().is_nightly() {
println!("cargo:rustc-cfg=rustc_is_nightly");
}
// These targets all have know support for the BASEPRI register. // These targets all have know support for the BASEPRI register.
if target.starts_with("thumbv7m") if target.starts_with("thumbv7m")
| target.starts_with("thumbv7em") | target.starts_with("thumbv7em")
| target.starts_with("thumbv8m.main") | target.starts_with("thumbv8m.main")
{ {
println!("cargo:rustc-cfg=have_basepri"); println!("cargo:rustc-cfg=cortex_m_basepri");
} else if target.starts_with("thumbv6m") | target.starts_with("thumbv8m.base") {
println!("cargo:rustc-cfg=cortex_m_source_masking");
} else if target.starts_with("riscv32i") {
panic!("No RISC-V support yet.");
// These targets are all known to _not_ have the BASEPRI register. // TODO: Add feature here for risc-v targets
} else if target.starts_with("thumb") // println!("cargo:rustc-cfg=riscv");
&& !(target.starts_with("thumbv6m") | target.starts_with("thumbv8m.base")) } else if target.starts_with("thumb") || target.starts_with("riscv32") {
{ panic!("Unknown target '{target}'. Need to update logic in build.rs.");
panic!("Unknown target '{target}'. Need to update BASEPRI logic in build.rs.");
} }
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");

View file

@ -12,7 +12,7 @@ use panic_semihosting as _;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)] #[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)]
mod app { mod app {
use cortex_m_semihosting::{debug, hprintln}; use cortex_m_semihosting::{debug, hprintln};
use rtic_monotonics::systick_monotonic::*; use rtic_monotonics::systick::*;
rtic_monotonics::make_systick_handler!(); rtic_monotonics::make_systick_handler!();

View file

@ -9,7 +9,7 @@
use cortex_m_semihosting::{debug, hprintln}; use cortex_m_semihosting::{debug, hprintln};
use panic_semihosting as _; use panic_semihosting as _;
use rtic_monotonics::systick_monotonic::*; use rtic_monotonics::systick::*;
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)] #[rtic::app(device = lm3s6965, dispatchers = [SSI0, UART0], peripherals = true)]
mod app { mod app {

View file

@ -4,13 +4,36 @@ pub use atomic_polyfill as atomic;
pub mod executor; pub mod executor;
// #[cfg(have_basepri)] #[cfg(all(
pub mod cortex_basepri; cortex_m_basepri,
not(any(feature = "thumbv7", feature = "thumbv8_main"))
))]
compile_error!(
"Building for Cortex-M with basepri, but 'thumbv7' or 'thumbv8_main' backend not selected"
);
// #[cfg(not(have_basepri))] #[cfg(all(
pub mod cortex_source_mask; cortex_m_source_masking,
not(any(feature = "thumbv6", feature = "thumbv8_base"))
))]
compile_error!(
"Building for Cortex-M with source masking, but 'thumbv6' or 'thumbv8_base' backend not selected"
);
#[cfg(cortex_m_basepri)]
pub use cortex_basepri::*;
#[cfg(cortex_m_basepri)]
mod cortex_basepri;
#[cfg(cortex_m_source_masking)]
pub use cortex_source_mask::*;
#[cfg(cortex_m_source_masking)]
mod cortex_source_mask;
/// Priority conversion, takes logical priorities 1..=N and converts it to NVIC priority. /// Priority conversion, takes logical priorities 1..=N and converts it to NVIC priority.
#[cfg(any(cortex_m_basepri, cortex_m_source_masking))]
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn cortex_logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 { pub const fn cortex_logical2hw(logical: u8, nvic_prio_bits: u8) -> u8 {

View file

@ -59,14 +59,14 @@ where
/// but can in theory be fixed. /// but can in theory be fixed.
/// ///
#[inline(always)] #[inline(always)]
pub unsafe fn lock<T, R, const M: usize>( pub unsafe fn lock<T, R>(
ptr: *mut T, ptr: *mut T,
ceiling: u8, ceiling: u8,
nvic_prio_bits: u8, nvic_prio_bits: u8,
f: impl FnOnce(&mut T) -> R, f: impl FnOnce(&mut T) -> R,
) -> R { ) -> R {
if ceiling == (1 << nvic_prio_bits) { if ceiling == (1 << nvic_prio_bits) {
let r = interrupt::free(|_| f(&mut *ptr)); let r = critical_section::with(|_| f(&mut *ptr));
r r
} else { } else {
let current = basepri::read(); let current = basepri::read();

View file

@ -126,7 +126,7 @@ pub unsafe fn lock<T, R, const M: usize>(
// execute closure under protection of raised system ceiling // execute closure under protection of raised system ceiling
// safe to manipulate outside critical section // safe to manipulate outside critical section
interrupt::free(|_| f(&mut *ptr)) critical_section::with(|_| f(&mut *ptr))
} else { } else {
// safe to manipulate outside critical section // safe to manipulate outside critical section
let mask = compute_mask(0, ceiling, masks); let mask = compute_mask(0, ceiling, masks);
@ -164,6 +164,7 @@ pub const fn compute_mask<const M: usize>(
idx += 1; idx += 1;
} }
// old code (non const)
// masks[from_prio as usize..to_prio as usize] // masks[from_prio as usize..to_prio as usize]
// .iter() // .iter()
// .for_each(|m| res |= *m); // .for_each(|m| res |= *m);