diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 56183c3ac9..8da98678e1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -85,7 +85,7 @@ jobs: command: check args: --target=${{ matrix.target }} - # Verify all examples + # Verify all examples, checks checkexamples: name: checkexamples runs-on: ubuntu-20.04 @@ -140,6 +140,51 @@ jobs: command: check args: --examples --target=${{ matrix.target }} --features __min_r1_43,${{ env.V7 }} + # Verify the example output with run-pass tests + testexamples: + name: testexamples + runs-on: ubuntu-20.04 + strategy: + matrix: + target: + - thumbv7m-none-eabi + - thumbv6m-none-eabi + toolchain: + - stable + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache cargo dependencies + uses: actions/cache@v2 + with: + path: | + - ~/.cargo/bin/ + - ~/.cargo/registry/index/ + - ~/.cargo/registry/cache/ + - ~/.cargo/git/db/ + key: ${{ runner.OS }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.OS }}-cargo-${{ hashFiles('**/Cargo.lock') }} + ${{ runner.OS }}-cargo- + + - name: Cache build output dependencies + uses: actions/cache@v2 + with: + path: target + key: ${{ runner.OS }}-build-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.OS }}-build-${{ hashFiles('**/Cargo.lock') }} + ${{ runner.OS }}-build- + + - name: Install Rust ${{ matrix.toolchain }} with target (${{ matrix.target }}) + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.toolchain }} + target: ${{ matrix.target }} + override: true + components: llvm-tools-preview + # Use precompiled binutils - name: cargo install cargo-binutils uses: actions-rs/install@v0.1 @@ -341,6 +386,56 @@ jobs: command: check args: --manifest-path macros/Cargo.toml --target=${{ matrix.target }} + # Run the macros test-suite + testmacros: + name: testmacros + runs-on: ubuntu-20.04 + strategy: + matrix: + target: + - x86_64-unknown-linux-gnu + toolchain: + - stable + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Cache cargo dependencies + uses: actions/cache@v2 + with: + path: | + - ~/.cargo/bin/ + - ~/.cargo/registry/index/ + - ~/.cargo/registry/cache/ + - ~/.cargo/git/db/ + key: ${{ runner.OS }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.OS }}-cargo-${{ hashFiles('**/Cargo.lock') }} + ${{ runner.OS }}-cargo- + + - name: Cache build output dependencies + uses: actions/cache@v2 + with: + path: target + key: ${{ runner.OS }}-build-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.OS }}-build-${{ hashFiles('**/Cargo.lock') }} + ${{ runner.OS }}-build- + + - name: Install Rust ${{ matrix.toolchain }} with target (${{ matrix.target }}) + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.toolchain }} + target: ${{ matrix.target }} + override: true + + - name: cargo check + uses: actions-rs/cargo@v1 + with: + use-cross: false + command: test + args: --manifest-path macros/Cargo.toml --target=${{ matrix.target }} + # Run test suite for thumbv7m testv7: name: testv7 @@ -513,7 +608,7 @@ jobs: - name: mdBook Action uses: peaceiris/actions-mdbook@v1.1.11 with: - mdbook-version: '0.3.1' + mdbook-version: 'latest' - name: Build book in English run: cd book/en && mdbook build @@ -541,7 +636,9 @@ jobs: - style - check - checkexamples + - testexamples - checkmacros + - testmacros - testv7 - testv6 - docs @@ -566,8 +663,7 @@ jobs: - name: mdBook Action uses: peaceiris/actions-mdbook@v1.1.11 with: - mdbook-version: '0.3.1' - # mdbook-version: 'latest' + mdbook-version: 'latest' - name: Remove cargo-config run: rm -f .cargo/config @@ -579,13 +675,16 @@ jobs: run: | langs=( en ru ) devver=( dev ) - # Query git for tagged releases, all releases start with "v" - # followed by MAJOR.MINOR.PATCH, see semver.org - # Then remove all pre-releases/tags with hyphens (-). - # The latest release is last, finally trim "v" and PATCH - stable=$(git tag | grep "^v" | grep -v "-" | tail -n 1 | cut -c2-4) + # The latest stable must be the first element in the array vers=( 0.5.x 0.4.x ) + # All releases start with "v" + # followed by MAJOR.MINOR.PATCH, see semver.org + # Retain MAJOR.MINOR as $stable + stable=${vers%.*} + + echo "Stable version: $stable" + # Create directories td=$(mktemp -d) mkdir -p $td/$devver/book/ @@ -630,8 +729,8 @@ jobs: rm -rf $src done - # Create alias for the stable release - ln -s $stable $td/stable + # Copy the stable book to the stable alias + cp -r $td/$stable $td/stable # Forward CNAME file cp CNAME $td/ @@ -654,7 +753,9 @@ jobs: - style - check - checkexamples + - testexamples - checkmacros + - testmacros - testv7 - testv6 - docs @@ -670,7 +771,9 @@ jobs: - style - check - checkexamples + - testexamples - checkmacros + - testmacros - testv7 - testv6 - docs diff --git a/README.md b/README.md index 45bb9de840..929a813c20 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,12 @@ A concurrency framework for building real-time systems. Formerly known as Real-Time For the Masses. -![crates.io](https://img.shields.io/crates/v/cortex-m-rtic) -![docs.rs](https://docs.rs/cortex-m-rtic/badge.svg) -![book](https://img.shields.io/badge/web-rtic.rs-red.svg?style=flat&label=book&colorB=d33847) -![rustc](https://img.shields.io/badge/rustc-1.36+-lightgray.svg) +[![crates.io](https://img.shields.io/crates/v/cortex-m-rtic)](https://crates.io/crates/cortex-m-rtic) +[![docs.rs](https://docs.rs/cortex-m-rtic/badge.svg)](https://docs.rs/cortex-m-rtic) +[![book](https://img.shields.io/badge/web-rtic.rs-red.svg?style=flat&label=book&colorB=d33847)](https://rtic.rs/) +[![rustc](https://img.shields.io/badge/rustc-1.36+-lightgray.svg)](https://github.com/rust-lang/rust/releases/tag/1.36.0) +[![matrix](https://img.shields.io/matrix/rtic:matrix.org)](https://matrix.to/#/#rtic:matrix.org) +[![Meeting notes](https://hackmd.io/badge.svg)](https://hackmd.io/@xmis9JvZT8Gvo9lOEKyZ4Q/SkBJKsjuH) ## Features @@ -52,23 +54,29 @@ Formerly known as Real-Time For the Masses. ## [User documentation](https://rtic.rs) -## [API reference](https://rtic.rs/0.5/api/) +## [API reference](https://rtic.rs/stable/api/) ## Chat + Join us and talk about RTIC in the [Matrix room][matrix-room]. +Weekly meeting notes can be found over at [HackMD][hackmd] + [matrix-room]: https://matrix.to/#/#rtic:matrix.org +[hackmd]: https://hackmd.io/@xmis9JvZT8Gvo9lOEKyZ4Q/SkBJKsjuH ## Contributing -New features and big changes should go through the RFC process in the [dedicated RFC repository][rfcs]. + +New features and big changes should go through the RFC process in the +[dedicated RFC repository][rfcs]. [rfcs]: https://github.com/rtic-rs/rfcs ## Acknowledgments -This crate is based on [the Real-Time For the Masses language][rtfm-lang] created by the Embedded -Systems group at [LuleƄ University of Technology][ltu], led by [Prof. Per -Lindgren][per]. +This crate is based on [the Real-Time For the Masses language][rtfm-lang] +created by the Embedded Systems group at [LuleƄ University of Technology][ltu], +led by [Prof. Per Lindgren][per]. [rtfm-lang]: http://www.rtfm-lang.org/ [ltu]: https://www.ltu.se/?l=en diff --git a/book/en/src/SUMMARY.md b/book/en/src/SUMMARY.md index a573cbb55a..e1a4a330c7 100644 --- a/book/en/src/SUMMARY.md +++ b/book/en/src/SUMMARY.md @@ -10,8 +10,10 @@ - [Types, Send and Sync](./by-example/types-send-sync.md) - [Starting a new project](./by-example/new.md) - [Tips & tricks](./by-example/tips.md) -- [Migrating from v0.4.x to v0.5.0](./migration.md) -- [Migrating from RTFM to RTIC](./migration_rtic.md) +- [Migration Guides](./migration.md) + - [v0.5.x to v0.6.x](./migration/migration_v5.md) + - [v0.4.x to v0.5.x](./migration/migration_v4.md) + - [RTFM to RTIC](./migration/migration_rtic.md) - [Under the hood](./internals.md) - [Interrupt configuration](./internals/interrupt-configuration.md) - [Non-reentrancy](./internals/non-reentrancy.md) diff --git a/book/en/src/by-example.md b/book/en/src/by-example.md index 38985da140..e4441fd962 100644 --- a/book/en/src/by-example.md +++ b/book/en/src/by-example.md @@ -14,3 +14,11 @@ program. Check [the embedded Rust book] for instructions on how to set up an embedded development environment that includes QEMU. [the embedded Rust book]: https://rust-embedded.github.io/book/intro/install.html + +## Real World Examples + +The following are examples of RTFM being used in real world projects. + +### RTFM V0.4.2 + +- [etrombly/sandbox](https://github.com/etrombly/sandbox/tree/41d423bcdd0d8e42fd46b79771400a8ca349af55). A hardware zen garden that draws patterns in sand. Patterns are sent over serial using G-code. diff --git a/book/en/src/by-example/resources.md b/book/en/src/by-example/resources.md index d082dfc143..9d90fbe366 100644 --- a/book/en/src/by-example/resources.md +++ b/book/en/src/by-example/resources.md @@ -1,4 +1,4 @@ -## Resources +# Resources The framework provides an abstraction to share data between any of the contexts we saw in the previous section (task handlers, `init` and `idle`): resources. @@ -116,7 +116,9 @@ are required to access the resource even if the resource is contended by several tasks running at different priorities. The downside is that the task only gets a shared reference (`&-`) to the resource, limiting the operations it can perform on it, but where a shared reference is enough this approach reduces the number -of required locks. +of required locks. In addition to simple immutable data, this shared access can +be useful where the resource type safely implements interior mutability, with +appropriate locking or atomic operations of its own. Note that in this release of RTIC it is not possible to request both exclusive access (`&mut-`) and shared access (`&-`) to the *same* resource from different diff --git a/book/en/src/by-example/tips.md b/book/en/src/by-example/tips.md index d8264c9050..090b30ad35 100644 --- a/book/en/src/by-example/tips.md +++ b/book/en/src/by-example/tips.md @@ -116,6 +116,7 @@ Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes. ``` rust {{#include ../../../../examples/pool.rs}} ``` + ``` console $ cargo run --example pool {{#include ../../../../ci/expected/pool.run}} diff --git a/book/en/src/migration.md b/book/en/src/migration.md index 7be30943c8..08feb81e1e 100644 --- a/book/en/src/migration.md +++ b/book/en/src/migration.md @@ -1,331 +1,4 @@ -# Migration of RTIC +# Migration Guides -## Migrating from v0.5.x to v0.6.0 - -This section describes how to upgrade from v0.5.x to v0.6.0 of the RTIC framework. - -### `Cargo.toml` - version bump - -Change the version of `cortex-m-rtic` to `"0.6.0"`. - -### Module instead of Const - -With the support of attributes on modules the `const APP` workaround is not needed. - -Change - -``` rust -#[rtic::app(/* .. */)] -const APP: () = { - [code here] -}; -``` - -into - -``` rust -#[rtic::app(/* .. */)] -mod app { - [code here] -} -``` - -Now that a regular Rust module is used it means it is possible to have custom -user code within that module. -Additionally, it means that `use`-statements for resources etc may be required. - -### Init always returns late resources - -In order to make the API more symmetric the #[init]-task always returns a late resource. - -From this: - -``` rust -#[rtic::app(device = lm3s6965)] -mod app { - #[init] - fn init(_: init::Context) { - rtic::pend(Interrupt::UART0); - } - [more code] -} -``` - -to this: - -``` rust -#[rtic::app(device = lm3s6965)] -mod app { - #[init] - fn init(_: init::Context) -> init::LateResources { - rtic::pend(Interrupt::UART0); - - init::LateResources {} - } - [more code] -} -``` - -### Resources struct - #[resources] - -Previously the RTIC resources had to be in in a struct named exactly "Resources": - -``` rust -struct Resources { - // Resources defined in here -} -``` - -With RTIC v0.6.0 the resources struct is annotated similarly like -`#[task]`, `#[init]`, `#[idle]`: with an attribute `#[resources]` - -``` rust -#[resources] -struct Resources { - // Resources defined in here -} -``` - -In fact, the name of the struct is now up to the developer: - -``` rust -#[resources] -struct whateveryouwant { - // Resources defined in here -} -``` - -would work equally well. - -## Migrating from v0.4.x to v0.5.0 - -This section covers how to upgrade an application written against RTIC v0.4.x to -the version v0.5.0 of the framework. - -### `Cargo.toml` - -First, the version of the `cortex-m-rtic` dependency needs to be updated to -`"0.5.0"`. The `timer-queue` feature needs to be removed. - -``` toml -[dependencies.cortex-m-rtic] -# change this -version = "0.4.3" - -# into this -version = "0.5.0" - -# and remove this Cargo feature -features = ["timer-queue"] -# ^^^^^^^^^^^^^ -``` - -### `Context` argument - -All functions inside the `#[rtic::app]` item need to take as first argument a -`Context` structure. This `Context` type will contain the variables that were -magically injected into the scope of the function by version v0.4.x of the -framework: `resources`, `spawn`, `schedule` -- these variables will become -fields of the `Context` structure. Each function within the `#[rtic::app]` item -gets a different `Context` type. - -``` rust -#[rtic::app(/* .. */)] -const APP: () = { - // change this - #[task(resources = [x], spawn = [a], schedule = [b])] - fn foo() { - resources.x.lock(|x| /* .. */); - spawn.a(message); - schedule.b(baseline); - } - - // into this - #[task(resources = [x], spawn = [a], schedule = [b])] - fn foo(mut cx: foo::Context) { - // ^^^^^^^^^^^^^^^^^^^^ - - cx.resources.x.lock(|x| /* .. */); - // ^^^ - - cx.spawn.a(message); - // ^^^ - - cx.schedule.b(message, baseline); - // ^^^ - } - - // change this - #[init] - fn init() { - // .. - } - - // into this - #[init] - fn init(cx: init::Context) { - // ^^^^^^^^^^^^^^^^^ - // .. - } - - // .. -}; -``` - -### Resources - -The syntax used to declare resources has been changed from `static mut` -variables to a `struct Resources`. - -``` rust -#[rtic::app(/* .. */)] -const APP: () = { - // change this - static mut X: u32 = 0; - static mut Y: u32 = (); // late resource - - // into this - struct Resources { - #[init(0)] // <- initial value - X: u32, // NOTE: we suggest changing the naming style to `snake_case` - - Y: u32, // late resource - } - - // .. -}; -``` - -### Device peripherals - -If your application was accessing the device peripherals in `#[init]` through -the `device` variable then you'll need to add `peripherals = true` to the -`#[rtic::app]` attribute to continue to access the device peripherals through -the `device` field of the `init::Context` structure. - -Change this: - -``` rust -#[rtic::app(/* .. */)] -const APP: () = { - #[init] - fn init() { - device.SOME_PERIPHERAL.write(something); - } - - // .. -}; -``` - -Into this: - -``` rust -#[rtic::app(/* .. */, peripherals = true)] -// ^^^^^^^^^^^^^^^^^^ -const APP: () = { - #[init] - fn init(cx: init::Context) { - // ^^^^^^^^^^^^^^^^^ - cx.device.SOME_PERIPHERAL.write(something); - // ^^^ - } - - // .. -}; -``` - -### `#[interrupt]` and `#[exception]` - -The `#[interrupt]` and `#[exception]` attributes have been removed. To declare -hardware tasks in v0.5.x use the `#[task]` attribute with the `binds` argument. - -Change this: - -``` rust -#[rtic::app(/* .. */)] -const APP: () = { - // hardware tasks - #[exception] - fn SVCall() { /* .. */ } - - #[interrupt] - fn UART0() { /* .. */ } - - // software task - #[task] - fn foo() { /* .. */ } - - // .. -}; -``` - -Into this: - -``` rust -#[rtic::app(/* .. */)] -const APP: () = { - #[task(binds = SVCall)] - // ^^^^^^^^^^^^^^ - fn svcall(cx: svcall::Context) { /* .. */ } - // ^^^^^^ we suggest you use a `snake_case` name here - - #[task(binds = UART0)] - // ^^^^^^^^^^^^^ - fn uart0(cx: uart0::Context) { /* .. */ } - - #[task] - fn foo(cx: foo::Context) { /* .. */ } - - // .. -}; -``` - -### `schedule` - -The `timer-queue` feature has been removed. To use the `schedule` API one must -first define the monotonic timer the runtime will use using the `monotonic` -argument of the `#[rtic::app]` attribute. To continue using the cycle counter -(CYCCNT) as the monotonic timer, and match the behavior of version v0.4.x, add -the `monotonic = rtic::cyccnt::CYCCNT` argument to the `#[rtic::app]` attribute. - -Also, the `Duration` and `Instant` types and the `U32Ext` trait have been moved -into the `rtic::cyccnt` module. This module is only available on ARMv7-M+ -devices. The removal of the `timer-queue` also brings back the `DWT` peripheral -inside the core peripherals struct, this will need to be enabled by the application -inside `init`. - -Change this: - -``` rust -use rtic::{Duration, Instant, U32Ext}; - -#[rtic::app(/* .. */)] -const APP: () = { - #[task(schedule = [b])] - fn a() { - // .. - } -}; -``` - -Into this: - -``` rust -use rtic::cyccnt::{Duration, Instant, U32Ext}; -// ^^^^^^^^ - -#[rtic::app(/* .. */, monotonic = rtic::cyccnt::CYCCNT)] -// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -const APP: () = { - #[init] - fn init(cx: init::Context) { - cx.core.DWT.enable_cycle_counter(); - // optional, configure the DWT run without a debugger connected - cx.core.DCB.enable_trace(); - } - #[task(schedule = [b])] - fn a(cx: a::Context) { - // .. - } -}; -``` +This section describes how to migrate between different version of RTIC. +It also acts as a comparing reference between versions. diff --git a/book/en/src/migration_rtic.md b/book/en/src/migration/migration_rtic.md similarity index 99% rename from book/en/src/migration_rtic.md rename to book/en/src/migration/migration_rtic.md index 555f1bb710..c027da35fd 100644 --- a/book/en/src/migration_rtic.md +++ b/book/en/src/migration/migration_rtic.md @@ -8,14 +8,11 @@ change. [RFC #33]: https://github.com/rtic-rs/rfcs/pull/33 - - ## `Cargo.toml` First, the `cortex-m-rtfm` dependency needs to be updated to `cortex-m-rtic`. - ``` toml [dependencies] # change this @@ -51,4 +48,3 @@ const APP: () = { }; ``` - diff --git a/book/en/src/migration/migration_v4.md b/book/en/src/migration/migration_v4.md new file mode 100644 index 0000000000..ac59d8c9fb --- /dev/null +++ b/book/en/src/migration/migration_v4.md @@ -0,0 +1,233 @@ +# Migrating from v0.4.x to v0.5.0 + +This section covers how to upgrade an application written against RTIC v0.4.x to +the version v0.5.0 of the framework. + +## `Cargo.toml` + +First, the version of the `cortex-m-rtic` dependency needs to be updated to +`"0.5.0"`. The `timer-queue` feature needs to be removed. + +``` toml +[dependencies.cortex-m-rtic] +# change this +version = "0.4.3" + +# into this +version = "0.5.0" + +# and remove this Cargo feature +features = ["timer-queue"] +# ^^^^^^^^^^^^^ +``` + +## `Context` argument + +All functions inside the `#[rtic::app]` item need to take as first argument a +`Context` structure. This `Context` type will contain the variables that were +magically injected into the scope of the function by version v0.4.x of the +framework: `resources`, `spawn`, `schedule` -- these variables will become +fields of the `Context` structure. Each function within the `#[rtic::app]` item +gets a different `Context` type. + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + // change this + #[task(resources = [x], spawn = [a], schedule = [b])] + fn foo() { + resources.x.lock(|x| /* .. */); + spawn.a(message); + schedule.b(baseline); + } + + // into this + #[task(resources = [x], spawn = [a], schedule = [b])] + fn foo(mut cx: foo::Context) { + // ^^^^^^^^^^^^^^^^^^^^ + + cx.resources.x.lock(|x| /* .. */); + // ^^^ + + cx.spawn.a(message); + // ^^^ + + cx.schedule.b(message, baseline); + // ^^^ + } + + // change this + #[init] + fn init() { + // .. + } + + // into this + #[init] + fn init(cx: init::Context) { + // ^^^^^^^^^^^^^^^^^ + // .. + } + + // .. +}; +``` + +## Resources + +The syntax used to declare resources has been changed from `static mut` +variables to a `struct Resources`. + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + // change this + static mut X: u32 = 0; + static mut Y: u32 = (); // late resource + + // into this + struct Resources { + #[init(0)] // <- initial value + X: u32, // NOTE: we suggest changing the naming style to `snake_case` + + Y: u32, // late resource + } + + // .. +}; +``` + +## Device peripherals + +If your application was accessing the device peripherals in `#[init]` through +the `device` variable then you'll need to add `peripherals = true` to the +`#[rtic::app]` attribute to continue to access the device peripherals through +the `device` field of the `init::Context` structure. + +Change this: + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + #[init] + fn init() { + device.SOME_PERIPHERAL.write(something); + } + + // .. +}; +``` + +Into this: + +``` rust +#[rtic::app(/* .. */, peripherals = true)] +// ^^^^^^^^^^^^^^^^^^ +const APP: () = { + #[init] + fn init(cx: init::Context) { + // ^^^^^^^^^^^^^^^^^ + cx.device.SOME_PERIPHERAL.write(something); + // ^^^ + } + + // .. +}; +``` + +## `#[interrupt]` and `#[exception]` + +The `#[interrupt]` and `#[exception]` attributes have been removed. To declare +hardware tasks in v0.5.x use the `#[task]` attribute with the `binds` argument. + +Change this: + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + // hardware tasks + #[exception] + fn SVCall() { /* .. */ } + + #[interrupt] + fn UART0() { /* .. */ } + + // software task + #[task] + fn foo() { /* .. */ } + + // .. +}; +``` + +Into this: + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + #[task(binds = SVCall)] + // ^^^^^^^^^^^^^^ + fn svcall(cx: svcall::Context) { /* .. */ } + // ^^^^^^ we suggest you use a `snake_case` name here + + #[task(binds = UART0)] + // ^^^^^^^^^^^^^ + fn uart0(cx: uart0::Context) { /* .. */ } + + #[task] + fn foo(cx: foo::Context) { /* .. */ } + + // .. +}; +``` + +## `schedule` + +The `schedule` API no longer requires the `timer-queue` cargo feature, which has +been removed. To use the `schedule` API one must +first define the monotonic timer the runtime will use using the `monotonic` +argument of the `#[rtic::app]` attribute. To continue using the cycle counter +(CYCCNT) as the monotonic timer, and match the behavior of version v0.4.x, add +the `monotonic = rtic::cyccnt::CYCCNT` argument to the `#[rtic::app]` attribute. + +Also, the `Duration` and `Instant` types and the `U32Ext` trait have been moved +into the `rtic::cyccnt` module. This module is only available on ARMv7-M+ +devices. The removal of the `timer-queue` also brings back the `DWT` peripheral +inside the core peripherals struct, this will need to be enabled by the application +inside `init`. + +Change this: + +``` rust +use rtic::{Duration, Instant, U32Ext}; + +#[rtic::app(/* .. */)] +const APP: () = { + #[task(schedule = [b])] + fn a() { + // .. + } +}; +``` + +Into this: + +``` rust +use rtic::cyccnt::{Duration, Instant, U32Ext}; +// ^^^^^^^^ + +#[rtic::app(/* .. */, monotonic = rtic::cyccnt::CYCCNT)] +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +const APP: () = { + #[init] + fn init(cx: init::Context) { + cx.core.DWT.enable_cycle_counter(); + // optional, configure the DWT run without a debugger connected + cx.core.DCB.enable_trace(); + } + #[task(schedule = [b])] + fn a(cx: a::Context) { + // .. + } +}; +``` diff --git a/book/en/src/migration/migration_v5.md b/book/en/src/migration/migration_v5.md new file mode 100644 index 0000000000..1d83444e09 --- /dev/null +++ b/book/en/src/migration/migration_v5.md @@ -0,0 +1,96 @@ +# Migrating from v0.5.x to v0.6.0 + +This section describes how to upgrade from v0.5.x to v0.6.0 of the RTIC framework. + +## `Cargo.toml` - version bump + +Change the version of `cortex-m-rtic` to `"0.6.0"`. + +## Module instead of Const + +With the support of attributes on modules the `const APP` workaround is not needed. + +Change + +``` rust +#[rtic::app(/* .. */)] +const APP: () = { + [code here] +}; +``` + +into + +``` rust +#[rtic::app(/* .. */)] +mod app { + [code here] +} +``` + +Now that a regular Rust module is used it means it is possible to have custom +user code within that module. +Additionally, it means that `use`-statements for resources etc may be required. + +## Init always returns late resources + +In order to make the API more symmetric the #[init]-task always returns a late resource. + +From this: + +``` rust +#[rtic::app(device = lm3s6965)] +mod app { + #[init] + fn init(_: init::Context) { + rtic::pend(Interrupt::UART0); + } + [more code] +} +``` + +to this: + +``` rust +#[rtic::app(device = lm3s6965)] +mod app { + #[init] + fn init(_: init::Context) -> init::LateResources { + rtic::pend(Interrupt::UART0); + + init::LateResources {} + } + [more code] +} +``` + +## Resources struct - #[resources] + +Previously the RTIC resources had to be in in a struct named exactly "Resources": + +``` rust +struct Resources { + // Resources defined in here +} +``` + +With RTIC v0.6.0 the resources struct is annotated similarly like +`#[task]`, `#[init]`, `#[idle]`: with an attribute `#[resources]` + +``` rust +#[resources] +struct Resources { + // Resources defined in here +} +``` + +In fact, the name of the struct is now up to the developer: + +``` rust +#[resources] +struct whateveryouwant { + // Resources defined in here +} +``` + +would work equally well. diff --git a/examples/baseline.rs b/examples/baseline.rs index e517bf080d..3ab40dbb32 100644 --- a/examples/baseline.rs +++ b/examples/baseline.rs @@ -13,13 +13,15 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)] mod app { #[init(spawn = [foo])] - fn init(cx: init::Context) { + fn init(cx: init::Context) -> init::LateResources { // omitted: initialization of `CYCCNT` hprintln!("init(baseline = {:?})", cx.start).unwrap(); // `foo` inherits the baseline of `init`: `Instant(0)` cx.spawn.foo().unwrap(); + + init::LateResources {} } #[task(schedule = [foo])] diff --git a/examples/binds.rs b/examples/binds.rs index 9c73433b06..42010ae243 100644 --- a/examples/binds.rs +++ b/examples/binds.rs @@ -13,10 +13,12 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::UART0); hprintln!("init").unwrap(); + + init::LateResources {} } #[idle] diff --git a/examples/capacity.rs b/examples/capacity.rs index 7ccb086af4..ba8b15b087 100644 --- a/examples/capacity.rs +++ b/examples/capacity.rs @@ -12,8 +12,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::UART0); + + init::LateResources {} } #[task(binds = UART0, spawn = [foo, bar])] diff --git a/examples/cfg.rs b/examples/cfg.rs index f4848302a8..d49f54c7ef 100644 --- a/examples/cfg.rs +++ b/examples/cfg.rs @@ -20,9 +20,11 @@ mod app { } #[init(spawn = [foo])] - fn init(cx: init::Context) { + fn init(cx: init::Context) -> init::LateResources { cx.spawn.foo().unwrap(); cx.spawn.foo().unwrap(); + + init::LateResources {} } #[idle] diff --git a/examples/destructure.rs b/examples/destructure.rs index 45d7319505..e7c53237d3 100644 --- a/examples/destructure.rs +++ b/examples/destructure.rs @@ -23,9 +23,11 @@ mod app { } #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); + + init::LateResources {} } // Direct destructure diff --git a/examples/generics.rs b/examples/generics.rs index c65e6518ea..3107dd1175 100644 --- a/examples/generics.rs +++ b/examples/generics.rs @@ -19,9 +19,11 @@ mod app { } #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); + + init::LateResources {} } #[task(binds = UART0, resources = [shared])] diff --git a/examples/hardware.rs b/examples/hardware.rs index 831b029cbc..f6a2d3758e 100644 --- a/examples/hardware.rs +++ b/examples/hardware.rs @@ -12,12 +12,14 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { // Pends the UART0 interrupt but its handler won't run until *after* // `init` returns because interrupts are disabled rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend hprintln!("init").unwrap(); + + init::LateResources {} } #[idle] diff --git a/examples/idle.rs b/examples/idle.rs index 0db05459b1..58c3c87d75 100644 --- a/examples/idle.rs +++ b/examples/idle.rs @@ -11,8 +11,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { hprintln!("init").unwrap(); + + init::LateResources {} } #[idle] diff --git a/examples/init.rs b/examples/init.rs index ea5433384a..6ac284a16a 100644 --- a/examples/init.rs +++ b/examples/init.rs @@ -11,7 +11,7 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965, peripherals = true)] mod app { #[init] - fn init(cx: init::Context) { + fn init(cx: init::Context) -> init::LateResources { static mut X: u32 = 0; // Cortex-M peripherals @@ -30,5 +30,7 @@ mod app { hprintln!("init").unwrap(); debug::exit(debug::EXIT_SUCCESS); + + init::LateResources {} } } diff --git a/examples/lock.rs b/examples/lock.rs index 6ce61dc6b8..669b1aedd8 100644 --- a/examples/lock.rs +++ b/examples/lock.rs @@ -18,8 +18,10 @@ mod app { } #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::GPIOA); + + init::LateResources {} } // when omitted priority is assumed to be `1` diff --git a/examples/message.rs b/examples/message.rs index 3f14a5a47f..f9736728fa 100644 --- a/examples/message.rs +++ b/examples/message.rs @@ -11,8 +11,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init(spawn = [foo])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { c.spawn.foo(/* no message */).unwrap(); + + init::LateResources {} } #[task(spawn = [bar])] diff --git a/examples/not-send.rs b/examples/not-send.rs index 45f7e4e79f..18071fc514 100644 --- a/examples/not-send.rs +++ b/examples/not-send.rs @@ -26,9 +26,11 @@ mod app { } #[init(spawn = [baz, quux])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { c.spawn.baz().unwrap(); c.spawn.quux().unwrap(); + + init::LateResources {} } #[task(spawn = [bar])] diff --git a/examples/not-sync.rs b/examples/not-sync.rs index 7581642433..75412e6343 100644 --- a/examples/not-sync.rs +++ b/examples/not-sync.rs @@ -26,8 +26,10 @@ mod app { } #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { debug::exit(debug::EXIT_SUCCESS); + + init::LateResources {} } #[task(resources = [&shared])] diff --git a/examples/periodic.rs b/examples/periodic.rs index 2d4c73b50d..d3aedd3207 100644 --- a/examples/periodic.rs +++ b/examples/periodic.rs @@ -16,10 +16,12 @@ const PERIOD: u32 = 8_000_000; mod app { #[init(schedule = [foo])] - fn init(cx: init::Context) { + fn init(cx: init::Context) -> init::LateResources { // omitted: initialization of `CYCCNT` cx.schedule.foo(cx.start + PERIOD.cycles()).unwrap(); + + init::LateResources {} } #[task(schedule = [foo])] diff --git a/examples/peripherals-taken.rs b/examples/peripherals-taken.rs index 10bc26036e..09f92427f5 100644 --- a/examples/peripherals-taken.rs +++ b/examples/peripherals-taken.rs @@ -9,8 +9,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn taskmain(_: taskmain::Context) { + fn init(_: init::Context) -> init::LateResources { assert!(cortex_m::Peripherals::take().is_none()); debug::exit(debug::EXIT_SUCCESS); + + init::LateResources {} } } diff --git a/examples/pool.rs b/examples/pool.rs index 27408d5596..cdbabca7b3 100644 --- a/examples/pool.rs +++ b/examples/pool.rs @@ -25,13 +25,15 @@ mod app { use super::P; #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { static mut MEMORY: [u8; 512] = [0; 512]; // Increase the capacity of the memory pool by ~4 P::grow(MEMORY); rtic::pend(Interrupt::I2C0); + + init::LateResources {} } #[task(binds = I2C0, priority = 2, spawn = [foo, bar])] diff --git a/examples/preempt.rs b/examples/preempt.rs index 0219301120..f6fc4b052e 100644 --- a/examples/preempt.rs +++ b/examples/preempt.rs @@ -11,8 +11,10 @@ use rtic::app; #[app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::GPIOA); + + init::LateResources {} } #[task(binds = GPIOA, priority = 1)] diff --git a/examples/ramfunc.rs b/examples/ramfunc.rs index 789d78718f..5ff167a32f 100644 --- a/examples/ramfunc.rs +++ b/examples/ramfunc.rs @@ -11,8 +11,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init(spawn = [bar])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { c.spawn.bar().unwrap(); + + init::LateResources {} } #[inline(never)] diff --git a/examples/resource-user-struct.rs b/examples/resource-user-struct.rs index dbda9a3fd9..a5bd0ddf5e 100644 --- a/examples/resource-user-struct.rs +++ b/examples/resource-user-struct.rs @@ -26,9 +26,11 @@ mod app { } #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); + + init::LateResources {} } // `shared` cannot be accessed from this context diff --git a/examples/resource.rs b/examples/resource.rs index 4cd0f4cabd..273af26a0e 100644 --- a/examples/resource.rs +++ b/examples/resource.rs @@ -19,9 +19,11 @@ mod app { } #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { rtic::pend(Interrupt::UART0); rtic::pend(Interrupt::UART1); + + init::LateResources {} } // `shared` cannot be accessed from this context diff --git a/examples/schedule.rs b/examples/schedule.rs index d5547b674b..7e6adc1aa7 100644 --- a/examples/schedule.rs +++ b/examples/schedule.rs @@ -14,7 +14,7 @@ use rtic::cyccnt::{Instant, U32Ext as _}; #[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)] mod app { #[init(schedule = [foo, bar])] - fn init(mut cx: init::Context) { + fn init(mut cx: init::Context) -> init::LateResources { // Initialize (enable) the monotonic timer (CYCCNT) cx.core.DCB.enable_trace(); // required on Cortex-M7 devices that software lock the DWT (e.g. STM32F7) @@ -32,6 +32,8 @@ mod app { // Schedule `bar` to run 4e6 cycles in the future cx.schedule.bar(now + 4_000_000.cycles()).unwrap(); + + init::LateResources {} } #[task] diff --git a/examples/shared-with-init.rs b/examples/shared-with-init.rs index 9f7e26aa06..85c72761bc 100644 --- a/examples/shared-with-init.rs +++ b/examples/shared-with-init.rs @@ -23,12 +23,14 @@ mod app { } #[init(resources = [shared])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { // this `message` will be sent to task `UART0` let message = MustBeSend; *c.resources.shared = Some(message); rtic::pend(Interrupt::UART0); + + init::LateResources {} } #[task(binds = UART0, resources = [shared])] diff --git a/examples/t-binds.rs b/examples/t-binds.rs index 7d7bd7d2d1..3ca4c66ec5 100644 --- a/examples/t-binds.rs +++ b/examples/t-binds.rs @@ -10,7 +10,9 @@ use panic_halt as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) {} + fn init(_: init::Context) -> init::LateResources { + init::LateResources {} + } // Cortex-M exception #[task(binds = SVCall)] diff --git a/examples/t-cfg.rs b/examples/t-cfg.rs index 3deb107ca4..3da20d4ee1 100644 --- a/examples/t-cfg.rs +++ b/examples/t-cfg.rs @@ -15,9 +15,11 @@ mod app { } #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { #[cfg(never)] static mut BAR: u32 = 0; + + init::LateResources {} } #[idle] diff --git a/examples/t-htask-main.rs b/examples/t-htask-main.rs index 998252e1f7..1e38e317c4 100644 --- a/examples/t-htask-main.rs +++ b/examples/t-htask-main.rs @@ -9,8 +9,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) { - rtic::pend(lm3s6965::Interrupt::UART0) + fn init(_: init::Context) -> init::LateResources { + rtic::pend(lm3s6965::Interrupt::UART0); + + init::LateResources {} } #[task(binds = UART0)] diff --git a/examples/t-idle-main.rs b/examples/t-idle-main.rs index 03a52cb26e..9078628ecd 100644 --- a/examples/t-idle-main.rs +++ b/examples/t-idle-main.rs @@ -9,7 +9,9 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) {} + fn init(_: init::Context) -> init::LateResources { + init::LateResources {} + } #[idle] fn taskmain(_: taskmain::Context) -> ! { diff --git a/examples/t-init-main.rs b/examples/t-init-main.rs index d0814877b5..7c23cc8307 100644 --- a/examples/t-init-main.rs +++ b/examples/t-init-main.rs @@ -9,7 +9,9 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn taskmain(_: taskmain::Context) { + fn init(_: init::Context) -> init::LateResources { debug::exit(debug::EXIT_SUCCESS); + + init::LateResources {} } } diff --git a/examples/t-resource.rs b/examples/t-resource.rs index 94b527faeb..91950d3e00 100644 --- a/examples/t-resource.rs +++ b/examples/t-resource.rs @@ -32,7 +32,7 @@ mod app { } #[init(resources = [o1, o4, o5, o6, s3])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { // owned by `init` == `&'static mut` let _: &'static mut u32 = c.resources.o1; @@ -43,6 +43,8 @@ mod app { let _: &mut u32 = c.resources.o4; let _: &mut u32 = c.resources.o5; let _: &mut u32 = c.resources.s3; + + init::LateResources {} } #[idle(resources = [o2, &o4, s1, &s3])] diff --git a/examples/t-schedule.rs b/examples/t-schedule.rs index ef2eb080e9..d5a6d3ff32 100644 --- a/examples/t-schedule.rs +++ b/examples/t-schedule.rs @@ -11,10 +11,12 @@ use rtic::cyccnt::{Instant, U32Ext as _}; #[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)] mod app { #[init(schedule = [foo, bar, baz])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { let _: Result<(), ()> = c.schedule.foo(c.start + 10.cycles()); let _: Result<(), u32> = c.schedule.bar(c.start + 20.cycles(), 0); let _: Result<(), (u32, u32)> = c.schedule.baz(c.start + 30.cycles(), 0, 1); + + init::LateResources {} } #[idle(schedule = [foo, bar, baz])] diff --git a/examples/t-spawn.rs b/examples/t-spawn.rs index 72143c5b25..efb748bc14 100644 --- a/examples/t-spawn.rs +++ b/examples/t-spawn.rs @@ -10,10 +10,12 @@ use panic_halt as _; #[rtic::app(device = lm3s6965)] mod app { #[init(spawn = [foo, bar, baz])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { let _: Result<(), ()> = c.spawn.foo(); let _: Result<(), u32> = c.spawn.bar(0); let _: Result<(), (u32, u32)> = c.spawn.baz(0, 1); + + init::LateResources {} } #[idle(spawn = [foo, bar, baz])] diff --git a/examples/t-stask-main.rs b/examples/t-stask-main.rs index 3e650f603a..74335c18a9 100644 --- a/examples/t-stask-main.rs +++ b/examples/t-stask-main.rs @@ -9,8 +9,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init(spawn = [taskmain])] - fn init(cx: init::Context) { + fn init(cx: init::Context) -> init::LateResources { cx.spawn.taskmain().ok(); + + init::LateResources {} } #[task] diff --git a/examples/task.rs b/examples/task.rs index f510df7450..80a9c4316d 100644 --- a/examples/task.rs +++ b/examples/task.rs @@ -11,8 +11,10 @@ use panic_semihosting as _; #[rtic::app(device = lm3s6965)] mod app { #[init(spawn = [foo])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { c.spawn.foo().unwrap(); + + init::LateResources {} } #[task(spawn = [bar, baz])] diff --git a/examples/types.rs b/examples/types.rs index cd7e8a2f13..251d004c4a 100644 --- a/examples/types.rs +++ b/examples/types.rs @@ -18,7 +18,7 @@ mod app { } #[init(schedule = [foo], spawn = [foo])] - fn init(cx: init::Context) { + fn init(cx: init::Context) -> init::LateResources { let _: cyccnt::Instant = cx.start; let _: rtic::Peripherals = cx.core; let _: lm3s6965::Peripherals = cx.device; @@ -26,6 +26,8 @@ mod app { let _: init::Spawn = cx.spawn; debug::exit(debug::EXIT_SUCCESS); + + init::LateResources {} } #[idle(schedule = [foo], spawn = [foo])] diff --git a/macros/src/codegen/init.rs b/macros/src/codegen/init.rs index 5f95f217a5..465a927d79 100644 --- a/macros/src/codegen/init.rs +++ b/macros/src/codegen/init.rs @@ -36,47 +36,38 @@ pub fn codegen( let mut root_init = vec![]; - let mut user_init_imports = vec![]; + let late_fields = analysis + .late_resources + .iter() + .flat_map(|resources| { + resources.iter().map(|name| { + let ty = &app.late_resources[name].ty; + let cfgs = &app.late_resources[name].cfgs; - let ret = { - let late_fields = analysis - .late_resources - .iter() - .flat_map(|resources| { - resources.iter().map(|name| { - let ty = &app.late_resources[name].ty; - let cfgs = &app.late_resources[name].cfgs; - - quote!( + quote!( #(#cfgs)* pub #name: #ty - ) - }) + ) }) - .collect::>(); + }) + .collect::>(); - if !late_fields.is_empty() { - let late_resources = util::late_resources_ident(&name); + let mut user_init_imports = vec![]; + let late_resources = util::late_resources_ident(&name); - root_init.push(quote!( - /// Resources initialized at runtime - #[allow(non_snake_case)] - pub struct #late_resources { - #(#late_fields),* - } - )); - - let name_late = format_ident!("{}LateResources", name); - user_init_imports.push(quote!( - #[allow(non_snake_case)] - use super::#name_late; - )); - - Some(quote!(-> #name::LateResources)) - } else { - None + root_init.push(quote!( + /// Resources initialized at runtime + #[allow(non_snake_case)] + pub struct #late_resources { + #(#late_fields),* } - }; + )); + + let name_late = format_ident!("{}LateResources", name); + user_init_imports.push(quote!( + #[allow(non_snake_case)] + use super::#name_late; + )); let mut locals_pat = None; let mut locals_new = None; @@ -95,7 +86,7 @@ pub fn codegen( let user_init = Some(quote!( #(#attrs)* #[allow(non_snake_case)] - fn #name(#(#locals_pat,)* #context: #name::Context) #ret { + fn #name(#(#locals_pat,)* #context: #name::Context) -> #name::LateResources { #(#stmts)* } )); diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 1fd3cd4273..526bf49106 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -267,14 +267,12 @@ pub fn codegen( if let Context::Init = ctxt { let init = &app.inits.first().unwrap(); - if init.returns_late_resources { - let late_resources = util::late_resources_ident(&init.name); + let late_resources = util::late_resources_ident(&init.name); - items.push(quote!( - #[doc(inline)] - pub use super::#late_resources as LateResources; - )); - } + items.push(quote!( + #[doc(inline)] + pub use super::#late_resources as LateResources; + )); } let doc = match ctxt { diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 94e7eec60c..e659559e9b 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -35,8 +35,7 @@ mod tests; /// /// The items allowed in the module block are specified below: /// -/// # 1. `#[resources] -/// struct ` +/// # 1. `#[resources] struct ` /// /// This structure contains the declaration of all the resources used by the application. Each field /// in this structure corresponds to a different resource. Each resource may optionally be given an diff --git a/ui/single/locals-cfg.rs b/ui/single/locals-cfg.rs index e04e5b939c..45a7a9116a 100644 --- a/ui/single/locals-cfg.rs +++ b/ui/single/locals-cfg.rs @@ -4,11 +4,13 @@ use panic_halt as _; #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) { + fn init(_: init::Context) -> init::LateResources { #[cfg(never)] static mut FOO: u32 = 0; FOO; + + init::LateResources {} } #[idle] diff --git a/ui/single/locals-cfg.stderr b/ui/single/locals-cfg.stderr index 39d56df2ae..e58bd935e3 100644 --- a/ui/single/locals-cfg.stderr +++ b/ui/single/locals-cfg.stderr @@ -5,27 +5,27 @@ error[E0425]: cannot find value `FOO` in this scope | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:19:9 + --> $DIR/locals-cfg.rs:21:9 | -19 | FOO; +21 | FOO; | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:29:9 + --> $DIR/locals-cfg.rs:31:9 | -29 | FOO; +31 | FOO; | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:37:9 + --> $DIR/locals-cfg.rs:39:9 | -37 | FOO; +39 | FOO; | ^^^ not found in this scope error[E0425]: cannot find value `FOO` in this scope - --> $DIR/locals-cfg.rs:45:9 + --> $DIR/locals-cfg.rs:47:9 | -45 | FOO; +47 | FOO; | ^^^ not found in this scope error: duplicate lang item in crate `panic_halt` (which `$CRATE` depends on): `panic_impl`. diff --git a/ui/single/resources-cfg.rs b/ui/single/resources-cfg.rs index f2569e92fc..2ba65a048a 100644 --- a/ui/single/resources-cfg.rs +++ b/ui/single/resources-cfg.rs @@ -43,12 +43,14 @@ mod app { } #[init(resources = [o1, o4, o5, o6, s3])] - fn init(c: init::Context) { + fn init(c: init::Context) -> init::LateResources { c.resources.o1; c.resources.o4; c.resources.o5; c.resources.o6; c.resources.s3; + + init::LateResources {} } #[idle(resources = [o2, &o4, s1, &s3])] diff --git a/ui/single/resources-cfg.stderr b/ui/single/resources-cfg.stderr index 9c39e5672e..17f08d8133 100644 --- a/ui/single/resources-cfg.stderr +++ b/ui/single/resources-cfg.stderr @@ -45,81 +45,81 @@ error[E0609]: no field `s3` on type `initResources<'_>` = note: available fields are: `__marker__` error[E0609]: no field `o2` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:56:21 + --> $DIR/resources-cfg.rs:58:21 | -56 | c.resources.o2; +58 | c.resources.o2; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o4` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:57:21 + --> $DIR/resources-cfg.rs:59:21 | -57 | c.resources.o4; +59 | c.resources.o4; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s1` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:58:21 + --> $DIR/resources-cfg.rs:60:21 | -58 | c.resources.s1; +60 | c.resources.s1; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s3` on type `idleResources<'_>` - --> $DIR/resources-cfg.rs:59:21 + --> $DIR/resources-cfg.rs:61:21 | -59 | c.resources.s3; +61 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o3` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:66:21 + --> $DIR/resources-cfg.rs:68:21 | -66 | c.resources.o3; +68 | c.resources.o3; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s1` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:67:21 + --> $DIR/resources-cfg.rs:69:21 | -67 | c.resources.s1; +69 | c.resources.s1; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s2` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:68:21 + --> $DIR/resources-cfg.rs:70:21 | -68 | c.resources.s2; +70 | c.resources.s2; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s3` on type `uart0Resources<'_>` - --> $DIR/resources-cfg.rs:69:21 + --> $DIR/resources-cfg.rs:71:21 | -69 | c.resources.s3; +71 | c.resources.s3; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `s2` on type `uart1Resources<'_>` - --> $DIR/resources-cfg.rs:74:21 + --> $DIR/resources-cfg.rs:76:21 | -74 | c.resources.s2; +76 | c.resources.s2; | ^^ unknown field | = note: available fields are: `__marker__` error[E0609]: no field `o5` on type `uart1Resources<'_>` - --> $DIR/resources-cfg.rs:75:21 + --> $DIR/resources-cfg.rs:77:21 | -75 | c.resources.o5; +77 | c.resources.o5; | ^^ unknown field | = note: available fields are: `__marker__` diff --git a/ui/single/task-priority-too-high.rs b/ui/single/task-priority-too-high.rs index fbafa4d21c..caa7b8ee24 100644 --- a/ui/single/task-priority-too-high.rs +++ b/ui/single/task-priority-too-high.rs @@ -3,7 +3,9 @@ #[rtic::app(device = lm3s6965)] mod app { #[init] - fn init(_: init::Context) {} + fn init(_: init::Context) -> init::LateResources { + init::LateResources {} + } #[task(binds = GPIOA, priority = 1)] fn gpioa(_: gpioa::Context) {}