mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-27 14:04:56 +01:00
Add feature flags
This commit is contained in:
parent
60f0342b69
commit
b9e0f36aff
12 changed files with 88 additions and 73 deletions
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
);));
|
);));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]]
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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!();
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue