Merge branch 'master' into master

This commit is contained in:
Román Cárdenas 2023-03-29 21:07:36 +02:00 committed by GitHub
commit ce508a1882
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 55 additions and 17 deletions

View file

@ -7,7 +7,7 @@ All examples in this part of the book are accessible at the
The examples are runnable on QEMU (emulating a Cortex M3 target), The examples are runnable on QEMU (emulating a Cortex M3 target),
thus no special hardware required to follow along. thus no special hardware required to follow along.
[repoexamples]: https://github.com/rtic-rs/rtic/tree/master/examples [repoexamples]: https://github.com/rtic-rs/rtic/tree/master/rtic/examples
## Running an example ## Running an example

View file

@ -11,6 +11,7 @@ use syn::Ident;
pub struct Analysis { pub struct Analysis {
parent: analyze::Analysis, parent: analyze::Analysis,
pub interrupts: BTreeMap<Priority, (Ident, Dispatcher)>, pub interrupts: BTreeMap<Priority, (Ident, Dispatcher)>,
pub max_async_prio: Option<u8>,
} }
impl ops::Deref for Analysis { impl ops::Deref for Analysis {
@ -42,8 +43,16 @@ pub fn app(analysis: analyze::Analysis, app: &App) -> Analysis {
.map(|p| (p, available_interrupt.pop().expect("UNREACHABLE"))) .map(|p| (p, available_interrupt.pop().expect("UNREACHABLE")))
.collect(); .collect();
let max_async_prio = app
.hardware_tasks
.iter()
.map(|(_, task)| task.args.priority)
.min()
.map(|v| v - 1); // One less than the smallest HW task
Analysis { Analysis {
parent: analysis, parent: analysis,
interrupts, interrupts,
max_async_prio,
} }
} }

View file

@ -45,6 +45,7 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
let device = &app.args.device; let device = &app.args.device;
let rt_err = util::rt_err_ident(); let rt_err = util::rt_err_ident();
let async_limit = bindings::async_prio_limit(app, analysis);
quote!( quote!(
/// The RTIC application module /// The RTIC application module
@ -52,6 +53,8 @@ pub fn app(app: &App, analysis: &Analysis) -> TokenStream2 {
/// Always include the device crate which contains the vector table /// Always include the device crate which contains the vector table
use #device as #rt_err; use #device as #rt_err;
#(#async_limit)*
#(#user_imports)* #(#user_imports)*
#(#user_code)* #(#user_code)*

View file

@ -322,3 +322,19 @@ pub fn interrupt_entry(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStre
pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> { pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![] vec![]
} }
pub fn async_prio_limit(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
let max = if let Some(max) = analysis.max_async_prio {
quote!(#max)
} else {
// No limit
let device = &app.args.device;
quote!(1 << #device::NVIC_PRIO_BITS)
};
vec![quote!(
/// Holds the maximum priority level for use by async HAL drivers.
#[no_mangle]
static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = #max;
)]
}

View file

@ -42,3 +42,7 @@ pub fn interrupt_entry(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStre
pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> { pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![] vec![]
} }
pub fn async_prio_limit(app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![]
}

View file

@ -289,11 +289,13 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
// Handle comma: , // Handle comma: ,
let _: Token![,] = content.parse()?; let _: Token![,] = content.parse()?;
} }
let priority = priority.unwrap_or(1);
let shared_resources = shared_resources.unwrap_or_default(); let shared_resources = shared_resources.unwrap_or_default();
let local_resources = local_resources.unwrap_or_default(); let local_resources = local_resources.unwrap_or_default();
Ok(if let Some(binds) = binds { Ok(if let Some(binds) = binds {
// Hardware tasks can't run at anything lower than 1
let priority = priority.unwrap_or(1);
if priority == 0 { if priority == 0 {
return Err(parse::Error::new( return Err(parse::Error::new(
prio_span.unwrap(), prio_span.unwrap(),
@ -308,6 +310,9 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
local_resources, local_resources,
}) })
} else { } else {
// Software tasks start at idle priority
let priority = priority.unwrap_or(0);
Either::Right(SoftwareTaskArgs { Either::Right(SoftwareTaskArgs {
priority, priority,
shared_resources, shared_resources,

View file

@ -138,7 +138,7 @@ impl embedded_hal_async::delay::DelayUs for Timer {
/// Register the Timer interrupt for the monotonic. /// Register the Timer interrupt for the monotonic.
#[macro_export] #[macro_export]
macro_rules! make_rp2040_monotonic_handler { macro_rules! create_rp2040_monotonic_token {
() => {{ () => {{
#[no_mangle] #[no_mangle]
#[allow(non_snake_case)] #[allow(non_snake_case)]

View file

@ -156,7 +156,7 @@ impl embedded_hal_async::delay::DelayUs for Systick {
/// Register the Systick interrupt for the monotonic. /// Register the Systick interrupt for the monotonic.
#[macro_export] #[macro_export]
macro_rules! make_systick_handler { macro_rules! create_systick_token {
() => {{ () => {{
#[no_mangle] #[no_mangle]
#[allow(non_snake_case)] #[allow(non_snake_case)]

View file

@ -15,6 +15,7 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
- `cortex-m` set as an optional dependency - `cortex-m` set as an optional dependency
- Moved `cortex-m`-related utilities from `rtic/lib.rs` to `rtic/export.rs` - Moved `cortex-m`-related utilities from `rtic/lib.rs` to `rtic/export.rs`
- Make async task priorities start at 0, instead of 1, to always start at the lowest priority
## [v1.1.4] - 2023-02-26 ## [v1.1.4] - 2023-02-26

View file

@ -24,7 +24,7 @@ mod app {
fn init(cx: init::Context) -> (Shared, Local) { fn init(cx: init::Context) -> (Shared, Local) {
hprintln!("init"); hprintln!("init");
let systick_token = rtic_monotonics::make_systick_handler!(); let systick_token = rtic_monotonics::create_systick_token!();
Systick::start(cx.core.SYST, 12_000_000, systick_token); Systick::start(cx.core.SYST, 12_000_000, systick_token);
foo::spawn().ok(); foo::spawn().ok();

View file

@ -53,13 +53,13 @@ mod app {
hprintln!("hello from hw"); hprintln!("hello from hw");
} }
#[task(shared = [a])] #[task(shared = [a], priority = 1)]
async fn async_task(cx: async_task::Context) { async fn async_task(cx: async_task::Context) {
let async_task::SharedResources { a: _, .. } = cx.shared; let async_task::SharedResources { a: _, .. } = cx.shared;
hprintln!("hello from async"); hprintln!("hello from async");
} }
#[task] #[task(priority = 1)]
async fn async_task_args(_cx: async_task_args::Context, a: u32, b: i32) { async fn async_task_args(_cx: async_task_args::Context, a: u32, b: i32) {
hprintln!("hello from async with args a: {}, b: {}", a, b); hprintln!("hello from async with args a: {}, b: {}", a, b);
} }

View file

@ -27,7 +27,7 @@ mod app {
fn init(cx: init::Context) -> (Shared, Local) { fn init(cx: init::Context) -> (Shared, Local) {
hprintln!("init"); hprintln!("init");
let systick_token = rtic_monotonics::make_systick_handler!(); let systick_token = rtic_monotonics::create_systick_token!();
Systick::start(cx.core.SYST, 12_000_000, systick_token); Systick::start(cx.core.SYST, 12_000_000, systick_token);
foo::spawn().ok(); foo::spawn().ok();

View file

@ -62,7 +62,7 @@ mod app {
} }
// `local_to_foo` can only be accessed from this context // `local_to_foo` can only be accessed from this context
#[task(local = [local_to_foo])] #[task(local = [local_to_foo], priority = 1)]
async fn foo(cx: foo::Context) { async fn foo(cx: foo::Context) {
let local_to_foo = cx.local.local_to_foo; let local_to_foo = cx.local.local_to_foo;
*local_to_foo += 1; *local_to_foo += 1;
@ -74,7 +74,7 @@ mod app {
} }
// `local_to_bar` can only be accessed from this context // `local_to_bar` can only be accessed from this context
#[task(local = [local_to_bar])] #[task(local = [local_to_bar], priority = 1)]
async fn bar(cx: bar::Context) { async fn bar(cx: bar::Context) {
let local_to_bar = cx.local.local_to_bar; let local_to_bar = cx.local.local_to_bar;
*local_to_bar += 1; *local_to_bar += 1;

View file

@ -38,7 +38,7 @@ mod app {
} }
// Direct destructure // Direct destructure
#[task(shared = [&a, &b, &c])] #[task(shared = [&a, &b, &c], priority = 1)]
async fn foo(cx: foo::Context) { async fn foo(cx: foo::Context) {
let a = cx.shared.a; let a = cx.shared.a;
let b = cx.shared.b; let b = cx.shared.b;
@ -48,7 +48,7 @@ mod app {
} }
// De-structure-ing syntax // De-structure-ing syntax
#[task(shared = [&a, &b, &c])] #[task(shared = [&a, &b, &c], priority = 1)]
async fn bar(cx: bar::Context) { async fn bar(cx: bar::Context) {
let bar::SharedResources { a, b, c, .. } = cx.shared; let bar::SharedResources { a, b, c, .. } = cx.shared;

View file

@ -62,7 +62,7 @@ mod app {
} }
// `local_to_foo` can only be accessed from this context // `local_to_foo` can only be accessed from this context
#[task(local = [local_to_foo])] #[task(local = [local_to_foo], priority = 1)]
async fn foo(cx: foo::Context) { async fn foo(cx: foo::Context) {
let local_to_foo = cx.local.local_to_foo; let local_to_foo = cx.local.local_to_foo;
*local_to_foo += 1; *local_to_foo += 1;
@ -74,7 +74,7 @@ mod app {
} }
// `local_to_bar` can only be accessed from this context // `local_to_bar` can only be accessed from this context
#[task(local = [local_to_bar])] #[task(local = [local_to_bar], priority = 1)]
async fn bar(cx: bar::Context) { async fn bar(cx: bar::Context) {
let local_to_bar = cx.local.local_to_bar; let local_to_bar = cx.local.local_to_bar;
*local_to_bar += 1; *local_to_bar += 1;

View file

@ -54,13 +54,13 @@ mod app {
loop {} loop {}
} }
#[task(shared = [&shared])] #[task(shared = [&shared], priority = 1)]
async fn foo(c: foo::Context) { async fn foo(c: foo::Context) {
let shared: &NotSync = c.shared.shared; let shared: &NotSync = c.shared.shared;
hprintln!("foo a {}", shared.data); hprintln!("foo a {}", shared.data);
} }
#[task(shared = [&shared])] #[task(shared = [&shared], priority = 1)]
async fn bar(c: bar::Context) { async fn bar(c: bar::Context) {
let shared: &NotSync = c.shared.shared; let shared: &NotSync = c.shared.shared;
hprintln!("bar a {}", shared.data); hprintln!("bar a {}", shared.data);

View file

@ -51,7 +51,7 @@ mod app {
} }
} }
#[task(local = [p, state: u32 = 0])] #[task(local = [p, state: u32 = 0], priority = 1)]
async fn foo(c: foo::Context) { async fn foo(c: foo::Context) {
*c.local.state += 1; *c.local.state += 1;