mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-30 15:34:33 +01:00
move dispatchers to app argument
This commit is contained in:
parent
86699039e9
commit
1c244a995d
37 changed files with 124 additions and 287 deletions
|
@ -5,6 +5,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
- Move dispatchers from extern block to app argument.
|
||||||
|
|
||||||
## [v0.5.5] - 2020-08-27
|
## [v0.5.5] - 2020-08-27
|
||||||
|
|
||||||
- Includes the previous soundness fix.
|
- Includes the previous soundness fix.
|
||||||
|
|
|
@ -6,6 +6,37 @@ This section describes how to upgrade from v0.5.x to v0.6.0 of the RTIC framewor
|
||||||
|
|
||||||
Change the version of `cortex-m-rtic` to `"0.6.0"`.
|
Change the version of `cortex-m-rtic` to `"0.6.0"`.
|
||||||
|
|
||||||
|
## Move Dispatchers from `extern "C"` to app arguments.
|
||||||
|
|
||||||
|
Change
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
#[rtic::app(/* .. */)]
|
||||||
|
const APP: () = {
|
||||||
|
[code here]
|
||||||
|
|
||||||
|
// RTIC requires that unused interrupts are declared in an extern block when
|
||||||
|
// using software tasks; these free interrupts will be used to dispatch the
|
||||||
|
// software tasks.
|
||||||
|
extern "C" {
|
||||||
|
fn SSI0();
|
||||||
|
fn QEI0();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
into
|
||||||
|
|
||||||
|
``` rust
|
||||||
|
#[rtic::app(/* .. */, dispatchers = [SSI0, QEI0])]
|
||||||
|
mod app {
|
||||||
|
[code here]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This works also for ram functions, see examples/ramfunc.rs
|
||||||
|
|
||||||
|
|
||||||
## Module instead of Const
|
## Module instead of Const
|
||||||
|
|
||||||
With the support of attributes on modules the `const APP` workaround is not needed.
|
With the support of attributes on modules the `const APP` workaround is not needed.
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
// NOTE: does NOT properly work on QEMU
|
// NOTE: does NOT properly work on QEMU
|
||||||
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
use lm3s6965::Interrupt;
|
use lm3s6965::Interrupt;
|
||||||
|
@ -47,11 +47,4 @@ mod app {
|
||||||
// `foo` inherits the baseline of `UART0`: its `start` time
|
// `foo` inherits the baseline of `UART0`: its `start` time
|
||||||
foo::spawn().unwrap();
|
foo::spawn().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
use lm3s6965::Interrupt;
|
use lm3s6965::Interrupt;
|
||||||
|
@ -40,11 +40,4 @@ mod app {
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS);
|
debug::exit(debug::EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::debug;
|
use cortex_m_semihosting::debug;
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
@ -83,12 +83,4 @@ mod app {
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
fn QEI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::debug;
|
use cortex_m_semihosting::debug;
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
@ -62,12 +62,4 @@ mod app {
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
fn QEI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use rtic::cyccnt::U32Ext;
|
use rtic::cyccnt::U32Ext;
|
||||||
|
|
||||||
|
@ -32,8 +32,4 @@ mod app {
|
||||||
fn task2(_cx: task2::Context) {
|
fn task2(_cx: task2::Context) {
|
||||||
task1::schedule(_cx.scheduled + 100.cycles()).ok();
|
task1::schedule(_cx.scheduled + 100.cycles()).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
|
|
||||||
|
@ -45,11 +45,4 @@ mod app {
|
||||||
|
|
||||||
foo::spawn().unwrap();
|
foo::spawn().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct NotSync {
|
||||||
_0: PhantomData<*const ()>,
|
_0: PhantomData<*const ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use super::NotSync;
|
use super::NotSync;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
@ -40,11 +40,4 @@ mod app {
|
||||||
fn bar(c: bar::Context) {
|
fn bar(c: bar::Context) {
|
||||||
let _: &NotSync = c.resources.shared;
|
let _: &NotSync = c.resources.shared;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
// NOTE: does NOT work on QEMU!
|
// NOTE: does NOT work on QEMU!
|
||||||
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::hprintln;
|
use cortex_m_semihosting::hprintln;
|
||||||
use rtic::cyccnt::{Instant, U32Ext};
|
use rtic::cyccnt::{Instant, U32Ext};
|
||||||
|
@ -31,11 +31,4 @@ mod app {
|
||||||
|
|
||||||
foo::schedule(cx.scheduled + PERIOD.cycles()).unwrap();
|
foo::schedule(cx.scheduled + PERIOD.cycles()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use rtic::app;
|
||||||
// Declare a pool of 128-byte memory blocks
|
// Declare a pool of 128-byte memory blocks
|
||||||
pool!(P: [u8; 128]);
|
pool!(P: [u8; 128]);
|
||||||
|
|
||||||
#[app(device = lm3s6965)]
|
#[app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use crate::{Box, Pool};
|
use crate::{Box, Pool};
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
|
@ -65,12 +65,4 @@ mod app {
|
||||||
// this is done automatically so we can omit the call to `drop`
|
// this is done automatically so we can omit the call to `drop`
|
||||||
// drop(x);
|
// drop(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
fn QEI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,14 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(
|
||||||
|
device = lm3s6965,
|
||||||
|
dispatchers = [
|
||||||
|
UART0,
|
||||||
|
#[link_section = ".data.UART1"]
|
||||||
|
UART1
|
||||||
|
])
|
||||||
|
]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
|
|
||||||
|
@ -33,12 +40,4 @@ mod app {
|
||||||
fn bar(_: bar::Context) {
|
fn bar(_: bar::Context) {
|
||||||
foo::spawn().unwrap();
|
foo::spawn().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn UART0();
|
|
||||||
|
|
||||||
// run the task dispatcher from RAM
|
|
||||||
#[link_section = ".data.UART1"]
|
|
||||||
fn UART1();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
// NOTE: does NOT work on QEMU!
|
// NOTE: does NOT work on QEMU!
|
||||||
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m::peripheral::DWT;
|
use cortex_m::peripheral::DWT;
|
||||||
use cortex_m_semihosting::hprintln;
|
use cortex_m_semihosting::hprintln;
|
||||||
|
@ -46,11 +46,4 @@ mod app {
|
||||||
fn bar(_: bar::Context) {
|
fn bar(_: bar::Context) {
|
||||||
hprintln!("bar @ {:?}", Instant::now()).unwrap();
|
hprintln!("bar @ {:?}", Instant::now()).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
|
|
||||||
|
@ -26,11 +26,4 @@ mod app {
|
||||||
}
|
}
|
||||||
foo::spawn(2, 3).unwrap();
|
foo::spawn(2, 3).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
|
|
||||||
|
@ -32,11 +32,4 @@ mod app {
|
||||||
hprintln!("foo2 {}", x).unwrap();
|
hprintln!("foo2 {}", x).unwrap();
|
||||||
foo::spawn(x, 0).unwrap();
|
foo::spawn(x, 0).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0, QEI0])]
|
||||||
mod app {
|
mod app {
|
||||||
#[resources]
|
#[resources]
|
||||||
struct Resources {
|
struct Resources {
|
||||||
|
@ -47,12 +47,4 @@ mod app {
|
||||||
#[cfg(never)]
|
#[cfg(never)]
|
||||||
#[task]
|
#[task]
|
||||||
fn quux(_: quux::Context) {}
|
fn quux(_: quux::Context) {}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
fn QEI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
#[init]
|
#[init]
|
||||||
fn init(c: init::Context) -> init::LateResources {
|
fn init(c: init::Context) -> init::LateResources {
|
||||||
|
@ -18,11 +18,4 @@ mod app {
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
fn some_task(_: some_task::Context) {}
|
fn some_task(_: some_task::Context) {}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use rtic::cyccnt::{Instant, U32Ext as _};
|
use rtic::cyccnt::{Instant, U32Ext as _};
|
||||||
|
|
||||||
|
@ -57,11 +57,4 @@ mod app {
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
fn baz(_: baz::Context, _x: u32, _y: u32) {}
|
fn baz(_: baz::Context, _x: u32, _y: u32) {}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
#[init]
|
#[init]
|
||||||
fn init(_: init::Context) -> init::LateResources {
|
fn init(_: init::Context) -> init::LateResources {
|
||||||
|
@ -55,11 +55,4 @@ mod app {
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
fn baz(_: baz::Context, _x: u32, _y: u32) {}
|
fn baz(_: baz::Context, _x: u32, _y: u32) {}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::debug;
|
use cortex_m_semihosting::debug;
|
||||||
|
|
||||||
|
@ -20,11 +20,4 @@ mod app {
|
||||||
fn taskmain(_: taskmain::Context) {
|
fn taskmain(_: taskmain::Context) {
|
||||||
debug::exit(debug::EXIT_SUCCESS);
|
debug::exit(debug::EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use cortex_m_semihosting::{debug, hprintln};
|
||||||
|
|
||||||
|
@ -47,12 +47,4 @@ mod app {
|
||||||
fn baz(_: baz::Context) {
|
fn baz(_: baz::Context) {
|
||||||
hprintln!("baz").unwrap();
|
hprintln!("baz").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
fn QEI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use panic_semihosting as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]
|
#[rtic::app(device = lm3s6965, peripherals = true, monotonic = rtic::cyccnt::CYCCNT, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::debug;
|
use cortex_m_semihosting::debug;
|
||||||
use rtic::cyccnt;
|
use rtic::cyccnt;
|
||||||
|
@ -48,11 +48,4 @@ mod app {
|
||||||
let _: &mut u32 = cx.resources.shared;
|
let _: &mut u32 = cx.resources.shared;
|
||||||
let _: foo::Resources = cx.resources;
|
let _: foo::Resources = cx.resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTIC requires that unused interrupts are declared in an extern block when
|
|
||||||
// using software tasks; these free interrupts will be used to dispatch the
|
|
||||||
// software tasks.
|
|
||||||
extern "C" {
|
|
||||||
fn SSI0();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
use rtic_syntax::{
|
use rtic_syntax::{
|
||||||
analyze::{self, Priority},
|
analyze::{self, Priority},
|
||||||
ast::App,
|
ast::{App, ExternInterrupt},
|
||||||
P,
|
P,
|
||||||
};
|
};
|
||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
|
@ -11,7 +11,7 @@ use syn::Ident;
|
||||||
/// Extend the upstream `Analysis` struct with our field
|
/// Extend the upstream `Analysis` struct with our field
|
||||||
pub struct Analysis {
|
pub struct Analysis {
|
||||||
parent: P<analyze::Analysis>,
|
parent: P<analyze::Analysis>,
|
||||||
pub interrupts: BTreeMap<Priority, Ident>,
|
pub interrupts: BTreeMap<Priority, (Ident, ExternInterrupt)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Deref for Analysis {
|
impl ops::Deref for Analysis {
|
||||||
|
@ -22,23 +22,23 @@ impl ops::Deref for Analysis {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign an `extern` interrupt to each priority level
|
// Assign an interrupt to each priority level
|
||||||
pub fn app(analysis: P<analyze::Analysis>, app: &App) -> P<Analysis> {
|
pub fn app(analysis: P<analyze::Analysis>, app: &App) -> P<Analysis> {
|
||||||
let mut interrupts = BTreeMap::new();
|
// the set of priorities (each priority only once)
|
||||||
let priorities = app
|
let priorities = app
|
||||||
.software_tasks
|
.software_tasks
|
||||||
.values()
|
.values()
|
||||||
.map(|task| task.args.priority)
|
.map(|task| task.args.priority)
|
||||||
.collect::<BTreeSet<_>>();
|
.collect::<BTreeSet<_>>();
|
||||||
|
|
||||||
if !priorities.is_empty() {
|
// map from priorities to interrupts (holding name and attributes)
|
||||||
interrupts = priorities
|
let interrupts: BTreeMap<Priority, _> = priorities
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.rev()
|
.rev()
|
||||||
.zip(app.extern_interrupts.keys().cloned())
|
.zip(&app.args.extern_interrupts)
|
||||||
.collect();
|
.map(|(p, (id, ext))| (p, (id.clone(), ext.clone())))
|
||||||
}
|
.collect();
|
||||||
|
|
||||||
P::new(Analysis {
|
P::new(Analysis {
|
||||||
parent: analysis,
|
parent: analysis,
|
||||||
|
|
|
@ -1,28 +1,19 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use rtic_syntax::{
|
use rtic_syntax::{analyze::Analysis, ast::App};
|
||||||
analyze::Analysis,
|
|
||||||
ast::{App, CustomArg},
|
|
||||||
};
|
|
||||||
use syn::{parse, Path};
|
use syn::{parse, Path};
|
||||||
|
|
||||||
pub struct Extra<'a> {
|
pub struct Extra {
|
||||||
pub device: &'a Path,
|
pub device: Path,
|
||||||
pub monotonic: Option<&'a Path>,
|
pub monotonic: Option<Path>,
|
||||||
pub peripherals: bool,
|
pub peripherals: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Extra<'a> {
|
pub fn app(app: &App, _analysis: &Analysis) -> parse::Result<Extra> {
|
||||||
pub fn monotonic(&self) -> &'a Path {
|
|
||||||
self.monotonic.expect("UNREACHABLE")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn app<'a>(app: &'a App, _analysis: &Analysis) -> parse::Result<Extra<'a>> {
|
|
||||||
// Check that external (device-specific) interrupts are not named after known (Cortex-M)
|
// Check that external (device-specific) interrupts are not named after known (Cortex-M)
|
||||||
// exceptions
|
// exceptions
|
||||||
for name in app.extern_interrupts.keys() {
|
for name in app.args.extern_interrupts.keys() {
|
||||||
let name_s = name.to_string();
|
let name_s = name.to_string();
|
||||||
|
|
||||||
match &*name_s {
|
match &*name_s {
|
||||||
|
@ -51,11 +42,11 @@ pub fn app<'a>(app: &'a App, _analysis: &Analysis) -> parse::Result<Extra<'a>> {
|
||||||
.collect::<HashSet<_>>();
|
.collect::<HashSet<_>>();
|
||||||
|
|
||||||
let need = priorities.len();
|
let need = priorities.len();
|
||||||
let given = app.extern_interrupts.len();
|
let given = app.args.extern_interrupts.len();
|
||||||
if need > given {
|
if need > given {
|
||||||
let s = {
|
let s = {
|
||||||
format!(
|
format!(
|
||||||
"not enough `extern` interrupts to dispatch \
|
"not enough interrupts to dispatch \
|
||||||
all software tasks (need: {}; given: {})",
|
all software tasks (need: {}; given: {})",
|
||||||
need, given
|
need, given
|
||||||
)
|
)
|
||||||
|
@ -66,52 +57,6 @@ pub fn app<'a>(app: &'a App, _analysis: &Analysis) -> parse::Result<Extra<'a>> {
|
||||||
return Err(parse::Error::new(first.unwrap().span(), &s));
|
return Err(parse::Error::new(first.unwrap().span(), &s));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut device = None;
|
|
||||||
let mut monotonic = None;
|
|
||||||
let mut peripherals = false;
|
|
||||||
|
|
||||||
for (k, v) in &app.args.custom {
|
|
||||||
let ks = k.to_string();
|
|
||||||
|
|
||||||
match &*ks {
|
|
||||||
"device" => match v {
|
|
||||||
CustomArg::Path(p) => device = Some(p),
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
return Err(parse::Error::new(
|
|
||||||
k.span(),
|
|
||||||
"unexpected argument value; this should be a path",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"monotonic" => match v {
|
|
||||||
CustomArg::Path(p) => monotonic = Some(p),
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
return Err(parse::Error::new(
|
|
||||||
k.span(),
|
|
||||||
"unexpected argument value; this should be a path",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"peripherals" => match v {
|
|
||||||
CustomArg::Bool(x) => peripherals = *x,
|
|
||||||
_ => {
|
|
||||||
return Err(parse::Error::new(
|
|
||||||
k.span(),
|
|
||||||
"unexpected argument value; this should be a boolean",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
return Err(parse::Error::new(k.span(), "unexpected argument"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that all exceptions are valid; only exceptions with configurable priorities are
|
// Check that all exceptions are valid; only exceptions with configurable priorities are
|
||||||
// accepted
|
// accepted
|
||||||
for (name, task) in &app.hardware_tasks {
|
for (name, task) in &app.hardware_tasks {
|
||||||
|
@ -119,7 +64,7 @@ pub fn app<'a>(app: &'a App, _analysis: &Analysis) -> parse::Result<Extra<'a>> {
|
||||||
match &*name_s {
|
match &*name_s {
|
||||||
"SysTick" => {
|
"SysTick" => {
|
||||||
// If the timer queue is used, then SysTick is unavailable
|
// If the timer queue is used, then SysTick is unavailable
|
||||||
if monotonic.is_some() {
|
if app.args.monotonic.is_some() {
|
||||||
return Err(parse::Error::new(
|
return Err(parse::Error::new(
|
||||||
name.span(),
|
name.span(),
|
||||||
"this exception can't be used because it's being used by the runtime",
|
"this exception can't be used because it's being used by the runtime",
|
||||||
|
@ -140,11 +85,11 @@ pub fn app<'a>(app: &'a App, _analysis: &Analysis) -> parse::Result<Extra<'a>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(device) = device {
|
if let Some(device) = app.args.device.clone() {
|
||||||
Ok(Extra {
|
Ok(Extra {
|
||||||
device,
|
device,
|
||||||
monotonic,
|
monotonic: app.args.monotonic.clone(),
|
||||||
peripherals,
|
peripherals: app.args.peripherals,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(parse::Error::new(
|
Err(parse::Error::new(
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
|
||||||
let user_imports = &app.user_imports;
|
let user_imports = &app.user_imports;
|
||||||
let user_code = &app.user_code;
|
let user_code = &app.user_code;
|
||||||
let name = &app.name;
|
let name = &app.name;
|
||||||
let device = extra.device;
|
let device = &extra.device;
|
||||||
|
|
||||||
// Get the list of all tasks
|
// Get the list of all tasks
|
||||||
// Currently unused, might be useful
|
// Currently unused, might be useful
|
||||||
|
|
|
@ -119,11 +119,13 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
||||||
));
|
));
|
||||||
|
|
||||||
let doc = format!("Interrupt handler to dispatch tasks at priority {}", level);
|
let doc = format!("Interrupt handler to dispatch tasks at priority {}", level);
|
||||||
let interrupt = util::suffixed(&interrupts[&level].to_string());
|
let interrupt = util::suffixed(&interrupts[&level].0.to_string());
|
||||||
|
let attribute = &interrupts[&level].1.attrs;
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[doc = #doc]
|
#[doc = #doc]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
#(#attribute)*
|
||||||
unsafe fn #interrupt() {
|
unsafe fn #interrupt() {
|
||||||
/// The priority of this interrupt handler
|
/// The priority of this interrupt handler
|
||||||
const PRIORITY: u8 = #level;
|
const PRIORITY: u8 = #level;
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub fn codegen(
|
||||||
let mut user_tasks = vec![];
|
let mut user_tasks = vec![];
|
||||||
|
|
||||||
for (name, task) in &app.hardware_tasks {
|
for (name, task) in &app.hardware_tasks {
|
||||||
let (let_instant, instant) = if let Some(m) = extra.monotonic {
|
let (let_instant, instant) = if let Some(ref m) = extra.monotonic {
|
||||||
(
|
(
|
||||||
Some(quote!(let instant = <#m as rtic::Monotonic>::now();)),
|
Some(quote!(let instant = <#m as rtic::Monotonic>::now();)),
|
||||||
Some(quote!(, instant)),
|
Some(quote!(, instant)),
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub fn codegen(
|
||||||
let mut lt = None;
|
let mut lt = None;
|
||||||
match ctxt {
|
match ctxt {
|
||||||
Context::Init => {
|
Context::Init => {
|
||||||
if let Some(m) = extra.monotonic {
|
if let Some(m) = &extra.monotonic {
|
||||||
fields.push(quote!(
|
fields.push(quote!(
|
||||||
/// System start time = `Instant(0 /* cycles */)`
|
/// System start time = `Instant(0 /* cycles */)`
|
||||||
pub start: <#m as rtic::Monotonic>::Instant
|
pub start: <#m as rtic::Monotonic>::Instant
|
||||||
|
@ -43,7 +43,7 @@ pub fn codegen(
|
||||||
}
|
}
|
||||||
|
|
||||||
if extra.peripherals {
|
if extra.peripherals {
|
||||||
let device = extra.device;
|
let device = &extra.device;
|
||||||
|
|
||||||
fields.push(quote!(
|
fields.push(quote!(
|
||||||
/// Device peripherals
|
/// Device peripherals
|
||||||
|
@ -67,7 +67,7 @@ pub fn codegen(
|
||||||
Context::Idle => {}
|
Context::Idle => {}
|
||||||
|
|
||||||
Context::HardwareTask(..) => {
|
Context::HardwareTask(..) => {
|
||||||
if let Some(m) = extra.monotonic {
|
if let Some(m) = &extra.monotonic {
|
||||||
fields.push(quote!(
|
fields.push(quote!(
|
||||||
/// Time at which this handler started executing
|
/// Time at which this handler started executing
|
||||||
pub start: <#m as rtic::Monotonic>::Instant
|
pub start: <#m as rtic::Monotonic>::Instant
|
||||||
|
@ -80,7 +80,7 @@ pub fn codegen(
|
||||||
}
|
}
|
||||||
|
|
||||||
Context::SoftwareTask(..) => {
|
Context::SoftwareTask(..) => {
|
||||||
if let Some(m) = extra.monotonic {
|
if let Some(m) = &extra.monotonic {
|
||||||
fields.push(quote!(
|
fields.push(quote!(
|
||||||
/// The time at which this task was scheduled to run
|
/// The time at which this task was scheduled to run
|
||||||
pub scheduled: <#m as rtic::Monotonic>::Instant
|
pub scheduled: <#m as rtic::Monotonic>::Instant
|
||||||
|
@ -162,7 +162,7 @@ pub fn codegen(
|
||||||
};
|
};
|
||||||
|
|
||||||
let instant = if needs_instant {
|
let instant = if needs_instant {
|
||||||
let m = extra.monotonic();
|
let m = extra.monotonic.clone().expect("RTIC-ICE: UNREACHABLE");
|
||||||
|
|
||||||
Some(quote!(, instant: <#m as rtic::Monotonic>::Instant))
|
Some(quote!(, instant: <#m as rtic::Monotonic>::Instant))
|
||||||
} else {
|
} else {
|
||||||
|
@ -205,9 +205,13 @@ pub fn codegen(
|
||||||
let app_name = &app.name;
|
let app_name = &app.name;
|
||||||
let app_path = quote! {crate::#app_name};
|
let app_path = quote! {crate::#app_name};
|
||||||
|
|
||||||
let device = extra.device;
|
let device = &extra.device;
|
||||||
let enum_ = util::interrupt_ident();
|
let enum_ = util::interrupt_ident();
|
||||||
let interrupt = &analysis.interrupts.get(&priority);
|
let interrupt = &analysis
|
||||||
|
.interrupts
|
||||||
|
.get(&priority)
|
||||||
|
.expect("RTIC-ICE: interrupt identifer not found")
|
||||||
|
.0;
|
||||||
|
|
||||||
// Spawn caller
|
// Spawn caller
|
||||||
items.push(quote!(
|
items.push(quote!(
|
||||||
|
@ -240,7 +244,7 @@ pub fn codegen(
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Schedule caller
|
// Schedule caller
|
||||||
if let Some(m) = extra.monotonic {
|
if let Some(m) = &extra.monotonic {
|
||||||
let instants = util::instants_ident(name);
|
let instants = util::instants_ident(name);
|
||||||
|
|
||||||
let tq = util::tq_ident();
|
let tq = util::tq_ident();
|
||||||
|
|
|
@ -26,22 +26,20 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
||||||
let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal().into();
|
let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal().into();
|
||||||
));
|
));
|
||||||
|
|
||||||
let device = extra.device;
|
let device = &extra.device;
|
||||||
let nvic_prio_bits = quote!(#device::NVIC_PRIO_BITS);
|
let nvic_prio_bits = quote!(#device::NVIC_PRIO_BITS);
|
||||||
|
|
||||||
|
let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
|
||||||
|
|
||||||
// Unmask interrupts and set their priorities
|
// Unmask interrupts and set their priorities
|
||||||
for (&priority, name) in analysis
|
for (&priority, name) in interrupt_ids.chain(app.hardware_tasks.values().flat_map(|task| {
|
||||||
.interrupts
|
if !util::is_exception(&task.args.binds) {
|
||||||
.iter()
|
Some((&task.args.priority, &task.args.binds))
|
||||||
.chain(app.hardware_tasks.values().flat_map(|task| {
|
} else {
|
||||||
if !util::is_exception(&task.args.binds) {
|
// We do exceptions in another pass
|
||||||
Some((&task.args.priority, &task.args.binds))
|
None
|
||||||
} else {
|
}
|
||||||
// We do exceptions in another pass
|
})) {
|
||||||
None
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
// 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)];));
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub fn codegen(
|
||||||
.map(|_| quote!(core::mem::MaybeUninit::uninit()))
|
.map(|_| quote!(core::mem::MaybeUninit::uninit()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if let Some(m) = extra.monotonic {
|
if let Some(m) = &extra.monotonic {
|
||||||
let instants = util::instants_ident(name);
|
let instants = util::instants_ident(name);
|
||||||
|
|
||||||
let uninit = mk_uninit();
|
let uninit = mk_uninit();
|
||||||
|
|
|
@ -8,7 +8,7 @@ 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 items = vec![];
|
let mut items = vec![];
|
||||||
|
|
||||||
if let Some(m) = extra.monotonic {
|
if let Some(m) = &extra.monotonic {
|
||||||
let t = util::schedule_t_ident();
|
let t = util::schedule_t_ident();
|
||||||
|
|
||||||
// Enumeration of `schedule`-able tasks
|
// Enumeration of `schedule`-able tasks
|
||||||
|
@ -71,7 +71,7 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream
|
||||||
let rq = util::rq_ident(priority);
|
let rq = util::rq_ident(priority);
|
||||||
let rqt = util::spawn_t_ident(priority);
|
let rqt = util::spawn_t_ident(priority);
|
||||||
let enum_ = util::interrupt_ident();
|
let enum_ = util::interrupt_ident();
|
||||||
let interrupt = &analysis.interrupts.get(&priority);
|
let interrupt = &analysis.interrupts.get(&priority).expect("RTIC-ICE: interrupt not found").0;
|
||||||
|
|
||||||
let pend = {
|
let pend = {
|
||||||
quote!(
|
quote!(
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub fn impl_mutex(
|
||||||
(quote!(#name), quote!(self.priority))
|
(quote!(#name), quote!(self.priority))
|
||||||
};
|
};
|
||||||
|
|
||||||
let device = extra.device;
|
let device = &extra.device;
|
||||||
quote!(
|
quote!(
|
||||||
#(#cfgs)*
|
#(#cfgs)*
|
||||||
impl<'a> rtic::Mutex for #path<'a> {
|
impl<'a> rtic::Mutex for #path<'a> {
|
||||||
|
|
|
@ -6,7 +6,8 @@ fn analyze() {
|
||||||
let mut settings = Settings::default();
|
let mut settings = Settings::default();
|
||||||
settings.parse_extern_interrupt = true;
|
settings.parse_extern_interrupt = true;
|
||||||
let (app, analysis) = rtic_syntax::parse2(
|
let (app, analysis) = rtic_syntax::parse2(
|
||||||
quote!(device = pac),
|
// First interrupt is assigned to the highest priority dispatcher
|
||||||
|
quote!(device = pac, dispatchers = [B, A]),
|
||||||
quote!(
|
quote!(
|
||||||
mod app {
|
mod app {
|
||||||
#[task(priority = 1)]
|
#[task(priority = 1)]
|
||||||
|
@ -14,12 +15,6 @@ fn analyze() {
|
||||||
|
|
||||||
#[task(priority = 2)]
|
#[task(priority = 2)]
|
||||||
fn b(_: b::Context) {}
|
fn b(_: b::Context) {}
|
||||||
|
|
||||||
// First interrupt is assigned to the highest priority dispatcher
|
|
||||||
extern "C" {
|
|
||||||
fn B();
|
|
||||||
fn A();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
settings,
|
settings,
|
||||||
|
@ -29,6 +24,6 @@ fn analyze() {
|
||||||
let analysis = crate::analyze::app(analysis, &app);
|
let analysis = crate::analyze::app(analysis, &app);
|
||||||
let interrupts = &analysis.interrupts;
|
let interrupts = &analysis.interrupts;
|
||||||
assert_eq!(interrupts.len(), 2);
|
assert_eq!(interrupts.len(), 2);
|
||||||
assert_eq!(interrupts[&2].to_string(), "B");
|
assert_eq!(interrupts[&2].0.to_string(), "B");
|
||||||
assert_eq!(interrupts[&1].to_string(), "A");
|
assert_eq!(interrupts[&1].0.to_string(), "A");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: not enough `extern` interrupts to dispatch all software tasks (need: 1; given: 0)
|
error: not enough interrupts to dispatch all software tasks (need: 1; given: 0)
|
||||||
--> $DIR/extern-interrupt-not-enough.rs:6:8
|
--> $DIR/extern-interrupt-not-enough.rs:6:8
|
||||||
|
|
|
|
||||||
6 | fn a(_: a::Context) {}
|
6 | fn a(_: a::Context) {}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [UART0])]
|
||||||
mod app {
|
mod app {
|
||||||
#[task(binds = UART0)]
|
#[task(binds = UART0)]
|
||||||
fn a(_: a::Context) {}
|
fn a(_: a::Context) {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
error: `extern` interrupts can't be used as hardware tasks
|
error: dispatcher interrupts can't be used as hardware tasks
|
||||||
--> $DIR/extern-interrupt-used.rs:5:20
|
--> $DIR/extern-interrupt-used.rs:5:20
|
||||||
|
|
|
|
||||||
5 | #[task(binds = UART0)]
|
5 | #[task(binds = UART0)]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
#[init]
|
#[init]
|
||||||
fn init(_: init::Context) -> init::LateResources {
|
fn init(_: init::Context) -> init::LateResources {
|
||||||
|
@ -46,8 +46,4 @@ mod app {
|
||||||
|
|
||||||
FOO;
|
FOO;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn UART1();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue