mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-12-03 16:57:14 +01:00
Embedded ci works
This commit is contained in:
parent
a765f3fffa
commit
ca2577e3b8
131 changed files with 792 additions and 490 deletions
62
.github/workflows/build.yml
vendored
62
.github/workflows/build.yml
vendored
|
@ -135,8 +135,8 @@ jobs:
|
||||||
args: --examples --target=${{ matrix.target }}
|
args: --examples --target=${{ matrix.target }}
|
||||||
|
|
||||||
# Verify the example output with run-pass tests
|
# Verify the example output with run-pass tests
|
||||||
testexamples:
|
testexamplesqemu:
|
||||||
name: testexamples
|
name: testexamplesqemu
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -157,13 +157,6 @@ jobs:
|
||||||
override: true
|
override: true
|
||||||
components: llvm-tools-preview
|
components: llvm-tools-preview
|
||||||
|
|
||||||
# Use precompiled binutils
|
|
||||||
- name: cargo install cargo-binutils
|
|
||||||
uses: actions-rs/install@v0.1
|
|
||||||
with:
|
|
||||||
crate: cargo-binutils
|
|
||||||
version: latest
|
|
||||||
|
|
||||||
- name: Cache Dependencies
|
- name: Cache Dependencies
|
||||||
uses: Swatinem/rust-cache@v1
|
uses: Swatinem/rust-cache@v1
|
||||||
|
|
||||||
|
@ -176,8 +169,49 @@ jobs:
|
||||||
run: sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' src/lib.rs macros/src/lib.rs
|
run: sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' src/lib.rs macros/src/lib.rs
|
||||||
|
|
||||||
- name: Run-pass tests
|
- name: Run-pass tests
|
||||||
run:
|
run: |
|
||||||
cargo xtask --target ${{ matrix.target }}
|
cd examples-runner
|
||||||
|
cargo xtask --target ${{ matrix.target }} --runner qemu
|
||||||
|
|
||||||
|
testexamplesembeddedci:
|
||||||
|
name: testexamplesembeddedci
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
target:
|
||||||
|
- thumbv7m-none-eabi
|
||||||
|
- thumbv6m-none-eabi
|
||||||
|
toolchain:
|
||||||
|
- stable
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
|
- name: Cache Dependencies
|
||||||
|
uses: Swatinem/rust-cache@v1
|
||||||
|
|
||||||
|
- name: Install embedded-ci-client
|
||||||
|
run: |
|
||||||
|
cargo install --git https://github.com/korken89/embedded-ci.git embedded-ci-client
|
||||||
|
|
||||||
|
- name: Fail on warnings
|
||||||
|
run: sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' src/lib.rs macros/src/lib.rs
|
||||||
|
|
||||||
|
- name: Run-pass tests
|
||||||
|
env:
|
||||||
|
EMBEDDED_CI_TOKEN: ${{ secrets.EMBEDDED_CI_TOKEN }}
|
||||||
|
EMBEDDED_CI_SERVER: ${{ secrets.EMBEDDED_CI_SERVER }}
|
||||||
|
run: |
|
||||||
|
cd examples-runner
|
||||||
|
cargo xtask --target ${{ matrix.target }} --runner embedded-ci
|
||||||
|
|
||||||
# Check the correctness of macros/ crate
|
# Check the correctness of macros/ crate
|
||||||
checkmacros:
|
checkmacros:
|
||||||
|
@ -373,7 +407,8 @@ jobs:
|
||||||
- check
|
- check
|
||||||
- clippy
|
- clippy
|
||||||
- checkexamples
|
- checkexamples
|
||||||
- testexamples
|
- testexamplesqemu
|
||||||
|
- testexamplesembeddedci
|
||||||
- checkmacros
|
- checkmacros
|
||||||
- testmacros
|
- testmacros
|
||||||
- tests
|
- tests
|
||||||
|
@ -555,7 +590,8 @@ jobs:
|
||||||
- check
|
- check
|
||||||
- clippy
|
- clippy
|
||||||
- checkexamples
|
- checkexamples
|
||||||
- testexamples
|
- testexamplesqemu
|
||||||
|
- testexamplesembeddedci
|
||||||
- checkmacros
|
- checkmacros
|
||||||
- testmacros
|
- testmacros
|
||||||
- tests
|
- tests
|
||||||
|
|
|
@ -9,6 +9,7 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- HIL tests (embedded-ci)
|
||||||
- Improve how CHANGELOG.md merges are handled
|
- Improve how CHANGELOG.md merges are handled
|
||||||
- If current $stable and master version matches, dev-book redirects to $stable book
|
- If current $stable and master version matches, dev-book redirects to $stable book
|
||||||
- During deploy stage, merge master branch into current stable IFF cargo package version matches
|
- During deploy stage, merge master branch into current stable IFF cargo package version matches
|
||||||
|
|
|
@ -49,7 +49,9 @@ lto = true
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"macros",
|
"macros",
|
||||||
"xtask",
|
]
|
||||||
|
exclude = [
|
||||||
|
"examples-runner",
|
||||||
]
|
]
|
||||||
|
|
||||||
# do not optimize proc-macro deps or build scripts
|
# do not optimize proc-macro deps or build scripts
|
||||||
|
|
|
@ -28,5 +28,5 @@ $ cargo run --target thumbv7m-none-eabi --example locals
|
||||||
Yields this output:
|
Yields this output:
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
{{#include ../../../ci/expected/locals.run}}
|
{{#include ../../../examples-runner/ci/expected/locals.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -22,5 +22,5 @@ To give a flavour of RTIC, the following example contains commonly used features
|
||||||
In the following sections we will go through each feature in detail.
|
In the following sections we will go through each feature in detail.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/common.rs}}
|
{{#include ../../../../examples-runner/src/bin/common.rs}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -17,12 +17,12 @@ are safe to access.
|
||||||
The example below shows that `idle` runs after `init`.
|
The example below shows that `idle` runs after `init`.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/idle.rs}}
|
{{#include ../../../../examples-runner/src/bin/idle.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example idle
|
$ cargo run --target thumbv7m-none-eabi --example idle
|
||||||
{{#include ../../../../ci/expected/idle.run}}
|
{{#include ../../../../examples-runner/ci/expected/idle.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, the RTIC `idle` task does not try to optimize for any specific targets.
|
By default, the RTIC `idle` task does not try to optimize for any specific targets.
|
||||||
|
@ -43,10 +43,10 @@ default [`nop()`][NOP] with [`wfi()`][WFI].
|
||||||
[NOP]: https://developer.arm.com/documentation/dui0662/b/The-Cortex-M0--Instruction-Set/Miscellaneous-instructions/NOP
|
[NOP]: https://developer.arm.com/documentation/dui0662/b/The-Cortex-M0--Instruction-Set/Miscellaneous-instructions/NOP
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/idle-wfi.rs}}
|
{{#include ../../../../examples-runner/src/bin/idle-wfi.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example idle-wfi
|
$ cargo run --target thumbv7m-none-eabi --example idle-wfi
|
||||||
{{#include ../../../../ci/expected/idle-wfi.run}}
|
{{#include ../../../../examples-runner/ci/expected/idle-wfi.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -19,14 +19,14 @@ The `device` field is available when the `peripherals` argument is set to the de
|
||||||
In the rare case you want to implement an ultra-slim application you can explicitly set `peripherals` to `false`.
|
In the rare case you want to implement an ultra-slim application you can explicitly set `peripherals` to `false`.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/init.rs}}
|
{{#include ../../../../examples-runner/src/bin/init.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Running the example will print `init` to the console and then exit the QEMU process.
|
Running the example will print `init` to the console and then exit the QEMU process.
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example init
|
$ cargo run --target thumbv7m-none-eabi --example init
|
||||||
{{#include ../../../../ci/expected/init.run}}
|
{{#include ../../../../examples-runner/ci/expected/init.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **NOTE**: You can choose target device by passing a target
|
> **NOTE**: You can choose target device by passing a target
|
||||||
|
|
|
@ -3,5 +3,5 @@
|
||||||
This is the smallest possible RTIC application:
|
This is the smallest possible RTIC application:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/smallest.rs}}
|
{{#include ../../../../examples-runner/src/bin/smallest.rs}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -39,12 +39,12 @@ Task Priority
|
||||||
The following example showcases the priority based scheduling of tasks:
|
The following example showcases the priority based scheduling of tasks:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/preempt.rs}}
|
{{#include ../../../../examples-runner/src/bin/preempt.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example preempt
|
$ cargo run --target thumbv7m-none-eabi --example preempt
|
||||||
{{#include ../../../../ci/expected/preempt.run}}
|
{{#include ../../../../examples-runner/ci/expected/preempt.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that the task `bar` does *not* preempt task `baz` because its priority
|
Note that the task `bar` does *not* preempt task `baz` because its priority
|
||||||
|
|
|
@ -28,10 +28,10 @@ The example below demonstrates the use of the `#[task(binds = InterruptName)]` a
|
||||||
hardware task bound to an interrupt handler.
|
hardware task bound to an interrupt handler.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/hardware.rs}}
|
{{#include ../../../../examples-runner/src/bin/hardware.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example hardware
|
$ cargo run --target thumbv7m-none-eabi --example hardware
|
||||||
{{#include ../../../../ci/expected/hardware.run}}
|
{{#include ../../../../examples-runner/ci/expected/hardware.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -11,10 +11,10 @@ pending spawns of `foo`. Exceeding this capacity is an `Error`.
|
||||||
The number of arguments to a task is not limited:
|
The number of arguments to a task is not limited:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/message_passing.rs}}
|
{{#include ../../../../examples-runner/src/bin/message_passing.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example message_passing
|
$ cargo run --target thumbv7m-none-eabi --example message_passing
|
||||||
{{#include ../../../../ci/expected/message_passing.run}}
|
{{#include ../../../../examples-runner/ci/expected/message_passing.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -35,12 +35,12 @@ This activates the monotonics making it possible to use them.
|
||||||
See the following example:
|
See the following example:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/schedule.rs}}
|
{{#include ../../../../examples-runner/src/bin/schedule.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example schedule
|
$ cargo run --target thumbv7m-none-eabi --example schedule
|
||||||
{{#include ../../../../ci/expected/schedule.run}}
|
{{#include ../../../../examples-runner/ci/expected/schedule.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Canceling or rescheduling a scheduled task
|
## Canceling or rescheduling a scheduled task
|
||||||
|
@ -51,10 +51,10 @@ If `cancel` or `reschedule_at`/`reschedule_after` returns an `Err` it means that
|
||||||
too late and that the task is already sent for execution. The following example shows this in action:
|
too late and that the task is already sent for execution. The following example shows this in action:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/cancel-reschedule.rs}}
|
{{#include ../../../../examples-runner/src/bin/cancel-reschedule.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example cancel-reschedule
|
$ cargo run --target thumbv7m-none-eabi --example cancel-reschedule
|
||||||
{{#include ../../../../ci/expected/cancel-reschedule.run}}
|
{{#include ../../../../examples-runner/ci/expected/cancel-reschedule.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -39,14 +39,14 @@ The example application shown below contains two tasks where each task has acces
|
||||||
`#[local]` resource, plus that the `idle` task has its own `#[local]` as well.
|
`#[local]` resource, plus that the `idle` task has its own `#[local]` as well.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/locals.rs}}
|
{{#include ../../../../examples-runner/src/bin/locals.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Running the example:
|
Running the example:
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example locals
|
$ cargo run --target thumbv7m-none-eabi --example locals
|
||||||
{{#include ../../../../ci/expected/locals.run}}
|
{{#include ../../../../examples-runner/ci/expected/locals.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Task local initialized resources
|
### Task local initialized resources
|
||||||
|
@ -64,12 +64,12 @@ are not crossing any thread boundary.
|
||||||
In the example below the different uses and lifetimes are shown:
|
In the example below the different uses and lifetimes are shown:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/declared_locals.rs}}
|
{{#include ../../../../examples-runner/src/bin/declared_locals.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- ``` console
|
<!-- ``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example declared_locals
|
$ cargo run --target thumbv7m-none-eabi --example declared_locals
|
||||||
{{#include ../../../../ci/expected/declared_locals.run}}
|
{{#include ../../../../examples-runner/ci/expected/declared_locals.run}}
|
||||||
``` -->
|
``` -->
|
||||||
|
|
||||||
## `#[shared]` resources and `lock`
|
## `#[shared]` resources and `lock`
|
||||||
|
@ -97,12 +97,12 @@ resource for accessing the data. The highest priority handler, which do not acce
|
||||||
resource, is free to preempt the critical section created by the lowest priority handler.
|
resource, is free to preempt the critical section created by the lowest priority handler.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/lock.rs}}
|
{{#include ../../../../examples-runner/src/bin/lock.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example lock
|
$ cargo run --target thumbv7m-none-eabi --example lock
|
||||||
{{#include ../../../../ci/expected/lock.run}}
|
{{#include ../../../../examples-runner/ci/expected/lock.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Types of `#[shared]` resources have to be both [`Send`] and [`Sync`].
|
Types of `#[shared]` resources have to be both [`Send`] and [`Sync`].
|
||||||
|
@ -113,12 +113,12 @@ As an extension to `lock`, and to reduce rightward drift, locks can be taken as
|
||||||
following examples show this in use:
|
following examples show this in use:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/multilock.rs}}
|
{{#include ../../../../examples-runner/src/bin/multilock.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example multilock
|
$ cargo run --target thumbv7m-none-eabi --example multilock
|
||||||
{{#include ../../../../ci/expected/multilock.run}}
|
{{#include ../../../../examples-runner/ci/expected/multilock.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Only shared (`&-`) access
|
## Only shared (`&-`) access
|
||||||
|
@ -143,12 +143,12 @@ In the example below a key (e.g. a cryptographic key) is loaded (or created) at
|
||||||
used from two tasks that run at different priorities without any kind of lock.
|
used from two tasks that run at different priorities without any kind of lock.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/only-shared-access.rs}}
|
{{#include ../../../../examples-runner/src/bin/only-shared-access.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example only-shared-access
|
$ cargo run --target thumbv7m-none-eabi --example only-shared-access
|
||||||
{{#include ../../../../ci/expected/only-shared-access.run}}
|
{{#include ../../../../examples-runner/ci/expected/only-shared-access.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Lock-free resource access of shared resources
|
## Lock-free resource access of shared resources
|
||||||
|
@ -165,10 +165,10 @@ tasks running at different priorities will result in a *compile-time* error -- n
|
||||||
API would be a data race in that case.
|
API would be a data race in that case.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/lock-free.rs}}
|
{{#include ../../../../examples-runner/src/bin/lock-free.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example lock-free
|
$ cargo run --target thumbv7m-none-eabi --example lock-free
|
||||||
{{#include ../../../../ci/expected/lock-free.run}}
|
{{#include ../../../../examples-runner/ci/expected/lock-free.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -34,10 +34,10 @@ The framework will give a compilation error if there are not enough dispatchers
|
||||||
See the following example:
|
See the following example:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/spawn.rs}}
|
{{#include ../../../../examples-runner/src/bin/spawn.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example spawn
|
$ cargo run --target thumbv7m-none-eabi --example spawn
|
||||||
{{#include ../../../../ci/expected/spawn.run}}
|
{{#include ../../../../examples-runner/ci/expected/spawn.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -5,10 +5,10 @@ resources.
|
||||||
Here are two examples on how to split up the resource struct:
|
Here are two examples on how to split up the resource struct:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/destructure.rs}}
|
{{#include ../../../../examples-runner/src/bin/destructure.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example destructure
|
$ cargo run --target thumbv7m-none-eabi --example destructure
|
||||||
{{#include ../../../../ci/expected/destructure.run}}
|
{{#include ../../../../examples-runner/ci/expected/destructure.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -20,14 +20,14 @@ improve performance in some cases.
|
||||||
The example below shows how to place the higher priority task, `bar`, in RAM.
|
The example below shows how to place the higher priority task, `bar`, in RAM.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/ramfunc.rs}}
|
{{#include ../../../../examples-runner/src/bin/ramfunc.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Running this program produces the expected output.
|
Running this program produces the expected output.
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example ramfunc
|
$ cargo run --target thumbv7m-none-eabi --example ramfunc
|
||||||
{{#include ../../../../ci/expected/ramfunc.run}}
|
{{#include ../../../../examples-runner/ci/expected/ramfunc.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
One can look at the output of `cargo-nm` to confirm that `bar` ended in RAM
|
One can look at the output of `cargo-nm` to confirm that `bar` ended in RAM
|
||||||
|
@ -35,10 +35,10 @@ One can look at the output of `cargo-nm` to confirm that `bar` ended in RAM
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo nm --example ramfunc --release | grep ' foo::'
|
$ cargo nm --example ramfunc --release | grep ' foo::'
|
||||||
{{#include ../../../../ci/expected/ramfunc.run.grep.foo}}
|
{{#include ../../../../examples-runner/ci/expected/ramfunc.run.grep.foo}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo nm --example ramfunc --release | grep ' bar::'
|
$ cargo nm --example ramfunc --release | grep ' bar::'
|
||||||
{{#include ../../../../ci/expected/ramfunc.run.grep.bar}}
|
{{#include ../../../../examples-runner/ci/expected/ramfunc.run.grep.bar}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -18,10 +18,10 @@ or one can use a statically allocated memory pool like [`heapless::Pool`].
|
||||||
Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes.
|
Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes.
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/pool.rs}}
|
{{#include ../../../../examples-runner/src/bin/pool.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example pool
|
$ cargo run --target thumbv7m-none-eabi --example pool
|
||||||
{{#include ../../../../ci/expected/pool.run}}
|
{{#include ../../../../examples-runner/ci/expected/pool.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -13,12 +13,12 @@ for lock-free access to the shared queue.
|
||||||
[`heapless::spsc::Queue`]: https://docs.rs/heapless/0.7.5/heapless/spsc/struct.Queue.html
|
[`heapless::spsc::Queue`]: https://docs.rs/heapless/0.7.5/heapless/spsc/struct.Queue.html
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
{{#include ../../../../examples/static.rs}}
|
{{#include ../../../../examples-runner/src/bin/static.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Running this program produces the expected output.
|
Running this program produces the expected output.
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --target thumbv7m-none-eabi --example static
|
$ cargo run --target thumbv7m-none-eabi --example static
|
||||||
{{#include ../../../../ci/expected/static.run}}
|
{{#include ../../../../examples-runner/ci/expected/static.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example init
|
$ cargo run --example init
|
||||||
{{#include ../../../../ci/expected/init.run}}
|
{{#include ../../../../examples-runner/ci/expected/init.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
> **ПРИМЕЧАНИЕ**: Не забывайте указывать выбранное вами целевое устройство, передавая параметр target
|
> **ПРИМЕЧАНИЕ**: Не забывайте указывать выбранное вами целевое устройство, передавая параметр target
|
||||||
|
@ -87,7 +87,7 @@ $ cargo run --example init
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example idle
|
$ cargo run --example idle
|
||||||
{{#include ../../../../ci/expected/idle.run}}
|
{{#include ../../../../examples-runner/ci/expected/idle.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Аппаратные задачи
|
## Аппаратные задачи
|
||||||
|
@ -109,7 +109,7 @@ mut` переменные безопасны для использования
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example hardware
|
$ cargo run --example hardware
|
||||||
{{#include ../../../../ci/expected/hardware.run}}
|
{{#include ../../../../examples-runner/ci/expected/hardware.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
До сих пор все программы на RTIC, которые мы видели, не отличались от программ,
|
До сих пор все программы на RTIC, которые мы видели, не отличались от программ,
|
||||||
|
@ -145,7 +145,7 @@ $ cargo run --example hardware
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example preempt
|
$ cargo run --example preempt
|
||||||
{{#include ../../../../ci/expected/preempt.run}}
|
{{#include ../../../../examples-runner/ci/expected/preempt.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Заметьте, что задача `gpiob` *не* вытесняет задачу `gpioc`, потому что ее приоритет
|
Заметьте, что задача `gpiob` *не* вытесняет задачу `gpioc`, потому что ее приоритет
|
||||||
|
|
|
@ -80,5 +80,5 @@ $ cargo add panic-semihosting
|
||||||
``` console
|
``` console
|
||||||
$ # ПРИМЕЧАНИЕ: Я раскомментировал опцию `runner` в `.cargo/config`
|
$ # ПРИМЕЧАНИЕ: Я раскомментировал опцию `runner` в `.cargo/config`
|
||||||
$ cargo run
|
$ cargo run
|
||||||
{{#include ../../../../ci/expected/init.run}}
|
{{#include ../../../../examples-runner/ci/expected/init.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example resource
|
$ cargo run --example resource
|
||||||
{{#include ../../../../ci/expected/resource.run}}
|
{{#include ../../../../examples-runner/ci/expected/resource.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
К ресурсу `#[local]` нельзя получить доступ извне задачи к которой он
|
К ресурсу `#[local]` нельзя получить доступ извне задачи к которой он
|
||||||
|
@ -76,7 +76,7 @@ $ cargo run --example resource
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example lock
|
$ cargo run --example lock
|
||||||
{{#include ../../../../ci/expected/lock.run}}
|
{{#include ../../../../examples-runner/ci/expected/lock.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Множественное блокировка
|
## Множественное блокировка
|
||||||
|
@ -115,7 +115,7 @@ $ cargo run --example lock
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example only-shared-access
|
$ cargo run --example only-shared-access
|
||||||
{{#include ../../../../ci/expected/only-shared-access.run}}
|
{{#include ../../../../examples-runner/ci/expected/only-shared-access.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Неблокируемый доступ к изменяемым ресурсам
|
## Неблокируемый доступ к изменяемым ресурсам
|
||||||
|
@ -136,5 +136,5 @@ $ cargo run --example only-shared-access
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example lock-free
|
$ cargo run --example lock-free
|
||||||
{{#include ../../../../ci/expected/lock-free.run}}
|
{{#include ../../../../examples-runner/ci/expected/lock-free.run}}
|
||||||
```
|
```
|
|
@ -22,7 +22,7 @@ RTIC также поддерживает *программные* задачи,
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example task
|
$ cargo run --example task
|
||||||
{{#include ../../../../ci/expected/task.run}}
|
{{#include ../../../../examples-runner/ci/expected/task.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Передача сообщений
|
## Передача сообщений
|
||||||
|
@ -39,7 +39,7 @@ $ cargo run --example task
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example message
|
$ cargo run --example message
|
||||||
{{#include ../../../../ci/expected/message.run}}
|
{{#include ../../../../examples-runner/ci/expected/message.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Вместимость
|
## Вместимость
|
||||||
|
@ -63,7 +63,7 @@ RTIC *не* производит никакого рода аллокаций п
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example capacity
|
$ cargo run --example capacity
|
||||||
{{#include ../../../../ci/expected/capacity.run}}
|
{{#include ../../../../examples-runner/ci/expected/capacity.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Обработка ошибок
|
## Обработка ошибок
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
Запусе программы на реальном оборудовании создает следующий вывод в консоли:
|
Запусе программы на реальном оборудовании создает следующий вывод в консоли:
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
{{#include ../../../../ci/expected/schedule.run}}
|
{{#include ../../../../examples-runner/ci/expected/schedule.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Когда интерфейс `schedule` используется, среда исполнения использует внутри
|
Когда интерфейс `schedule` используется, среда исполнения использует внутри
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
`Instant::now` вместо `scheduled` вызвало бы дрейф / колебания.
|
`Instant::now` вместо `scheduled` вызвало бы дрейф / колебания.
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
{{#include ../../../../ci/expected/periodic.run}}
|
{{#include ../../../../examples-runner/ci/expected/periodic.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Базовое время
|
## Базовое время
|
||||||
|
@ -104,5 +104,5 @@
|
||||||
Запуск программы на реальном оборудовании приведет к следующему выводу в консоли:
|
Запуск программы на реальном оборудовании приведет к следующему выводу в консоли:
|
||||||
|
|
||||||
``` text
|
``` text
|
||||||
{{#include ../../../../ci/expected/baseline.run}}
|
{{#include ../../../../examples-runner/ci/expected/baseline.run}}
|
||||||
```
|
```
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example generics
|
$ cargo run --example generics
|
||||||
{{#include ../../../../ci/expected/generics.run}}
|
{{#include ../../../../examples-runner/ci/expected/generics.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Условная компиляция
|
## Условная компиляция
|
||||||
|
@ -43,7 +43,7 @@ $ cargo run --example generics
|
||||||
$ cargo run --example cfg --release
|
$ cargo run --example cfg --release
|
||||||
|
|
||||||
$ cargo run --example cfg
|
$ cargo run --example cfg
|
||||||
{{#include ../../../../ci/expected/cfg.run}}
|
{{#include ../../../../examples-runner/ci/expected/cfg.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Запуск задач из ОЗУ
|
## Запуск задач из ОЗУ
|
||||||
|
@ -75,7 +75,7 @@ RTIC v0.4.x была возможность взаимодействия с др
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example ramfunc
|
$ cargo run --example ramfunc
|
||||||
{{#include ../../../../ci/expected/ramfunc.run}}
|
{{#include ../../../../examples-runner/ci/expected/ramfunc.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
Можно посмотреть на вывод `cargo-nm`, чтобы убедиться, что `bar` расположен в ОЗУ
|
Можно посмотреть на вывод `cargo-nm`, чтобы убедиться, что `bar` расположен в ОЗУ
|
||||||
|
@ -83,12 +83,12 @@ $ cargo run --example ramfunc
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo nm --example ramfunc --release | grep ' foo::'
|
$ cargo nm --example ramfunc --release | grep ' foo::'
|
||||||
{{#include ../../../../ci/expected/ramfunc.run.grep.foo}}
|
{{#include ../../../../examples-runner/ci/expected/ramfunc.run.grep.foo}}
|
||||||
```
|
```
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo nm --example ramfunc --release | grep ' bar::'
|
$ cargo nm --example ramfunc --release | grep ' bar::'
|
||||||
{{#include ../../../../ci/expected/ramfunc.run.grep.bar}}
|
{{#include ../../../../examples-runner/ci/expected/ramfunc.run.grep.bar}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Обходной путь для быстрой передачи сообщений
|
## Обходной путь для быстрой передачи сообщений
|
||||||
|
@ -113,7 +113,7 @@ $ cargo nm --example ramfunc --release | grep ' bar::'
|
||||||
|
|
||||||
``` console
|
``` console
|
||||||
$ cargo run --example pool
|
$ cargo run --example pool
|
||||||
{{#include ../../../../ci/expected/pool.run}}
|
{{#include ../../../../examples-runner/ci/expected/pool.run}}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Инспектирование раскрываемого кода
|
## Инспектирование раскрываемого кода
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
foo Instant { ticks: 0 }
|
|
||||||
foo Instant { ticks: 100 }
|
|
||||||
foo Instant { ticks: 200 }
|
|
||||||
foo Instant { ticks: 300 }
|
|
|
@ -1,7 +0,0 @@
|
||||||
foo Instant { ticks: 0 }
|
|
||||||
bar Instant { ticks: 10 }
|
|
||||||
foo Instant { ticks: 110 }
|
|
||||||
bar Instant { ticks: 120 }
|
|
||||||
foo Instant { ticks: 220 }
|
|
||||||
bar Instant { ticks: 230 }
|
|
||||||
foo Instant { ticks: 330 }
|
|
|
@ -1,2 +0,0 @@
|
||||||
bar(0x20000088)
|
|
||||||
foo(0x2000010c)
|
|
22
examples-runner/.cargo/config.toml
Normal file
22
examples-runner/.cargo/config.toml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
[target.thumbv6m-none-eabi]
|
||||||
|
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
|
||||||
|
|
||||||
|
[target.thumbv7m-none-eabi]
|
||||||
|
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
|
||||||
|
|
||||||
|
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||||
|
rustflags = [
|
||||||
|
#"-C", "link-arg=-Tlink.x",
|
||||||
|
"-C", "link-arg=-Tdefmt.x",
|
||||||
|
"-C", "link-arg=--nmagic",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build]
|
||||||
|
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||||||
|
# target = "thumbv7m-none-eabi" # Cortex-M3
|
||||||
|
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
|
||||||
|
# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
|
||||||
|
|
||||||
|
[alias]
|
||||||
|
rrb = "run --release --bin"
|
||||||
|
brb = "build --release --bin"
|
2
examples-runner/.gitignore
vendored
Normal file
2
examples-runner/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
79
examples-runner/Cargo.toml
Normal file
79
examples-runner/Cargo.toml
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
[package]
|
||||||
|
# TODO(1) fix `authors` and `name` if you didn't use `cargo-generate`
|
||||||
|
authors = ["Emil Fresk <emil.fresk@gmail.com>"]
|
||||||
|
name = "examples-runner"
|
||||||
|
edition = "2018"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
defmt = { version = "0.3.0", optional = true }
|
||||||
|
defmt-rtt = { version = "0.3.0", optional = true }
|
||||||
|
panic-probe = { version = "0.3.0", optional = true }
|
||||||
|
cortex-m-rtic = { path = ".." }
|
||||||
|
cortex-m = "0.7"
|
||||||
|
systick-monotonic = "1"
|
||||||
|
fugit = { version = "0.3", features = ["defmt"] }
|
||||||
|
cortex-m-semihosting = { version = "0.3.7", optional = true }
|
||||||
|
panic-semihosting = { version = "0.5.6", optional = true }
|
||||||
|
heapless = "0.7"
|
||||||
|
rtic-monotonic = "1"
|
||||||
|
bare-metal = "1"
|
||||||
|
|
||||||
|
[dependencies.embedded-ci-pac]
|
||||||
|
version = "0.1.0"
|
||||||
|
git = "https://github.com/korken89/embedded-ci-pac.git"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"xtask",
|
||||||
|
]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
embedded-ci = ["defmt", "defmt-rtt", "panic-probe/print-defmt"]
|
||||||
|
qemu = ["cortex-m-semihosting", "panic-semihosting/exit"]
|
||||||
|
|
||||||
|
# cargo build/run
|
||||||
|
[profile.dev]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = true # <-
|
||||||
|
incremental = false
|
||||||
|
opt-level = "s" # <-
|
||||||
|
overflow-checks = true # <-
|
||||||
|
|
||||||
|
# cargo test
|
||||||
|
[profile.test]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = true # <-
|
||||||
|
incremental = false
|
||||||
|
opt-level = "s" # <-
|
||||||
|
overflow-checks = true # <-
|
||||||
|
|
||||||
|
# cargo build/run --release
|
||||||
|
[profile.release]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = false # <-
|
||||||
|
incremental = false
|
||||||
|
lto = 'fat'
|
||||||
|
opt-level = "s" # <-
|
||||||
|
overflow-checks = false # <-
|
||||||
|
|
||||||
|
# cargo test --release
|
||||||
|
[profile.bench]
|
||||||
|
codegen-units = 1
|
||||||
|
debug = 2
|
||||||
|
debug-assertions = false # <-
|
||||||
|
incremental = false
|
||||||
|
lto = 'fat'
|
||||||
|
opt-level = "s" # <-
|
||||||
|
overflow-checks = false # <-
|
||||||
|
|
||||||
|
# uncomment this to switch from the crates.io version of defmt to its git version
|
||||||
|
# check app-template's README for instructions
|
||||||
|
# [patch.crates-io]
|
||||||
|
# defmt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
||||||
|
# defmt-rtt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
||||||
|
# defmt-test = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
||||||
|
# panic-probe = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
38
examples-runner/build.rs
Normal file
38
examples-runner/build.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Put the linker script somewhere the linker can find it
|
||||||
|
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||||
|
|
||||||
|
#[cfg(feature = "embedded-ci")]
|
||||||
|
let bytes = include_bytes!("embedded-ci.x");
|
||||||
|
|
||||||
|
#[cfg(feature = "qemu")]
|
||||||
|
let bytes = include_bytes!("qemu.x");
|
||||||
|
|
||||||
|
// If running in test mode, use the memory layout that can be flashed
|
||||||
|
// onto the chip directly
|
||||||
|
File::create(out.join("memory.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(bytes)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
#[cfg(feature = "qemu")]
|
||||||
|
File::create(out.join("defmt.x"))
|
||||||
|
.unwrap()
|
||||||
|
.write_all(b"")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!("cargo:rustc-link-search={}", out.display());
|
||||||
|
|
||||||
|
// Only re-run the build script when memory.x is changed,
|
||||||
|
// instead of when any part of the source code changes.
|
||||||
|
println!("cargo:rerun-if-changed=memory.x");
|
||||||
|
println!("cargo:rerun-if-changed=embedded-ci.x");
|
||||||
|
println!("cargo:rerun-if-changed=qemu.x");
|
||||||
|
println!("cargo:rerun-if-changed=link.x");
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
}
|
4
examples-runner/ci/expected/periodic-at.run
Normal file
4
examples-runner/ci/expected/periodic-at.run
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
foo ticks: 0
|
||||||
|
foo ticks: 100
|
||||||
|
foo ticks: 200
|
||||||
|
foo ticks: 300
|
7
examples-runner/ci/expected/periodic-at2.run
Normal file
7
examples-runner/ci/expected/periodic-at2.run
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
foo ticks: 0
|
||||||
|
bar ticks: 10
|
||||||
|
foo ticks: 110
|
||||||
|
bar ticks: 120
|
||||||
|
foo ticks: 220
|
||||||
|
bar ticks: 230
|
||||||
|
foo ticks: 330
|
2
examples-runner/ci/expected/pool.run
Normal file
2
examples-runner/ci/expected/pool.run
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
bar
|
||||||
|
foo
|
10
examples-runner/embedded-ci.x
Normal file
10
examples-runner/embedded-ci.x
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x20000000, LENGTH = 22K
|
||||||
|
RAM : ORIGIN = 0x20000000+22K, LENGTH = 10K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is where the call stack will be allocated. */
|
||||||
|
/* The stack is of the full descending type. */
|
||||||
|
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
|
||||||
|
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
|
9
examples-runner/examples_to_runner.sh
Normal file
9
examples-runner/examples_to_runner.sh
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
# Convert old examples to CI runner
|
||||||
|
cp ../examples/* ./src/bin/
|
||||||
|
sd "use panic_semihosting as _;" "use examples_runner as _;" src/bin/*
|
||||||
|
sd "lm3s6965" "examples_runner::pac" src/bin/*
|
||||||
|
sd "use cortex_m_semihosting::.*" "use examples_runner::{println, exit};" src/bin/*
|
||||||
|
sd "debug::exit.*" "exit();" src/bin/*
|
||||||
|
sd "hprintln" "println" src/bin/*
|
||||||
|
sd "\"\).unwrap\(\)" "\")" src/bin/*
|
13
examples-runner/qemu.x
Normal file
13
examples-runner/qemu.x
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH : ORIGIN = 0x00000000, LENGTH = 32K
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 32K
|
||||||
|
# RAM only runner
|
||||||
|
# FLASH : ORIGIN = 0x20000000, LENGTH = 22K
|
||||||
|
# RAM : ORIGIN = 0x20000000+22K, LENGTH = 10K
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is where the call stack will be allocated. */
|
||||||
|
/* The stack is of the full descending type. */
|
||||||
|
/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */
|
||||||
|
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
|
|
@ -6,7 +6,7 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
/// Some big struct
|
/// Some big struct
|
||||||
pub struct BigStruct {
|
pub struct BigStruct {
|
||||||
|
@ -20,11 +20,11 @@ impl BigStruct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
use super::BigStruct;
|
use super::BigStruct;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
use cortex_m_semihosting::debug;
|
use examples_runner::exit;
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
|
@ -42,8 +42,6 @@ mod app {
|
||||||
&mut *cx.local.bs.as_mut_ptr()
|
&mut *cx.local.bs.as_mut_ptr()
|
||||||
};
|
};
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
|
||||||
|
|
||||||
(
|
(
|
||||||
Shared {
|
Shared {
|
||||||
// assign the reference so we can use the resource
|
// assign the reference so we can use the resource
|
||||||
|
@ -54,6 +52,11 @@ mod app {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[idle]
|
||||||
|
fn idle(_: idle::Context) -> ! {
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
#[task(binds = UART0, shared = [big_struct])]
|
#[task(binds = UART0, shared = [big_struct])]
|
||||||
fn task(_: task::Context) {}
|
fn task(_: task::Context) {}
|
||||||
}
|
}
|
|
@ -5,13 +5,13 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
// `examples/interrupt.rs` rewritten to use `binds`
|
// `examples/interrupt.rs` rewritten to use `binds`
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
use lm3s6965::Interrupt;
|
use examples_runner::pac::Interrupt;
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -23,33 +23,28 @@ mod app {
|
||||||
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
rtic::pend(Interrupt::UART0);
|
rtic::pend(Interrupt::UART0);
|
||||||
|
|
||||||
hprintln!("init").unwrap();
|
println!("init");
|
||||||
|
|
||||||
(Shared {}, Local {}, init::Monotonics())
|
(Shared {}, Local {}, init::Monotonics())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[idle]
|
#[idle]
|
||||||
fn idle(_: idle::Context) -> ! {
|
fn idle(_: idle::Context) -> ! {
|
||||||
hprintln!("idle").unwrap();
|
println!("idle");
|
||||||
|
|
||||||
rtic::pend(Interrupt::UART0);
|
rtic::pend(Interrupt::UART0);
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
loop {
|
|
||||||
cortex_m::asm::nop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(binds = UART0, local = [times: u32 = 0])]
|
#[task(binds = UART0, local = [times: u32 = 0])]
|
||||||
fn foo(cx: foo::Context) {
|
fn foo(cx: foo::Context) {
|
||||||
*cx.local.times += 1;
|
*cx.local.times += 1;
|
||||||
|
|
||||||
hprintln!(
|
println!(
|
||||||
"foo called {} time{}",
|
"foo called {} time{}",
|
||||||
*cx.local.times,
|
*cx.local.times,
|
||||||
if *cx.local.times > 1 { "s" } else { "" }
|
if *cx.local.times > 1 { "s" } else { "" }
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
use systick_monotonic::*;
|
use systick_monotonic::*;
|
||||||
|
|
||||||
#[monotonic(binds = SysTick, default = true)]
|
#[monotonic(binds = SysTick, default = true)]
|
||||||
|
@ -28,7 +28,7 @@ mod app {
|
||||||
// Initialize the monotonic (SysTick rate in QEMU is 12 MHz)
|
// Initialize the monotonic (SysTick rate in QEMU is 12 MHz)
|
||||||
let mono = Systick::new(systick, 12_000_000);
|
let mono = Systick::new(systick, 12_000_000);
|
||||||
|
|
||||||
hprintln!("init").ok();
|
println!("init");
|
||||||
|
|
||||||
// Schedule `foo` to run 1 second in the future
|
// Schedule `foo` to run 1 second in the future
|
||||||
foo::spawn_after(1.secs()).unwrap();
|
foo::spawn_after(1.secs()).unwrap();
|
||||||
|
@ -42,7 +42,7 @@ mod app {
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
fn foo(_: foo::Context) {
|
fn foo(_: foo::Context) {
|
||||||
hprintln!("foo").ok();
|
println!("foo");
|
||||||
|
|
||||||
// Schedule `bar` to run 2 seconds in the future (1 second after foo runs)
|
// Schedule `bar` to run 2 seconds in the future (1 second after foo runs)
|
||||||
let spawn_handle = baz::spawn_after(2.secs()).unwrap();
|
let spawn_handle = baz::spawn_after(2.secs()).unwrap();
|
||||||
|
@ -51,7 +51,7 @@ mod app {
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
fn bar(_: bar::Context, baz_handle: baz::SpawnHandle, do_reschedule: bool) {
|
fn bar(_: bar::Context, baz_handle: baz::SpawnHandle, do_reschedule: bool) {
|
||||||
hprintln!("bar").ok();
|
println!("bar");
|
||||||
|
|
||||||
if do_reschedule {
|
if do_reschedule {
|
||||||
// Reschedule baz 2 seconds from now, instead of the original 1 second
|
// Reschedule baz 2 seconds from now, instead of the original 1 second
|
||||||
|
@ -61,13 +61,13 @@ mod app {
|
||||||
} else {
|
} else {
|
||||||
// Or cancel it
|
// Or cancel it
|
||||||
baz_handle.cancel().unwrap();
|
baz_handle.cancel().unwrap();
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
fn baz(_: baz::Context) {
|
fn baz(_: baz::Context) {
|
||||||
hprintln!("baz").ok();
|
println!("baz");
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,12 +5,12 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
use lm3s6965::Interrupt;
|
use examples_runner::pac::Interrupt;
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -37,13 +37,13 @@ mod app {
|
||||||
|
|
||||||
#[task(capacity = 4)]
|
#[task(capacity = 4)]
|
||||||
fn foo(_: foo::Context, x: u32) {
|
fn foo(_: foo::Context, x: u32) {
|
||||||
hprintln!("foo({})", x).unwrap();
|
println!("foo({})", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
fn bar(_: bar::Context) {
|
fn bar(_: bar::Context) {
|
||||||
hprintln!("bar").unwrap();
|
println!("bar");
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,13 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0, QEI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::debug;
|
use examples_runner::exit;
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
use cortex_m_semihosting::hprintln;
|
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
|
@ -41,11 +39,11 @@ mod app {
|
||||||
|
|
||||||
#[idle]
|
#[idle]
|
||||||
fn idle(_: idle::Context) -> ! {
|
fn idle(_: idle::Context) -> ! {
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
loop {
|
// loop {
|
||||||
cortex_m::asm::nop();
|
// cortex_m::asm::nop();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(capacity = 2, shared = [count])]
|
#[task(capacity = 2, shared = [count])]
|
||||||
|
@ -84,11 +82,10 @@ mod app {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
#[task(capacity = 2)]
|
#[task(capacity = 2)]
|
||||||
fn log(_: log::Context, n: u32) {
|
fn log(_: log::Context, n: u32) {
|
||||||
hprintln!(
|
println!(
|
||||||
"foo has been called {} time{}",
|
"foo has been called {} time{}",
|
||||||
n,
|
n,
|
||||||
if n == 1 { "" } else { "s" }
|
if n == 1 { "" } else { "s" }
|
||||||
)
|
);
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0, QEI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
use systick_monotonic::*; // Implements the `Monotonic` trait
|
use systick_monotonic::*; // Implements the `Monotonic` trait
|
||||||
|
|
||||||
// A monotonic timer to enable scheduling in RTIC
|
// A monotonic timer to enable scheduling in RTIC
|
||||||
|
@ -31,12 +31,7 @@ mod app {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(_cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
let systick = cx.core.SYST;
|
|
||||||
|
|
||||||
// Initialize the monotonic (SysTick rate in QEMU is 12 MHz)
|
|
||||||
let mono = Systick::new(systick, 12_000_000);
|
|
||||||
|
|
||||||
// Spawn the task `foo` directly after `init` finishes
|
// Spawn the task `foo` directly after `init` finishes
|
||||||
foo::spawn().unwrap();
|
foo::spawn().unwrap();
|
||||||
|
|
||||||
|
@ -44,17 +39,17 @@ mod app {
|
||||||
// by the `#[monotonic(..)]` above
|
// by the `#[monotonic(..)]` above
|
||||||
bar::spawn_after(1.secs()).unwrap();
|
bar::spawn_after(1.secs()).unwrap();
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
(
|
// (
|
||||||
// Initialization of shared resources
|
// // Initialization of shared resources
|
||||||
Shared { s1: 0, s2: 1 },
|
// Shared { s1: 0, s2: 1 },
|
||||||
// Initialization of task local resources
|
// // Initialization of task local resources
|
||||||
Local { l1: 2, l2: 3 },
|
// Local { l1: 2, l2: 3 },
|
||||||
// Move the monotonic timer to the RTIC run-time, this enables
|
// // Move the monotonic timer to the RTIC run-time, this enables
|
||||||
// scheduling
|
// // scheduling
|
||||||
init::Monotonics(mono),
|
// init::Monotonics(mono),
|
||||||
)
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background task, runs whenever no other tasks are running
|
// Background task, runs whenever no other tasks are running
|
||||||
|
@ -73,7 +68,7 @@ mod app {
|
||||||
// This task is only spawned once in `init`, hence this task will run
|
// This task is only spawned once in `init`, hence this task will run
|
||||||
// only once
|
// only once
|
||||||
|
|
||||||
hprintln!("foo").ok();
|
println!("foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Software task, also not bound to a hardware interrupt
|
// Software task, also not bound to a hardware interrupt
|
||||||
|
@ -81,7 +76,7 @@ mod app {
|
||||||
// The resources `s1` and `s2` are shared between all other tasks.
|
// The resources `s1` and `s2` are shared between all other tasks.
|
||||||
#[task(shared = [s1, s2], local = [l2])]
|
#[task(shared = [s1, s2], local = [l2])]
|
||||||
fn bar(_: bar::Context) {
|
fn bar(_: bar::Context) {
|
||||||
hprintln!("bar").ok();
|
println!("bar");
|
||||||
|
|
||||||
// Run `bar` once per second
|
// Run `bar` once per second
|
||||||
bar::spawn_after(1.secs()).unwrap();
|
bar::spawn_after(1.secs()).unwrap();
|
||||||
|
@ -97,6 +92,6 @@ mod app {
|
||||||
// Note that RTIC does NOT clear the interrupt flag, this is up to the
|
// Note that RTIC does NOT clear the interrupt flag, this is up to the
|
||||||
// user
|
// user
|
||||||
|
|
||||||
hprintln!("UART0 interrupt!").ok();
|
println!("UART0 interrupt!");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,13 +5,13 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
|
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::pac::Interrupt;
|
||||||
use lm3s6965::Interrupt;
|
use examples_runner::{exit, println};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
|
@ -25,7 +25,7 @@ mod app {
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
hprintln!("init").unwrap();
|
println!("init");
|
||||||
|
|
||||||
(
|
(
|
||||||
Shared {
|
Shared {
|
||||||
|
@ -40,37 +40,37 @@ mod app {
|
||||||
|
|
||||||
#[idle(shared = [s2, s3])]
|
#[idle(shared = [s2, s3])]
|
||||||
fn idle(mut cx: idle::Context) -> ! {
|
fn idle(mut cx: idle::Context) -> ! {
|
||||||
hprintln!("idle p0 started").ok();
|
println!("idle p0 started");
|
||||||
rtic::pend(Interrupt::GPIOC);
|
rtic::pend(Interrupt::GPIOC);
|
||||||
cx.shared.s3.lock(|s| {
|
cx.shared.s3.lock(|s| {
|
||||||
hprintln!("idle enter lock s3 {}", s).ok();
|
println!("idle enter lock s3 {}", s);
|
||||||
hprintln!("idle pend t0").ok();
|
println!("idle pend t0");
|
||||||
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 3
|
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 3
|
||||||
hprintln!("idle pend t1").ok();
|
println!("idle pend t1");
|
||||||
rtic::pend(Interrupt::GPIOB); // t1 p3, with shared ceiling 3
|
rtic::pend(Interrupt::GPIOB); // t1 p3, with shared ceiling 3
|
||||||
hprintln!("idle pend t2").ok();
|
println!("idle pend t2");
|
||||||
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
|
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
|
||||||
hprintln!("idle still in lock s3 {}", s).ok();
|
println!("idle still in lock s3 {}", s);
|
||||||
});
|
});
|
||||||
hprintln!("\nback in idle").ok();
|
println!("\nback in idle");
|
||||||
|
|
||||||
cx.shared.s2.lock(|s| {
|
cx.shared.s2.lock(|s| {
|
||||||
hprintln!("enter lock s2 {}", s).ok();
|
println!("enter lock s2 {}", s);
|
||||||
hprintln!("idle pend t0").ok();
|
println!("idle pend t0");
|
||||||
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
|
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
|
||||||
hprintln!("idle pend t1").ok();
|
println!("idle pend t1");
|
||||||
rtic::pend(Interrupt::GPIOB); // t1 p3, no sharing
|
rtic::pend(Interrupt::GPIOB); // t1 p3, no sharing
|
||||||
hprintln!("idle pend t2").ok();
|
println!("idle pend t2");
|
||||||
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
|
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
|
||||||
hprintln!("idle still in lock s2 {}", s).ok();
|
println!("idle still in lock s2 {}", s);
|
||||||
});
|
});
|
||||||
hprintln!("\nidle exit").ok();
|
println!("\nidle exit");
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
loop {
|
// loop {
|
||||||
cortex_m::asm::nop();
|
// cortex_m::asm::nop();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(binds = GPIOA, priority = 2, local = [times: u32 = 0], shared = [s2, s3])]
|
#[task(binds = GPIOA, priority = 2, local = [times: u32 = 0], shared = [s2, s3])]
|
||||||
|
@ -78,13 +78,12 @@ mod app {
|
||||||
// Safe access to local `static mut` variable
|
// Safe access to local `static mut` variable
|
||||||
*cx.local.times += 1;
|
*cx.local.times += 1;
|
||||||
|
|
||||||
hprintln!(
|
println!(
|
||||||
"t0 p2 called {} time{}",
|
"t0 p2 called {} time{}",
|
||||||
*cx.local.times,
|
*cx.local.times,
|
||||||
if *cx.local.times > 1 { "s" } else { "" }
|
if *cx.local.times > 1 { "s" } else { "" }
|
||||||
)
|
);
|
||||||
.ok();
|
println!("t0 p2 exit");
|
||||||
hprintln!("t0 p2 exit").ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(binds = GPIOB, priority = 3, local = [times: u32 = 0], shared = [s3, s4])]
|
#[task(binds = GPIOB, priority = 3, local = [times: u32 = 0], shared = [s3, s4])]
|
||||||
|
@ -92,23 +91,22 @@ mod app {
|
||||||
// Safe access to local `static mut` variable
|
// Safe access to local `static mut` variable
|
||||||
*cx.local.times += 1;
|
*cx.local.times += 1;
|
||||||
|
|
||||||
hprintln!(
|
println!(
|
||||||
"t1 p3 called {} time{}",
|
"t1 p3 called {} time{}",
|
||||||
*cx.local.times,
|
*cx.local.times,
|
||||||
if *cx.local.times > 1 { "s" } else { "" }
|
if *cx.local.times > 1 { "s" } else { "" }
|
||||||
)
|
);
|
||||||
.ok();
|
|
||||||
|
|
||||||
cx.shared.s4.lock(|s| {
|
cx.shared.s4.lock(|s| {
|
||||||
hprintln!("t1 enter lock s4 {}", s).ok();
|
println!("t1 enter lock s4 {}", s);
|
||||||
hprintln!("t1 pend t0").ok();
|
println!("t1 pend t0");
|
||||||
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
|
rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2
|
||||||
hprintln!("t1 pend t2").ok();
|
println!("t1 pend t2");
|
||||||
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
|
rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing
|
||||||
hprintln!("t1 still in lock s4 {}", s).ok();
|
println!("t1 still in lock s4 {}", s);
|
||||||
});
|
});
|
||||||
|
|
||||||
hprintln!("t1 p3 exit").ok();
|
println!("t1 p3 exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(binds = GPIOC, priority = 4, local = [times: u32 = 0], shared = [s4])]
|
#[task(binds = GPIOC, priority = 4, local = [times: u32 = 0], shared = [s4])]
|
||||||
|
@ -116,17 +114,16 @@ mod app {
|
||||||
// Safe access to local `static mut` variable
|
// Safe access to local `static mut` variable
|
||||||
*cx.local.times += 1;
|
*cx.local.times += 1;
|
||||||
|
|
||||||
hprintln!(
|
println!(
|
||||||
"t2 p4 called {} time{}",
|
"t2 p4 called {} time{}",
|
||||||
*cx.local.times,
|
*cx.local.times,
|
||||||
if *cx.local.times > 1 { "s" } else { "" }
|
if *cx.local.times > 1 { "s" } else { "" }
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
cx.shared.s4.lock(|s| {
|
cx.shared.s4.lock(|s| {
|
||||||
hprintln!("enter lock s4 {}", s).ok();
|
println!("enter lock s4 {}", s);
|
||||||
*s += 1;
|
*s += 1;
|
||||||
});
|
});
|
||||||
hprintln!("t3 p4 exit").ok();
|
println!("t3 p4 exit");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [UART0])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [UART0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::debug;
|
use examples_runner::exit;
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -22,9 +22,9 @@ mod app {
|
||||||
// Locals in `#[init]` have 'static lifetime
|
// Locals in `#[init]` have 'static lifetime
|
||||||
let _a: &'static mut u32 = cx.local.a;
|
let _a: &'static mut u32 = cx.local.a;
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
(Shared {}, Local {}, init::Monotonics())
|
// (Shared {}, Local {}, init::Monotonics())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[idle(local = [a: u32 = 0])]
|
#[idle(local = [a: u32 = 0])]
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [UART0])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [UART0])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
|
@ -31,8 +31,8 @@ mod app {
|
||||||
|
|
||||||
#[idle]
|
#[idle]
|
||||||
fn idle(_: idle::Context) -> ! {
|
fn idle(_: idle::Context) -> ! {
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
loop {}
|
// loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Direct destructure
|
// Direct destructure
|
||||||
|
@ -42,7 +42,7 @@ mod app {
|
||||||
let b = cx.shared.b;
|
let b = cx.shared.b;
|
||||||
let c = cx.shared.c;
|
let c = cx.shared.c;
|
||||||
|
|
||||||
hprintln!("foo: a = {}, b = {}, c = {}", a, b, c).unwrap();
|
println!("foo: a = {}, b = {}, c = {}", a, b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-structure-ing syntax
|
// De-structure-ing syntax
|
||||||
|
@ -50,6 +50,6 @@ mod app {
|
||||||
fn bar(cx: bar::Context) {
|
fn bar(cx: bar::Context) {
|
||||||
let bar::SharedResources { a, b, c } = cx.shared;
|
let bar::SharedResources { a, b, c } = cx.shared;
|
||||||
|
|
||||||
hprintln!("bar: a = {}, b = {}, c = {}", a, b, c).unwrap();
|
println!("bar: a = {}, b = {}, c = {}", a, b, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,19 +5,19 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use cortex_m_semihosting::hprintln;
|
use examples_runner as _;
|
||||||
use panic_semihosting as _;
|
use examples_runner::println;
|
||||||
|
|
||||||
// Free function implementing the interrupt bound task `foo`.
|
// Free function implementing the interrupt bound task `foo`.
|
||||||
fn foo(_: app::foo::Context) {
|
fn foo(_: app::foo::Context) {
|
||||||
hprintln!("foo called").ok();
|
println!("foo called");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
use crate::foo;
|
use crate::foo;
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::pac::Interrupt;
|
||||||
use lm3s6965::Interrupt;
|
use examples_runner::{exit, println};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -29,22 +29,22 @@ mod app {
|
||||||
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
rtic::pend(Interrupt::UART0);
|
rtic::pend(Interrupt::UART0);
|
||||||
|
|
||||||
hprintln!("init").unwrap();
|
println!("init");
|
||||||
|
|
||||||
(Shared {}, Local {}, init::Monotonics())
|
(Shared {}, Local {}, init::Monotonics())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[idle]
|
#[idle]
|
||||||
fn idle(_: idle::Context) -> ! {
|
fn idle(_: idle::Context) -> ! {
|
||||||
hprintln!("idle").unwrap();
|
println!("idle");
|
||||||
|
|
||||||
rtic::pend(Interrupt::UART0);
|
rtic::pend(Interrupt::UART0);
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
loop {
|
// loop {
|
||||||
cortex_m::asm::nop();
|
// cortex_m::asm::nop();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "Rust" {
|
extern "Rust" {
|
|
@ -5,19 +5,19 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
// Free function implementing the spawnable task `foo`.
|
// Free function implementing the spawnable task `foo`.
|
||||||
fn foo(_c: app::foo::Context, x: i32, y: u32) {
|
fn foo(_c: app::foo::Context, x: i32, y: u32) {
|
||||||
hprintln!("foo {}, {}", x, y).unwrap();
|
println!("foo {}, {}", x, y);
|
||||||
if x == 2 {
|
if x == 2 {
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
}
|
}
|
||||||
app::foo::spawn(2, 3).unwrap();
|
app::foo::spawn(2, 3).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [SSI0])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])]
|
||||||
mod app {
|
mod app {
|
||||||
use crate::foo;
|
use crate::foo;
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use cortex_m_semihosting::hprintln;
|
use examples_runner as _;
|
||||||
use panic_semihosting as _;
|
use examples_runner::println;
|
||||||
use rtic::Mutex;
|
use rtic::Mutex;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::pac::Interrupt;
|
||||||
use lm3s6965::Interrupt;
|
use examples_runner::{exit, println};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
|
@ -32,19 +32,19 @@ mod app {
|
||||||
|
|
||||||
#[task(binds = UART0, shared = [shared], local = [state: u32 = 0])]
|
#[task(binds = UART0, shared = [shared], local = [state: u32 = 0])]
|
||||||
fn uart0(c: uart0::Context) {
|
fn uart0(c: uart0::Context) {
|
||||||
hprintln!("UART0(STATE = {})", *c.local.state).unwrap();
|
println!("UART0(STATE = {})", *c.local.state);
|
||||||
|
|
||||||
// second argument has type `shared::shared`
|
// second argument has type `shared::shared`
|
||||||
super::advance(c.local.state, c.shared.shared);
|
super::advance(c.local.state, c.shared.shared);
|
||||||
|
|
||||||
rtic::pend(Interrupt::UART1);
|
rtic::pend(Interrupt::UART1);
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(binds = UART1, priority = 2, shared = [shared], local = [state: u32 = 0])]
|
#[task(binds = UART1, priority = 2, shared = [shared], local = [state: u32 = 0])]
|
||||||
fn uart1(c: uart1::Context) {
|
fn uart1(c: uart1::Context) {
|
||||||
hprintln!("UART1(STATE = {})", *c.local.state).unwrap();
|
println!("UART1(STATE = {})", *c.local.state);
|
||||||
|
|
||||||
// second argument has type `shared::shared`
|
// second argument has type `shared::shared`
|
||||||
super::advance(c.local.state, c.shared.shared);
|
super::advance(c.local.state, c.shared.shared);
|
||||||
|
@ -61,5 +61,5 @@ fn advance(state: &mut u32, mut shared: impl Mutex<T = u32>) {
|
||||||
(old, *shared)
|
(old, *shared)
|
||||||
});
|
});
|
||||||
|
|
||||||
hprintln!("shared: {} -> {}", old, new).unwrap();
|
println!("shared: {} -> {}", old, new);
|
||||||
}
|
}
|
|
@ -5,12 +5,12 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::pac::Interrupt;
|
||||||
use lm3s6965::Interrupt;
|
use examples_runner::{exit, println};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -24,7 +24,7 @@ mod app {
|
||||||
// `init` returns because interrupts are disabled
|
// `init` returns because interrupts are disabled
|
||||||
rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend
|
rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend
|
||||||
|
|
||||||
hprintln!("init").unwrap();
|
println!("init");
|
||||||
|
|
||||||
(Shared {}, Local {}, init::Monotonics())
|
(Shared {}, Local {}, init::Monotonics())
|
||||||
}
|
}
|
||||||
|
@ -33,15 +33,15 @@ mod app {
|
||||||
fn idle(_: idle::Context) -> ! {
|
fn idle(_: idle::Context) -> ! {
|
||||||
// interrupts are enabled again; the `UART0` handler runs at this point
|
// interrupts are enabled again; the `UART0` handler runs at this point
|
||||||
|
|
||||||
hprintln!("idle").unwrap();
|
println!("idle");
|
||||||
|
|
||||||
rtic::pend(Interrupt::UART0);
|
rtic::pend(Interrupt::UART0);
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
loop {
|
// loop {
|
||||||
cortex_m::asm::nop();
|
// cortex_m::asm::nop();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(binds = UART0, local = [times: u32 = 0])]
|
#[task(binds = UART0, local = [times: u32 = 0])]
|
||||||
|
@ -49,11 +49,10 @@ mod app {
|
||||||
// Safe access to local `static mut` variable
|
// Safe access to local `static mut` variable
|
||||||
*cx.local.times += 1;
|
*cx.local.times += 1;
|
||||||
|
|
||||||
hprintln!(
|
println!(
|
||||||
"UART0 called {} time{}",
|
"UART0 called {} time{}",
|
||||||
*cx.local.times,
|
*cx.local.times,
|
||||||
if *cx.local.times > 1 { "s" } else { "" }
|
if *cx.local.times > 1 { "s" } else { "" }
|
||||||
)
|
);
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -19,7 +19,7 @@ mod app {
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
hprintln!("init").unwrap();
|
println!("init");
|
||||||
|
|
||||||
// Set the ARM SLEEPONEXIT bit to go to sleep after handling interrupts
|
// Set the ARM SLEEPONEXIT bit to go to sleep after handling interrupts
|
||||||
// See https://developer.arm.com/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
|
// See https://developer.arm.com/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit
|
||||||
|
@ -33,15 +33,15 @@ mod app {
|
||||||
// Locals in idle have lifetime 'static
|
// Locals in idle have lifetime 'static
|
||||||
let _x: &'static mut u32 = cx.local.x;
|
let _x: &'static mut u32 = cx.local.x;
|
||||||
|
|
||||||
hprintln!("idle").unwrap();
|
println!("idle");
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
loop {
|
// loop {
|
||||||
// Now Wait For Interrupt is used instead of a busy-wait loop
|
// // Now Wait For Interrupt is used instead of a busy-wait loop
|
||||||
// to allow MCU to sleep between interrupts
|
// // to allow MCU to sleep between interrupts
|
||||||
// https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/WFI
|
// // https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/WFI
|
||||||
rtic::export::wfi()
|
// rtic::export::wfi()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965)]
|
#[rtic::app(device = examples_runner::pac)]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -19,7 +19,7 @@ mod app {
|
||||||
|
|
||||||
#[init]
|
#[init]
|
||||||
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||||
hprintln!("init").unwrap();
|
println!("init");
|
||||||
|
|
||||||
(Shared {}, Local {}, init::Monotonics())
|
(Shared {}, Local {}, init::Monotonics())
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,12 @@ mod app {
|
||||||
// Locals in idle have lifetime 'static
|
// Locals in idle have lifetime 'static
|
||||||
let _x: &'static mut u32 = cx.local.x;
|
let _x: &'static mut u32 = cx.local.x;
|
||||||
|
|
||||||
hprintln!("idle").unwrap();
|
println!("idle");
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
loop {
|
// loop {
|
||||||
cortex_m::asm::nop();
|
// cortex_m::asm::nop();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, peripherals = true)]
|
#[rtic::app(device = examples_runner::pac, peripherals = true)]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -23,7 +23,7 @@ mod app {
|
||||||
let _core: cortex_m::Peripherals = cx.core;
|
let _core: cortex_m::Peripherals = cx.core;
|
||||||
|
|
||||||
// Device specific peripherals
|
// Device specific peripherals
|
||||||
let _device: lm3s6965::Peripherals = cx.device;
|
let _device: examples_runner::pac::Peripherals = cx.device;
|
||||||
|
|
||||||
// Locals in `init` have 'static lifetime
|
// Locals in `init` have 'static lifetime
|
||||||
let _x: &'static mut u32 = cx.local.x;
|
let _x: &'static mut u32 = cx.local.x;
|
||||||
|
@ -32,10 +32,10 @@ mod app {
|
||||||
// to indicate that this is a critical seciton
|
// to indicate that this is a critical seciton
|
||||||
let _cs_token: bare_metal::CriticalSection = cx.cs;
|
let _cs_token: bare_metal::CriticalSection = cx.cs;
|
||||||
|
|
||||||
hprintln!("init").unwrap();
|
println!("init");
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
(Shared {}, Local {}, init::Monotonics())
|
// (Shared {}, Local {}, init::Monotonics())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [UART0, UART1])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {}
|
struct Shared {}
|
||||||
|
@ -45,9 +45,9 @@ mod app {
|
||||||
let local_to_idle = cx.local.local_to_idle;
|
let local_to_idle = cx.local.local_to_idle;
|
||||||
*local_to_idle += 1;
|
*local_to_idle += 1;
|
||||||
|
|
||||||
hprintln!("idle: local_to_idle = {}", local_to_idle).unwrap();
|
println!("idle: local_to_idle = {}", local_to_idle);
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
|
|
||||||
// error: no `local_to_foo` field in `idle::LocalResources`
|
// error: no `local_to_foo` field in `idle::LocalResources`
|
||||||
// _cx.local.local_to_foo += 1;
|
// _cx.local.local_to_foo += 1;
|
||||||
|
@ -55,9 +55,9 @@ mod app {
|
||||||
// error: no `local_to_bar` field in `idle::LocalResources`
|
// error: no `local_to_bar` field in `idle::LocalResources`
|
||||||
// _cx.local.local_to_bar += 1;
|
// _cx.local.local_to_bar += 1;
|
||||||
|
|
||||||
loop {
|
// loop {
|
||||||
cortex_m::asm::nop();
|
// cortex_m::asm::nop();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// `local_to_foo` can only be accessed from this context
|
// `local_to_foo` can only be accessed from this context
|
||||||
|
@ -69,7 +69,7 @@ mod app {
|
||||||
// error: no `local_to_bar` field in `foo::LocalResources`
|
// error: no `local_to_bar` field in `foo::LocalResources`
|
||||||
// cx.local.local_to_bar += 1;
|
// cx.local.local_to_bar += 1;
|
||||||
|
|
||||||
hprintln!("foo: local_to_foo = {}", local_to_foo).unwrap();
|
println!("foo: local_to_foo = {}", local_to_foo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// `local_to_bar` can only be accessed from this context
|
// `local_to_bar` can only be accessed from this context
|
||||||
|
@ -81,6 +81,6 @@ mod app {
|
||||||
// error: no `local_to_foo` field in `bar::LocalResources`
|
// error: no `local_to_foo` field in `bar::LocalResources`
|
||||||
// cx.local.local_to_foo += 1;
|
// cx.local.local_to_foo += 1;
|
||||||
|
|
||||||
hprintln!("bar: local_to_bar = {}", local_to_bar).unwrap();
|
println!("bar: local_to_bar = {}", local_to_bar);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [GPIOA])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
|
@ -33,7 +33,7 @@ mod app {
|
||||||
|
|
||||||
*c.shared.counter += 1; // <- no lock API required
|
*c.shared.counter += 1; // <- no lock API required
|
||||||
let counter = *c.shared.counter;
|
let counter = *c.shared.counter;
|
||||||
hprintln!(" foo = {}", counter).unwrap();
|
println!(" foo = {}", counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(shared = [counter])] // <- same priority
|
#[task(shared = [counter])] // <- same priority
|
||||||
|
@ -42,8 +42,8 @@ mod app {
|
||||||
|
|
||||||
*c.shared.counter += 1; // <- no lock API required
|
*c.shared.counter += 1; // <- no lock API required
|
||||||
let counter = *c.shared.counter;
|
let counter = *c.shared.counter;
|
||||||
hprintln!(" bar = {}", counter).unwrap();
|
println!(" bar = {}", counter);
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use panic_semihosting as _;
|
use examples_runner as _;
|
||||||
|
|
||||||
#[rtic::app(device = lm3s6965, dispatchers = [GPIOA, GPIOB, GPIOC])]
|
#[rtic::app(device = examples_runner::pac, dispatchers = [GPIOA, GPIOB, GPIOC])]
|
||||||
mod app {
|
mod app {
|
||||||
use cortex_m_semihosting::{debug, hprintln};
|
use examples_runner::{println, exit};
|
||||||
|
|
||||||
#[shared]
|
#[shared]
|
||||||
struct Shared {
|
struct Shared {
|
||||||
|
@ -29,7 +29,7 @@ mod app {
|
||||||
// when omitted priority is assumed to be `1`
|
// when omitted priority is assumed to be `1`
|
||||||
#[task(shared = [shared])]
|
#[task(shared = [shared])]
|
||||||
fn foo(mut c: foo::Context) {
|
fn foo(mut c: foo::Context) {
|
||||||
hprintln!("A").unwrap();
|
println!("A");
|
||||||
|
|
||||||
// the lower priority task requires a critical section to access the data
|
// the lower priority task requires a critical section to access the data
|
||||||
c.shared.shared.lock(|shared| {
|
c.shared.shared.lock(|shared| {
|
||||||
|
@ -39,7 +39,7 @@ mod app {
|
||||||
// bar will *not* run right now due to the critical section
|
// bar will *not* run right now due to the critical section
|
||||||
bar::spawn().unwrap();
|
bar::spawn().unwrap();
|
||||||
|
|
||||||
hprintln!("B - shared = {}", *shared).unwrap();
|
println!("B - shared = {}", *shared);
|
||||||
|
|
||||||
// baz does not contend for `shared` so it's allowed to run now
|
// baz does not contend for `shared` so it's allowed to run now
|
||||||
baz::spawn().unwrap();
|
baz::spawn().unwrap();
|
||||||
|
@ -47,9 +47,9 @@ mod app {
|
||||||
|
|
||||||
// critical section is over: bar can now start
|
// critical section is over: bar can now start
|
||||||
|
|
||||||
hprintln!("E").unwrap();
|
println!("E");
|
||||||
|
|
||||||
debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(priority = 2, shared = [shared])]
|
#[task(priority = 2, shared = [shared])]
|
||||||
|
@ -61,11 +61,11 @@ mod app {
|
||||||
*shared
|
*shared
|
||||||
});
|
});
|
||||||
|
|
||||||
hprintln!("D - shared = {}", shared).unwrap();
|
println!("D - shared = {}", shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[task(priority = 3)]
|
#[task(priority = 3)]
|
||||||
fn baz(_: baz::Context) {
|
fn baz(_: baz::Context) {
|
||||||
hprintln!("C").unwrap();
|
println!("C");
|
||||||
}
|
}
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue