mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-23 20:22:51 +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])]
|
#[app(device = lm3s6965, dispatchers = [UART])]
|
||||||
mod app {
|
mod app {
|
||||||
#[monotonic(binds = SomeISR1)]
|
#[monotonic(binds = SysTick)]
|
||||||
type MyMono1 = hal::Mono1;
|
type MyMono1 = hal::Mono1;
|
||||||
|
|
||||||
#[monotonic(binds = SomeISR2, default = true)]
|
#[monotonic(binds = SomeISR2, default = true)]
|
||||||
|
|
|
@ -114,11 +114,13 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let rt_err = util::rt_err_ident();
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
/// Implementation details
|
/// Implementation details
|
||||||
pub mod #name {
|
pub mod #name {
|
||||||
/// Always include the device crate which contains the vector table
|
/// 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)*
|
#(#monotonic_imports)*
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,19 @@ pub fn codegen(
|
||||||
items.push(quote!(pub use #m::spawn_at;));
|
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!(
|
items.push(quote!(
|
||||||
pub mod #m {
|
pub mod #m {
|
||||||
#(#cfgs)*
|
#(#cfgs)*
|
||||||
|
@ -287,8 +300,8 @@ pub fn codegen(
|
||||||
|
|
||||||
rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(
|
rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(
|
||||||
nr,
|
nr,
|
||||||
|| rtic::export::NVIC::unmask(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr),
|
|| #unmask,
|
||||||
|| rtic::pend(#app_path::you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#m_isr),
|
|| #pend,
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -8,6 +8,8 @@ use crate::{analyze::Analysis, check::Extra, codegen::util};
|
||||||
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
|
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
|
||||||
let mut stmts = vec![];
|
let mut stmts = vec![];
|
||||||
|
|
||||||
|
let rt_err = util::rt_err_ident();
|
||||||
|
|
||||||
// Disable interrupts -- `init` must run with interrupts disabled
|
// Disable interrupts -- `init` must run with interrupts disabled
|
||||||
stmts.push(quote!(rtic::export::interrupt::disable();));
|
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();
|
let interrupt = util::interrupt_ident();
|
||||||
stmts.push(quote!(
|
stmts.push(quote!(
|
||||||
core.NVIC.set_priority(
|
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),
|
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
||||||
);
|
);
|
||||||
));
|
));
|
||||||
|
|
||||||
// NOTE unmask the interrupt *after* setting its priority: changing the priority of a pended
|
// NOTE unmask the interrupt *after* setting its priority: changing the priority of a pended
|
||||||
// interrupt is implementation defined
|
// 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
|
// 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
|
// Compile time assert that this priority is supported by the device
|
||||||
stmts.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
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();
|
if &*name.to_string() == "SysTick" {
|
||||||
stmts.push(quote!(
|
stmts.push(quote!(
|
||||||
core.NVIC.set_priority(
|
core.SCB.set_priority(
|
||||||
you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#interrupt::#name,
|
rtic::export::SystemHandler::SysTick,
|
||||||
rtic::export::logical2hw(#priority, #nvic_prio_bits),
|
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
|
// 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
|
// Timer queue handler
|
||||||
{
|
{
|
||||||
let enum_ = util::interrupt_ident();
|
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
|
let arms = app
|
||||||
.software_tasks
|
.software_tasks
|
||||||
|
@ -83,7 +86,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
||||||
|
|
||||||
let pend = {
|
let pend = {
|
||||||
quote!(
|
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<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let bound_interrupt = &monotonic.args.binds;
|
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!(
|
items.push(quote!(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -106,7 +114,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec<TokenStrea
|
||||||
use rtic::Mutex as _;
|
use rtic::Mutex as _;
|
||||||
|
|
||||||
while let Some((task, index)) = rtic::export::interrupt::free(|_| #tq.dequeue(
|
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 {
|
match task {
|
||||||
|
|
|
@ -217,7 +217,7 @@ pub fn rq_ident(priority: u8) -> Ident {
|
||||||
|
|
||||||
/// Generates an identifier for the `enum` of `schedule`-able tasks
|
/// Generates an identifier for the `enum` of `schedule`-able tasks
|
||||||
pub fn schedule_t_ident() -> Ident {
|
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
|
/// 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())
|
Ident::new(&format!("P{}_T", priority), Span::call_site())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Suffixed identifier
|
||||||
pub fn suffixed(name: &str) -> Ident {
|
pub fn suffixed(name: &str) -> Ident {
|
||||||
let span = Span::call_site();
|
let span = Span::call_site();
|
||||||
Ident::new(name, span)
|
Ident::new(name, span)
|
||||||
|
@ -237,3 +238,11 @@ pub fn suffixed(name: &str) -> Ident {
|
||||||
pub fn tq_ident(name: &str) -> Ident {
|
pub fn tq_ident(name: &str) -> Ident {
|
||||||
Ident::new(&format!("TQ_{}", name), Span::call_site())
|
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