2019-06-29 09:11:42 +02:00
|
|
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
|
2022-12-31 14:45:13 +01:00
|
|
|
use crate::syntax::{ast::App, Context};
|
2019-06-13 23:56:59 +02:00
|
|
|
use proc_macro2::{Span, TokenStream as TokenStream2};
|
|
|
|
use quote::quote;
|
2023-01-03 15:10:59 +01:00
|
|
|
use syn::{Attribute, Ident};
|
2019-06-13 23:56:59 +02:00
|
|
|
|
2021-08-19 21:32:12 +02:00
|
|
|
const RTIC_INTERNAL: &str = "__rtic_internal";
|
|
|
|
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Generates a `Mutex` implementation
|
|
|
|
pub fn impl_mutex(
|
2022-12-31 14:45:13 +01:00
|
|
|
app: &App,
|
2019-06-13 23:56:59 +02:00
|
|
|
cfgs: &[Attribute],
|
|
|
|
resources_prefix: bool,
|
|
|
|
name: &Ident,
|
2022-02-18 19:38:48 +01:00
|
|
|
ty: &TokenStream2,
|
2019-06-13 23:56:59 +02:00
|
|
|
ceiling: u8,
|
2022-02-18 19:38:48 +01:00
|
|
|
ptr: &TokenStream2,
|
2019-06-13 23:56:59 +02:00
|
|
|
) -> TokenStream2 {
|
2023-01-07 11:24:13 +01:00
|
|
|
let path = if resources_prefix {
|
|
|
|
quote!(shared_resources::#name)
|
2019-06-13 23:56:59 +02:00
|
|
|
} else {
|
2023-01-07 11:24:13 +01:00
|
|
|
quote!(#name)
|
2019-06-13 23:56:59 +02:00
|
|
|
};
|
|
|
|
|
2022-12-31 14:45:13 +01:00
|
|
|
let device = &app.args.device;
|
2022-04-20 10:46:03 +02:00
|
|
|
let masks_name = priority_masks_ident();
|
2019-06-13 23:56:59 +02:00
|
|
|
quote!(
|
|
|
|
#(#cfgs)*
|
2020-06-11 19:18:29 +02:00
|
|
|
impl<'a> rtic::Mutex for #path<'a> {
|
2019-06-13 23:56:59 +02:00
|
|
|
type T = #ty;
|
|
|
|
|
|
|
|
#[inline(always)]
|
2020-10-21 20:24:06 +02:00
|
|
|
fn lock<RTIC_INTERNAL_R>(&mut self, f: impl FnOnce(&mut #ty) -> RTIC_INTERNAL_R) -> RTIC_INTERNAL_R {
|
2019-06-13 23:56:59 +02:00
|
|
|
/// Priority ceiling
|
|
|
|
const CEILING: u8 = #ceiling;
|
|
|
|
|
|
|
|
unsafe {
|
2020-06-11 19:18:29 +02:00
|
|
|
rtic::export::lock(
|
2019-06-13 23:56:59 +02:00
|
|
|
#ptr,
|
|
|
|
CEILING,
|
|
|
|
#device::NVIC_PRIO_BITS,
|
2022-04-20 10:46:03 +02:00
|
|
|
&#masks_name,
|
2019-06-13 23:56:59 +02:00
|
|
|
f,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-12-31 14:45:13 +01:00
|
|
|
/// Generates an identifier for the `EXECUTOR_RUN` atomics (`async` API)
|
|
|
|
pub fn executor_run_ident(task: &Ident) -> Ident {
|
|
|
|
mark_internal_name(&format!("{}_EXECUTOR_RUN", task))
|
|
|
|
}
|
|
|
|
|
2020-08-27 13:21:56 +02:00
|
|
|
pub fn interrupt_ident() -> Ident {
|
2019-06-18 10:31:31 +02:00
|
|
|
let span = Span::call_site();
|
2020-10-14 20:27:43 +02:00
|
|
|
Ident::new("interrupt", span)
|
2019-06-18 10:31:31 +02:00
|
|
|
}
|
|
|
|
|
2019-06-20 06:19:59 +02:00
|
|
|
/// Whether `name` is an exception with configurable priority
|
|
|
|
pub fn is_exception(name: &Ident) -> bool {
|
|
|
|
let s = name.to_string();
|
|
|
|
|
2020-10-13 16:16:33 +02:00
|
|
|
matches!(
|
|
|
|
&*s,
|
|
|
|
"MemoryManagement"
|
|
|
|
| "BusFault"
|
|
|
|
| "UsageFault"
|
|
|
|
| "SecureFault"
|
|
|
|
| "SVCall"
|
|
|
|
| "DebugMonitor"
|
|
|
|
| "PendSV"
|
|
|
|
| "SysTick"
|
|
|
|
)
|
2019-06-20 06:19:59 +02:00
|
|
|
}
|
|
|
|
|
2021-08-19 21:32:12 +02:00
|
|
|
/// Mark a name as internal
|
|
|
|
pub fn mark_internal_name(name: &str) -> Ident {
|
|
|
|
Ident::new(&format!("{}_{}", RTIC_INTERNAL, name), Span::call_site())
|
|
|
|
}
|
|
|
|
|
2021-05-06 19:40:37 +02:00
|
|
|
/// Generate an internal identifier for tasks
|
|
|
|
pub fn internal_task_ident(task: &Ident, ident_name: &str) -> Ident {
|
2022-02-09 18:56:35 +01:00
|
|
|
mark_internal_name(&format!("{}_{}", task, ident_name))
|
2021-05-06 19:40:37 +02:00
|
|
|
}
|
|
|
|
|
2019-06-29 09:11:42 +02:00
|
|
|
fn link_section_index() -> usize {
|
|
|
|
static INDEX: AtomicUsize = AtomicUsize::new(0);
|
|
|
|
|
|
|
|
INDEX.fetch_add(1, Ordering::Relaxed)
|
|
|
|
}
|
|
|
|
|
2022-02-18 19:38:48 +01:00
|
|
|
/// Add `link_section` attribute
|
|
|
|
pub fn link_section_uninit() -> TokenStream2 {
|
2021-07-08 23:18:44 +02:00
|
|
|
let section = format!(".uninit.rtic{}", link_section_index());
|
2019-06-29 09:11:42 +02:00
|
|
|
|
2022-02-18 19:38:48 +01:00
|
|
|
quote!(#[link_section = #section])
|
2019-06-29 09:11:42 +02:00
|
|
|
}
|
|
|
|
|
2021-07-07 22:50:59 +02:00
|
|
|
/// Get the ident for the name of the task
|
|
|
|
pub fn get_task_name(ctxt: Context, app: &App) -> Ident {
|
|
|
|
let s = match ctxt {
|
|
|
|
Context::Init => app.init.name.to_string(),
|
2022-12-31 14:45:13 +01:00
|
|
|
Context::Idle => app
|
|
|
|
.idle
|
|
|
|
.as_ref()
|
|
|
|
.expect("RTIC-ICE: unable to find idle name")
|
|
|
|
.name
|
|
|
|
.to_string(),
|
2021-07-07 22:50:59 +02:00
|
|
|
Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
|
|
|
|
};
|
|
|
|
|
|
|
|
Ident::new(&s, Span::call_site())
|
|
|
|
}
|
|
|
|
|
2021-07-05 21:40:01 +02:00
|
|
|
/// Generates a pre-reexport identifier for the "shared resources" struct
|
|
|
|
pub fn shared_resources_ident(ctxt: Context, app: &App) -> Ident {
|
2019-06-13 23:56:59 +02:00
|
|
|
let mut s = match ctxt {
|
2021-07-05 21:40:01 +02:00
|
|
|
Context::Init => app.init.name.to_string(),
|
2022-12-31 14:45:13 +01:00
|
|
|
Context::Idle => app
|
|
|
|
.idle
|
|
|
|
.as_ref()
|
|
|
|
.expect("RTIC-ICE: unable to find idle name")
|
|
|
|
.name
|
|
|
|
.to_string(),
|
2019-06-13 23:56:59 +02:00
|
|
|
Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
|
|
|
|
};
|
|
|
|
|
2021-07-05 21:40:01 +02:00
|
|
|
s.push_str("SharedResources");
|
|
|
|
|
2021-08-19 21:32:12 +02:00
|
|
|
mark_internal_name(&s)
|
2021-07-05 21:40:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Generates a pre-reexport identifier for the "local resources" struct
|
|
|
|
pub fn local_resources_ident(ctxt: Context, app: &App) -> Ident {
|
|
|
|
let mut s = match ctxt {
|
|
|
|
Context::Init => app.init.name.to_string(),
|
2022-12-31 14:45:13 +01:00
|
|
|
Context::Idle => app
|
|
|
|
.idle
|
|
|
|
.as_ref()
|
|
|
|
.expect("RTIC-ICE: unable to find idle name")
|
|
|
|
.name
|
|
|
|
.to_string(),
|
2021-07-05 21:40:01 +02:00
|
|
|
Context::HardwareTask(ident) | Context::SoftwareTask(ident) => ident.to_string(),
|
|
|
|
};
|
|
|
|
|
|
|
|
s.push_str("LocalResources");
|
2019-06-13 23:56:59 +02:00
|
|
|
|
2021-08-19 21:32:12 +02:00
|
|
|
mark_internal_name(&s)
|
2019-06-13 23:56:59 +02:00
|
|
|
}
|
|
|
|
|
2022-12-31 14:45:13 +01:00
|
|
|
/// Generates an identifier for a ready queue, async task version
|
|
|
|
pub fn rq_async_ident(async_task_name: &Ident) -> Ident {
|
2023-01-04 21:33:41 +01:00
|
|
|
mark_internal_name(&format!("ASYNC_TASK_{}_RQ", async_task_name))
|
2022-12-31 14:45:13 +01:00
|
|
|
}
|
|
|
|
|
2020-12-13 14:52:16 +01:00
|
|
|
/// Suffixed identifier
|
2020-08-27 13:21:56 +02:00
|
|
|
pub fn suffixed(name: &str) -> Ident {
|
2019-06-18 10:31:31 +02:00
|
|
|
let span = Span::call_site();
|
2020-08-27 13:21:56 +02:00
|
|
|
Ident::new(name, span)
|
2019-06-18 10:31:31 +02:00
|
|
|
}
|
|
|
|
|
2021-07-06 22:47:48 +02:00
|
|
|
pub fn static_shared_resource_ident(name: &Ident) -> Ident {
|
2022-02-09 18:56:35 +01:00
|
|
|
mark_internal_name(&format!("shared_resource_{}", name))
|
2021-07-06 22:47:48 +02:00
|
|
|
}
|
|
|
|
|
2022-07-03 18:24:11 +02:00
|
|
|
/// Generates an Ident for the number of 32 bit chunks used for Mask storage.
|
|
|
|
pub fn priority_mask_chunks_ident() -> Ident {
|
|
|
|
mark_internal_name("MASK_CHUNKS")
|
|
|
|
}
|
|
|
|
|
2022-04-20 10:46:03 +02:00
|
|
|
pub fn priority_masks_ident() -> Ident {
|
|
|
|
mark_internal_name("MASKS")
|
|
|
|
}
|
|
|
|
|
2021-07-06 22:47:48 +02:00
|
|
|
pub fn static_local_resource_ident(name: &Ident) -> Ident {
|
2022-02-09 18:56:35 +01:00
|
|
|
mark_internal_name(&format!("local_resource_{}", name))
|
2021-07-07 22:50:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn declared_static_local_resource_ident(name: &Ident, task_name: &Ident) -> Ident {
|
2022-02-09 18:56:35 +01:00
|
|
|
mark_internal_name(&format!("local_{}_{}", task_name, name))
|
2021-07-06 22:47:48 +02:00
|
|
|
}
|
|
|
|
|
2021-11-11 14:22:47 +01:00
|
|
|
pub fn need_to_lock_ident(name: &Ident) -> Ident {
|
2022-02-09 18:56:35 +01:00
|
|
|
Ident::new(&format!("{}_that_needs_to_be_locked", name), name.span())
|
2021-11-11 14:22:47 +01:00
|
|
|
}
|
|
|
|
|
2023-01-08 21:10:06 +01:00
|
|
|
pub fn zero_prio_dispatcher_ident() -> Ident {
|
|
|
|
Ident::new("__rtic_internal_async_0_prio_dispatcher", Span::call_site())
|
|
|
|
}
|
|
|
|
|
2020-12-13 14:52:16 +01:00
|
|
|
/// The name to get better RT flag errors
|
|
|
|
pub fn rt_err_ident() -> Ident {
|
|
|
|
Ident::new(
|
2021-12-25 13:17:16 +01:00
|
|
|
"you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml",
|
2020-12-13 14:52:16 +01:00
|
|
|
Span::call_site(),
|
|
|
|
)
|
|
|
|
}
|