aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml150
-rw-r--r--.gitignore3
-rw-r--r--ci/expected/hifive1/prio_inheritance.run17
-rw-r--r--ci/expected/hifive1/static.run (renamed from rtic/ci/expected/static.run)0
-rw-r--r--ci/expected/hifive1/task.run (renamed from rtic/ci/expected/task.run)0
-rw-r--r--ci/expected/hifive1/zero_prio_task.run (renamed from rtic/ci/expected/zero-prio-task.run)0
-rw-r--r--ci/expected/lm3s6965/async-channel-done.run (renamed from rtic/ci/expected/async-channel-done.run)0
-rw-r--r--ci/expected/lm3s6965/async-channel-no-receiver.run (renamed from rtic/ci/expected/async-channel-no-receiver.run)0
-rw-r--r--ci/expected/lm3s6965/async-channel-no-sender.run (renamed from rtic/ci/expected/async-channel-no-sender.run)0
-rw-r--r--ci/expected/lm3s6965/async-channel-try.run (renamed from rtic/ci/expected/async-channel-try.run)0
-rw-r--r--ci/expected/lm3s6965/async-channel.run (renamed from rtic/ci/expected/async-channel.run)0
-rw-r--r--ci/expected/lm3s6965/async-delay.run (renamed from rtic/ci/expected/async-delay.run)0
-rw-r--r--ci/expected/lm3s6965/async-infinite-loop.run (renamed from rtic/ci/expected/async-infinite-loop.run)0
-rw-r--r--ci/expected/lm3s6965/async-task-multiple-prios.run (renamed from rtic/ci/expected/async-task-multiple-prios.run)0
-rw-r--r--ci/expected/lm3s6965/async-task.run (renamed from rtic/ci/expected/async-task.run)0
-rw-r--r--ci/expected/lm3s6965/async-timeout.run (renamed from rtic/ci/expected/async-timeout.run)0
-rw-r--r--ci/expected/lm3s6965/big-struct-opt.run (renamed from rtic/ci/expected/big-struct-opt.run)0
-rw-r--r--ci/expected/lm3s6965/binds.run (renamed from rtic/ci/expected/binds.run)0
-rw-r--r--ci/expected/lm3s6965/cancel-reschedule.run (renamed from rtic/ci/expected/cancel-reschedule.run)0
-rw-r--r--ci/expected/lm3s6965/capacity.run (renamed from rtic/ci/expected/capacity.run)0
-rw-r--r--ci/expected/lm3s6965/cfg-whole-task.run (renamed from rtic/ci/expected/cfg-whole-task.run)0
-rw-r--r--ci/expected/lm3s6965/common.run (renamed from rtic/ci/expected/common.run)0
-rw-r--r--ci/expected/lm3s6965/complex.run (renamed from rtic/ci/expected/complex.run)0
-rw-r--r--ci/expected/lm3s6965/declared_locals.run (renamed from rtic/ci/expected/declared_locals.run)0
-rw-r--r--ci/expected/lm3s6965/destructure.run (renamed from rtic/ci/expected/destructure.run)0
-rw-r--r--ci/expected/lm3s6965/executor-size.run (renamed from rtic/ci/expected/executor-size.run)0
-rw-r--r--ci/expected/lm3s6965/extern_binds.run (renamed from rtic/ci/expected/extern_binds.run)0
-rw-r--r--ci/expected/lm3s6965/extern_spawn.run (renamed from rtic/ci/expected/extern_spawn.run)0
-rw-r--r--ci/expected/lm3s6965/generics.run (renamed from rtic/ci/expected/generics.run)0
-rw-r--r--ci/expected/lm3s6965/hardware.run (renamed from rtic/ci/expected/hardware.run)0
-rw-r--r--ci/expected/lm3s6965/idle-wfi.run (renamed from rtic/ci/expected/idle-wfi.run)0
-rw-r--r--ci/expected/lm3s6965/idle.run (renamed from rtic/ci/expected/idle.run)0
-rw-r--r--ci/expected/lm3s6965/init.run (renamed from rtic/ci/expected/init.run)0
-rw-r--r--ci/expected/lm3s6965/locals.run (renamed from rtic/ci/expected/locals.run)0
-rw-r--r--ci/expected/lm3s6965/lock-free.run (renamed from rtic/ci/expected/lock-free.run)0
-rw-r--r--ci/expected/lm3s6965/lock.run (renamed from rtic/ci/expected/lock.run)0
-rw-r--r--ci/expected/lm3s6965/message.run (renamed from rtic/ci/expected/message.run)0
-rw-r--r--ci/expected/lm3s6965/multilock.run (renamed from rtic/ci/expected/multilock.run)0
-rw-r--r--ci/expected/lm3s6965/not-sync.run (renamed from rtic/ci/expected/not-sync.run)0
-rw-r--r--ci/expected/lm3s6965/only-shared-access.run (renamed from rtic/ci/expected/only-shared-access.run)0
-rw-r--r--ci/expected/lm3s6965/periodic-at.run (renamed from rtic/ci/expected/periodic-at.run)0
-rw-r--r--ci/expected/lm3s6965/periodic-at2.run (renamed from rtic/ci/expected/periodic-at2.run)0
-rw-r--r--ci/expected/lm3s6965/periodic.run (renamed from rtic/ci/expected/periodic.run)0
-rw-r--r--ci/expected/lm3s6965/peripherals-taken.run (renamed from rtic/ci/expected/peripherals-taken.run)0
-rw-r--r--ci/expected/lm3s6965/pool.run (renamed from rtic/ci/expected/pool.run)0
-rw-r--r--ci/expected/lm3s6965/preempt.run (renamed from rtic/ci/expected/preempt.run)0
-rw-r--r--ci/expected/lm3s6965/prio-inversion.run (renamed from rtic/ci/expected/prio-inversion.run)0
-rw-r--r--ci/expected/lm3s6965/ramfunc.run (renamed from rtic/ci/expected/ramfunc.run)0
-rw-r--r--ci/expected/lm3s6965/ramfunc.run.grep.bar (renamed from rtic/ci/expected/ramfunc.run.grep.bar)0
-rw-r--r--ci/expected/lm3s6965/ramfunc.run.grep.foo (renamed from rtic/ci/expected/ramfunc.run.grep.foo)0
-rw-r--r--ci/expected/lm3s6965/resource-user-struct.run (renamed from rtic/ci/expected/resource-user-struct.run)0
-rw-r--r--ci/expected/lm3s6965/schedule.run (renamed from rtic/ci/expected/schedule.run)0
-rw-r--r--ci/expected/lm3s6965/shared.run (renamed from rtic/ci/expected/shared.run)0
-rw-r--r--ci/expected/lm3s6965/smallest.run (renamed from rtic/ci/expected/smallest.run)0
-rw-r--r--ci/expected/lm3s6965/spawn.run (renamed from rtic/ci/expected/spawn.run)0
-rw-r--r--ci/expected/lm3s6965/spawn_arguments.run (renamed from rtic/ci/expected/spawn_arguments.run)0
-rw-r--r--ci/expected/lm3s6965/spawn_err.run (renamed from rtic/ci/expected/spawn_err.run)0
-rw-r--r--ci/expected/lm3s6965/spawn_loop.run (renamed from rtic/ci/expected/spawn_loop.run)0
-rw-r--r--ci/expected/lm3s6965/static.run3
-rw-r--r--ci/expected/lm3s6965/t-binds.run (renamed from rtic/ci/expected/t-binds.run)0
-rw-r--r--ci/expected/lm3s6965/t-cfg-resources.run (renamed from rtic/ci/expected/t-cfg-resources.run)0
-rw-r--r--ci/expected/lm3s6965/t-htask-main.run (renamed from rtic/ci/expected/t-htask-main.run)0
-rw-r--r--ci/expected/lm3s6965/t-idle-main.run (renamed from rtic/ci/expected/t-idle-main.run)0
-rw-r--r--ci/expected/lm3s6965/t-late-not-send.run (renamed from rtic/ci/expected/t-late-not-send.run)0
-rw-r--r--ci/expected/lm3s6965/t-schedule.run (renamed from rtic/ci/expected/t-schedule.run)0
-rw-r--r--ci/expected/lm3s6965/t-spawn.run (renamed from rtic/ci/expected/t-spawn.run)0
-rw-r--r--ci/expected/lm3s6965/task.run5
-rw-r--r--ci/expected/lm3s6965/zero-prio-task.run3
-rw-r--r--examples/hifive1/.cargo/config.toml11
-rw-r--r--examples/hifive1/Cargo.lock364
-rw-r--r--examples/hifive1/Cargo.toml22
-rw-r--r--examples/hifive1/examples/prio_inheritance.rs140
-rw-r--r--examples/hifive1/examples/static.rs60
-rw-r--r--examples/hifive1/examples/task.rs57
-rw-r--r--examples/hifive1/examples/zero_prio_task.rs61
-rw-r--r--examples/hifive1/rust-toolchain.toml4
-rw-r--r--examples/lm3s6965/.cargo/config.toml13
-rw-r--r--examples/lm3s6965/Cargo.lock527
-rw-r--r--examples/lm3s6965/Cargo.toml36
-rw-r--r--examples/lm3s6965/examples/async-channel-done.rs (renamed from rtic/examples/async-channel-done.rs)0
-rw-r--r--examples/lm3s6965/examples/async-channel-no-receiver.rs (renamed from rtic/examples/async-channel-no-receiver.rs)0
-rw-r--r--examples/lm3s6965/examples/async-channel-no-sender.rs (renamed from rtic/examples/async-channel-no-sender.rs)0
-rw-r--r--examples/lm3s6965/examples/async-channel-try.rs (renamed from rtic/examples/async-channel-try.rs)0
-rw-r--r--examples/lm3s6965/examples/async-channel.rs (renamed from rtic/examples/async-channel.rs)0
-rw-r--r--examples/lm3s6965/examples/async-delay.rs (renamed from rtic/examples/async-delay.rs)0
-rw-r--r--examples/lm3s6965/examples/async-task-multiple-prios.rs (renamed from rtic/examples/async-task-multiple-prios.rs)0
-rw-r--r--examples/lm3s6965/examples/async-task.rs (renamed from rtic/examples/async-task.rs)0
-rw-r--r--examples/lm3s6965/examples/async-timeout.rs (renamed from rtic/examples/async-timeout.rs)0
-rw-r--r--examples/lm3s6965/examples/big-struct-opt.rs (renamed from rtic/examples/big-struct-opt.rs)0
-rw-r--r--examples/lm3s6965/examples/binds.rs (renamed from rtic/examples/binds.rs)0
-rw-r--r--examples/lm3s6965/examples/common.rs (renamed from rtic/examples/common.rs)0
-rw-r--r--examples/lm3s6965/examples/complex.rs (renamed from rtic/examples/complex.rs)0
-rw-r--r--examples/lm3s6965/examples/declared_locals.rs (renamed from rtic/examples/declared_locals.rs)0
-rw-r--r--examples/lm3s6965/examples/destructure.rs (renamed from rtic/examples/destructure.rs)0
-rw-r--r--examples/lm3s6965/examples/executor-size.rs (renamed from rtic/examples/executor-size.rs)0
-rw-r--r--examples/lm3s6965/examples/extern_binds.rs (renamed from rtic/examples/extern_binds.rs)0
-rw-r--r--examples/lm3s6965/examples/extern_spawn.rs (renamed from rtic/examples/extern_spawn.rs)0
-rw-r--r--examples/lm3s6965/examples/generics.rs (renamed from rtic/examples/generics.rs)0
-rw-r--r--examples/lm3s6965/examples/hardware.rs (renamed from rtic/examples/hardware.rs)0
-rw-r--r--examples/lm3s6965/examples/idle-wfi.rs (renamed from rtic/examples/idle-wfi.rs)0
-rw-r--r--examples/lm3s6965/examples/idle.rs (renamed from rtic/examples/idle.rs)0
-rw-r--r--examples/lm3s6965/examples/init.rs (renamed from rtic/examples/init.rs)0
-rw-r--r--examples/lm3s6965/examples/locals.rs (renamed from rtic/examples/locals.rs)0
-rw-r--r--examples/lm3s6965/examples/lock-free.rs (renamed from rtic/examples/lock-free.rs)0
-rw-r--r--examples/lm3s6965/examples/lock.rs (renamed from rtic/examples/lock.rs)0
-rw-r--r--examples/lm3s6965/examples/multilock.rs (renamed from rtic/examples/multilock.rs)0
-rw-r--r--examples/lm3s6965/examples/not-sync.rs (renamed from rtic/examples/not-sync.rs)0
-rw-r--r--examples/lm3s6965/examples/only-shared-access.rs (renamed from rtic/examples/only-shared-access.rs)0
-rw-r--r--examples/lm3s6965/examples/peripherals-taken.rs (renamed from rtic/examples/peripherals-taken.rs)0
-rw-r--r--examples/lm3s6965/examples/pool.rs_old (renamed from rtic/examples/pool.rs_old)0
-rw-r--r--examples/lm3s6965/examples/preempt.rs (renamed from rtic/examples/preempt.rs)0
-rw-r--r--examples/lm3s6965/examples/prio-inversion.rs (renamed from rtic/examples/prio-inversion.rs)0
-rw-r--r--examples/lm3s6965/examples/ramfunc.rs (renamed from rtic/examples/ramfunc.rs)0
-rw-r--r--examples/lm3s6965/examples/resource-user-struct.rs (renamed from rtic/examples/resource-user-struct.rs)0
-rw-r--r--examples/lm3s6965/examples/shared.rs (renamed from rtic/examples/shared.rs)0
-rw-r--r--examples/lm3s6965/examples/smallest.rs (renamed from rtic/examples/smallest.rs)0
-rw-r--r--examples/lm3s6965/examples/spawn.rs (renamed from rtic/examples/spawn.rs)0
-rw-r--r--examples/lm3s6965/examples/spawn_arguments.rs (renamed from rtic/examples/spawn_arguments.rs)0
-rw-r--r--examples/lm3s6965/examples/spawn_err.rs (renamed from rtic/examples/spawn_err.rs)0
-rw-r--r--examples/lm3s6965/examples/spawn_loop.rs (renamed from rtic/examples/spawn_loop.rs)0
-rw-r--r--examples/lm3s6965/examples/static.rs (renamed from rtic/examples/static.rs)0
-rw-r--r--examples/lm3s6965/examples/t-binds.rs (renamed from rtic/examples/t-binds.rs)0
-rw-r--r--examples/lm3s6965/examples/t-cfg-resources.rs (renamed from rtic/examples/t-cfg-resources.rs)0
-rw-r--r--examples/lm3s6965/examples/t-htask-main.rs (renamed from rtic/examples/t-htask-main.rs)0
-rw-r--r--examples/lm3s6965/examples/t-idle-main.rs (renamed from rtic/examples/t-idle-main.rs)0
-rw-r--r--examples/lm3s6965/examples/t-late-not-send.rs (renamed from rtic/examples/t-late-not-send.rs)0
-rw-r--r--examples/lm3s6965/examples/task.rs (renamed from rtic/examples/task.rs)0
-rw-r--r--examples/lm3s6965/examples/zero-prio-task.rs (renamed from rtic/examples/zero-prio-task.rs)0
-rw-r--r--rtic-macros/CHANGELOG.md1
-rw-r--r--rtic-macros/Cargo.toml4
-rw-r--r--rtic-macros/src/codegen.rs1
-rw-r--r--rtic-macros/src/codegen/async_dispatchers.rs7
-rw-r--r--rtic-macros/src/codegen/bindings.rs11
-rw-r--r--rtic-macros/src/codegen/bindings/cortex.rs18
-rw-r--r--rtic-macros/src/codegen/bindings/esp32c3.rs14
-rw-r--r--rtic-macros/src/codegen/bindings/riscv_slic.rs255
-rw-r--r--rtic-macros/src/codegen/bindings/template.rs60
-rw-r--r--rtic-macros/src/codegen/extra_mods.rs9
-rw-r--r--rtic-macros/src/codegen/main.rs16
-rw-r--r--rtic-macros/src/codegen/module.rs29
-rw-r--r--rtic-macros/src/codegen/pre_init.rs10
-rw-r--r--rtic-macros/src/codegen/util.rs2
-rw-r--r--rtic-macros/src/lib.rs17
-rw-r--r--rtic-macros/src/preprocess.rs7
-rw-r--r--rtic-macros/src/syntax.rs1
-rw-r--r--rtic-macros/src/syntax/ast.rs10
-rw-r--r--rtic-macros/src/syntax/backend.rs32
-rw-r--r--rtic-macros/src/syntax/backend/cortex.rs16
-rw-r--r--rtic-macros/src/syntax/backend/esp32c3.rs16
-rw-r--r--rtic-macros/src/syntax/backend/riscv_slic.rs16
-rw-r--r--rtic-macros/src/syntax/backend/template.rs15
-rw-r--r--rtic-macros/src/syntax/parse/app.rs28
-rw-r--r--rtic-monotonics/CHANGELOG.md1
-rw-r--r--rtic/.cargo/config.toml8
-rw-r--r--rtic/CHANGELOG.md1
-rw-r--r--rtic/Cargo.toml14
-rw-r--r--rtic/build.rs51
-rw-r--r--rtic/src/export.rs30
-rw-r--r--rtic/src/export/riscv_common.rs3
-rw-r--r--rtic/src/export/riscv_esp32c3.rs1
-rw-r--r--rtic/src/export/slic.rs19
-rw-r--r--rtic/src/lib.rs1
-rw-r--r--xtask/src/argument_parsing.rs194
-rw-r--r--xtask/src/cargo_command.rs71
-rw-r--r--xtask/src/main.rs66
-rw-r--r--xtask/src/run.rs78
166 files changed, 2308 insertions, 301 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 578ca40..3a4ed8f 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -31,9 +31,9 @@ jobs:
- name: cargo xtask fmt
run: cargo xtask --verbose fmt -c
- # Compilation check
- check:
- name: check
+ # Compilation check (lm3s6965)
+ checklm3s6965:
+ name: check (lm3s6965)
runs-on: ubuntu-22.04
strategy:
matrix:
@@ -62,11 +62,14 @@ jobs:
- name: Cache Dependencies
uses: Swatinem/rust-cache@v2
- - run: cargo xtask --deny-warnings --backend ${{ matrix.backend }} check
+ - run: cargo xtask --deny-warnings --platform lm3s6965 --backend ${{ matrix.backend }} check
- # Clippy
- clippy:
- name: clippy
+ # Compilation check (hifive1) TODO
+ # checkhifive1:
+
+ # Clippy (lm3s6965)
+ clippylm3s6965:
+ name: clippy (lm3s6965)
runs-on: ubuntu-22.04
strategy:
matrix:
@@ -98,11 +101,14 @@ jobs:
- name: Cache Dependencies
uses: Swatinem/rust-cache@v2
- - run: cargo xtask --deny-warnings --backend ${{ matrix.backend }} clippy
+ - run: cargo xtask --deny-warnings --platform lm3s6965 --backend ${{ matrix.backend }} clippy
+
+ # Clippy (hifive1) TODO
+ # clippyhifive1:
- # Verify all examples, checks
- checkexamples:
- name: check examples
+ # Platform lm3s6965: verify all examples, checks
+ checkexampleslm3s6965:
+ name: check examples (lm3s6965)
runs-on: ubuntu-22.04
strategy:
matrix:
@@ -133,44 +139,46 @@ jobs:
- name: Check the examples
if: ${{ matrix.backend == 'thumbv8-base' }}
- run: cargo xtask --backend ${{ matrix.backend }} --exampleexclude pool example-check
+ run: cargo xtask --platform lm3s6965 --backend ${{ matrix.backend }} --exampleexclude pool example-check
- name: Check the examples
if: ${{ matrix.backend != 'thumbv8-base' }}
- run: cargo xtask --backend ${{ matrix.backend }} example-check
-
- # Check that the usage examples build
- usageexamples:
- name: Build usage examples
+ run: cargo xtask --platform lm3s6965 --backend ${{ matrix.backend }} example-check
+
+ # Platform hifive1: verify all examples, checks
+ checkexampleshifive1:
+ name: check examples (hifive1)
runs-on: ubuntu-22.04
strategy:
matrix:
+ backend:
+ - riscv32-imc-clint
+ - riscv32-imac-clint
toolchain:
- stable
steps:
- name: Checkout
uses: actions/checkout@v4
- - name: Install rust ${{ matrix.toolchain }}
+ - name: Install Rust ${{ matrix.toolchain }}
run: |
- rustup set profile minimal
rustup override set ${{ matrix.toolchain }}
- - name: Configure rust target (v6, v7)
+ - name: Configure Rust target
run: |
- rustup target add thumbv7em-none-eabihf
- rustup target add thumbv7m-none-eabi
- rustup target add thumbv6m-none-eabi
- rustup component add rust-src
+ rustup target add riscv32imac-unknown-none-elf
+ rustup target add riscv32imc-unknown-none-elf
- name: Cache Dependencies
uses: Swatinem/rust-cache@v2
-
- - name: Install flip-link
- run: cargo install flip-link
+
+ - name: Check the examples
+ if: ${{ matrix.backend == 'riscv32-imc-clint' }}
+ run: cargo xtask --platform hifive1 --backend ${{ matrix.backend }} --exampleexclude static example-check
- name: Check the examples
- run: cargo xtask usage-example-build
+ if: ${{ matrix.backend != 'riscv32-imc-clint' }}
+ run: cargo xtask --platform hifive1 --backend ${{ matrix.backend }} example-check
buildqemu:
name: Get modern QEMU, build and store
@@ -192,7 +200,7 @@ jobs:
- name: Install QEMU to get dependencies
run: |
sudo apt update
- sudo apt install -y qemu-system-arm
+ sudo apt install -y qemu-system-arm qemu-system-riscv32
sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build
- if: ${{ steps.cache-qemu.outputs.cache-hit != 'true' }}
@@ -226,9 +234,9 @@ jobs:
name: qemu
path: qemu.tar
- # Verify the example output with run-pass tests
- testexamples:
- name: QEMU run
+ # Platform lm3s6965: verify the example output with run-pass tests
+ testexampleslm3s6965:
+ name: QEMU run (lm3s6965)
needs: buildqemu
runs-on: ubuntu-22.04
strategy:
@@ -283,7 +291,71 @@ jobs:
which qemu-system-riscv32
- name: Run-pass tests
- run: cargo xtask --deny-warnings --backend ${{ matrix.backend }} qemu
+ run: cargo xtask --deny-warnings --platform lm3s6965 --backend ${{ matrix.backend }} qemu
+
+ # Platform hifive1: verify the example output with run-pass tests
+ testexampleshifive1:
+ name: QEMU run (hifive1)
+ needs: buildqemu
+ runs-on: ubuntu-22.04
+ strategy:
+ matrix:
+ backend:
+ - riscv32-imc-clint
+ - riscv32-imac-clint
+ toolchain:
+ - stable
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Install Rust ${{ matrix.toolchain }}
+ run: |
+ rustup set profile minimal
+ rustup override set ${{ matrix.toolchain }}
+
+ - name: Configure Rust target
+ run: |
+ rustup target add riscv32imac-unknown-none-elf
+ rustup target add riscv32imc-unknown-none-elf
+
+ - name: Add Rust component llvm-tools-preview
+ run: rustup component add llvm-tools-preview
+
+ # Use precompiled binutils
+ - name: Install cargo-binutils
+ uses: taiki-e/install-action@v2
+ with:
+ tool: cargo-binutils
+
+ - name: Cache Dependencies
+ uses: Swatinem/rust-cache@v2
+
+ - name: Install QEMU to get dependencies
+ run: |
+ sudo apt update
+ sudo apt install -y qemu-system-riscv32
+
+ - name: Download built QEMU
+ uses: actions/download-artifact@v4
+ with:
+ name: qemu
+
+ - name: Extract QEMU into local path
+ run: tar -xf qemu.tar -C /usr/local/bin
+
+ - name: Check which QEMU is used
+ run: |
+ which qemu-system-arm
+ which qemu-system-riscv32
+
+ - name: Run-pass tests
+ if: ${{ matrix.backend == 'riscv32-imc-clint' }}
+ run: cargo xtask --deny-warnings --platform hifive1 --backend ${{ matrix.backend }} --exampleexclude static qemu
+
+ - name: Run-pass tests
+ if: ${{ matrix.backend != 'riscv32-imc-clint' }}
+ run: cargo xtask --deny-warnings --platform hifive1 --backend ${{ matrix.backend }} qemu
# Run test suite
tests:
@@ -719,10 +791,14 @@ jobs:
if: github.event_name == 'push' && success()
needs:
- formatcheck
- - check
- - clippy
- - checkexamples
- - testexamples
+ - checklm3s6965
+ # checkhifive1 TODO
+ - clippylm3s6965
+ # clippyhifive1 TODO
+ - checkexampleslm3s6965
+ - checkexampleshifive1
+ - testexampleslm3s6965
+ - testexampleshifive1
- tests
- docs
- mdbook
diff --git a/.gitignore b/.gitignore
index d081dc3..88b19b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,6 @@
Cargo.lock
*.hex
book-target/
+
+.DS_Store
+.vscode/
diff --git a/ci/expected/hifive1/prio_inheritance.run b/ci/expected/hifive1/prio_inheritance.run
new file mode 100644
index 0000000..c60b241
--- /dev/null
+++ b/ci/expected/hifive1/prio_inheritance.run
@@ -0,0 +1,17 @@
+[Idle]: Started
+ [SoftMedium]: Started
+ [SoftMedium]: Shared: 1
+ [SoftHigh]: Started
+ [SoftHigh]: Shared: 2
+ [SoftHigh]: Finished
+ [SoftMedium]: Finished
+ [SoftLow1]: Started
+ [SoftLow1]: Shared: 3
+ [SoftLow1]: Yield
+ [SoftLow2]: Started
+ [SoftLow2]: Shared: 4
+ [SoftLow2]: Yield
+ [SoftLow1]: Finished
+ [SoftLow2]: Finished
+[Idle]: Shared: 4
+[Idle]: Finished
diff --git a/rtic/ci/expected/static.run b/ci/expected/hifive1/static.run
index 3d3f46f..3d3f46f 100644
--- a/rtic/ci/expected/static.run
+++ b/ci/expected/hifive1/static.run
diff --git a/rtic/ci/expected/task.run b/ci/expected/hifive1/task.run
index de45dce..de45dce 100644
--- a/rtic/ci/expected/task.run
+++ b/ci/expected/hifive1/task.run
diff --git a/rtic/ci/expected/zero-prio-task.run b/ci/expected/hifive1/zero_prio_task.run
index 123b0f2..123b0f2 100644
--- a/rtic/ci/expected/zero-prio-task.run
+++ b/ci/expected/hifive1/zero_prio_task.run
diff --git a/rtic/ci/expected/async-channel-done.run b/ci/expected/lm3s6965/async-channel-done.run
index 525962a..525962a 100644
--- a/rtic/ci/expected/async-channel-done.run
+++ b/ci/expected/lm3s6965/async-channel-done.run
diff --git a/rtic/ci/expected/async-channel-no-receiver.run b/ci/expected/lm3s6965/async-channel-no-receiver.run
index 34624e1..34624e1 100644
--- a/rtic/ci/expected/async-channel-no-receiver.run
+++ b/ci/expected/lm3s6965/async-channel-no-receiver.run
diff --git a/rtic/ci/expected/async-channel-no-sender.run b/ci/expected/lm3s6965/async-channel-no-sender.run
index 237f2f1..237f2f1 100644
--- a/rtic/ci/expected/async-channel-no-sender.run
+++ b/ci/expected/lm3s6965/async-channel-no-sender.run
diff --git a/rtic/ci/expected/async-channel-try.run b/ci/expected/lm3s6965/async-channel-try.run
index c3a4092..c3a4092 100644
--- a/rtic/ci/expected/async-channel-try.run
+++ b/ci/expected/lm3s6965/async-channel-try.run
diff --git a/rtic/ci/expected/async-channel.run b/ci/expected/lm3s6965/async-channel.run
index 4e313a1..4e313a1 100644
--- a/rtic/ci/expected/async-channel.run
+++ b/ci/expected/lm3s6965/async-channel.run
diff --git a/rtic/ci/expected/async-delay.run b/ci/expected/lm3s6965/async-delay.run
index 61852ab..61852ab 100644
--- a/rtic/ci/expected/async-delay.run
+++ b/ci/expected/lm3s6965/async-delay.run
diff --git a/rtic/ci/expected/async-infinite-loop.run b/ci/expected/lm3s6965/async-infinite-loop.run
index f9fd4e4..f9fd4e4 100644
--- a/rtic/ci/expected/async-infinite-loop.run
+++ b/ci/expected/lm3s6965/async-infinite-loop.run
diff --git a/rtic/ci/expected/async-task-multiple-prios.run b/ci/expected/lm3s6965/async-task-multiple-prios.run
index 0b42df0..0b42df0 100644
--- a/rtic/ci/expected/async-task-multiple-prios.run
+++ b/ci/expected/lm3s6965/async-task-multiple-prios.run
diff --git a/rtic/ci/expected/async-task.run b/ci/expected/lm3s6965/async-task.run
index 1f93a4c..1f93a4c 100644
--- a/rtic/ci/expected/async-task.run
+++ b/ci/expected/lm3s6965/async-task.run
diff --git a/rtic/ci/expected/async-timeout.run b/ci/expected/lm3s6965/async-timeout.run
index 6b4c089..6b4c089 100644
--- a/rtic/ci/expected/async-timeout.run
+++ b/ci/expected/lm3s6965/async-timeout.run
diff --git a/rtic/ci/expected/big-struct-opt.run b/ci/expected/lm3s6965/big-struct-opt.run
index 7fdef35..7fdef35 100644
--- a/rtic/ci/expected/big-struct-opt.run
+++ b/ci/expected/lm3s6965/big-struct-opt.run
diff --git a/rtic/ci/expected/binds.run b/ci/expected/lm3s6965/binds.run
index f84cff0..f84cff0 100644
--- a/rtic/ci/expected/binds.run
+++ b/ci/expected/lm3s6965/binds.run
diff --git a/rtic/ci/expected/cancel-reschedule.run b/ci/expected/lm3s6965/cancel-reschedule.run
index 5a94752..5a94752 100644
--- a/rtic/ci/expected/cancel-reschedule.run
+++ b/ci/expected/lm3s6965/cancel-reschedule.run
diff --git a/rtic/ci/expected/capacity.run b/ci/expected/lm3s6965/capacity.run
index f96815d..f96815d 100644
--- a/rtic/ci/expected/capacity.run
+++ b/ci/expected/lm3s6965/capacity.run
diff --git a/rtic/ci/expected/cfg-whole-task.run b/ci/expected/lm3s6965/cfg-whole-task.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/cfg-whole-task.run
+++ b/ci/expected/lm3s6965/cfg-whole-task.run
diff --git a/rtic/ci/expected/common.run b/ci/expected/lm3s6965/common.run
index 4f1d350..4f1d350 100644
--- a/rtic/ci/expected/common.run
+++ b/ci/expected/lm3s6965/common.run
diff --git a/rtic/ci/expected/complex.run b/ci/expected/lm3s6965/complex.run
index 5df884d..5df884d 100644
--- a/rtic/ci/expected/complex.run
+++ b/ci/expected/lm3s6965/complex.run
diff --git a/rtic/ci/expected/declared_locals.run b/ci/expected/lm3s6965/declared_locals.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/declared_locals.run
+++ b/ci/expected/lm3s6965/declared_locals.run
diff --git a/rtic/ci/expected/destructure.run b/ci/expected/lm3s6965/destructure.run
index 25a4b1b..25a4b1b 100644
--- a/rtic/ci/expected/destructure.run
+++ b/ci/expected/lm3s6965/destructure.run
diff --git a/rtic/ci/expected/executor-size.run b/ci/expected/lm3s6965/executor-size.run
index 2bb0d06..2bb0d06 100644
--- a/rtic/ci/expected/executor-size.run
+++ b/ci/expected/lm3s6965/executor-size.run
diff --git a/rtic/ci/expected/extern_binds.run b/ci/expected/lm3s6965/extern_binds.run
index 9d925d5..9d925d5 100644
--- a/rtic/ci/expected/extern_binds.run
+++ b/ci/expected/lm3s6965/extern_binds.run
diff --git a/rtic/ci/expected/extern_spawn.run b/ci/expected/lm3s6965/extern_spawn.run
index 257cc56..257cc56 100644
--- a/rtic/ci/expected/extern_spawn.run
+++ b/ci/expected/lm3s6965/extern_spawn.run
diff --git a/rtic/ci/expected/generics.run b/ci/expected/lm3s6965/generics.run
index fb31731..fb31731 100644
--- a/rtic/ci/expected/generics.run
+++ b/ci/expected/lm3s6965/generics.run
diff --git a/rtic/ci/expected/hardware.run b/ci/expected/lm3s6965/hardware.run
index ef00864..ef00864 100644
--- a/rtic/ci/expected/hardware.run
+++ b/ci/expected/lm3s6965/hardware.run
diff --git a/rtic/ci/expected/idle-wfi.run b/ci/expected/lm3s6965/idle-wfi.run
index 4307776..4307776 100644
--- a/rtic/ci/expected/idle-wfi.run
+++ b/ci/expected/lm3s6965/idle-wfi.run
diff --git a/rtic/ci/expected/idle.run b/ci/expected/lm3s6965/idle.run
index 4307776..4307776 100644
--- a/rtic/ci/expected/idle.run
+++ b/ci/expected/lm3s6965/idle.run
diff --git a/rtic/ci/expected/init.run b/ci/expected/lm3s6965/init.run
index b1b7161..b1b7161 100644
--- a/rtic/ci/expected/init.run
+++ b/ci/expected/lm3s6965/init.run
diff --git a/rtic/ci/expected/locals.run b/ci/expected/lm3s6965/locals.run
index 4f1d350..4f1d350 100644
--- a/rtic/ci/expected/locals.run
+++ b/ci/expected/lm3s6965/locals.run
diff --git a/rtic/ci/expected/lock-free.run b/ci/expected/lm3s6965/lock-free.run
index 18de0ec..18de0ec 100644
--- a/rtic/ci/expected/lock-free.run
+++ b/ci/expected/lm3s6965/lock-free.run
diff --git a/rtic/ci/expected/lock.run b/ci/expected/lm3s6965/lock.run
index a987b37..a987b37 100644
--- a/rtic/ci/expected/lock.run
+++ b/ci/expected/lm3s6965/lock.run
diff --git a/rtic/ci/expected/message.run b/ci/expected/lm3s6965/message.run
index 11814db..11814db 100644
--- a/rtic/ci/expected/message.run
+++ b/ci/expected/lm3s6965/message.run
diff --git a/rtic/ci/expected/multilock.run b/ci/expected/lm3s6965/multilock.run
index dd8c1f2..dd8c1f2 100644
--- a/rtic/ci/expected/multilock.run
+++ b/ci/expected/lm3s6965/multilock.run
diff --git a/rtic/ci/expected/not-sync.run b/ci/expected/lm3s6965/not-sync.run
index cd91476..cd91476 100644
--- a/rtic/ci/expected/not-sync.run
+++ b/ci/expected/lm3s6965/not-sync.run
diff --git a/rtic/ci/expected/only-shared-access.run b/ci/expected/lm3s6965/only-shared-access.run
index dcc73e6..dcc73e6 100644
--- a/rtic/ci/expected/only-shared-access.run
+++ b/ci/expected/lm3s6965/only-shared-access.run
diff --git a/rtic/ci/expected/periodic-at.run b/ci/expected/lm3s6965/periodic-at.run
index bf5bb06..bf5bb06 100644
--- a/rtic/ci/expected/periodic-at.run
+++ b/ci/expected/lm3s6965/periodic-at.run
diff --git a/rtic/ci/expected/periodic-at2.run b/ci/expected/lm3s6965/periodic-at2.run
index 6e56421..6e56421 100644
--- a/rtic/ci/expected/periodic-at2.run
+++ b/ci/expected/lm3s6965/periodic-at2.run
diff --git a/rtic/ci/expected/periodic.run b/ci/expected/lm3s6965/periodic.run
index a1f8944..a1f8944 100644
--- a/rtic/ci/expected/periodic.run
+++ b/ci/expected/lm3s6965/periodic.run
diff --git a/rtic/ci/expected/peripherals-taken.run b/ci/expected/lm3s6965/peripherals-taken.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/peripherals-taken.run
+++ b/ci/expected/lm3s6965/peripherals-taken.run
diff --git a/rtic/ci/expected/pool.run b/ci/expected/lm3s6965/pool.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/pool.run
+++ b/ci/expected/lm3s6965/pool.run
diff --git a/rtic/ci/expected/preempt.run b/ci/expected/lm3s6965/preempt.run
index 932b2b3..932b2b3 100644
--- a/rtic/ci/expected/preempt.run
+++ b/ci/expected/lm3s6965/preempt.run
diff --git a/rtic/ci/expected/prio-inversion.run b/ci/expected/lm3s6965/prio-inversion.run
index 9191436..9191436 100644
--- a/rtic/ci/expected/prio-inversion.run
+++ b/ci/expected/lm3s6965/prio-inversion.run
diff --git a/rtic/ci/expected/ramfunc.run b/ci/expected/lm3s6965/ramfunc.run
index 257cc56..257cc56 100644
--- a/rtic/ci/expected/ramfunc.run
+++ b/ci/expected/lm3s6965/ramfunc.run
diff --git a/rtic/ci/expected/ramfunc.run.grep.bar b/ci/expected/lm3s6965/ramfunc.run.grep.bar
index 33e002f..33e002f 100644
--- a/rtic/ci/expected/ramfunc.run.grep.bar
+++ b/ci/expected/lm3s6965/ramfunc.run.grep.bar
diff --git a/rtic/ci/expected/ramfunc.run.grep.foo b/ci/expected/lm3s6965/ramfunc.run.grep.foo
index 44e8822..44e8822 100644
--- a/rtic/ci/expected/ramfunc.run.grep.foo
+++ b/ci/expected/lm3s6965/ramfunc.run.grep.foo
diff --git a/rtic/ci/expected/resource-user-struct.run b/ci/expected/lm3s6965/resource-user-struct.run
index a587a94..a587a94 100644
--- a/rtic/ci/expected/resource-user-struct.run
+++ b/ci/expected/lm3s6965/resource-user-struct.run
diff --git a/rtic/ci/expected/schedule.run b/ci/expected/lm3s6965/schedule.run
index 1dbd445..1dbd445 100644
--- a/rtic/ci/expected/schedule.run
+++ b/ci/expected/lm3s6965/schedule.run
diff --git a/rtic/ci/expected/shared.run b/ci/expected/lm3s6965/shared.run
index 6d3d3e4..6d3d3e4 100644
--- a/rtic/ci/expected/shared.run
+++ b/ci/expected/lm3s6965/shared.run
diff --git a/rtic/ci/expected/smallest.run b/ci/expected/lm3s6965/smallest.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/smallest.run
+++ b/ci/expected/lm3s6965/smallest.run
diff --git a/rtic/ci/expected/spawn.run b/ci/expected/lm3s6965/spawn.run
index 240cd18..240cd18 100644
--- a/rtic/ci/expected/spawn.run
+++ b/ci/expected/lm3s6965/spawn.run
diff --git a/rtic/ci/expected/spawn_arguments.run b/ci/expected/lm3s6965/spawn_arguments.run
index 9085e13..9085e13 100644
--- a/rtic/ci/expected/spawn_arguments.run
+++ b/ci/expected/lm3s6965/spawn_arguments.run
diff --git a/rtic/ci/expected/spawn_err.run b/ci/expected/lm3s6965/spawn_err.run
index 97c4112..97c4112 100644
--- a/rtic/ci/expected/spawn_err.run
+++ b/ci/expected/lm3s6965/spawn_err.run
diff --git a/rtic/ci/expected/spawn_loop.run b/ci/expected/lm3s6965/spawn_loop.run
index ee6e1e3..ee6e1e3 100644
--- a/rtic/ci/expected/spawn_loop.run
+++ b/ci/expected/lm3s6965/spawn_loop.run
diff --git a/ci/expected/lm3s6965/static.run b/ci/expected/lm3s6965/static.run
new file mode 100644
index 0000000..3d3f46f
--- /dev/null
+++ b/ci/expected/lm3s6965/static.run
@@ -0,0 +1,3 @@
+received message: 1
+received message: 2
+received message: 3
diff --git a/rtic/ci/expected/t-binds.run b/ci/expected/lm3s6965/t-binds.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/t-binds.run
+++ b/ci/expected/lm3s6965/t-binds.run
diff --git a/rtic/ci/expected/t-cfg-resources.run b/ci/expected/lm3s6965/t-cfg-resources.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/t-cfg-resources.run
+++ b/ci/expected/lm3s6965/t-cfg-resources.run
diff --git a/rtic/ci/expected/t-htask-main.run b/ci/expected/lm3s6965/t-htask-main.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/t-htask-main.run
+++ b/ci/expected/lm3s6965/t-htask-main.run
diff --git a/rtic/ci/expected/t-idle-main.run b/ci/expected/lm3s6965/t-idle-main.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/t-idle-main.run
+++ b/ci/expected/lm3s6965/t-idle-main.run
diff --git a/rtic/ci/expected/t-late-not-send.run b/ci/expected/lm3s6965/t-late-not-send.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/t-late-not-send.run
+++ b/ci/expected/lm3s6965/t-late-not-send.run
diff --git a/rtic/ci/expected/t-schedule.run b/ci/expected/lm3s6965/t-schedule.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/t-schedule.run
+++ b/ci/expected/lm3s6965/t-schedule.run
diff --git a/rtic/ci/expected/t-spawn.run b/ci/expected/lm3s6965/t-spawn.run
index e69de29..e69de29 100644
--- a/rtic/ci/expected/t-spawn.run
+++ b/ci/expected/lm3s6965/t-spawn.run
diff --git a/ci/expected/lm3s6965/task.run b/ci/expected/lm3s6965/task.run
new file mode 100644
index 0000000..de45dce
--- /dev/null
+++ b/ci/expected/lm3s6965/task.run
@@ -0,0 +1,5 @@
+foo - start
+foo - middle
+baz
+foo - end
+bar
diff --git a/ci/expected/lm3s6965/zero-prio-task.run b/ci/expected/lm3s6965/zero-prio-task.run
new file mode 100644
index 0000000..123b0f2
--- /dev/null
+++ b/ci/expected/lm3s6965/zero-prio-task.run
@@ -0,0 +1,3 @@
+init
+hello from async
+hello from async2
diff --git a/examples/hifive1/.cargo/config.toml b/examples/hifive1/.cargo/config.toml
new file mode 100644
index 0000000..2ce90b2
--- /dev/null
+++ b/examples/hifive1/.cargo/config.toml
@@ -0,0 +1,11 @@
+[target.'cfg(all(target_arch = "riscv32", target_os = "none"))']
+runner = "qemu-system-riscv32 -machine sifive_e,revb=true -nographic -semihosting-config enable=on,target=native -kernel"
+# runner = "riscv64-unknown-elf-gdb -q -x gdb_init"
+rustflags = [
+ "-C", "link-arg=-Thifive1-link.x",
+]
+
+[build]
+# Pick ONE of these compilation targets
+# target = "riscv32imc-unknown-none-elf" # non-atomic support
+target = "riscv32imac-unknown-none-elf" # atomic support (partial)
diff --git a/examples/hifive1/Cargo.lock b/examples/hifive1/Cargo.lock
new file mode 100644
index 0000000..7cd694c
--- /dev/null
+++ b/examples/hifive1/Cargo.lock
@@ -0,0 +1,364 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "atomic-polyfill"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
+name = "bare-metal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "critical-section"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
+
+[[package]]
+name = "e310x"
+version = "0.11.0"
+source = "git+https://github.com/greenlsi/e310x.git?branch=master#50536cc5be2fd6adf7f879f002fdd98f66fb05f9"
+dependencies = [
+ "critical-section",
+ "riscv-pac",
+ "riscv-peripheral",
+ "vcell",
+]
+
+[[package]]
+name = "e310x"
+version = "0.11.0"
+source = "git+https://github.com/greenlsi/e310x.git#50536cc5be2fd6adf7f879f002fdd98f66fb05f9"
+dependencies = [
+ "riscv-pac",
+ "riscv-peripheral",
+ "vcell",
+]
+
+[[package]]
+name = "e310x-hal"
+version = "0.11.0"
+source = "git+https://github.com/greenlsi/e310x-hal.git?branch=master#931aea7ab142c1eb9eaadd4150946d8452229f27"
+dependencies = [
+ "e310x 0.11.0 (git+https://github.com/greenlsi/e310x.git?branch=master)",
+ "embedded-hal 0.2.7",
+ "nb 1.1.0",
+ "portable-atomic",
+ "riscv",
+]
+
+[[package]]
+name = "embedded-hal"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
+dependencies = [
+ "nb 0.1.3",
+ "void",
+]
+
+[[package]]
+name = "embedded-hal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "hash32"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+
+[[package]]
+name = "heapless"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
+dependencies = [
+ "hash32",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "hifive1"
+version = "0.11.0"
+source = "git+https://github.com/romancardenas/hifive1.git#ef8cea8b90bddb04509785d3e148ff145137520a"
+dependencies = [
+ "e310x-hal",
+ "embedded-hal 0.2.7",
+ "nb 1.1.0",
+ "riscv",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "nb"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
+dependencies = [
+ "nb 1.1.0",
+]
+
+[[package]]
+name = "nb"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
+
+[[package]]
+name = "portable-atomic"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "riscv"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9"
+dependencies = [
+ "critical-section",
+ "embedded-hal 1.0.0",
+]
+
+[[package]]
+name = "riscv-pac"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18ceb4af23fdad434f938afdc35ce895a63d84f7333bb127d8065030848eb6a6"
+
+[[package]]
+name = "riscv-peripheral"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07c799fe4e144bd4dd0c68fa33a41c1485f19730eea505d195124636e1253358"
+dependencies = [
+ "embedded-hal 1.0.0",
+ "riscv",
+ "riscv-pac",
+]
+
+[[package]]
+name = "riscv-rt"
+version = "0.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0d35e32cf1383183e8885d8a9aa4402a087fd094dc34c2cb6df6687d0229dfe"
+dependencies = [
+ "riscv",
+ "riscv-rt-macros",
+]
+
+[[package]]
+name = "riscv-rt-macros"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8d100d466dbb76681ef6a9386f3da9abc570d57394e86da0ba5af8c4408486d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "riscv-slic"
+version = "0.1.0"
+source = "git+https://github.com/romancardenas/riscv-slic.git?rev=2a91edb#2a91edbff50bcc73169549923d278ff953d0986e"
+dependencies = [
+ "critical-section",
+ "heapless",
+ "riscv",
+ "riscv-slic-macros",
+]
+
+[[package]]
+name = "riscv-slic-macros"
+version = "0.1.0"
+source = "git+https://github.com/romancardenas/riscv-slic.git?rev=2a91edb#2a91edbff50bcc73169549923d278ff953d0986e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.49",
+]
+
+[[package]]
+name = "rtic"
+version = "2.1.0"
+dependencies = [
+ "atomic-polyfill",
+ "bare-metal",
+ "critical-section",
+ "riscv",
+ "riscv-slic",
+ "rtic-core",
+ "rtic-macros",
+]
+
+[[package]]
+name = "rtic-core"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
+
+[[package]]
+name = "rtic-macros"
+version = "2.1.0"
+dependencies = [
+ "indexmap",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.49",
+]
+
+[[package]]
+name = "rtic_hifive1"
+version = "0.1.0"
+dependencies = [
+ "e310x 0.11.0 (git+https://github.com/greenlsi/e310x.git)",
+ "heapless",
+ "hifive1",
+ "riscv",
+ "riscv-rt",
+ "rtic",
+ "semihosting",
+]
+
+[[package]]
+name = "semihosting"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab7a0be8d9e9893dfb5ce313aa0324396936d8bf788f5ef493c9f122ad84fd8"
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.49"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "vcell"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
diff --git a/examples/hifive1/Cargo.toml b/examples/hifive1/Cargo.toml
new file mode 100644
index 0000000..42d60a7
--- /dev/null
+++ b/examples/hifive1/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+name = "rtic_hifive1"
+categories = ["embedded", "no-std"]
+description = "Examples of RTIC apps for the HiFive1 board"
+license = "MIT OR Apache-2.0"
+version = "0.1.0"
+edition = "2021"
+
+[workspace]
+
+[dependencies]
+rtic = { path = "../../rtic" }
+heapless = "0.8.0"
+hifive1 = { git = "https://github.com/romancardenas/hifive1.git", features = ["board-redv"] }
+e310x = { git = "https://github.com/greenlsi/e310x.git", features = ["rt"]}
+riscv-rt = {version = "0.12.1", features = ["single-hart"]}
+riscv = "0.11.0"
+semihosting = { version = "0.1", features = ["stdio", "panic-handler"] }
+
+[features]
+riscv-clint-backend = ["rtic/riscv-clint-backend"]
+test-critical-section = []
diff --git a/examples/hifive1/examples/prio_inheritance.rs b/examples/hifive1/examples/prio_inheritance.rs
new file mode 100644
index 0000000..5fc2399
--- /dev/null
+++ b/examples/hifive1/examples/prio_inheritance.rs
@@ -0,0 +1,140 @@
+#![no_main]
+#![no_std]
+
+use riscv_rt as _;
+
+#[rtic::app(device = e310x, backend = HART0)]
+mod app {
+ use core::{future::Future, pin::Pin, task::Context, task::Poll};
+ use hifive1::hal::prelude::*;
+ use semihosting::{println, process::exit};
+
+ /// Dummy asynchronous function to showcase SW tasks
+ pub async fn yield_now(task: &str) {
+ /// Yield implementation
+ struct YieldNow {
+ yielded: bool,
+ }
+ println!(" [{}]: Yield", task);
+
+ impl Future for YieldNow {
+ type Output = ();
+
+ fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+ if self.yielded {
+ return Poll::Ready(());
+ }
+
+ self.yielded = true;
+ cx.waker().wake_by_ref();
+
+ Poll::Pending
+ }
+ }
+
+ YieldNow { yielded: false }.await
+ }
+
+ #[shared]
+ struct Shared {
+ counter: u32,
+ }
+
+ #[local]
+ struct Local {}
+
+ #[init]
+ fn init(_: init::Context) -> (Shared, Local) {
+ // Pends the SoftLow interrupt but its handler won't run until *after*
+ // `init` returns because interrupts are disabled
+ let resources = unsafe { hifive1::hal::DeviceResources::steal() };
+ let peripherals = resources.peripherals;
+
+ let clocks =
+ hifive1::configure_clocks(peripherals.PRCI, peripherals.AONCLK, 64.mhz().into());
+ let gpio = resources.pins;
+
+ // Configure UART for stdout
+ hifive1::stdout::configure(
+ peripherals.UART0,
+ hifive1::pin!(gpio, uart0_tx),
+ hifive1::pin!(gpio, uart0_rx),
+ 115_200.bps(),
+ clocks,
+ );
+
+ (Shared { counter: 0 }, Local {})
+ }
+
+ #[idle(shared = [counter])]
+ fn idle(mut cx: idle::Context) -> ! {
+ println!("[Idle]: Started");
+ // pend the medium priority SW task only once
+ soft_medium::spawn().unwrap();
+ cx.shared.counter.lock(|counter| {
+ println!("[Idle]: Shared: {}", *counter);
+ });
+ // exit QEMU simulator
+ println!("[Idle]: Finished");
+ exit(0);
+ }
+
+ /// Medium priority SW task. It is triggered by the idle and spawns the rest of the SW tasks
+ #[task(shared = [counter], priority = 2)]
+ async fn soft_medium(mut cx: soft_medium::Context) {
+ // Safe access to local `static mut` variable
+ println!(" [SoftMedium]: Started");
+ cx.shared.counter.lock(|counter| {
+ // Spawn the other SW tasks INSIDE the critical section (just for showing priority inheritance)
+ soft_low_1::spawn().unwrap();
+ soft_high::spawn().unwrap();
+ soft_low_2::spawn().unwrap();
+
+ *counter += 1;
+ println!(" [SoftMedium]: Shared: {}", *counter);
+ });
+ println!(" [SoftMedium]: Finished");
+ }
+
+ /// Low priority SW task. It runs cooperatively with soft_low_2
+ #[task(shared = [counter], priority = 1)]
+ async fn soft_low_1(mut cx: soft_low_1::Context) {
+ println!(" [SoftLow1]: Started");
+ cx.shared.counter.lock(|counter| {
+ *counter += 1;
+ println!(" [SoftLow1]: Shared: {}", *counter);
+ });
+ // Yield to the other SW task
+ yield_now("SoftLow1").await;
+
+ println!(" [SoftLow1]: Finished");
+ }
+
+ /// Low priority SW task. It runs cooperatively with soft_low_2
+ #[task(shared = [counter], priority = 1)]
+ async fn soft_low_2(mut cx: soft_low_2::Context) {
+ println!(" [SoftLow2]: Started");
+ cx.shared.counter.lock(|counter| {
+ *counter += 1;
+ println!(" [SoftLow2]: Shared: {}", *counter);
+ });
+
+ // Yield to the other SW task
+ yield_now("SoftLow2").await;
+
+ println!(" [SoftLow2]: Finished");
+ }
+
+ /// High priority SW task
+ #[task(shared = [counter], priority = 3)]
+ async fn soft_high(mut cx: soft_high::Context) {
+ println!(" [SoftHigh]: Started");
+
+ cx.shared.counter.lock(|counter| {
+ *counter += 1;
+ println!(" [SoftHigh]: Shared: {}", counter);
+ });
+
+ println!(" [SoftHigh]: Finished");
+ }
+}
diff --git a/examples/hifive1/examples/static.rs b/examples/hifive1/examples/static.rs
new file mode 100644
index 0000000..34e71c6
--- /dev/null
+++ b/examples/hifive1/examples/static.rs
@@ -0,0 +1,60 @@
+//! zero priority task
+#![no_main]
+#![no_std]
+#![deny(warnings)]
+#![deny(unsafe_code)]
+#![deny(missing_docs)]
+
+use hifive1 as _;
+use riscv_rt as _;
+
+#[rtic::app(device = e310x, backend = HART0)]
+mod app {
+ use semihosting::{process::exit, println};
+ use heapless::spsc::{Consumer, Producer, Queue};
+
+ #[shared]
+ struct Shared {}
+
+ #[local]
+ struct Local {
+ p: Producer<'static, u32, 5>,
+ c: Consumer<'static, u32, 5>,
+ }
+
+ #[init(local = [q: Queue<u32, 5> = Queue::new()])]
+ fn init(cx: init::Context) -> (Shared, Local) {
+ // q has 'static life-time so after the split and return of `init`
+ // it will continue to exist and be allocated
+ let (p, c) = cx.local.q.split();
+
+ foo::spawn().unwrap();
+
+ (Shared {}, Local { p, c })
+ }
+
+ #[idle(local = [c])]
+ fn idle(c: idle::Context) -> ! {
+ loop {
+ // Lock-free access to the same underlying queue!
+ if let Some(data) = c.local.c.dequeue() {
+ println!("received message: {}", data);
+
+ // Run foo until data
+ if data == 3 {
+ exit(0); // Exit QEMU simulator
+ } else {
+ foo::spawn().unwrap();
+ }
+ }
+ }
+ }
+
+ #[task(local = [p, state: u32 = 0], priority = 1)]
+ async fn foo(c: foo::Context) {
+ *c.local.state += 1;
+
+ // Lock-free access to the same underlying queue!
+ c.local.p.enqueue(*c.local.state).unwrap();
+ }
+}
diff --git a/examples/hifive1/examples/task.rs b/examples/hifive1/examples/task.rs
new file mode 100644
index 0000000..6968edb
--- /dev/null
+++ b/examples/hifive1/examples/task.rs
@@ -0,0 +1,57 @@
+//! zero priority task
+#![no_main]
+#![no_std]
+#![deny(warnings)]
+#![deny(unsafe_code)]
+#![deny(missing_docs)]
+
+use hifive1 as _;
+use riscv_rt as _;
+
+#[rtic::app(device = e310x, backend = HART0)]
+mod app {
+ use semihosting::{println, process::exit};
+
+ #[shared]
+ struct Shared {}
+
+ #[local]
+ struct Local {}
+
+ #[init]
+ fn init(_: init::Context) -> (Shared, Local) {
+ foo::spawn().unwrap();
+
+ (Shared {}, Local {})
+ }
+
+ #[task]
+ async fn foo(_: foo::Context) {
+ println!("foo - start");
+
+ // spawns `bar` onto the task scheduler
+ // `foo` and `bar` have the same priority so `bar` will not run until
+ // after `foo` terminates
+ bar::spawn().unwrap();
+
+ println!("foo - middle");
+
+ // spawns `baz` onto the task scheduler
+ // `baz` has higher priority than `foo` so it immediately preempts `foo`
+ baz::spawn().unwrap();
+
+ println!("foo - end");
+ }
+
+ #[task]
+ async fn bar(_: bar::Context) {
+ println!("bar");
+
+ exit(0); // Exit QEMU simulator
+ }
+
+ #[task(priority = 2)]
+ async fn baz(_: baz::Context) {
+ println!("baz");
+ }
+}
diff --git a/examples/hifive1/examples/zero_prio_task.rs b/examples/hifive1/examples/zero_prio_task.rs
new file mode 100644
index 0000000..2528c4f
--- /dev/null
+++ b/examples/hifive1/examples/zero_prio_task.rs
@@ -0,0 +1,61 @@
+//! zero priority task
+#![no_main]
+#![no_std]
+#![deny(warnings)]
+#![deny(unsafe_code)]
+#![deny(missing_docs)]
+
+use core::marker::PhantomData;
+use hifive1 as _;
+use riscv_rt as _;
+
+/// Does not impl send
+pub struct NotSend {
+ _0: PhantomData<*const ()>,
+}
+
+#[rtic::app(device = e310x, backend = HART0)]
+mod app {
+ use super::NotSend;
+ use core::marker::PhantomData;
+ use semihosting::{println, process::exit};
+
+ #[shared]
+ struct Shared {
+ x: NotSend,
+ }
+
+ #[local]
+ struct Local {
+ y: NotSend,
+ }
+
+ #[init]
+ fn init(_cx: init::Context) -> (Shared, Local) {
+ println!("init");
+
+ async_task::spawn().unwrap();
+ async_task2::spawn().unwrap();
+
+ (
+ Shared {
+ x: NotSend { _0: PhantomData },
+ },
+ Local {
+ y: NotSend { _0: PhantomData },
+ },
+ )
+ }
+
+ #[task(priority = 0, shared = [x], local = [y])]
+ async fn async_task(_: async_task::Context) {
+ println!("hello from async");
+ }
+
+ #[task(priority = 0, shared = [x])]
+ async fn async_task2(_: async_task2::Context) {
+ println!("hello from async2");
+
+ exit(0); // Exit QEMU simulator
+ }
+}
diff --git a/examples/hifive1/rust-toolchain.toml b/examples/hifive1/rust-toolchain.toml
new file mode 100644
index 0000000..3dc1c7e
--- /dev/null
+++ b/examples/hifive1/rust-toolchain.toml
@@ -0,0 +1,4 @@
+[toolchain]
+channel = "stable"
+components = [ "rust-src", "rustfmt" ]
+targets = [ "riscv32imc-unknown-none-elf", "riscv32imac-unknown-none-elf" ]
diff --git a/examples/lm3s6965/.cargo/config.toml b/examples/lm3s6965/.cargo/config.toml
new file mode 100644
index 0000000..46b5177
--- /dev/null
+++ b/examples/lm3s6965/.cargo/config.toml
@@ -0,0 +1,13 @@
+[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",
+]
+
+[build]
+target = "thumbv7m-none-eabi"
diff --git a/examples/lm3s6965/Cargo.lock b/examples/lm3s6965/Cargo.lock
new file mode 100644
index 0000000..696c606
--- /dev/null
+++ b/examples/lm3s6965/Cargo.lock
@@ -0,0 +1,527 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "atomic-polyfill"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
+name = "bare-metal"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3"
+dependencies = [
+ "rustc_version",
+]
+
+[[package]]
+name = "bare-metal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603"
+
+[[package]]
+name = "bitfield"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cortex-m"
+version = "0.7.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
+dependencies = [
+ "bare-metal 0.2.5",
+ "bitfield",
+ "critical-section",
+ "embedded-hal 0.2.7",
+ "volatile-register",
+]
+
+[[package]]
+name = "cortex-m-rt"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1"
+dependencies = [
+ "cortex-m-rt-macros",
+]
+
+[[package]]
+name = "cortex-m-rt-macros"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "cortex-m-semihosting"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c23234600452033cc77e4b761e740e02d2c4168e11dbf36ab14a0f58973592b0"
+dependencies = [
+ "cortex-m",
+]
+
+[[package]]
+name = "critical-section"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
+
+[[package]]
+name = "embedded-hal"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
+dependencies = [
+ "nb 0.1.3",
+ "void",
+]
+
+[[package]]
+name = "embedded-hal"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
+
+[[package]]
+name = "embedded-hal-async"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884"
+dependencies = [
+ "embedded-hal 1.0.0",
+]
+
+[[package]]
+name = "embedded-hal-bus"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57b4e6ede84339ebdb418cd986e6320a34b017cdf99b5cc3efceec6450b06886"
+dependencies = [
+ "critical-section",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "fugit"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7"
+dependencies = [
+ "gcd",
+]
+
+[[package]]
+name = "futures"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+
+[[package]]
+name = "futures-io"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.49",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
+
+[[package]]
+name = "futures-task"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+
+[[package]]
+name = "futures-util"
+version = "0.3.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+dependencies = [
+ "futures-core",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "gcd"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a"
+
+[[package]]
+name = "hash32"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+
+[[package]]
+name = "heapless"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
+dependencies = [
+ "hash32",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "lm3s6965"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13d7ed5360fee8fd434cf7995ef1d7ad42697abb538e34383a39da8df5495446"
+dependencies = [
+ "cortex-m",
+ "cortex-m-rt",
+]
+
+[[package]]
+name = "nb"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f"
+dependencies = [
+ "nb 1.1.0",
+]
+
+[[package]]
+name = "nb"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d"
+
+[[package]]
+name = "panic-semihosting"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee8a3e1233d9073d76a870223512ce4eeea43c067a94a445c13bd6d792d7b1ab"
+dependencies = [
+ "cortex-m",
+ "cortex-m-semihosting",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "portable-atomic"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rtic"
+version = "2.1.0"
+dependencies = [
+ "atomic-polyfill",
+ "bare-metal 1.0.0",
+ "cortex-m",
+ "critical-section",
+ "rtic-core",
+ "rtic-macros",
+ "rtic-monotonics",
+]
+
+[[package]]
+name = "rtic-common"
+version = "1.0.1"
+dependencies = [
+ "critical-section",
+ "portable-atomic",
+]
+
+[[package]]
+name = "rtic-core"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42"
+
+[[package]]
+name = "rtic-macros"
+version = "2.1.0"
+dependencies = [
+ "indexmap",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.49",
+]
+
+[[package]]
+name = "rtic-monotonics"
+version = "1.5.0"
+dependencies = [
+ "atomic-polyfill",
+ "cfg-if",
+ "cortex-m",
+ "embedded-hal 1.0.0",
+ "fugit",
+ "rtic-time",
+]
+
+[[package]]
+name = "rtic-sync"
+version = "1.3.0"
+dependencies = [
+ "critical-section",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+ "embedded-hal-bus",
+ "heapless",
+ "portable-atomic",
+ "rtic-common",
+]
+
+[[package]]
+name = "rtic-time"
+version = "1.3.0"
+dependencies = [
+ "critical-section",
+ "futures-util",
+ "rtic-common",
+]
+
+[[package]]
+name = "rtic_lm3s6965"
+version = "0.1.0"
+dependencies = [
+ "bare-metal 1.0.0",
+ "cortex-m",
+ "cortex-m-semihosting",
+ "futures",
+ "heapless",
+ "lm3s6965",
+ "panic-semihosting",
+ "rtic",
+ "rtic-monotonics",
+ "rtic-sync",
+ "rtic-time",
+]
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.49"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "vcell"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "void"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
+
+[[package]]
+name = "volatile-register"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc"
+dependencies = [
+ "vcell",
+]
diff --git a/examples/lm3s6965/Cargo.toml b/examples/lm3s6965/Cargo.toml
new file mode 100644
index 0000000..86a7cbb
--- /dev/null
+++ b/examples/lm3s6965/Cargo.toml
@@ -0,0 +1,36 @@
+[package]
+name = "rtic_lm3s6965"
+categories = ["embedded", "no-std"]
+description = "Examples of RTIC apps for the lm3s6965 chip"
+license = "MIT OR Apache-2.0"
+version = "0.1.0"
+edition = "2021"
+
+[workspace]
+
+[dependencies]
+heapless = "0.8"
+lm3s6965 = "0.2"
+cortex-m = "0.7.0"
+bare-metal = "1.0.0"
+cortex-m-semihosting = "0.5.0"
+rtic-time = { path = "../../rtic-time" }
+rtic-sync = { path = "../../rtic-sync" }
+rtic-monotonics = { path = "../../rtic-monotonics", features = ["cortex-m-systick"] }
+rtic = { path = "../../rtic" }
+
+[dependencies.futures]
+version = "0.3.26"
+default-features = false
+features = ["async-await"]
+
+[dependencies.panic-semihosting]
+features = ["exit"]
+version = "0.6.0"
+
+[features]
+test-critical-section = ["rtic/test-critical-section"]
+thumbv6-backend = ["rtic/thumbv6-backend"]
+thumbv7-backend = ["rtic/thumbv7-backend"]
+thumbv8base-backend = ["rtic/thumbv8base-backend"]
+thumbv8main-backend = ["rtic/thumbv8main-backend"]
diff --git a/rtic/examples/async-channel-done.rs b/examples/lm3s6965/examples/async-channel-done.rs
index e9b9887..e9b9887 100644
--- a/rtic/examples/async-channel-done.rs
+++ b/examples/lm3s6965/examples/async-channel-done.rs
diff --git a/rtic/examples/async-channel-no-receiver.rs b/examples/lm3s6965/examples/async-channel-no-receiver.rs
index 7e416be..7e416be 100644
--- a/rtic/examples/async-channel-no-receiver.rs
+++ b/examples/lm3s6965/examples/async-channel-no-receiver.rs
diff --git a/rtic/examples/async-channel-no-sender.rs b/examples/lm3s6965/examples/async-channel-no-sender.rs
index c4f043c..c4f043c 100644
--- a/rtic/examples/async-channel-no-sender.rs
+++ b/examples/lm3s6965/examples/async-channel-no-sender.rs
diff --git a/rtic/examples/async-channel-try.rs b/examples/lm3s6965/examples/async-channel-try.rs
index 92c6ab6..92c6ab6 100644
--- a/rtic/examples/async-channel-try.rs
+++ b/examples/lm3s6965/examples/async-channel-try.rs
diff --git a/rtic/examples/async-channel.rs b/examples/lm3s6965/examples/async-channel.rs
index 642e218..642e218 100644
--- a/rtic/examples/async-channel.rs
+++ b/examples/lm3s6965/examples/async-channel.rs
diff --git a/rtic/examples/async-delay.rs b/examples/lm3s6965/examples/async-delay.rs
index 9ccfc02..9ccfc02 100644
--- a/rtic/examples/async-delay.rs
+++ b/examples/lm3s6965/examples/async-delay.rs
diff --git a/rtic/examples/async-task-multiple-prios.rs b/examples/lm3s6965/examples/async-task-multiple-prios.rs
index 39b6d60..39b6d60 100644
--- a/rtic/examples/async-task-multiple-prios.rs
+++ b/examples/lm3s6965/examples/async-task-multiple-prios.rs
diff --git a/rtic/examples/async-task.rs b/examples/lm3s6965/examples/async-task.rs
index 1867c4d..1867c4d 100644
--- a/rtic/examples/async-task.rs
+++ b/examples/lm3s6965/examples/async-task.rs
diff --git a/rtic/examples/async-timeout.rs b/examples/lm3s6965/examples/async-timeout.rs
index e5e129f..e5e129f 100644
--- a/rtic/examples/async-timeout.rs
+++ b/examples/lm3s6965/examples/async-timeout.rs
diff --git a/rtic/examples/big-struct-opt.rs b/examples/lm3s6965/examples/big-struct-opt.rs
index 109cc5d..109cc5d 100644
--- a/rtic/examples/big-struct-opt.rs
+++ b/examples/lm3s6965/examples/big-struct-opt.rs
diff --git a/rtic/examples/binds.rs b/examples/lm3s6965/examples/binds.rs
index b101d54..b101d54 100644
--- a/rtic/examples/binds.rs
+++ b/examples/lm3s6965/examples/binds.rs
diff --git a/rtic/examples/common.rs b/examples/lm3s6965/examples/common.rs
index 7f68739..7f68739 100644
--- a/rtic/examples/common.rs
+++ b/examples/lm3s6965/examples/common.rs
diff --git a/rtic/examples/complex.rs b/examples/lm3s6965/examples/complex.rs
index a4fe659..a4fe659 100644
--- a/rtic/examples/complex.rs
+++ b/examples/lm3s6965/examples/complex.rs
diff --git a/rtic/examples/declared_locals.rs b/examples/lm3s6965/examples/declared_locals.rs
index b1bb9f4..b1bb9f4 100644
--- a/rtic/examples/declared_locals.rs
+++ b/examples/lm3s6965/examples/declared_locals.rs
diff --git a/rtic/examples/destructure.rs b/examples/lm3s6965/examples/destructure.rs
index ac35187..ac35187 100644
--- a/rtic/examples/destructure.rs
+++ b/examples/lm3s6965/examples/destructure.rs
diff --git a/rtic/examples/executor-size.rs b/examples/lm3s6965/examples/executor-size.rs
index d825729..d825729 100644
--- a/rtic/examples/executor-size.rs
+++ b/examples/lm3s6965/examples/executor-size.rs
diff --git a/rtic/examples/extern_binds.rs b/examples/lm3s6965/examples/extern_binds.rs
index 45939d2..45939d2 100644
--- a/rtic/examples/extern_binds.rs
+++ b/examples/lm3s6965/examples/extern_binds.rs
diff --git a/rtic/examples/extern_spawn.rs b/examples/lm3s6965/examples/extern_spawn.rs
index 7f68b42..7f68b42 100644
--- a/rtic/examples/extern_spawn.rs
+++ b/examples/lm3s6965/examples/extern_spawn.rs
diff --git a/rtic/examples/generics.rs b/examples/lm3s6965/examples/generics.rs
index dd042a3..dd042a3 100644
--- a/rtic/examples/generics.rs
+++ b/examples/lm3s6965/examples/generics.rs
diff --git a/rtic/examples/hardware.rs b/examples/lm3s6965/examples/hardware.rs
index 3bd62b6..3bd62b6 100644
--- a/rtic/examples/hardware.rs
+++ b/examples/lm3s6965/examples/hardware.rs
diff --git a/rtic/examples/idle-wfi.rs b/examples/lm3s6965/examples/idle-wfi.rs
index 72aaa95..72aaa95 100644
--- a/rtic/examples/idle-wfi.rs
+++ b/examples/lm3s6965/examples/idle-wfi.rs
diff --git a/rtic/examples/idle.rs b/examples/lm3s6965/examples/idle.rs
index 4149818..4149818 100644
--- a/rtic/examples/idle.rs
+++ b/examples/lm3s6965/examples/idle.rs
diff --git a/rtic/examples/init.rs b/examples/lm3s6965/examples/init.rs
index 634d309..634d309 100644
--- a/rtic/examples/init.rs
+++ b/examples/lm3s6965/examples/init.rs
diff --git a/rtic/examples/locals.rs b/examples/lm3s6965/examples/locals.rs
index 5d5e246..5d5e246 100644
--- a/rtic/examples/locals.rs
+++ b/examples/lm3s6965/examples/locals.rs
diff --git a/rtic/examples/lock-free.rs b/examples/lm3s6965/examples/lock-free.rs
index c9d2ab0..c9d2ab0 100644
--- a/rtic/examples/lock-free.rs
+++ b/examples/lm3s6965/examples/lock-free.rs
diff --git a/rtic/examples/lock.rs b/examples/lm3s6965/examples/lock.rs
index 091a1b0..091a1b0 100644
--- a/rtic/examples/lock.rs
+++ b/examples/lm3s6965/examples/lock.rs
diff --git a/rtic/examples/multilock.rs b/examples/lm3s6965/examples/multilock.rs
index 77245ae..77245ae 100644
--- a/rtic/examples/multilock.rs
+++ b/examples/lm3s6965/examples/multilock.rs
diff --git a/rtic/examples/not-sync.rs b/examples/lm3s6965/examples/not-sync.rs
index 09ba77e..09ba77e 100644
--- a/rtic/examples/not-sync.rs
+++ b/examples/lm3s6965/examples/not-sync.rs
diff --git a/rtic/examples/only-shared-access.rs b/examples/lm3s6965/examples/only-shared-access.rs
index c83dca5..c83dca5 100644
--- a/rtic/examples/only-shared-access.rs
+++ b/examples/lm3s6965/examples/only-shared-access.rs
diff --git a/rtic/examples/peripherals-taken.rs b/examples/lm3s6965/examples/peripherals-taken.rs
index 2f63001..2f63001 100644
--- a/rtic/examples/peripherals-taken.rs
+++ b/examples/lm3s6965/examples/peripherals-taken.rs
diff --git a/rtic/examples/pool.rs_old b/examples/lm3s6965/examples/pool.rs_old
index b399202..b399202 100644
--- a/rtic/examples/pool.rs_old
+++ b/examples/lm3s6965/examples/pool.rs_old
diff --git a/rtic/examples/preempt.rs b/examples/lm3s6965/examples/preempt.rs
index 62c67dc..62c67dc 100644
--- a/rtic/examples/preempt.rs
+++ b/examples/lm3s6965/examples/preempt.rs
diff --git a/rtic/examples/prio-inversion.rs b/examples/lm3s6965/examples/prio-inversion.rs
index 36dcbe2..36dcbe2 100644
--- a/rtic/examples/prio-inversion.rs
+++ b/examples/lm3s6965/examples/prio-inversion.rs
diff --git a/rtic/examples/ramfunc.rs b/examples/lm3s6965/examples/ramfunc.rs
index d072ecb..d072ecb 100644
--- a/rtic/examples/ramfunc.rs
+++ b/examples/lm3s6965/examples/ramfunc.rs
diff --git a/rtic/examples/resource-user-struct.rs b/examples/lm3s6965/examples/resource-user-struct.rs
index cad42d7..cad42d7 100644
--- a/rtic/examples/resource-user-struct.rs
+++ b/examples/lm3s6965/examples/resource-user-struct.rs
diff --git a/rtic/examples/shared.rs b/examples/lm3s6965/examples/shared.rs
index 79ebab8..79ebab8 100644
--- a/rtic/examples/shared.rs
+++ b/examples/lm3s6965/examples/shared.rs
diff --git a/rtic/examples/smallest.rs b/examples/lm3s6965/examples/smallest.rs
index fee3f05..fee3f05 100644
--- a/rtic/examples/smallest.rs
+++ b/examples/lm3s6965/examples/smallest.rs
diff --git a/rtic/examples/spawn.rs b/examples/lm3s6965/examples/spawn.rs
index 448bcda..448bcda 100644
--- a/rtic/examples/spawn.rs
+++ b/examples/lm3s6965/examples/spawn.rs
diff --git a/rtic/examples/spawn_arguments.rs b/examples/lm3s6965/examples/spawn_arguments.rs
index 61c4608..61c4608 100644
--- a/rtic/examples/spawn_arguments.rs
+++ b/examples/lm3s6965/examples/spawn_arguments.rs
diff --git a/rtic/examples/spawn_err.rs b/examples/lm3s6965/examples/spawn_err.rs
index e5a9420..e5a9420 100644
--- a/rtic/examples/spawn_err.rs
+++ b/examples/lm3s6965/examples/spawn_err.rs
diff --git a/rtic/examples/spawn_loop.rs b/examples/lm3s6965/examples/spawn_loop.rs
index 13e386a..13e386a 100644
--- a/rtic/examples/spawn_loop.rs
+++ b/examples/lm3s6965/examples/spawn_loop.rs
diff --git a/rtic/examples/static.rs b/examples/lm3s6965/examples/static.rs
index fec73fc..fec73fc 100644
--- a/rtic/examples/static.rs
+++ b/examples/lm3s6965/examples/static.rs
diff --git a/rtic/examples/t-binds.rs b/examples/lm3s6965/examples/t-binds.rs
index 01c262c..01c262c 100644
--- a/rtic/examples/t-binds.rs
+++ b/examples/lm3s6965/examples/t-binds.rs
diff --git a/rtic/examples/t-cfg-resources.rs b/examples/lm3s6965/examples/t-cfg-resources.rs
index 2ddfae7..2ddfae7 100644
--- a/rtic/examples/t-cfg-resources.rs
+++ b/examples/lm3s6965/examples/t-cfg-resources.rs
diff --git a/rtic/examples/t-htask-main.rs b/examples/lm3s6965/examples/t-htask-main.rs
index 61280f8..61280f8 100644
--- a/rtic/examples/t-htask-main.rs
+++ b/examples/lm3s6965/examples/t-htask-main.rs
diff --git a/rtic/examples/t-idle-main.rs b/examples/lm3s6965/examples/t-idle-main.rs
index 88566a9..88566a9 100644
--- a/rtic/examples/t-idle-main.rs
+++ b/examples/lm3s6965/examples/t-idle-main.rs
diff --git a/rtic/examples/t-late-not-send.rs b/examples/lm3s6965/examples/t-late-not-send.rs
index be5cc66..be5cc66 100644
--- a/rtic/examples/t-late-not-send.rs
+++ b/examples/lm3s6965/examples/t-late-not-send.rs
diff --git a/rtic/examples/task.rs b/examples/lm3s6965/examples/task.rs
index b6b6bbd..b6b6bbd 100644
--- a/rtic/examples/task.rs
+++ b/examples/lm3s6965/examples/task.rs
diff --git a/rtic/examples/zero-prio-task.rs b/examples/lm3s6965/examples/zero-prio-task.rs
index 8cfd705..8cfd705 100644
--- a/rtic/examples/zero-prio-task.rs
+++ b/examples/lm3s6965/examples/zero-prio-task.rs
diff --git a/rtic-macros/CHANGELOG.md b/rtic-macros/CHANGELOG.md
index 66bd9bc..a0d761b 100644
--- a/rtic-macros/CHANGELOG.md
+++ b/rtic-macros/CHANGELOG.md
@@ -11,6 +11,7 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
### Added
+- Unstable support for RISC-V targets compatible with `riscv-slic`
- RTIC v2 now works on stable.
- Unstable ESP32-C3 support.
diff --git a/rtic-macros/Cargo.toml b/rtic-macros/Cargo.toml
index 423fe31..443ed0d 100644
--- a/rtic-macros/Cargo.toml
+++ b/rtic-macros/Cargo.toml
@@ -36,8 +36,8 @@ cortex-m-basepri = []
riscv-esp32c3 = []
# riscv-clic = []
# riscv-ch32 = []
-
-
+riscv-slic = []
+
# backend API test
test-template = []
diff --git a/rtic-macros/src/codegen.rs b/rtic-macros/src/codegen.rs
index c04f213..060db6d 100644
--- a/rtic-macros/src/codegen.rs
+++ b/rtic-macros/src/codegen.rs
@@ -8,6 +8,7 @@ pub mod bindings;
mod assertions;
mod async_dispatchers;
+mod extra_mods;
mod hardware_tasks;
mod idle;
mod init;
diff --git a/rtic-macros/src/codegen/async_dispatchers.rs b/rtic-macros/src/codegen/async_dispatchers.rs
index 9144b2a..3d166ca 100644
--- a/rtic-macros/src/codegen/async_dispatchers.rs
+++ b/rtic-macros/src/codegen/async_dispatchers.rs
@@ -2,7 +2,7 @@ use crate::syntax::ast::App;
use crate::{
analyze::Analysis,
codegen::{
- bindings::{async_entry, handler_config, interrupt_entry, interrupt_exit},
+ bindings::{async_entry, handler_config, interrupt_entry, interrupt_exit, interrupt_mod},
util,
},
};
@@ -36,10 +36,9 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
};
let pend_interrupt = if level > 0 {
- let device = &app.args.device;
- let enum_ = util::interrupt_ident();
+ let int_mod = interrupt_mod(app);
- quote!(rtic::export::pend(#device::#enum_::#dispatcher_name);)
+ quote!(rtic::export::pend(#int_mod::#dispatcher_name);)
} else {
// For 0 priority tasks we don't need to pend anything
quote!()
diff --git a/rtic-macros/src/codegen/bindings.rs b/rtic-macros/src/codegen/bindings.rs
index 60605f3..501ccdf 100644
--- a/rtic-macros/src/codegen/bindings.rs
+++ b/rtic-macros/src/codegen/bindings.rs
@@ -2,7 +2,8 @@
feature = "cortex-m-source-masking",
feature = "cortex-m-basepri",
feature = "test-template",
- feature = "riscv-esp32c3"
+ feature = "riscv-esp32c3",
+ feature = "riscv-slic",
)))]
compile_error!("No backend selected");
@@ -22,4 +23,10 @@ mod template;
pub use esp32c3::*;
#[cfg(feature = "riscv-esp32c3")]
-mod esp32c3; \ No newline at end of file
+mod esp32c3;
+
+#[cfg(feature = "riscv-slic")]
+pub use riscv_slic::*;
+
+#[cfg(feature = "riscv-slic")]
+mod riscv_slic;
diff --git a/rtic-macros/src/codegen/bindings/cortex.rs b/rtic-macros/src/codegen/bindings/cortex.rs
index 69b5ee5..5c56261 100644
--- a/rtic-macros/src/codegen/bindings/cortex.rs
+++ b/rtic-macros/src/codegen/bindings/cortex.rs
@@ -35,6 +35,12 @@ pub fn interrupt_ident() -> Ident {
Ident::new("interrupt", span)
}
+pub fn interrupt_mod(app: &App) -> TokenStream2 {
+ let device = &app.args.device;
+ let interrupt = interrupt_ident();
+ quote!(#device::#interrupt)
+}
+
pub fn check_stack_overflow_before_init(
_app: &App,
_analysis: &CodegenAnalysis,
@@ -199,12 +205,16 @@ mod basepri {
}
}
+pub fn pre_init_preprocessing(_app: &mut App, _analysis: &SyntaxAnalysis) -> parse::Result<()> {
+ Ok(())
+}
+
pub fn pre_init_checks(app: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> {
let mut stmts = vec![];
// check that all dispatchers exists in the `Interrupt` enumeration regardless of whether
// they are used or not
- let interrupt = util::interrupt_ident();
+ let interrupt = interrupt_ident();
let rt_err = util::rt_err_ident();
for name in app.args.dispatchers.keys() {
@@ -217,7 +227,7 @@ pub fn pre_init_checks(app: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> {
pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
let mut stmts = vec![];
- let interrupt = util::interrupt_ident();
+ let interrupt = interrupt_ident();
let rt_err = util::rt_err_ident();
let device = &app.args.device;
let nvic_prio_bits = quote!(#device::NVIC_PRIO_BITS);
@@ -381,3 +391,7 @@ pub fn handler_config(
) -> Vec<TokenStream2> {
vec![]
}
+
+pub fn extra_modules(_app: &App, _analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+ vec![]
+}
diff --git a/rtic-macros/src/codegen/bindings/esp32c3.rs b/rtic-macros/src/codegen/bindings/esp32c3.rs
index 4b14cae..f8ea22a 100644
--- a/rtic-macros/src/codegen/bindings/esp32c3.rs
+++ b/rtic-macros/src/codegen/bindings/esp32c3.rs
@@ -55,10 +55,20 @@ mod esp32c3 {
Ident::new("Interrupt", span)
}
+ pub fn interrupt_mod(app: &App) -> TokenStream2 {
+ let device = &app.args.device;
+ let interrupt = interrupt_ident();
+ quote!(#device::#interrupt)
+ }
+
pub fn extra_assertions(_: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> {
vec![]
}
+ pub fn pre_init_preprocessing(_app: &mut App, _analysis: &SyntaxAnalysis) -> parse::Result<()> {
+ Ok(())
+ }
+
pub fn pre_init_checks(app: &App, _: &SyntaxAnalysis) -> Vec<TokenStream2> {
let mut stmts = vec![];
// check that all dispatchers exists in the `Interrupt` enumeration regardless of whether
@@ -232,3 +242,7 @@ mod esp32c3 {
stmts
}
}
+
+pub fn extra_modules(_app: &App, _analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+ vec![]
+}
diff --git a/rtic-macros/src/codegen/bindings/riscv_slic.rs b/rtic-macros/src/codegen/bindings/riscv_slic.rs
new file mode 100644
index 0000000..c9bf50a
--- /dev/null
+++ b/rtic-macros/src/codegen/bindings/riscv_slic.rs
@@ -0,0 +1,255 @@
+use crate::{
+ analyze::Analysis as CodegenAnalysis,
+ syntax::{
+ analyze::Analysis as SyntaxAnalysis,
+ ast::{App, Dispatcher},
+ },
+};
+use proc_macro2::{Span, TokenStream as TokenStream2};
+use quote::quote;
+use std::{collections::HashSet, vec};
+use syn::{parse, Attribute, Ident};
+
+/// Utility function to get the SLIC interrupt module.
+pub fn interrupt_ident() -> Ident {
+ let span = Span::call_site();
+ Ident::new("Interrupt", span)
+}
+
+pub fn interrupt_mod(_app: &App) -> TokenStream2 {
+ let interrupt = interrupt_ident();
+ quote!(slic::#interrupt)
+}
+
+/// This macro implements the [`rtic::Mutex`] trait for shared resources using the SLIC.
+#[allow(clippy::too_many_arguments)]
+pub fn impl_mutex(
+ _app: &App,
+ _analysis: &CodegenAnalysis,
+ cfgs: &[Attribute],
+ resources_prefix: bool,
+ name: &Ident,
+ ty: &TokenStream2,
+ ceiling: u8,
+ ptr: &TokenStream2,
+) -> TokenStream2 {
+ let path = if resources_prefix {
+ quote!(shared_resources::#name)
+ } else {
+ quote!(#name)
+ };
+
+ quote!(
+ #(#cfgs)*
+ impl<'a> rtic::Mutex for #path<'a> {
+ type T = #ty;
+
+ #[inline(always)]
+ fn lock<RTIC_INTERNAL_R>(&mut self, f: impl FnOnce(&mut #ty) -> RTIC_INTERNAL_R) -> RTIC_INTERNAL_R {
+
+ const CEILING: u8 = #ceiling;
+
+ unsafe {
+ rtic::export::lock(#ptr, CEILING, f)
+ }
+ }
+ }
+ )
+}
+
+/// This macro is used to define additional compile-time assertions in case the platform needs it.
+/// The Cortex-M implementations do not use it. Thus, we think we do not need it either.
+pub fn extra_assertions(_app: &App, _analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+ vec![]
+}
+
+pub fn pre_init_preprocessing(app: &mut App, _analysis: &SyntaxAnalysis) -> parse::Result<()> {
+ app.args.core = false; // RISC-V SLIC is not compatible with using core peripherals
+ if !app.args.dispatchers.is_empty() {
+ return Err(parse::Error::new(
+ Span::call_site(),
+ "this backend does not support explicit interrupt dispatchers; remove the `dispatchers` argument from `#[app]`",
+ ));
+ }
+
+ // Compute the number of handlers we need to dispatch the software tasks
+ let soft_priorities = app
+ .software_tasks
+ .iter()
+ .map(|(_, task)| task.args.priority)
+ .filter(|prio| *prio > 0)
+ .collect::<HashSet<_>>();
+
+ for i in 0..soft_priorities.len() {
+ let dispatcher_ident = Ident::new(&format!("__RTICDispatcher{}", i), Span::call_site());
+ app.args
+ .dispatchers
+ .insert(dispatcher_ident, Dispatcher { attrs: vec![] });
+ }
+
+ Ok(())
+}
+
+/// This macro is used to check at run-time that all the interruption dispatchers exist.
+pub fn pre_init_checks(app: &App, _analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+ let mut stmts: Vec<TokenStream2> = vec![];
+ let int_mod = interrupt_mod(app);
+
+ // check that all dispatchers exists in the `slic::Interrupt` enumeration
+ for name in app.args.dispatchers.keys() {
+ stmts.push(quote!(let _ = #int_mod::#name;));
+ }
+
+ stmts
+}
+
+/// This macro must perform all the required operations to activate the
+/// interrupt sources with their corresponding priority level.
+pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+ let mut stmts = vec![];
+
+ // First, we reset and disable all the interrupt controllers
+ stmts.push(quote!(rtic::export::clear_interrupts();));
+
+ // Then, we set the corresponding priorities
+ let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
+ for (&p, name) in interrupt_ids.chain(
+ app.hardware_tasks
+ .values()
+ .map(|task| (&task.args.priority, &task.args.binds)),
+ ) {
+ stmts.push(quote!(
+ rtic::export::set_priority(slic::Interrupt::#name, #p);
+ ));
+ }
+ // Finally, we activate the interrupts
+ stmts.push(quote!(rtic::export::set_interrupts();));
+ stmts
+}
+
+/// Any additional checks that depend on the system architecture.
+pub fn architecture_specific_analysis(app: &App, _analysis: &SyntaxAnalysis) -> parse::Result<()> {
+ // Check that there are enough external interrupts to dispatch the software tasks and the timer queue handler
+ let mut first = None;
+ let priorities = app
+ .software_tasks
+ .iter()
+ .map(|(name, task)| {
+ first = Some(name);
+ task.args.priority
+ })
+ .filter(|prio| *prio > 0)
+ .collect::<HashSet<_>>();
+
+ let need = priorities.len();
+ let given = app.args.dispatchers.len();
+ if need > given {
+ let s = {
+ format!(
+ "not enough interrupts to dispatch \
+ all software tasks (need: {need}; given: {given})"
+ )
+ };
+
+ return Err(parse::Error::new(first.unwrap().span(), s));
+ }
+
+ if app.args.backend.is_none() {
+ return Err(parse::Error::new(
+ Span::call_site(),
+ "SLIC requires backend-specific configuration",
+ ));
+ }
+
+ Ok(())
+}
+
+/// Macro to add statements to be executed at the beginning of all the interrupt handlers.
+pub fn interrupt_entry(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+ vec![]
+}
+
+/// Macro to add statements to be executed at the end of all the interrupt handlers.
+pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+ vec![]
+}
+
+pub fn check_stack_overflow_before_init(
+ _app: &App,
+ _analysis: &CodegenAnalysis,
+) -> Vec<TokenStream2> {
+ vec![quote!(
+ // Check for stack overflow using symbols from `risc-v-rt`.
+ extern "C" {
+ pub static _stack_start: u32;
+ pub static _ebss: u32;
+ }
+
+ let stack_start = &_stack_start as *const _ as u32;
+ let ebss = &_ebss as *const _ as u32;
+
+ if stack_start > ebss {
+ // No flip-link usage, check the SP for overflow.
+ if rtic::export::read_sp() <= ebss {
+ panic!("Stack overflow after allocating executors");
+ }
+ }
+ )]
+}
+
+pub fn async_entry(
+ _app: &App,
+ _analysis: &CodegenAnalysis,
+ _dispatcher_name: Ident,
+) -> Vec<TokenStream2> {
+ vec![]
+}
+
+/// Macro to define a maximum priority level for async tasks.
+pub fn async_prio_limit(_app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+ let max = if let Some(max) = analysis.max_async_prio {
+ quote!(#max)
+ } else {
+ quote!(u8::MAX) // No limit
+ };
+
+ vec![quote!(
+ /// Holds the maximum priority level for use by async HAL drivers.
+ #[no_mangle]
+ static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = #max;
+ )]
+}
+
+pub fn handler_config(
+ _app: &App,
+ _analysis: &CodegenAnalysis,
+ _dispatcher_name: Ident,
+) -> Vec<TokenStream2> {
+ vec![]
+}
+
+/// The SLIC requires us to call to the [`riscv_rtic::codegen`] macro to generate
+/// the appropriate SLIC structure, interrupt enumerations, etc.
+pub fn extra_modules(app: &App, _analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+ let mut stmts = vec![];
+
+ let hw_slice: Vec<_> = app
+ .hardware_tasks
+ .values()
+ .map(|task| &task.args.binds)
+ .collect();
+ let sw_slice: Vec<_> = app.args.dispatchers.keys().collect();
+
+ let swi_slice: Vec<_> = hw_slice.iter().chain(sw_slice.iter()).collect();
+
+ let device = &app.args.device;
+
+ stmts.push(quote!(
+ use rtic::export::riscv_slic;
+ ));
+ let hart_id = &app.args.backend.as_ref().unwrap().hart_id;
+
+ stmts.push(quote!(rtic::export::codegen!(pac = #device, swi = [#(#swi_slice,)*], backend = [hart_id = #hart_id]);));
+
+ stmts
+}
diff --git a/rtic-macros/src/codegen/bindings/template.rs b/rtic-macros/src/codegen/bindings/template.rs
index b5488b7..ecb46d5 100644
--- a/rtic-macros/src/codegen/bindings/template.rs
+++ b/rtic-macros/src/codegen/bindings/template.rs
@@ -6,40 +6,55 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{parse, Attribute, Ident};
+pub fn interrupt_ident() -> Ident {
+ let span = Span::call_site();
+ Ident::new("interrupt", span)
+}
+
+pub fn interrupt_mod(app: &App) -> TokenStream2 {
+ let device = &app.args.device;
+ let interrupt = interrupt_ident();
+ quote!(#device::#interrupt)
+}
+
pub fn impl_mutex(
- _app: &App,
- _analysis: &CodegenAnalysis,
- _cfgs: &[Attribute],
- _resources_prefix: bool,
- _name: &Ident,
- _ty: &TokenStream2,
- _ceiling: u8,
- _ptr: &TokenStream2,
+ app: &App,
+ analysis: &CodegenAnalysis,
+ cfgs: &[Attribute],
+ resources_prefix: bool,
+ name: &Ident,
+ ty: &TokenStream2,
+ ceiling: u8,
+ ptr: &TokenStream2,
) -> TokenStream2 {
quote!()
}
-pub fn extra_assertions(_app: &App, _analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+pub fn extra_assertions(app: &App, analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
vec![]
}
-pub fn pre_init_checks(_app: &App, _analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+pub fn pre_init_preprocessing(app: &mut App, analysis: &SyntaxAnalysis) -> parse::Result<()> {
+ Ok(())
+}
+
+pub fn pre_init_checks(app: &App, analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
vec![]
}
-pub fn pre_init_enable_interrupts(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![]
}
-pub fn architecture_specific_analysis(_app: &App, _analysis: &SyntaxAnalysis) -> parse::Result<()> {
+pub fn architecture_specific_analysis(app: &App, analysis: &SyntaxAnalysis) -> parse::Result<()> {
Ok(())
}
-pub fn interrupt_entry(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+pub fn interrupt_entry(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![]
}
-pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+pub fn interrupt_exit(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![]
}
@@ -51,20 +66,25 @@ pub fn check_stack_overflow_before_init(
}
pub fn async_entry(
- _app: &App,
- _analysis: &CodegenAnalysis,
- _dispatcher_name: Ident,
+ app: &App,
+ analysis: &CodegenAnalysis,
+ dispatcher_name: Ident,
) -> Vec<TokenStream2> {
vec![]
}
-pub fn async_prio_limit(app: &App, _analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
+pub fn async_prio_limit(app: &App, analysis: &CodegenAnalysis) -> Vec<TokenStream2> {
vec![]
}
+
pub fn handler_config(
- _app: &App,
- _analysis: &CodegenAnalysis,
+ app: &App,
+ analysis: &CodegenAnalysis,
dispatcher_name: Ident,
) -> Vec<TokenStream2> {
vec![]
}
+
+pub fn extra_modules(app: &App, analysis: &SyntaxAnalysis) -> Vec<TokenStream2> {
+ vec![]
+}
diff --git a/rtic-macros/src/codegen/extra_mods.rs b/rtic-macros/src/codegen/extra_mods.rs
new file mode 100644
index 0000000..b92dda6
--- /dev/null
+++ b/rtic-macros/src/codegen/extra_mods.rs
@@ -0,0 +1,9 @@
+use super::bindings::extra_modules;
+use crate::analyze::Analysis;
+use crate::syntax::ast::App;
+use proc_macro2::TokenStream as TokenStream2;
+
+/// Generates code that runs before `#[init]`
+pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
+ extra_modules(app, analysis)
+}
diff --git a/rtic-macros/src/codegen/main.rs b/rtic-macros/src/codegen/main.rs
index 5612796..80f2cf6 100644
--- a/rtic-macros/src/codegen/main.rs
+++ b/rtic-macros/src/codegen/main.rs
@@ -1,4 +1,3 @@
-use super::{assertions, post_init, pre_init};
use crate::{
analyze::Analysis,
codegen::{bindings, util},
@@ -7,8 +6,12 @@ use crate::{
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
+use super::{assertions, extra_mods, post_init, pre_init};
+
/// Generates code for `fn main`
pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
+ let extra_mods_stmts = extra_mods::codegen(app, analysis);
+
let assertion_stmts = assertions::codegen(app, analysis);
let pre_init_stmts = pre_init::codegen(app, analysis);
@@ -40,9 +43,18 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
let main = util::suffixed("main");
let init_name = &app.init.name;
+
+ let init_args = if app.args.core {
+ quote!(core.into(), executors_size)
+ } else {
+ quote!(executors_size)
+ };
+
let msp_check = bindings::check_stack_overflow_before_init(app, analysis);
quote!(
+ #(#extra_mods_stmts)*
+
#[doc(hidden)]
#[no_mangle]
unsafe extern "C" fn #main() -> ! {
@@ -63,7 +75,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
// Wrap late_init_stmts in a function to ensure that stack space is reclaimed.
__rtic_init_resources(||{
- let (shared_resources, local_resources) = #init_name(#init_name::Context::new(core.into(), executors_size));
+ let (shared_resources, local_resources) = #init_name(#init_name::Context::new(#init_args));
#(#post_init_stmts)*
});
diff --git a/rtic-macros/src/codegen/module.rs b/rtic-macros/src/codegen/module.rs
index c8afe07..17c8ce7 100644
--- a/rtic-macros/src/codegen/module.rs
+++ b/rtic-macros/src/codegen/module.rs
@@ -1,5 +1,5 @@
use crate::syntax::{ast::App, Context};
-use crate::{analyze::Analysis, codegen::util};
+use crate::{analyze::Analysis, codegen::bindings::interrupt_mod, codegen::util};
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
@@ -17,15 +17,19 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
match ctxt {
Context::Init => {
fields.push(quote!(
- /// Core peripherals
- pub core: rtic::export::Peripherals
- ));
-
- fields.push(quote!(
/// The space used to allocate async executors in bytes.
pub executors_size: usize
));
+ if app.args.core {
+ fields.push(quote!(
+ /// Core peripherals
+ pub core: rtic::export::Peripherals
+ ));
+
+ values.push(quote!(core: core));
+ }
+
if app.args.peripherals {
let device = &app.args.device;
@@ -43,8 +47,6 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
));
values.push(quote!(cs: rtic::export::CriticalSection::new()));
-
- values.push(quote!(core));
values.push(quote!(executors_size));
}
@@ -98,7 +100,11 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
};
let core = if ctxt.is_init() {
- Some(quote!(core: rtic::export::Peripherals, executors_size: usize))
+ if app.args.core {
+ Some(quote!(core: rtic::export::Peripherals, executors_size: usize))
+ } else {
+ Some(quote!(executors_size: usize))
+ }
} else {
None
};
@@ -144,10 +150,9 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
task_cfgs = cfgs.clone();
let pend_interrupt = if priority > 0 {
- let device = &app.args.device;
- let enum_ = util::interrupt_ident();
+ let int_mod = interrupt_mod(app);
let interrupt = &analysis.interrupts.get(&priority).expect("UREACHABLE").0;
- quote!(rtic::export::pend(#device::#enum_::#interrupt);)
+ quote!(rtic::export::pend(#int_mod::#interrupt);)
} else {
quote!()
};
diff --git a/rtic-macros/src/codegen/pre_init.rs b/rtic-macros/src/codegen/pre_init.rs
index a2d0e8c..8de75ff 100644
--- a/rtic-macros/src/codegen/pre_init.rs
+++ b/rtic-macros/src/codegen/pre_init.rs
@@ -11,10 +11,12 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
// Disable interrupts -- `init` must run with interrupts disabled
stmts.push(quote!(rtic::export::interrupt::disable();));
- stmts.push(quote!(
- // To set the variable in cortex_m so the peripherals cannot be taken multiple times
- let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal().into();
- ));
+ if app.args.core {
+ stmts.push(quote!(
+ // To set the variable in cortex_m so the peripherals cannot be taken multiple times
+ let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal().into();
+ ));
+ }
stmts.append(&mut pre_init_checks(app, analysis));
diff --git a/rtic-macros/src/codegen/util.rs b/rtic-macros/src/codegen/util.rs
index b4682ee..dda7e29 100644
--- a/rtic-macros/src/codegen/util.rs
+++ b/rtic-macros/src/codegen/util.rs
@@ -3,8 +3,6 @@ use core::sync::atomic::{AtomicUsize, Ordering};
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::quote;
use syn::{Ident, PatType};
-//hook the target specific interrupt_ident function
-pub use super::bindings::interrupt_ident;
const RTIC_INTERNAL: &str = "__rtic_internal";
diff --git a/rtic-macros/src/lib.rs b/rtic-macros/src/lib.rs
index 38eed8f..c464ab0 100644
--- a/rtic-macros/src/lib.rs
+++ b/rtic-macros/src/lib.rs
@@ -14,13 +14,14 @@ macro_rules! with_backend {
feature = "cortex-m-source-masking",
feature = "cortex-m-basepri",
feature = "test-template",
- feature = "riscv-esp32c3"
+ feature = "riscv-esp32c3",
+ feature = "riscv-slic",
))]
$($tokens)*
};
}
-with_backend! { mod: [analyze, check, codegen, syntax] }
+with_backend! { mod: [analyze, check, codegen, preprocess, syntax] }
with_backend! { use std::{fs, env, path::Path}; }
with_backend! { use proc_macro::TokenStream; }
@@ -47,11 +48,18 @@ with_backend! {
/// Should never panic, cargo feeds a path which is later converted to a string
#[proc_macro_attribute]
pub fn app(_args: TokenStream, _input: TokenStream) -> TokenStream {
- let (app, analysis) = match syntax::parse(_args, _input) {
+ let (mut app, analysis) = match syntax::parse(_args, _input) {
Err(e) => return e.to_compile_error().into(),
Ok(x) => x,
};
+ // Modify app based on backend before continuing
+ if let Err(e) = preprocess::app(&mut app, &analysis) {
+ return e.to_compile_error().into();
+ }
+ let app = app;
+ // App is not mutable after this point
+
if let Err(e) = check::app(&app, &analysis) {
return e.to_compile_error().into();
}
@@ -109,6 +117,7 @@ with_backend! {
feature = "cortex-m-source-masking",
feature = "cortex-m-basepri",
feature = "test-template",
- feature = "riscv-esp32c3"
+ feature = "riscv-esp32c3",
+ feature = "riscv-slic",
)))]
compile_error!("Cannot compile. No backend feature selected.");
diff --git a/rtic-macros/src/preprocess.rs b/rtic-macros/src/preprocess.rs
new file mode 100644
index 0000000..2fcd10b
--- /dev/null
+++ b/rtic-macros/src/preprocess.rs
@@ -0,0 +1,7 @@
+use crate::codegen::bindings::pre_init_preprocessing;
+use crate::syntax::{analyze::Analysis, ast::App};
+use syn::parse;
+
+pub fn app(app: &mut App, analysis: &Analysis) -> parse::Result<()> {
+ pre_init_preprocessing(app, analysis)
+}
diff --git a/rtic-macros/src/syntax.rs b/rtic-macros/src/syntax.rs
index d6f5a47..a44b1ec 100644
--- a/rtic-macros/src/syntax.rs
+++ b/rtic-macros/src/syntax.rs
@@ -12,6 +12,7 @@ use crate::syntax::ast::App;
mod accessors;
pub mod analyze;
pub mod ast;
+mod backend;
mod check;
mod parse;
diff --git a/rtic-macros/src/syntax/ast.rs b/rtic-macros/src/syntax/ast.rs
index f0067b8..06feb1f 100644
--- a/rtic-macros/src/syntax/ast.rs
+++ b/rtic-macros/src/syntax/ast.rs
@@ -2,7 +2,7 @@
use syn::{Attribute, Expr, Ident, Item, ItemUse, Pat, PatType, Path, Stmt, Type};
-use crate::syntax::Map;
+use crate::syntax::{backend::BackendArgs, Map};
/// The `#[app]` attribute
#[derive(Debug)]
@@ -60,11 +60,17 @@ pub struct AppArgs {
/// Device
pub device: Path,
- /// Peripherals
+ /// Core peripherals
+ pub core: bool,
+
+ /// Device peripherals
pub peripherals: bool,
/// Interrupts used to dispatch software tasks
pub dispatchers: Dispatchers,
+
+ /// Backend-specific arguments
+ pub backend: Option<BackendArgs>,
}
/// The `init`-ialization function
diff --git a/rtic-macros/src/syntax/backend.rs b/rtic-macros/src/syntax/backend.rs
new file mode 100644
index 0000000..460ef56
--- /dev/null
+++ b/rtic-macros/src/syntax/backend.rs
@@ -0,0 +1,32 @@
+#[cfg(not(any(
+ feature = "cortex-m-source-masking",
+ feature = "cortex-m-basepri",
+ feature = "test-template",
+ feature = "riscv-esp32c3",
+ feature = "riscv-slic",
+)))]
+compile_error!("No backend selected");
+
+#[cfg(any(feature = "cortex-m-source-masking", feature = "cortex-m-basepri"))]
+pub use cortex::*;
+
+#[cfg(feature = "test-template")]
+pub use template::*;
+
+#[cfg(feature = "riscv-esp32c3")]
+pub use esp32c3::*;
+
+#[cfg(feature = "riscv-slic")]
+pub use riscv_slic::*;
+
+#[cfg(any(feature = "cortex-m-source-masking", feature = "cortex-m-basepri"))]
+mod cortex;
+
+#[cfg(feature = "test-template")]
+mod template;
+
+#[cfg(feature = "riscv-esp32c3")]
+mod esp32c3;
+
+#[cfg(feature = "riscv-slic")]
+mod riscv_slic;
diff --git a/rtic-macros/src/syntax/backend/cortex.rs b/rtic-macros/src/syntax/backend/cortex.rs
new file mode 100644
index 0000000..b53e927
--- /dev/null
+++ b/rtic-macros/src/syntax/backend/cortex.rs
@@ -0,0 +1,16 @@
+use syn::{
+ parse::{Parse, ParseStream},
+ Error, Result,
+};
+
+#[derive(Debug)]
+pub struct BackendArgs();
+
+impl Parse for BackendArgs {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Err(Error::new(
+ input.span(),
+ "cortex backend does not accept any arguments",
+ ))
+ }
+}
diff --git a/rtic-macros/src/syntax/backend/esp32c3.rs b/rtic-macros/src/syntax/backend/esp32c3.rs
new file mode 100644
index 0000000..33143f4
--- /dev/null
+++ b/rtic-macros/src/syntax/backend/esp32c3.rs
@@ -0,0 +1,16 @@
+use syn::{
+ parse::{Parse, ParseStream},
+ Error, Result,
+};
+
+#[derive(Debug)]
+pub struct BackendArgs();
+
+impl Parse for BackendArgs {
+ fn parse(input: ParseStream) -> Result<Self> {
+ Err(Error::new(
+ input.span(),
+ "esp32c3 backend does not accept any arguments",
+ ))
+ }
+}
diff --git a/rtic-macros/src/syntax/backend/riscv_slic.rs b/rtic-macros/src/syntax/backend/riscv_slic.rs
new file mode 100644
index 0000000..2ed8e77
--- /dev/null
+++ b/rtic-macros/src/syntax/backend/riscv_slic.rs
@@ -0,0 +1,16 @@
+use syn::{
+ parse::{Parse, ParseStream},
+ Ident, Result,
+};
+
+#[derive(Debug)]
+pub struct BackendArgs {
+ pub hart_id: Ident,
+}
+
+impl Parse for BackendArgs {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let hart_id = input.parse()?;
+ Ok(BackendArgs { hart_id })
+ }
+}
diff --git a/rtic-macros/src/syntax/backend/template.rs b/rtic-macros/src/syntax/backend/template.rs
new file mode 100644
index 0000000..6dad114
--- /dev/null
+++ b/rtic-macros/src/syntax/backend/template.rs
@@ -0,0 +1,15 @@
+use syn::{
+ parse::{Parse, ParseStream},
+ Result,
+};
+
+#[derive(Debug)]
+pub struct BackendArgs {
+ // Define your backend-specific input here
+}
+
+impl Parse for BackendArgs {
+ fn parse(input: ParseStream) -> Result<Self> {
+ todo!("define how to parse your backend-specific arguments")
+ }
+}
diff --git a/rtic-macros/src/syntax/parse/app.rs b/rtic-macros/src/syntax/parse/app.rs
index efcafbe..469bcb8 100644
--- a/rtic-macros/src/syntax/parse/app.rs
+++ b/rtic-macros/src/syntax/parse/app.rs
@@ -13,6 +13,7 @@ use crate::syntax::{
App, AppArgs, Dispatcher, Dispatchers, HardwareTask, Idle, IdleArgs, Init, InitArgs,
LocalResource, SharedResource, SoftwareTask,
},
+ backend::BackendArgs,
parse::{self as syntax_parse, util},
Either, Map, Set,
};
@@ -24,8 +25,10 @@ impl AppArgs {
(|input: ParseStream<'_>| -> parse::Result<Self> {
let mut custom = Set::new();
let mut device = None;
+ let mut core = true;
let mut peripherals = true;
let mut dispatchers = Dispatchers::new();
+ let mut backend = None;
loop {
if input.is_empty() {
@@ -59,6 +62,17 @@ impl AppArgs {
}
}
+ "core" => {
+ if let Ok(p) = input.parse::<LitBool>() {
+ core = p.value;
+ } else {
+ return Err(parse::Error::new(
+ ident.span(),
+ "unexpected argument value; this should be a boolean",
+ ));
+ }
+ }
+
"peripherals" => {
if let Ok(p) = input.parse::<LitBool>() {
peripherals = p.value;
@@ -113,6 +127,18 @@ impl AppArgs {
));
}
}
+
+ "backend" => {
+ if let Ok(p) = input.parse::<BackendArgs>() {
+ backend = Some(p);
+ } else {
+ return Err(parse::Error::new(
+ ident.span(),
+ "unable to parse backend configuration",
+ ));
+ }
+ }
+
_ => {
return Err(parse::Error::new(ident.span(), "unexpected argument"));
}
@@ -134,8 +160,10 @@ impl AppArgs {
Ok(AppArgs {
device,
+ core,
peripherals,
dispatchers,
+ backend,
})
})
.parse2(tokens)
diff --git a/rtic-monotonics/CHANGELOG.md b/rtic-monotonics/CHANGELOG.md
index af39143..ef5840f 100644
--- a/rtic-monotonics/CHANGELOG.md
+++ b/rtic-monotonics/CHANGELOG.md
@@ -9,6 +9,7 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
### Changed
+- Tweak `build.rs` to avoid warnings in Nightly 1.78+
- Removed unused `rust-toolchain.toml`
## v1.5.0 - 2024-01-10
diff --git a/rtic/.cargo/config.toml b/rtic/.cargo/config.toml
index ddec650..1595860 100644
--- a/rtic/.cargo/config.toml
+++ b/rtic/.cargo/config.toml
@@ -4,7 +4,13 @@ runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semiho
[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"))']
+[target.riscv32imc-unknown-none-elf]
+runner = "qemu-system-riscv32 -machine sifive_e,revb=true -nographic -semihosting-config enable=on,target=native -kernel"
+
+[target.riscv32imac-unknown-none-elf]
+runner = "qemu-system-riscv32 -machine sifive_e,revb=true -nographic -semihosting-config enable=on,target=native -kernel"
+
+[target.'cfg(all(any(target_arch = "arm", target_arch = "riscv32"), target_os = "none"))']
rustflags = [
"-C", "link-arg=-Tlink.x",
]
diff --git a/rtic/CHANGELOG.md b/rtic/CHANGELOG.md
index 0f6e85d..c2cd678 100644
--- a/rtic/CHANGELOG.md
+++ b/rtic/CHANGELOG.md
@@ -17,6 +17,7 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
### Added
+- Unstable support for RISC-V targets compatible with `riscv-slic`
- Unstable support for ESP32-C3
### Fixed
diff --git a/rtic/Cargo.toml b/rtic/Cargo.toml
index 2fcda6d..f23c650 100644
--- a/rtic/Cargo.toml
+++ b/rtic/Cargo.toml
@@ -31,11 +31,12 @@ features = ["rtic-macros/test-template"]
name = "rtic"
[dependencies]
+riscv-slic = { git = "https://github.com/romancardenas/riscv-slic.git", rev = "2a91edb", optional = true }
esp32c3 = { version = "0.20.0", optional = true}
riscv = {version = "0.11.0", optional = true}
cortex-m = { version = "0.7.0", optional = true }
bare-metal = "1.0.0"
-#portable-atomic = { version = "0.3.19" }
+# portable-atomic = { version = "0.3.19" }
atomic-polyfill = "1"
rtic-monotonics = { path = "../rtic-monotonics", version = "1.4.0", optional = true }
rtic-macros = { path = "../rtic-macros", version = "=2.1.0" }
@@ -43,12 +44,8 @@ rtic-core = "1"
critical-section = "1"
[dev-dependencies]
-heapless = "0.8"
lm3s6965 = "0.2"
cortex-m-semihosting = "0.5.0"
-rtic-time = { path = "../rtic-time" }
-rtic-sync = { path = "../rtic-sync" }
-rtic-monotonics = { path = "../rtic-monotonics", features = ["cortex-m-systick"] }
[dev-dependencies.futures]
version = "0.3.26"
@@ -71,12 +68,7 @@ thumbv8main-backend = ["cortex-m", "rtic-macros/cortex-m-basepri"]
# riscv-clic-backend = ["rtic-macros/riscv-clic"]
# riscv-ch32-backend = ["rtic-macros/riscv-ch32"]
riscv-esp32c3-backend = ["esp32c3", "riscv", "rtic-macros/riscv-esp32c3"]
+riscv-clint-backend = ["riscv", "riscv-slic/clint-backend", "rtic-macros/riscv-slic"]
# needed for testing
-rtic-uitestv7 = ["thumbv7-backend"]
-rtic-uitestv6 = ["thumbv6-backend"]
test-critical-section = ["cortex-m/critical-section-single-core", "rtic-monotonics/systick-100hz"]
-
-# [[example]]
-# name = "pool"
-# required-features = ["test-critical-section"]
diff --git a/rtic/build.rs b/rtic/build.rs
index 6a02188..8c87b56 100644
--- a/rtic/build.rs
+++ b/rtic/build.rs
@@ -1,27 +1,38 @@
use std::env;
fn main() {
- let target = env::var("TARGET").unwrap();
-
- // These targets all have know support for the BASEPRI register.
- if target.starts_with("thumbv7m")
- | target.starts_with("thumbv7em")
- | target.starts_with("thumbv8m.main")
- {
- println!("cargo:rustc-cfg=feature=\"cortex-m-basepri\"");
- } else if target.starts_with("thumbv6m") | target.starts_with("thumbv8m.base") {
- println!("cargo:rustc-cfg=feature=\"cortex-m-source-masking\"");
- //this should not be this general
- //riscv processors differ in interrupt implementation
- //even within the same target
- //need some other way to discern
- } else if target.starts_with("riscv32i") {
- println!("cargo:rustc-cfg=feature=\"riscv-esp32c3\"");
+ // Get the backend feature selected by the user
+ let mut backends: Vec<_> = env::vars()
+ .filter_map(|(key, _value)| {
+ if key.starts_with("CARGO_FEATURE") && key.ends_with("BACKEND") {
+ // strip 'CARGO_FEATURE_', convert to lowercase, and replace '_' with '-'
+ Some(key[14..].to_lowercase().replace('_', "-"))
+ } else {
+ None
+ }
+ })
+ .collect();
+ if backends.len() > 1 {
+ panic!("More than one backend feature selected: {:?}", backends);
+ }
+ let backend = backends.pop().expect("No backend feature selected.");
- // TODO: Add feature here for risc-v targets
- // println!("cargo:rustc-cfg=feature=\"riscv\"");
- } else if target.starts_with("thumb") || target.starts_with("riscv32") {
- panic!("Unknown target '{target}'. Need to update logic in build.rs.");
+ match backend.as_str() {
+ "thumbv6-backend" | "thumbv8base-backend" => {
+ println!("cargo:rustc-cfg=feature=\"cortex-m-source-masking\"");
+ }
+ "thumbv7-backend" | "thumbv8main-backend" => {
+ println!("cargo:rustc-cfg=feature=\"cortex-m-basepri\"");
+ }
+ "riscv-esp32c3-backend" => {
+ println!("cargo:rustc-cfg=feature=\"riscv-esp32c3\"");
+ }
+ "riscv-clint-backend" => {
+ println!("cargo:rustc-cfg=feature=\"riscv-slic\"");
+ }
+ _ => {
+ panic!("Unknown backend feature: {:?}", backend);
+ }
}
println!("cargo:rerun-if-changed=build.rs");
diff --git a/rtic/src/export.rs b/rtic/src/export.rs
index 0fc995e..4fd8e78 100644
--- a/rtic/src/export.rs
+++ b/rtic/src/export.rs
@@ -12,41 +12,37 @@ pub use cortex_common::*;
mod cortex_common;
// Cortex-M target with basepri support
-#[cfg(any(feature = "cortex-m-basepri", feature = "rtic-uitestv7"))]
+#[cfg(feature = "cortex-m-basepri")]
mod cortex_basepri;
-#[cfg(any(feature = "cortex-m-basepri", feature = "rtic-uitestv7"))]
+#[cfg(feature = "cortex-m-basepri")]
pub use cortex_basepri::*;
// Cortex-M target with source mask support
-#[cfg(any(feature = "cortex-m-source-masking", feature = "rtic-uitestv6"))]
+#[cfg(feature = "cortex-m-source-masking")]
mod cortex_source_mask;
-#[cfg(any(feature = "cortex-m-source-masking", feature = "rtic-uitestv6"))]
+#[cfg(feature = "cortex-m-source-masking")]
pub use cortex_source_mask::*;
-// RISC-V target (any)
#[cfg(feature = "riscv")]
-pub use riscv_common::*;
+pub mod riscv_common;
#[cfg(feature = "riscv")]
-mod riscv_common;
+pub use riscv_common::*;
#[cfg(feature = "riscv-esp32c3")]
mod riscv_esp32c3;
#[cfg(feature = "riscv-esp32c3")]
pub use riscv_esp32c3::*;
+#[cfg(feature = "riscv-slic")]
+mod slic;
+#[cfg(feature = "riscv-slic")]
+pub use slic::*;
+
#[inline(always)]
-pub fn assert_send<T>()
-where
- T: Send,
-{
-}
+pub fn assert_send<T: Send>() {}
#[inline(always)]
-pub fn assert_sync<T>()
-where
- T: Sync,
-{
-}
+pub fn assert_sync<T: Sync>() {}
diff --git a/rtic/src/export/riscv_common.rs b/rtic/src/export/riscv_common.rs
index 6189335..d3028b4 100644
--- a/rtic/src/export/riscv_common.rs
+++ b/rtic/src/export/riscv_common.rs
@@ -1,10 +1,9 @@
/// GENERIC RE-EXPORTS: needed for all RTIC backends
-pub use riscv::interrupt;
/// Read the stack pointer.
#[inline(always)]
pub fn read_sp() -> u32 {
let r;
- unsafe { asm!("mv {}, sp", out(reg) r, options(nomem, nostack, preserves_flags)) };
+ unsafe { core::arch::asm!("mv {}, sp", out(reg) r, options(nomem, nostack, preserves_flags)) };
r
}
diff --git a/rtic/src/export/riscv_esp32c3.rs b/rtic/src/export/riscv_esp32c3.rs
index de09113..5780d40 100644
--- a/rtic/src/export/riscv_esp32c3.rs
+++ b/rtic/src/export/riscv_esp32c3.rs
@@ -1,5 +1,6 @@
use esp32c3::INTERRUPT_CORE0; //priority threshold control
pub use esp32c3::{Interrupt, Peripherals};
+pub use riscv::interrupt;
pub use riscv::register::mcause; //low level interrupt enable/disable
#[cfg(all(feature = "riscv-esp32c3", not(feature = "riscv-esp32c3-backend")))]
diff --git a/rtic/src/export/slic.rs b/rtic/src/export/slic.rs
new file mode 100644
index 0000000..f0c17a3
--- /dev/null
+++ b/rtic/src/export/slic.rs
@@ -0,0 +1,19 @@
+pub use riscv_slic::{lock, pend, run, InterruptNumber};
+
+#[cfg(all(feature = "riscv-slic", not(feature = "riscv-clint-backend")))]
+compile_error!("Building for the riscv-slic, but 'riscv-clint-backend' not selected");
+
+/// USE CASE RE-EXPORTS: needed for SLIC-only
+pub use riscv_slic::{self, clear_interrupts, codegen, set_interrupts, set_priority};
+
+pub mod interrupt {
+ pub fn disable() {
+ riscv_slic::disable();
+ riscv_slic::clear_interrupts();
+ }
+
+ pub unsafe fn enable() {
+ riscv_slic::set_interrupts();
+ riscv_slic::enable();
+ }
+}
diff --git a/rtic/src/lib.rs b/rtic/src/lib.rs
index bbdd5e2..2932c22 100644
--- a/rtic/src/lib.rs
+++ b/rtic/src/lib.rs
@@ -45,7 +45,6 @@ pub mod mutex {
#[doc(hidden)]
pub mod export;
-#[cfg(feature = "cortex-m")]
pub use export::pend;
use core::cell::UnsafeCell;
diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs
index 3893c61..a3a404f 100644
--- a/xtask/src/argument_parsing.rs
+++ b/xtask/src/argument_parsing.rs
@@ -1,4 +1,7 @@
-use crate::{cargo_command::CargoCommand, Target, ARMV6M, ARMV7M, ARMV8MBASE, ARMV8MMAIN};
+use crate::{
+ cargo_command::CargoCommand, Target, ARMV6M, ARMV7M, ARMV8MBASE, ARMV8MMAIN, RISCV32IMAC,
+ RISCV32IMC,
+};
use clap::{Args, Parser, Subcommand};
use core::fmt;
@@ -84,7 +87,7 @@ impl Package {
};
features
- .into_iter()
+ .iter()
.map(ToString::to_string)
.map(Some)
.chain(std::iter::once(None))
@@ -101,12 +104,7 @@ impl TestMetadata {
pub fn match_package(package: Package, backend: Backends) -> CargoCommand<'static> {
match package {
Package::Rtic => {
- let features = format!(
- "{},{}",
- backend.to_rtic_feature(),
- backend.to_rtic_uitest_feature()
- );
- let features = Some(backend.to_target().and_features(&features));
+ let features = Some(backend.to_target().and_features(backend.to_rtic_feature()));
CargoCommand::Test {
package: Some(package.name()),
features,
@@ -155,6 +153,9 @@ pub enum Backends {
Thumbv7,
Thumbv8Base,
Thumbv8Main,
+ RiscvEsp32C3,
+ Riscv32ImcClint, // not working yet (issues with portable-atomic features...)
+ Riscv32ImacClint,
}
impl Backends {
@@ -165,6 +166,8 @@ impl Backends {
Backends::Thumbv7 => ARMV7M,
Backends::Thumbv8Base => ARMV8MBASE,
Backends::Thumbv8Main => ARMV8MMAIN,
+ Backends::Riscv32ImcClint => RISCV32IMC,
+ Backends::RiscvEsp32C3 | Backends::Riscv32ImacClint => RISCV32IMAC,
}
}
@@ -175,6 +178,8 @@ impl Backends {
Backends::Thumbv7 => "thumbv7-backend",
Backends::Thumbv8Base => "thumbv8base-backend",
Backends::Thumbv8Main => "thumbv8main-backend",
+ Backends::RiscvEsp32C3 => "riscv-esp32c3-backend",
+ Backends::Riscv32ImcClint | Backends::Riscv32ImacClint => "riscv-clint-backend",
}
}
#[allow(clippy::wrong_self_convention)]
@@ -182,13 +187,8 @@ impl Backends {
match self {
Backends::Thumbv6 | Backends::Thumbv8Base => "cortex-m-source-masking",
Backends::Thumbv7 | Backends::Thumbv8Main => "cortex-m-basepri",
- }
- }
- #[allow(clippy::wrong_self_convention)]
- pub fn to_rtic_uitest_feature(&self) -> &'static str {
- match self {
- Backends::Thumbv6 | Backends::Thumbv8Base => "rtic-uitestv6",
- Backends::Thumbv7 | Backends::Thumbv8Main => "rtic-uitestv7",
+ Backends::RiscvEsp32C3 => "riscv-esp32c3",
+ Backends::Riscv32ImcClint | Backends::Riscv32ImacClint => "riscv-clint",
}
}
}
@@ -200,14 +200,127 @@ pub enum BuildOrCheck {
Build,
}
+#[derive(clap::ValueEnum, Copy, Clone, Default, Debug)]
+pub enum Platforms {
+ Hifive1,
+ #[default]
+ Lm3s6965,
+ Nrf52840,
+ Rp2040,
+ Stm32f3,
+ Stm32f411,
+ Teensy4,
+}
+
+impl Platforms {
+ pub fn name(&self) -> String {
+ let name = match self {
+ Platforms::Hifive1 => "hifive1",
+ Platforms::Lm3s6965 => "lm3s6965",
+ Platforms::Nrf52840 => "nrf52840",
+ Platforms::Rp2040 => "rp2040",
+ Platforms::Stm32f3 => "stm32f3",
+ Platforms::Stm32f411 => "stm32f411",
+ Platforms::Teensy4 => "teensy4",
+ };
+ name.to_string()
+ }
+
+ /// Rust flags needed for the platform when building
+ pub fn rust_flags(&self) -> Vec<String> {
+ let c = "-C".to_string();
+ match self {
+ Platforms::Hifive1 => vec![c, "link-arg=-Thifive1-link.x".to_string()],
+ Platforms::Lm3s6965 => vec![c, "link-arg=-Tlink.x".to_string()],
+ Platforms::Nrf52840 => vec![
+ c.clone(),
+ "linker=flip-link".to_string(),
+ c.clone(),
+ "link-arg=-Tlink.x".to_string(),
+ c.clone(),
+ "link-arg=-Tdefmt.x".to_string(),
+ c,
+ "link-arg=--nmagic".to_string(),
+ ],
+ Platforms::Rp2040 => vec![
+ c.clone(),
+ "link-arg=--nmagic".to_string(),
+ c,
+ "link-arg=-Tlink.x".to_string(),
+ ],
+ Platforms::Stm32f3 => vec![
+ c.clone(),
+ "link-arg=--nmagic".to_string(),
+ c,
+ "link-arg=-Tlink.x".to_string(),
+ ],
+ Platforms::Stm32f411 => vec![
+ c.clone(),
+ "link-arg=-Tlink.x".to_string(),
+ c,
+ "link-arg=-Tdefmt.x".to_string(),
+ ],
+ Platforms::Teensy4 => vec![c, "link-arg=-Tt4link.x".to_string()],
+ }
+ }
+
+ /// Get the default backend for the platform
+ pub fn default_backend(&self) -> Backends {
+ match self {
+ Platforms::Hifive1 => Backends::Riscv32ImcClint,
+ Platforms::Lm3s6965 => Backends::Thumbv7,
+ Platforms::Nrf52840 => unimplemented!(),
+ Platforms::Rp2040 => unimplemented!(),
+ Platforms::Stm32f3 => unimplemented!(),
+ Platforms::Stm32f411 => unimplemented!(),
+ Platforms::Teensy4 => unimplemented!(),
+ }
+ }
+
+ /// Get the features needed given the selected platform and backend.
+ /// If the backend is not supported for the platform, return Err.
+ /// If the backend is supported, but no special features are needed, return Ok(None).
+ pub fn features(&self, backend: &Backends) -> Result<Option<&'static str>, ()> {
+ match self {
+ Platforms::Hifive1 => match backend.to_target() {
+ RISCV32IMC | RISCV32IMAC => Ok(None),
+ _ => Err(()),
+ },
+ Platforms::Lm3s6965 => match backend.to_target() {
+ ARMV6M => Ok(Some("thumbv6-backend")),
+ ARMV7M => Ok(Some("thumbv7-backend")),
+ ARMV8MBASE => Ok(Some("thumbv8base-backend")),
+ ARMV8MMAIN => Ok(Some("thumbv8main-backend")),
+ _ => Err(()),
+ },
+ Platforms::Nrf52840 => unimplemented!(),
+ Platforms::Rp2040 => unimplemented!(),
+ Platforms::Stm32f3 => unimplemented!(),
+ Platforms::Stm32f411 => unimplemented!(),
+ Platforms::Teensy4 => unimplemented!(),
+ }
+ }
+}
+
#[derive(Parser, Clone)]
pub struct Globals {
/// Error out on warnings
#[arg(short = 'D', long)]
pub deny_warnings: bool,
+ /// For which platform to build.
+ ///
+ /// If omitted, the default platform (i.e., lm3s6965) is used.
+ ///
+ /// Example: `cargo xtask --platform lm3s6965`
+ #[arg(value_enum, short, default_value = "lm3s6965", long, global = true)]
+ pub platform: Option<Platforms>,
+
/// For which backend to build.
- #[arg(value_enum, short, default_value = "thumbv7", long, global = true)]
+ ///
+ /// If omitted, the default backend for the selected platform is used
+ /// (check [`Platforms::default_backend`]).
+ #[arg(value_enum, short, long, global = true)]
pub backend: Option<Backends>,
/// List of comma separated examples to include, all others are excluded
@@ -316,55 +429,6 @@ pub enum Commands {
/// Build books with mdbook
Book(Arg),
-
- /// Check one or more usage examples.
- ///
- /// Usage examples are located in ./examples
- UsageExampleCheck(UsageExamplesOpt),
-
- /// Build one or more usage examples.
- ///
- /// Usage examples are located in ./examples
- #[clap(alias = "./examples")]
- UsageExampleBuild(UsageExamplesOpt),
-}
-
-#[derive(Args, Clone, Debug)]
-pub struct UsageExamplesOpt {
- /// The usage examples to build. All usage examples are selected if this argument is not provided.
- ///
- /// Example: `rp2040_local_i2c_init,stm32f3_blinky`.
- examples: Option<String>,
-}
-
-impl UsageExamplesOpt {
- pub fn examples(&self) -> anyhow::Result<Vec<String>> {
- let usage_examples: Vec<_> = std::fs::read_dir("./examples")?
- .filter_map(Result::ok)
- .filter(|p| p.metadata().ok().map(|p| p.is_dir()).unwrap_or(false))
- .filter_map(|p| p.file_name().to_str().map(ToString::to_string))
- .collect();
-
- let selected_examples: Option<Vec<String>> = self
- .examples
- .clone()
- .map(|s| s.split(",").map(ToString::to_string).collect());
-
- if let Some(selected_examples) = selected_examples {
- if let Some(unfound_example) = selected_examples
- .iter()
- .find(|e| !usage_examples.contains(e))
- {
- Err(anyhow::anyhow!(
- "Usage example {unfound_example} does not exist"
- ))
- } else {
- Ok(selected_examples)
- }
- } else {
- Ok(usage_examples)
- }
- }
}
#[derive(Args, Debug, Clone)]
diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs
index c5387c2..78e81b1 100644
--- a/xtask/src/cargo_command.rs
+++ b/xtask/src/cargo_command.rs
@@ -1,4 +1,4 @@
-use crate::{ExtraArguments, Target};
+use crate::{ExtraArguments, Platforms, Target};
use core::fmt;
use std::path::PathBuf;
@@ -15,6 +15,7 @@ pub enum CargoCommand<'a> {
#[allow(dead_code)]
Run {
cargoarg: &'a Option<&'a str>,
+ platform: Platforms, // to tell which platform. If None, it assumes lm3s6965
example: &'a str,
target: Option<Target<'a>>,
features: Option<String>,
@@ -23,6 +24,7 @@ pub enum CargoCommand<'a> {
},
Qemu {
cargoarg: &'a Option<&'a str>,
+ platform: Platforms, // to tell which platform. If None, it assumes lm3s6965
example: &'a str,
target: Option<Target<'a>>,
features: Option<String>,
@@ -32,6 +34,7 @@ pub enum CargoCommand<'a> {
},
ExampleBuild {
cargoarg: &'a Option<&'a str>,
+ platform: Platforms, // to tell which platform. If None, it assumes lm3s6965
example: &'a str,
target: Option<Target<'a>>,
features: Option<String>,
@@ -41,10 +44,12 @@ pub enum CargoCommand<'a> {
},
ExampleCheck {
cargoarg: &'a Option<&'a str>,
+ platform: Platforms, // to tell which platform. If None, it assumes lm3s6965
example: &'a str,
target: Option<Target<'a>>,
features: Option<String>,
mode: BuildMode,
+ dir: Option<PathBuf>,
deny_warnings: bool,
},
Build {
@@ -94,6 +99,7 @@ pub enum CargoCommand<'a> {
},
ExampleSize {
cargoarg: &'a Option<&'a str>,
+ platform: Platforms, // to tell which platform. If None, it assumes lm3s6965
example: &'a str,
target: Option<Target<'a>>,
features: Option<String>,
@@ -137,6 +143,7 @@ impl core::fmt::Display for CargoCommand<'_> {
features: &Option<String>,
cargoarg: &&Option<&str>,
path: Option<&PathBuf>,
+ // no need to add platform, as it is implicit in the path
) -> String {
let feat = feat(features);
let carg = carg(cargoarg);
@@ -179,6 +186,7 @@ impl core::fmt::Display for CargoCommand<'_> {
match self {
CargoCommand::Run {
cargoarg,
+ platform: _,
example,
target,
features,
@@ -193,6 +201,7 @@ impl core::fmt::Display for CargoCommand<'_> {
}
CargoCommand::Qemu {
cargoarg,
+ platform: _,
example,
target,
features,
@@ -206,6 +215,7 @@ impl core::fmt::Display for CargoCommand<'_> {
}
CargoCommand::ExampleBuild {
cargoarg,
+ platform: _,
example,
target,
features,
@@ -219,16 +229,18 @@ impl core::fmt::Display for CargoCommand<'_> {
}
CargoCommand::ExampleCheck {
cargoarg,
+ platform: _,
example,
target,
features,
mode,
+ dir,
deny_warnings,
- } => write!(
- f,
- "Check example {example} {}",
- details(*deny_warnings, target, Some(mode), features, cargoarg, None)
- ),
+ } => {
+ let warns = *deny_warnings;
+ let details = details(warns, target, Some(mode), features, cargoarg, dir.as_ref());
+ write!(f, "Check example {example} {details}",)
+ }
CargoCommand::Build {
cargoarg,
package,
@@ -329,17 +341,14 @@ impl core::fmt::Display for CargoCommand<'_> {
.clone()
.map(|t| format!("test {t}"))
.unwrap_or("all tests".into());
- let deny_warnings = if *deny_warnings {
- format!("deny warnings, ")
- } else {
- format!("")
- };
- let feat = feat(features);
- write!(f, "Run {test} in {p} ({deny_warnings}features: {feat})")
+
+ let details = details(*deny_warnings, &None, None, features, &&None, None);
+ write!(f, "Run {test} in {p} {details}")
}
CargoCommand::Book { arguments: _ } => write!(f, "Build the book"),
CargoCommand::ExampleSize {
cargoarg,
+ platform: _,
example,
target,
features,
@@ -475,6 +484,7 @@ impl<'a> CargoCommand<'a> {
// For future embedded-ci, for now the same as Qemu
CargoCommand::Run {
cargoarg,
+ platform: _,
example,
features,
mode,
@@ -491,6 +501,7 @@ impl<'a> CargoCommand<'a> {
),
CargoCommand::Qemu {
cargoarg,
+ platform: _,
example,
features,
mode,
@@ -606,6 +617,7 @@ impl<'a> CargoCommand<'a> {
}
CargoCommand::ExampleBuild {
cargoarg,
+ platform: _,
example,
features,
mode,
@@ -624,9 +636,11 @@ impl<'a> CargoCommand<'a> {
),
CargoCommand::ExampleCheck {
cargoarg,
+ platform: _,
example,
features,
mode,
+ dir: _,
// Target is added by build_args
target: _,
// deny_warnings is exposed through `extra_env`
@@ -640,6 +654,7 @@ impl<'a> CargoCommand<'a> {
),
CargoCommand::ExampleSize {
cargoarg,
+ platform: _,
example,
features,
mode,
@@ -664,6 +679,7 @@ impl<'a> CargoCommand<'a> {
pub fn chdir(&self) -> Option<&PathBuf> {
match self {
CargoCommand::Qemu { dir, .. }
+ | CargoCommand::ExampleCheck { dir, .. }
| CargoCommand::ExampleBuild { dir, .. }
| CargoCommand::ExampleSize { dir, .. }
| CargoCommand::Build { dir, .. }
@@ -687,20 +703,35 @@ impl<'a> CargoCommand<'a> {
}
}
- pub fn extra_env(&self) -> Option<(&str, &str)> {
+ pub fn extra_env(&self) -> Option<(&str, String)> {
match self {
// Clippy is a special case: it sets deny warnings
// through an argument to rustc.
CargoCommand::Clippy { .. } => None,
- CargoCommand::Doc { .. } => Some(("RUSTDOCFLAGS", "-D warnings")),
+ CargoCommand::Doc { .. } => Some(("RUSTDOCFLAGS", "-D warnings".to_string())),
- CargoCommand::Qemu { deny_warnings, .. }
- | CargoCommand::ExampleBuild { deny_warnings, .. }
- | CargoCommand::ExampleSize { deny_warnings, .. } => {
+ CargoCommand::Qemu {
+ platform,
+ deny_warnings,
+ ..
+ }
+ | CargoCommand::ExampleBuild {
+ platform,
+ deny_warnings,
+ ..
+ }
+ | CargoCommand::ExampleSize {
+ platform,
+ deny_warnings,
+ ..
+ } => {
if *deny_warnings {
+ let rust_flags = platform.rust_flags().join(" ");
+ let rust_flags = format!("-D warnings {}", rust_flags);
// NOTE: this also needs the link-arg because .cargo/config.toml
// is ignored if you set the RUSTFLAGS env variable.
- Some(("RUSTFLAGS", "-D warnings -C link-arg=-Tlink.x"))
+ Some(("RUSTFLAGS", rust_flags))
+ // TODO make this configurable
} else {
None
}
@@ -711,7 +742,7 @@ impl<'a> CargoCommand<'a> {
| CargoCommand::Build { deny_warnings, .. }
| CargoCommand::Test { deny_warnings, .. } => {
if *deny_warnings {
- Some(("RUSTFLAGS", "-D warnings"))
+ Some(("RUSTFLAGS", "-D warnings".to_string()))
} else {
None
}
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 90ba13f..0c56b42 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -11,12 +11,12 @@ use std::{path::Path, str};
use log::{error, info, log_enabled, trace, Level};
use crate::{
- argument_parsing::{Backends, BuildOrCheck, Cli, Commands},
+ argument_parsing::{BuildOrCheck, Cli, Commands, Platforms},
build::init_build_dir,
run::*,
};
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct Target<'a> {
triple: &'a str,
has_std: bool,
@@ -54,6 +54,8 @@ const ARMV6M: Target = Target::new("thumbv6m-none-eabi", false);
const ARMV7M: Target = Target::new("thumbv7m-none-eabi", false);
const ARMV8MBASE: Target = Target::new("thumbv8m.base-none-eabi", false);
const ARMV8MMAIN: Target = Target::new("thumbv8m.main-none-eabi", false);
+const RISCV32IMC: Target = Target::new("riscv32imc-unknown-none-elf", false);
+const RISCV32IMAC: Target = Target::new("riscv32imac-unknown-none-elf", false);
fn main() -> anyhow::Result<()> {
// if there's an `xtask` folder, we're *probably* at the root of this repo (we can't just
@@ -65,13 +67,6 @@ fn main() -> anyhow::Result<()> {
));
}
- let examples: Vec<_> = std::fs::read_dir("./rtic/examples")?
- .filter_map(|p| p.ok())
- .map(|p| p.path())
- .filter(|p| p.display().to_string().ends_with(".rs"))
- .map(|path| path.file_stem().unwrap().to_str().unwrap().to_string())
- .collect();
-
let cli = Cli::parse();
let globals = &cli.globals;
@@ -94,12 +89,35 @@ fn main() -> anyhow::Result<()> {
);
log::debug!("Partial features: {}", globals.partial);
+ let platform = if let Some(platform) = globals.platform {
+ platform
+ } else {
+ Platforms::default()
+ };
+
let backend = if let Some(backend) = globals.backend {
backend
} else {
- Backends::default()
+ platform.default_backend()
};
+ // Check if the platform supports the backend
+ if platform.features(&backend).is_err() {
+ return Err(anyhow::anyhow!(
+ "platform {:?} does not support backend {:?}",
+ platform,
+ backend
+ ));
+ }
+
+ let examples_path = format!("./examples/{}/examples", platform.name());
+ let examples: Vec<_> = std::fs::read_dir(examples_path)?
+ .filter_map(|p| p.ok())
+ .map(|p| p.path())
+ .filter(|p| p.display().to_string().ends_with(".rs"))
+ .map(|path| path.file_stem().unwrap().to_str().unwrap().to_string())
+ .collect();
+
let example = globals.example.clone();
let exampleexclude = globals.exampleexclude.clone();
@@ -163,42 +181,45 @@ fn main() -> anyhow::Result<()> {
Commands::Format(args) => cargo_format(globals, &cargologlevel, &args.package, args.check),
Commands::Clippy(args) => {
info!("Running clippy on backend: {backend:?}");
- cargo_clippy(globals, &cargologlevel, &args, backend)
+ cargo_clippy(globals, &cargologlevel, args, backend)
}
Commands::Check(args) => {
info!("Checking on backend: {backend:?}");
- cargo(globals, BuildOrCheck::Check, &cargologlevel, &args, backend)
+ cargo(globals, BuildOrCheck::Check, &cargologlevel, args, backend)
}
Commands::Build(args) => {
info!("Building for backend: {backend:?}");
- cargo(globals, BuildOrCheck::Build, &cargologlevel, &args, backend)
+ cargo(globals, BuildOrCheck::Build, &cargologlevel, args, backend)
}
Commands::ExampleCheck => {
- info!("Checking on backend: {backend:?}");
+ info!("Checking on platform: {platform:?}, backend: {backend:?}");
cargo_example(
globals,
BuildOrCheck::Check,
&cargologlevel,
+ platform,
backend,
&examples_to_run,
)
}
Commands::ExampleBuild => {
- info!("Building for backend: {backend:?}");
+ info!("Building for platform: {platform:?}, backend: {backend:?}");
cargo_example(
globals,
BuildOrCheck::Build,
&cargologlevel,
+ platform,
backend,
&examples_to_run,
)
}
Commands::Size(args) => {
// x86_64 target not valid
- info!("Measuring for backend: {backend:?}");
+ info!("Measuring for platform: {platform:?}, backend: {backend:?}");
build_and_check_size(
globals,
&cargologlevel,
+ platform,
backend,
&examples_to_run,
&args.arguments,
@@ -206,10 +227,11 @@ fn main() -> anyhow::Result<()> {
}
Commands::Qemu(args) | Commands::Run(args) => {
// x86_64 target not valid
- info!("Testing for backend: {backend:?}");
+ info!("Testing for platform: {platform:?}, backend: {backend:?}");
qemu_run_examples(
globals,
&cargologlevel,
+ platform,
backend,
&examples_to_run,
args.overwrite_expected,
@@ -221,20 +243,12 @@ fn main() -> anyhow::Result<()> {
}
Commands::Test(args) => {
info!("Running cargo test on backend: {backend:?}");
- cargo_test(globals, &args, backend)
+ cargo_test(globals, args, backend)
}
Commands::Book(args) => {
info!("Running mdbook");
cargo_book(globals, &args.arguments)
}
- Commands::UsageExampleCheck(examples) => {
- info!("Checking usage examples");
- cargo_usage_example(globals, BuildOrCheck::Check, examples.examples()?)
- }
- Commands::UsageExampleBuild(examples) => {
- info!("Building usage examples");
- cargo_usage_example(globals, BuildOrCheck::Build, examples.examples()?)
- }
};
handle_results(globals, final_run_results).map_err(|_| anyhow::anyhow!("Commands failed"))
diff --git a/xtask/src/run.rs b/xtask/src/run.rs
index 6057551..ff81e6a 100644
--- a/xtask/src/run.rs
+++ b/xtask/src/run.rs
@@ -15,7 +15,9 @@ mod iter;
use iter::{into_iter, CoalescingRunner};
use crate::{
- argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata},
+ argument_parsing::{
+ Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, Platforms, TestMetadata,
+ },
cargo_command::{BuildMode, CargoCommand},
};
@@ -62,7 +64,12 @@ fn command_parser(
};
match *command {
- CargoCommand::Qemu { example, .. } | CargoCommand::Run { example, .. } => {
+ CargoCommand::Qemu {
+ platform, example, ..
+ }
+ | CargoCommand::Run {
+ platform, example, ..
+ } => {
/// Check if `run` was successful.
/// returns Ok in case the run went as expected,
/// Err otherwise
@@ -99,8 +106,9 @@ fn command_parser(
res
}
+ let platform_name = platform.name();
let run_file = format!("{example}.run");
- let expected_output_file = ["rtic", "ci", "expected", &run_file]
+ let expected_output_file = ["ci", "expected", &platform_name, &run_file]
.iter()
.collect::<PathBuf>()
.into_os_string()
@@ -191,72 +199,41 @@ pub fn cargo<'c>(
runner.run_and_coalesce()
}
-/// Cargo command to build a usage example.
-///
-/// The usage examples are in examples/
-pub fn cargo_usage_example(
- globals: &Globals,
- operation: BuildOrCheck,
- usage_examples: Vec<String>,
-) -> Vec<FinalRunResult<'_>> {
- into_iter(&usage_examples)
- .map(|example| {
- let path = format!("examples/{example}");
-
- let command = match operation {
- BuildOrCheck::Check => CargoCommand::Check {
- cargoarg: &None,
- mode: BuildMode::Release,
- dir: Some(path.into()),
- package: None,
- target: None,
- features: None,
- deny_warnings: globals.deny_warnings,
- },
- BuildOrCheck::Build => CargoCommand::Build {
- cargoarg: &None,
- package: None,
- target: None,
- features: None,
- mode: BuildMode::Release,
- dir: Some(path.into()),
- deny_warnings: globals.deny_warnings,
- },
- };
- (globals, command, false)
- })
- .run_and_coalesce()
-}
-
/// Cargo command to either build or check all examples
///
-/// The examples are in rtic/examples
+/// The examples are in examples/<platform>/examples
pub fn cargo_example<'c>(
globals: &Globals,
operation: BuildOrCheck,
cargoarg: &'c Option<&'c str>,
+ platform: Platforms,
backend: Backends,
examples: &'c [String],
) -> Vec<FinalRunResult<'c>> {
let runner = into_iter(examples).map(|example| {
+ let path = format!("examples/{}", platform.name());
+ let dir = Some(PathBuf::from(path));
let features = Some(backend.to_target().and_features(backend.to_rtic_feature()));
let command = match operation {
BuildOrCheck::Check => CargoCommand::ExampleCheck {
cargoarg,
+ platform,
example,
target: Some(backend.to_target()),
features,
mode: BuildMode::Release,
+ dir,
deny_warnings: globals.deny_warnings,
},
BuildOrCheck::Build => CargoCommand::ExampleBuild {
cargoarg,
+ platform,
example,
target: Some(backend.to_target()),
features,
mode: BuildMode::Release,
- dir: Some(PathBuf::from("./rtic")),
+ dir,
deny_warnings: globals.deny_warnings,
},
};
@@ -368,9 +345,12 @@ pub fn cargo_book<'c>(
/// Run examples
///
/// Supports updating the expected output via the overwrite argument
+///
+/// The examples are in examples/<platform>/examples
pub fn qemu_run_examples<'c>(
globals: &Globals,
cargoarg: &'c Option<&'c str>,
+ platform: Platforms,
backend: Backends,
examples: &'c [String],
overwrite: bool,
@@ -380,11 +360,13 @@ pub fn qemu_run_examples<'c>(
into_iter(examples)
.flat_map(|example| {
+ let path = format!("examples/{}", platform.name());
+ let dir = Some(PathBuf::from(path));
let target = target.into();
- let dir = Some(PathBuf::from("./rtic"));
let cmd_build = CargoCommand::ExampleBuild {
cargoarg: &None,
+ platform,
example,
target,
features: features.clone(),
@@ -395,6 +377,7 @@ pub fn qemu_run_examples<'c>(
let cmd_qemu = CargoCommand::Qemu {
cargoarg,
+ platform,
example,
target,
features: features.clone(),
@@ -413,6 +396,7 @@ pub fn qemu_run_examples<'c>(
pub fn build_and_check_size<'c>(
globals: &Globals,
cargoarg: &'c Option<&'c str>,
+ platform: Platforms,
backend: Backends,
examples: &'c [String],
arguments: &'c Option<ExtraArguments>,
@@ -422,27 +406,31 @@ pub fn build_and_check_size<'c>(
let runner = into_iter(examples)
.flat_map(|example| {
+ let path = format!("examples/{}", platform.name());
+ let dir = Some(PathBuf::from(path));
let target = target.into();
// Make sure the requested example(s) are built
let cmd_build = CargoCommand::ExampleBuild {
cargoarg: &Some("--quiet"),
+ platform,
example,
target,
features: features.clone(),
mode: BuildMode::Release,
- dir: Some(PathBuf::from("./rtic")),
+ dir: dir.clone(),
deny_warnings: globals.deny_warnings,
};
let cmd_size = CargoCommand::ExampleSize {
cargoarg,
+ platform,
example,
target,
features: features.clone(),
mode: BuildMode::Release,
arguments: arguments.clone(),
- dir: Some(PathBuf::from("./rtic")),
+ dir,
deny_warnings: globals.deny_warnings,
};