mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-23 20:22:51 +01:00
Merge branch 'master' into master
This commit is contained in:
commit
ce508a1882
17 changed files with 55 additions and 17 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)*
|
||||||
|
|
|
@ -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;
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
|
@ -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![]
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue