mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-24 19:09:33 +01:00
Merge #170
170: check task priority at compile time r=TeXitoi a=japaric before we were checking the priority at runtime. The compile time error message when the priority is too high is kind of awful though. Co-authored-by: Jorge Aparicio <jorge@japaric.io>
This commit is contained in:
commit
77def32454
5 changed files with 55 additions and 6 deletions
|
@ -69,6 +69,13 @@ the critical section created by the lowest priority handler.
|
||||||
$ cargo run --example lock
|
$ cargo run --example lock
|
||||||
{{#include ../../../../ci/expected/lock.run}}```
|
{{#include ../../../../ci/expected/lock.run}}```
|
||||||
|
|
||||||
|
One more note about priorities: choosing a priority higher than what the device
|
||||||
|
supports (that is `1 << NVIC_PRIO_BITS`) will result in a compile error. Due to
|
||||||
|
limitations in the language the error is currently far from helpful: it will say
|
||||||
|
something along the lines of "evaluation of constant value failed" and the span
|
||||||
|
of the error will *not* point out to the problematic interrupt value -- we are
|
||||||
|
sorry about this!
|
||||||
|
|
||||||
## Late resources
|
## Late resources
|
||||||
|
|
||||||
Unlike normal `static` variables, which need to be assigned an initial value
|
Unlike normal `static` variables, which need to be assigned an initial value
|
||||||
|
|
|
@ -1989,15 +1989,13 @@ fn pre_init(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::Toke
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO turn the assertions that check that the priority is not larger than what's supported by
|
|
||||||
// the device into compile errors
|
|
||||||
let device = &app.args.device;
|
let device = &app.args.device;
|
||||||
let nvic_prio_bits = quote!(#device::NVIC_PRIO_BITS);
|
let nvic_prio_bits = quote!(#device::NVIC_PRIO_BITS);
|
||||||
for (handler, interrupt) in &app.interrupts {
|
for (handler, interrupt) in &app.interrupts {
|
||||||
let name = interrupt.args.binds(handler);
|
let name = interrupt.args.binds(handler);
|
||||||
let priority = interrupt.args.priority;
|
let priority = interrupt.args.priority;
|
||||||
exprs.push(quote!(p.NVIC.enable(#device::Interrupt::#name);));
|
exprs.push(quote!(p.NVIC.enable(#device::Interrupt::#name);));
|
||||||
exprs.push(quote!(assert!(#priority <= (1 << #nvic_prio_bits));));
|
exprs.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
||||||
exprs.push(quote!(p.NVIC.set_priority(
|
exprs.push(quote!(p.NVIC.set_priority(
|
||||||
#device::Interrupt::#name,
|
#device::Interrupt::#name,
|
||||||
((1 << #nvic_prio_bits) - #priority) << (8 - #nvic_prio_bits),
|
((1 << #nvic_prio_bits) - #priority) << (8 - #nvic_prio_bits),
|
||||||
|
@ -2007,7 +2005,7 @@ fn pre_init(ctxt: &Context, app: &App, analysis: &Analysis) -> proc_macro2::Toke
|
||||||
for (priority, dispatcher) in &analysis.dispatchers {
|
for (priority, dispatcher) in &analysis.dispatchers {
|
||||||
let name = &dispatcher.interrupt;
|
let name = &dispatcher.interrupt;
|
||||||
exprs.push(quote!(p.NVIC.enable(#device::Interrupt::#name);));
|
exprs.push(quote!(p.NVIC.enable(#device::Interrupt::#name);));
|
||||||
exprs.push(quote!(assert!(#priority <= (1 << #nvic_prio_bits));));
|
exprs.push(quote!(let _ = [(); ((1 << #nvic_prio_bits) - #priority as usize)];));
|
||||||
exprs.push(quote!(p.NVIC.set_priority(
|
exprs.push(quote!(p.NVIC.set_priority(
|
||||||
#device::Interrupt::#name,
|
#device::Interrupt::#name,
|
||||||
((1 << #nvic_prio_bits) - #priority) << (8 - #nvic_prio_bits),
|
((1 << #nvic_prio_bits) - #priority) << (8 - #nvic_prio_bits),
|
||||||
|
|
|
@ -1039,10 +1039,10 @@ fn parse_args(
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = lit.value();
|
let value = lit.value();
|
||||||
if value > u64::from(u8::MAX) {
|
if value > u64::from(u8::MAX) || value == 0 {
|
||||||
return Err(parse::Error::new(
|
return Err(parse::Error::new(
|
||||||
lit.span(),
|
lit.span(),
|
||||||
"this literal must be in the range 0...255",
|
"this literal must be in the range 1...255",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
tests/cfail/priority-too-high.rs
Normal file
22
tests/cfail/priority-too-high.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate lm3s6965;
|
||||||
|
extern crate panic_halt;
|
||||||
|
extern crate rtfm;
|
||||||
|
|
||||||
|
use rtfm::app;
|
||||||
|
|
||||||
|
#[app(device = lm3s6965)] //~ error evaluation of constant value failed
|
||||||
|
const APP: () = {
|
||||||
|
#[init]
|
||||||
|
fn init() {}
|
||||||
|
|
||||||
|
// OK, this is the maximum priority supported by the device
|
||||||
|
#[interrupt(priority = 8)]
|
||||||
|
fn UART0() {}
|
||||||
|
|
||||||
|
// this value is too high!
|
||||||
|
#[interrupt(priority = 9)]
|
||||||
|
fn UART1() {}
|
||||||
|
};
|
22
tests/cfail/priority-too-low.rs
Normal file
22
tests/cfail/priority-too-low.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#![no_main]
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate lm3s6965;
|
||||||
|
extern crate panic_halt;
|
||||||
|
extern crate rtfm;
|
||||||
|
|
||||||
|
use rtfm::app;
|
||||||
|
|
||||||
|
#[app(device = lm3s6965)]
|
||||||
|
const APP: () = {
|
||||||
|
#[init]
|
||||||
|
fn init() {}
|
||||||
|
|
||||||
|
// OK, this is the minimum priority that tasks can have
|
||||||
|
#[interrupt(priority = 1)]
|
||||||
|
fn UART0() {}
|
||||||
|
|
||||||
|
// this value is too low!
|
||||||
|
#[interrupt(priority = 0)] //~ error this literal must be in the range 1...255
|
||||||
|
fn UART1() {}
|
||||||
|
};
|
Loading…
Reference in a new issue