mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-24 02:49:34 +01:00
Now handling SysTick as well
This commit is contained in:
parent
0e134a41b5
commit
6277183906
6 changed files with 61 additions and 17 deletions
|
@ -8,7 +8,7 @@ use rtic::app;
|
|||
|
||||
#[app(device = lm3s6965, dispatchers = [UART])]
|
||||
mod app {
|
||||
#[monotonic(binds = SomeISR1)]
|
||||
#[monotonic(binds = SysTick)]
|
||||
type MyMono1 = hal::Mono1;
|
||||
|
||||
#[monotonic(binds = SomeISR2, default = true)]
|
||||
|
|
|
@ -114,11 +114,13 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let rt_err = util::rt_err_ident();
|
||||
|
||||
quote!(
|
||||
/// Implementation details
|
||||
pub mod #name {
|
||||
/// Always include the device crate which contains the vector table
|
||||
use #device as you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml;
|
||||
use #device as #rt_err;
|
||||
|
||||
#(#monotonic_imports)*
|
||||
|
||||
|
|
|
@ -246,6 +246,19 @@ pub fn codegen(
|
|||
items.push(quote!(pub use #m::spawn_at;));
|
||||
}
|
||||
|
||||
let (unmask, pend) = if &*m_isr.to_string() == "SysTick" {
|
||||
(
|
||||
quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).disable_interrupt()),
|
||||
quote!(cortex_m::peripheral::SCB::set_pendst()),
|
||||
)
|
||||
} else {
|
||||
let rt_err = util::rt_err_ident();
|
||||
(
|
||||
quote!(rtic::export::NVIC::unmask(#app_path::#rt_err::#enum_::#m_isr)),
|
||||
quote!(rtic::pend(#app_path::#rt_err::#enum_::#m_isr)),
|
||||
)
|
||||
};
|
||||
|
||||
items.push(quote!(
|
||||
pub mod #m {
|
||||
#(#cfgs)*
|
||||
|
@ -287,8 +300,8 @@ pub fn codegen(
|
|||
|
||||
rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(
|
||||
nr,
|
||||
|| rtic::export::NVIC::unmask(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr),
|
||||
|| rtic::pend(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr),
|
||||
|| #unmask,
|
||||
|| #pend,
|
||||
));
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -8,6 +8,8 @@ use crate::{analyze::Analysis, check::Extra, codegen::util};
|
|||
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
|
||||
let mut stmts = vec![];
|
||||
|
||||
let rt_err = util::rt_err_ident();
|
||||
|
||||
// Disable interrupts -- `init` must run with interrupts disabled
|
||||
stmts.push(quote!(rtic::export::interrupt::disable();));
|
||||
|
||||
|
@ -47,14 +49,14 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
let interrupt = util::interrupt_ident();
|
||||
stmts.push(quote!(
|
||||
core.NVIC.set_priority(
|
||||
you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#interrupt::#name,
|
||||
#rt_err::#interrupt::#name,
|
||||
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||
);
|
||||
));
|
||||
|
||||
// NOTE unmask the interrupt *after* setting its priority: changing the priority of a pended
|
||||
// interrupt is implementation defined
|
||||
stmts.push(quote!(rtic::export::NVIC::unmask(you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#interrupt::#name);));
|
||||
stmts.push(quote!(rtic::export::NVIC::unmask(#rt_err::#interrupt::#name);));
|
||||
}
|
||||
|
||||
// Set exception priorities
|
||||
|
@ -83,14 +85,24 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
|||
// Compile time assert that this priority is supported by the device
|
||||
stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
||||
|
||||
// NOTE this also checks that the interrupt exists in the `Interrupt` enumeration
|
||||
let interrupt = util::interrupt_ident();
|
||||
stmts.push(quote!(
|
||||
core.NVIC.set_priority(
|
||||
you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#interrupt::#name,
|
||||
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||
);
|
||||
));
|
||||
|
||||
if &*name.to_string() == "SysTick" {
|
||||
stmts.push(quote!(
|
||||
core.SCB.set_priority(
|
||||
rtic::export::SystemHandler::SysTick,
|
||||
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||
);
|
||||
));
|
||||
} else {
|
||||
// NOTE this also checks that the interrupt exists in the `Interrupt` enumeration
|
||||
let interrupt = util::interrupt_ident();
|
||||
stmts.push(quote!(
|
||||
core.NVIC.set_priority(
|
||||
#rt_err::#interrupt::#name,
|
||||
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
// NOTE we do not unmask the interrupt as this is part of the monotonic to keep track of
|
||||
}
|
||||
|
|
|
@ -68,6 +68,9 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
// Timer queue handler
|
||||
{
|
||||
let enum_ = util::interrupt_ident();
|
||||
let app_name = &app.name;
|
||||
let app_path = quote! {crate::#app_name};
|
||||
let rt_err = util::rt_err_ident();
|
||||
|
||||
let arms = app
|
||||
.software_tasks
|
||||
|
@ -83,7 +86,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
|
||||
let pend = {
|
||||
quote!(
|
||||
rtic::pend(you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#interrupt);
|
||||
rtic::pend(#rt_err::#enum_::#interrupt);
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -99,6 +102,11 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
let bound_interrupt = &monotonic.args.binds;
|
||||
let enable_isr = if &*bound_interrupt.to_string() == "SysTick" {
|
||||
quote!(core::mem::transmute::<_, cortex_m::peripheral::SYST>(()).enable_interrupt())
|
||||
} else {
|
||||
quote!(rtic::export::NVIC::mask(#rt_err::#enum_::#bound_interrupt))
|
||||
};
|
||||
|
||||
items.push(quote!(
|
||||
#[no_mangle]
|
||||
|
@ -106,7 +114,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
|||
use rtic::Mutex as _;
|
||||
|
||||
while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue(
|
||||
|| rtic::export::NVIC::unmask(you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#bound_interrupt),
|
||||
|| #enable_isr,
|
||||
))
|
||||
{
|
||||
match task {
|
||||
|
|
|
@ -217,7 +217,7 @@ pub fn rq_ident(priority: u8) -> Ident {
|
|||
|
||||
/// Generates an identifier for the `enum` of `schedule`-able tasks
|
||||
pub fn schedule_t_ident() -> Ident {
|
||||
Ident::new(&"SCHED_T".to_string(), Span::call_site())
|
||||
Ident::new(&"SCHED_T", Span::call_site())
|
||||
}
|
||||
|
||||
/// Generates an identifier for the `enum` of `spawn`-able tasks
|
||||
|
@ -228,6 +228,7 @@ pub fn spawn_t_ident(priority: u8) -> Ident {
|
|||
Ident::new(&format!("P{}_T", priority), Span::call_site())
|
||||
}
|
||||
|
||||
/// Suffixed identifier
|
||||
pub fn suffixed(name: &str) -> Ident {
|
||||
let span = Span::call_site();
|
||||
Ident::new(name, span)
|
||||
|
@ -237,3 +238,11 @@ pub fn suffixed(name: &str) -> Ident {
|
|||
pub fn tq_ident(name: &str) -> Ident {
|
||||
Ident::new(&format!("TQ_{}", name), Span::call_site())
|
||||
}
|
||||
|
||||
/// The name to get better RT flag errors
|
||||
pub fn rt_err_ident() -> Ident {
|
||||
Ident::new(
|
||||
&"you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml",
|
||||
Span::call_site(),
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue