Now handling SysTick as well

This commit is contained in:
Emil Fresk 2020-12-13 14:52:16 +01:00
parent 0e134a41b5
commit 6277183906
6 changed files with 61 additions and 17 deletions

View file

@ -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)]

View file

@ -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)*

View file

@ -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(())

View file

@ -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)];));
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(
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 we do not unmask the interrupt as this is part of the monotonic to keep track of
}

View file

@ -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 {

View file

@ -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(),
)
}