diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 875c3f39d185..f6a39b1d50a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -158,11 +158,11 @@ jobs: components: llvm-tools-preview # Use precompiled binutils - - name: cargo install cargo-binutils - uses: actions-rs/install@v0.1 - with: - crate: cargo-binutils - version: latest + # - name: cargo install cargo-binutils + # uses: actions-rs/install@v0.1 + # with: + # crate: cargo-binutils + # version: latest - name: Cache Dependencies uses: Swatinem/rust-cache@v1 @@ -172,12 +172,21 @@ jobs: sudo apt update sudo apt install -y qemu-system-arm + - name: Install embedded-ci-client + run: | + cargo install --git https://github.com/korken89/embedded-ci.git embedded-ci-client + - name: Fail on warnings run: sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' src/lib.rs macros/src/lib.rs - name: Run-pass tests - run: - cargo xtask --target ${{ matrix.target }} + env: + EMBEDDED_CI_TOKEN: ${{ secrets.EMBEDDED_CI_TOKEN }} + EMBEDDED_CI_SERVER: ${{ secrets.EMBEDDED_CI_SERVER }} + run: | + cd examples-runner + cargo xtask --target ${{ matrix.target }} --runner embedded-ci + cargo xtask --target ${{ matrix.target }} --runner qemu # Check the correctness of macros/ crate checkmacros: diff --git a/CHANGELOG.md b/CHANGELOG.md index f05aeeaf714b..70cff1a905d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top! ### Added +- HIL tests (embedded-ci) - Improve how CHANGELOG.md merges are handled - If current $stable and master version matches, dev-book redirects to $stable book - During deploy stage, merge master branch into current stable IFF cargo package version matches diff --git a/Cargo.toml b/Cargo.toml index 4393533b3077..4723f540aa47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,9 @@ lto = true [workspace] members = [ "macros", - "xtask", +] +exclude = [ + "examples-runner", ] # do not optimize proc-macro deps or build scripts diff --git a/book/en/src/by-example.md b/book/en/src/by-example.md index 3a523e51bb4b..b4eabd67e3da 100644 --- a/book/en/src/by-example.md +++ b/book/en/src/by-example.md @@ -28,5 +28,5 @@ $ cargo run --target thumbv7m-none-eabi --example locals Yields this output: ``` console -{{#include ../../../ci/expected/locals.run}} +{{#include ../../../example-runner/ci/expected/locals.run}} ``` diff --git a/book/en/src/by-example/app.md b/book/en/src/by-example/app.md index 2c6aca7a2b52..85028f3254be 100644 --- a/book/en/src/by-example/app.md +++ b/book/en/src/by-example/app.md @@ -22,5 +22,5 @@ To give a flavour of RTIC, the following example contains commonly used features In the following sections we will go through each feature in detail. ``` rust -{{#include ../../../../examples/common.rs}} +{{#include ../../../../example-runner/src/bin/common.rs}} ``` diff --git a/book/en/src/by-example/app_idle.md b/book/en/src/by-example/app_idle.md index 537902a4423d..a6047b36d5e2 100644 --- a/book/en/src/by-example/app_idle.md +++ b/book/en/src/by-example/app_idle.md @@ -17,12 +17,12 @@ are safe to access. The example below shows that `idle` runs after `init`. ``` rust -{{#include ../../../../examples/idle.rs}} +{{#include ../../../../example-runner/src/bin/idle.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example idle -{{#include ../../../../ci/expected/idle.run}} +{{#include ../../../../example-runner/ci/expected/idle.run}} ``` By default, the RTIC `idle` task does not try to optimize for any specific targets. @@ -43,10 +43,10 @@ default [`nop()`][NOP] with [`wfi()`][WFI]. [NOP]: https://developer.arm.com/documentation/dui0662/b/The-Cortex-M0--Instruction-Set/Miscellaneous-instructions/NOP ``` rust -{{#include ../../../../examples/idle-wfi.rs}} +{{#include ../../../../example-runner/src/bin/idle-wfi.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example idle-wfi -{{#include ../../../../ci/expected/idle-wfi.run}} +{{#include ../../../../example-runner/ci/expected/idle-wfi.run}} ``` diff --git a/book/en/src/by-example/app_init.md b/book/en/src/by-example/app_init.md index 615c2991027e..40e72c4107d4 100644 --- a/book/en/src/by-example/app_init.md +++ b/book/en/src/by-example/app_init.md @@ -19,14 +19,14 @@ The `device` field is available when the `peripherals` argument is set to the de In the rare case you want to implement an ultra-slim application you can explicitly set `peripherals` to `false`. ``` rust -{{#include ../../../../examples/init.rs}} +{{#include ../../../../example-runner/src/bin/init.rs}} ``` Running the example will print `init` to the console and then exit the QEMU process. ``` console $ cargo run --target thumbv7m-none-eabi --example init -{{#include ../../../../ci/expected/init.run}} +{{#include ../../../../example-runner/ci/expected/init.run}} ``` > **NOTE**: You can choose target device by passing a target diff --git a/book/en/src/by-example/app_minimal.md b/book/en/src/by-example/app_minimal.md index d0ff40a3039f..066fde9df32d 100644 --- a/book/en/src/by-example/app_minimal.md +++ b/book/en/src/by-example/app_minimal.md @@ -3,5 +3,5 @@ This is the smallest possible RTIC application: ``` rust -{{#include ../../../../examples/smallest.rs}} +{{#include ../../../../example-runner/src/bin/smallest.rs}} ``` diff --git a/book/en/src/by-example/app_priorities.md b/book/en/src/by-example/app_priorities.md index 1a92ec846cd8..bca9461da0f7 100644 --- a/book/en/src/by-example/app_priorities.md +++ b/book/en/src/by-example/app_priorities.md @@ -39,12 +39,12 @@ Task Priority The following example showcases the priority based scheduling of tasks: ``` rust -{{#include ../../../../examples/preempt.rs}} +{{#include ../../../../example-runner/src/bin/preempt.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example preempt -{{#include ../../../../ci/expected/preempt.run}} +{{#include ../../../../example-runner/ci/expected/preempt.run}} ``` Note that the task `bar` does *not* preempt task `baz` because its priority diff --git a/book/en/src/by-example/hardware_tasks.md b/book/en/src/by-example/hardware_tasks.md index 7f8d3c6e14f8..67af5766f3e5 100644 --- a/book/en/src/by-example/hardware_tasks.md +++ b/book/en/src/by-example/hardware_tasks.md @@ -28,10 +28,10 @@ The example below demonstrates the use of the `#[task(binds = InterruptName)]` a hardware task bound to an interrupt handler. ``` rust -{{#include ../../../../examples/hardware.rs}} +{{#include ../../../../example-runner/src/bin/hardware.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example hardware -{{#include ../../../../ci/expected/hardware.run}} +{{#include ../../../../example-runner/ci/expected/hardware.run}} ``` diff --git a/book/en/src/by-example/message_passing.md b/book/en/src/by-example/message_passing.md index 0dc8f85814c1..ad31ce458849 100644 --- a/book/en/src/by-example/message_passing.md +++ b/book/en/src/by-example/message_passing.md @@ -11,10 +11,10 @@ pending spawns of `foo`. Exceeding this capacity is an `Error`. The number of arguments to a task is not limited: ``` rust -{{#include ../../../../examples/message_passing.rs}} +{{#include ../../../../example-runner/src/bin/message_passing.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example message_passing -{{#include ../../../../ci/expected/message_passing.run}} +{{#include ../../../../example-runner/ci/expected/message_passing.run}} ``` diff --git a/book/en/src/by-example/monotonic.md b/book/en/src/by-example/monotonic.md index 094bd5df0257..7e5e3140b1c2 100644 --- a/book/en/src/by-example/monotonic.md +++ b/book/en/src/by-example/monotonic.md @@ -35,12 +35,12 @@ This activates the monotonics making it possible to use them. See the following example: ``` rust -{{#include ../../../../examples/schedule.rs}} +{{#include ../../../../example-runner/src/bin/schedule.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example schedule -{{#include ../../../../ci/expected/schedule.run}} +{{#include ../../../../example-runner/ci/expected/schedule.run}} ``` ## Canceling or rescheduling a scheduled task @@ -51,10 +51,10 @@ If `cancel` or `reschedule_at`/`reschedule_after` returns an `Err` it means that too late and that the task is already sent for execution. The following example shows this in action: ``` rust -{{#include ../../../../examples/cancel-reschedule.rs}} +{{#include ../../../../example-runner/src/bin/cancel-reschedule.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example cancel-reschedule -{{#include ../../../../ci/expected/cancel-reschedule.run}} +{{#include ../../../../example-runner/ci/expected/cancel-reschedule.run}} ``` diff --git a/book/en/src/by-example/resources.md b/book/en/src/by-example/resources.md index 9d51d6c97ad7..ef74db98fb1d 100644 --- a/book/en/src/by-example/resources.md +++ b/book/en/src/by-example/resources.md @@ -39,14 +39,14 @@ The example application shown below contains two tasks where each task has acces `#[local]` resource, plus that the `idle` task has its own `#[local]` as well. ``` rust -{{#include ../../../../examples/locals.rs}} +{{#include ../../../../example-runner/src/bin/locals.rs}} ``` Running the example: ``` console $ cargo run --target thumbv7m-none-eabi --example locals -{{#include ../../../../ci/expected/locals.run}} +{{#include ../../../../example-runner/ci/expected/locals.run}} ``` ### Task local initialized resources @@ -64,12 +64,12 @@ are not crossing any thread boundary. In the example below the different uses and lifetimes are shown: ``` rust -{{#include ../../../../examples/declared_locals.rs}} +{{#include ../../../../example-runner/src/bin/declared_locals.rs}} ``` ## `#[shared]` resources and `lock` @@ -97,12 +97,12 @@ resource for accessing the data. The highest priority handler, which do not acce resource, is free to preempt the critical section created by the lowest priority handler. ``` rust -{{#include ../../../../examples/lock.rs}} +{{#include ../../../../example-runner/src/bin/lock.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example lock -{{#include ../../../../ci/expected/lock.run}} +{{#include ../../../../example-runner/ci/expected/lock.run}} ``` Types of `#[shared]` resources have to be both [`Send`] and [`Sync`]. @@ -113,12 +113,12 @@ As an extension to `lock`, and to reduce rightward drift, locks can be taken as following examples show this in use: ``` rust -{{#include ../../../../examples/multilock.rs}} +{{#include ../../../../example-runner/src/bin/multilock.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example multilock -{{#include ../../../../ci/expected/multilock.run}} +{{#include ../../../../example-runner/ci/expected/multilock.run}} ``` ## Only shared (`&-`) access @@ -143,12 +143,12 @@ In the example below a key (e.g. a cryptographic key) is loaded (or created) at used from two tasks that run at different priorities without any kind of lock. ``` rust -{{#include ../../../../examples/only-shared-access.rs}} +{{#include ../../../../example-runner/src/bin/only-shared-access.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example only-shared-access -{{#include ../../../../ci/expected/only-shared-access.run}} +{{#include ../../../../example-runner/ci/expected/only-shared-access.run}} ``` ## Lock-free resource access of shared resources @@ -165,10 +165,10 @@ tasks running at different priorities will result in a *compile-time* error -- n API would be a data race in that case. ``` rust -{{#include ../../../../examples/lock-free.rs}} +{{#include ../../../../example-runner/src/bin/lock-free.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example lock-free -{{#include ../../../../ci/expected/lock-free.run}} +{{#include ../../../../example-runner/ci/expected/lock-free.run}} ``` diff --git a/book/en/src/by-example/software_tasks.md b/book/en/src/by-example/software_tasks.md index ea40697d274b..961d53e1aed6 100644 --- a/book/en/src/by-example/software_tasks.md +++ b/book/en/src/by-example/software_tasks.md @@ -34,10 +34,10 @@ The framework will give a compilation error if there are not enough dispatchers See the following example: ``` rust -{{#include ../../../../examples/spawn.rs}} +{{#include ../../../../example-runner/src/bin/spawn.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example spawn -{{#include ../../../../ci/expected/spawn.run}} +{{#include ../../../../example-runner/ci/expected/spawn.run}} ``` diff --git a/book/en/src/by-example/tips_destructureing.md b/book/en/src/by-example/tips_destructureing.md index 4637b4834327..af8df03b3d19 100644 --- a/book/en/src/by-example/tips_destructureing.md +++ b/book/en/src/by-example/tips_destructureing.md @@ -5,10 +5,10 @@ resources. Here are two examples on how to split up the resource struct: ``` rust -{{#include ../../../../examples/destructure.rs}} +{{#include ../../../../example-runner/src/bin/destructure.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example destructure -{{#include ../../../../ci/expected/destructure.run}} +{{#include ../../../../example-runner/ci/expected/destructure.run}} ``` diff --git a/book/en/src/by-example/tips_from_ram.md b/book/en/src/by-example/tips_from_ram.md index fc47803f9da3..e04e773175e5 100644 --- a/book/en/src/by-example/tips_from_ram.md +++ b/book/en/src/by-example/tips_from_ram.md @@ -20,14 +20,14 @@ improve performance in some cases. The example below shows how to place the higher priority task, `bar`, in RAM. ``` rust -{{#include ../../../../examples/ramfunc.rs}} +{{#include ../../../../example-runner/src/bin/ramfunc.rs}} ``` Running this program produces the expected output. ``` console $ cargo run --target thumbv7m-none-eabi --example ramfunc -{{#include ../../../../ci/expected/ramfunc.run}} +{{#include ../../../../example-runner/ci/expected/ramfunc.run}} ``` One can look at the output of `cargo-nm` to confirm that `bar` ended in RAM @@ -35,10 +35,10 @@ One can look at the output of `cargo-nm` to confirm that `bar` ended in RAM ``` console $ cargo nm --example ramfunc --release | grep ' foo::' -{{#include ../../../../ci/expected/ramfunc.run.grep.foo}} +{{#include ../../../../example-runner/ci/expected/ramfunc.run.grep.foo}} ``` ``` console $ cargo nm --example ramfunc --release | grep ' bar::' -{{#include ../../../../ci/expected/ramfunc.run.grep.bar}} +{{#include ../../../../example-runner/ci/expected/ramfunc.run.grep.bar}} ``` diff --git a/book/en/src/by-example/tips_indirection.md b/book/en/src/by-example/tips_indirection.md index 1a330c516250..ac6148dbfa2e 100644 --- a/book/en/src/by-example/tips_indirection.md +++ b/book/en/src/by-example/tips_indirection.md @@ -18,10 +18,10 @@ or one can use a statically allocated memory pool like [`heapless::Pool`]. Here's an example where `heapless::Pool` is used to "box" buffers of 128 bytes. ``` rust -{{#include ../../../../examples/pool.rs}} +{{#include ../../../../example-runner/src/bin/pool.rs}} ``` ``` console $ cargo run --target thumbv7m-none-eabi --example pool -{{#include ../../../../ci/expected/pool.run}} +{{#include ../../../../example-runner/ci/expected/pool.run}} ``` diff --git a/book/en/src/by-example/tips_static_lifetimes.md b/book/en/src/by-example/tips_static_lifetimes.md index 8d3a832c4ebb..4baf324a62cc 100644 --- a/book/en/src/by-example/tips_static_lifetimes.md +++ b/book/en/src/by-example/tips_static_lifetimes.md @@ -13,12 +13,12 @@ for lock-free access to the shared queue. [`heapless::spsc::Queue`]: https://docs.rs/heapless/0.7.5/heapless/spsc/struct.Queue.html ``` rust -{{#include ../../../../examples/static.rs}} +{{#include ../../../../example-runner/src/bin/static.rs}} ``` Running this program produces the expected output. ``` console $ cargo run --target thumbv7m-none-eabi --example static -{{#include ../../../../ci/expected/static.run}} +{{#include ../../../../example-runner/ci/expected/static.run}} ``` diff --git a/book/ru/src/by-example/app.md b/book/ru/src/by-example/app.md index 5259bfa08ed0..daf57714a377 100644 --- a/book/ru/src/by-example/app.md +++ b/book/ru/src/by-example/app.md @@ -51,7 +51,7 @@ ``` console $ cargo run --example init -{{#include ../../../../ci/expected/init.run}} +{{#include ../../../../example-runner/ci/expected/init.run}} ``` > **ПРИМЕЧАНИЕ**: Не забывайте указывать выбранное вами целевое устройство, передавая параметр target @@ -87,7 +87,7 @@ $ cargo run --example init ``` console $ cargo run --example idle -{{#include ../../../../ci/expected/idle.run}} +{{#include ../../../../example-runner/ci/expected/idle.run}} ``` ## Аппаратные задачи @@ -109,7 +109,7 @@ mut` переменные безопасны для использования ``` console $ cargo run --example hardware -{{#include ../../../../ci/expected/hardware.run}} +{{#include ../../../../example-runner/ci/expected/hardware.run}} ``` До сих пор все программы на RTIC, которые мы видели, не отличались от программ, @@ -145,7 +145,7 @@ $ cargo run --example hardware ``` console $ cargo run --example preempt -{{#include ../../../../ci/expected/preempt.run}} +{{#include ../../../../example-runner/ci/expected/preempt.run}} ``` Заметьте, что задача `gpiob` *не* вытесняет задачу `gpioc`, потому что ее приоритет diff --git a/book/ru/src/by-example/new.md b/book/ru/src/by-example/new.md index fcf523701a32..53d66489f8b7 100644 --- a/book/ru/src/by-example/new.md +++ b/book/ru/src/by-example/new.md @@ -80,5 +80,5 @@ $ cargo add panic-semihosting ``` console $ # ПРИМЕЧАНИЕ: Я раскомментировал опцию `runner` в `.cargo/config` $ cargo run -{{#include ../../../../ci/expected/init.run}} +{{#include ../../../../example-runner/ci/expected/init.run}} ``` diff --git a/book/ru/src/by-example/resources.md b/book/ru/src/by-example/resources.md index ed8904ba93b9..d8130ba6c786 100644 --- a/book/ru/src/by-example/resources.md +++ b/book/ru/src/by-example/resources.md @@ -34,7 +34,7 @@ ``` console $ cargo run --example resource -{{#include ../../../../ci/expected/resource.run}} +{{#include ../../../../example-runner/ci/expected/resource.run}} ``` К ресурсу `#[local]` нельзя получить доступ извне задачи к которой он @@ -76,7 +76,7 @@ $ cargo run --example resource ``` console $ cargo run --example lock -{{#include ../../../../ci/expected/lock.run}} +{{#include ../../../../example-runner/ci/expected/lock.run}} ``` ## Множественное блокировка @@ -115,7 +115,7 @@ $ cargo run --example lock ``` console $ cargo run --example only-shared-access -{{#include ../../../../ci/expected/only-shared-access.run}} +{{#include ../../../../example-runner/ci/expected/only-shared-access.run}} ``` ## Неблокируемый доступ к изменяемым ресурсам @@ -136,5 +136,5 @@ $ cargo run --example only-shared-access ``` console $ cargo run --example lock-free -{{#include ../../../../ci/expected/lock-free.run}} +{{#include ../../../../example-runner/ci/expected/lock-free.run}} ``` \ No newline at end of file diff --git a/book/ru/src/by-example/tasks.md b/book/ru/src/by-example/tasks.md index 3c99d00efca1..19c502331643 100644 --- a/book/ru/src/by-example/tasks.md +++ b/book/ru/src/by-example/tasks.md @@ -22,7 +22,7 @@ RTIC также поддерживает *программные* задачи, ``` console $ cargo run --example task -{{#include ../../../../ci/expected/task.run}} +{{#include ../../../../example-runner/ci/expected/task.run}} ``` ## Передача сообщений @@ -39,7 +39,7 @@ $ cargo run --example task ``` console $ cargo run --example message -{{#include ../../../../ci/expected/message.run}} +{{#include ../../../../example-runner/ci/expected/message.run}} ``` ## Вместимость @@ -63,7 +63,7 @@ RTIC *не* производит никакого рода аллокаций п ``` console $ cargo run --example capacity -{{#include ../../../../ci/expected/capacity.run}} +{{#include ../../../../example-runner/ci/expected/capacity.run}} ``` ## Обработка ошибок diff --git a/book/ru/src/by-example/timer-queue.md b/book/ru/src/by-example/timer-queue.md index c8818d7d505a..5ecec9ef9b89 100644 --- a/book/ru/src/by-example/timer-queue.md +++ b/book/ru/src/by-example/timer-queue.md @@ -49,7 +49,7 @@ Запусе программы на реальном оборудовании создает следующий вывод в консоли: ``` text -{{#include ../../../../ci/expected/schedule.run}} +{{#include ../../../../example-runner/ci/expected/schedule.run}} ``` Когда интерфейс `schedule` используется, среда исполнения использует внутри @@ -73,7 +73,7 @@ `Instant::now` вместо `scheduled` вызвало бы дрейф / колебания. ``` text -{{#include ../../../../ci/expected/periodic.run}} +{{#include ../../../../example-runner/ci/expected/periodic.run}} ``` ## Базовое время @@ -104,5 +104,5 @@ Запуск программы на реальном оборудовании приведет к следующему выводу в консоли: ``` text -{{#include ../../../../ci/expected/baseline.run}} +{{#include ../../../../example-runner/ci/expected/baseline.run}} ``` diff --git a/book/ru/src/by-example/tips.md b/book/ru/src/by-example/tips.md index 7d4fc2f47b17..e919bb0b5851 100644 --- a/book/ru/src/by-example/tips.md +++ b/book/ru/src/by-example/tips.md @@ -22,7 +22,7 @@ ``` console $ cargo run --example generics -{{#include ../../../../ci/expected/generics.run}} +{{#include ../../../../example-runner/ci/expected/generics.run}} ``` ## Условная компиляция @@ -43,7 +43,7 @@ $ cargo run --example generics $ cargo run --example cfg --release $ cargo run --example cfg -{{#include ../../../../ci/expected/cfg.run}} +{{#include ../../../../example-runner/ci/expected/cfg.run}} ``` ## Запуск задач из ОЗУ @@ -75,7 +75,7 @@ RTIC v0.4.x была возможность взаимодействия с др ``` console $ cargo run --example ramfunc -{{#include ../../../../ci/expected/ramfunc.run}} +{{#include ../../../../example-runner/ci/expected/ramfunc.run}} ``` Можно посмотреть на вывод `cargo-nm`, чтобы убедиться, что `bar` расположен в ОЗУ @@ -83,12 +83,12 @@ $ cargo run --example ramfunc ``` console $ cargo nm --example ramfunc --release | grep ' foo::' -{{#include ../../../../ci/expected/ramfunc.run.grep.foo}} +{{#include ../../../../example-runner/ci/expected/ramfunc.run.grep.foo}} ``` ``` console $ cargo nm --example ramfunc --release | grep ' bar::' -{{#include ../../../../ci/expected/ramfunc.run.grep.bar}} +{{#include ../../../../example-runner/ci/expected/ramfunc.run.grep.bar}} ``` ## Обходной путь для быстрой передачи сообщений @@ -113,7 +113,7 @@ $ cargo nm --example ramfunc --release | grep ' bar::' ``` console $ cargo run --example pool -{{#include ../../../../ci/expected/pool.run}} +{{#include ../../../../example-runner/ci/expected/pool.run}} ``` ## Инспектирование раскрываемого кода diff --git a/ci/expected/periodic-at.run b/ci/expected/periodic-at.run deleted file mode 100644 index 54020f9e953d..000000000000 --- a/ci/expected/periodic-at.run +++ /dev/null @@ -1,4 +0,0 @@ -foo Instant { ticks: 0 } -foo Instant { ticks: 100 } -foo Instant { ticks: 200 } -foo Instant { ticks: 300 } diff --git a/ci/expected/periodic-at2.run b/ci/expected/periodic-at2.run deleted file mode 100644 index 47adbef486fa..000000000000 --- a/ci/expected/periodic-at2.run +++ /dev/null @@ -1,7 +0,0 @@ -foo Instant { ticks: 0 } -bar Instant { ticks: 10 } -foo Instant { ticks: 110 } -bar Instant { ticks: 120 } -foo Instant { ticks: 220 } -bar Instant { ticks: 230 } -foo Instant { ticks: 330 } diff --git a/ci/expected/pool.run b/ci/expected/pool.run deleted file mode 100644 index 81f79d41e9aa..000000000000 --- a/ci/expected/pool.run +++ /dev/null @@ -1,2 +0,0 @@ -bar(0x20000088) -foo(0x2000010c) diff --git a/examples-runner/.cargo/config.toml b/examples-runner/.cargo/config.toml new file mode 100644 index 000000000000..8425d873dab4 --- /dev/null +++ b/examples-runner/.cargo/config.toml @@ -0,0 +1,22 @@ +[target.thumbv6m-none-eabi] +runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.thumbv7m-none-eabi] +runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +rustflags = [ + #"-C", "link-arg=-Tlink.x", + "-C", "link-arg=-Tdefmt.x", + "-C", "link-arg=--nmagic", +] + +[build] +# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +# target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) + +[alias] +rrb = "run --release --bin" +brb = "build --release --bin" diff --git a/examples-runner/.gitignore b/examples-runner/.gitignore new file mode 100644 index 000000000000..96ef6c0b944e --- /dev/null +++ b/examples-runner/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/examples-runner/Cargo.toml b/examples-runner/Cargo.toml new file mode 100644 index 000000000000..17ad3c5aa7f7 --- /dev/null +++ b/examples-runner/Cargo.toml @@ -0,0 +1,79 @@ +[package] +# TODO(1) fix `authors` and `name` if you didn't use `cargo-generate` +authors = ["Emil Fresk "] +name = "examples-runner" +edition = "2018" +version = "0.1.0" + +[dependencies] +defmt = { version = "0.3.0", optional = true } +defmt-rtt = { version = "0.3.0", optional = true } +panic-probe = { version = "0.3.0", optional = true } +cortex-m-rtic = { path = ".." } +cortex-m = "0.7" +systick-monotonic = "1" +fugit = { version = "0.3", features = ["defmt"] } +cortex-m-semihosting = { version = "0.3.7", optional = true } +panic-semihosting = { version = "0.5.6", optional = true } +heapless = "0.7" +rtic-monotonic = "1" +bare-metal = "1" + +[dependencies.embedded-ci-pac] +version = "0.1.0" +git = "https://github.com/korken89/embedded-ci-pac.git" + +[workspace] +members = [ + "xtask", +] + +[features] +embedded-ci = ["defmt", "defmt-rtt", "panic-probe/print-defmt"] +qemu = ["cortex-m-semihosting", "panic-semihosting/exit"] + +# cargo build/run +[profile.dev] +codegen-units = 1 +debug = 2 +debug-assertions = true # <- +incremental = false +opt-level = "s" # <- +overflow-checks = true # <- + +# cargo test +[profile.test] +codegen-units = 1 +debug = 2 +debug-assertions = true # <- +incremental = false +opt-level = "s" # <- +overflow-checks = true # <- + +# cargo build/run --release +[profile.release] +codegen-units = 1 +debug = 2 +debug-assertions = false # <- +incremental = false +lto = 'fat' +opt-level = "s" # <- +overflow-checks = false # <- + +# cargo test --release +[profile.bench] +codegen-units = 1 +debug = 2 +debug-assertions = false # <- +incremental = false +lto = 'fat' +opt-level = "s" # <- +overflow-checks = false # <- + +# uncomment this to switch from the crates.io version of defmt to its git version +# check app-template's README for instructions +# [patch.crates-io] +# defmt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" } +# defmt-rtt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" } +# defmt-test = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" } +# panic-probe = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" } diff --git a/examples-runner/LICENSE-APACHE b/examples-runner/LICENSE-APACHE new file mode 100644 index 000000000000..11069edd7901 --- /dev/null +++ b/examples-runner/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/examples-runner/LICENSE-MIT b/examples-runner/LICENSE-MIT new file mode 100644 index 000000000000..468cd79a8f6e --- /dev/null +++ b/examples-runner/LICENSE-MIT @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/examples-runner/build.rs b/examples-runner/build.rs new file mode 100644 index 000000000000..f8514e7a66a9 --- /dev/null +++ b/examples-runner/build.rs @@ -0,0 +1,38 @@ +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put the linker script somewhere the linker can find it + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + #[cfg(feature = "embedded-ci")] + let bytes = include_bytes!("ci.x"); + + #[cfg(feature = "qemu")] + let bytes = include_bytes!("qemu.x"); + + // If running in test mode, use the memory layout that can be flashed + // onto the chip directly + File::create(out.join("memory.x")) + .unwrap() + .write_all(bytes) + .unwrap(); + + #[cfg(feature = "qemu")] + File::create(out.join("defmt.x")) + .unwrap() + .write_all(b"") + .unwrap(); + + println!("cargo:rustc-link-search={}", out.display()); + + // Only re-run the build script when memory.x is changed, + // instead of when any part of the source code changes. + println!("cargo:rerun-if-changed=memory.x"); + println!("cargo:rerun-if-changed=ci.x"); + println!("cargo:rerun-if-changed=qemu.x"); + println!("cargo:rerun-if-changed=link.x"); + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/examples-runner/ci.x b/examples-runner/ci.x new file mode 100644 index 000000000000..f57bc988658b --- /dev/null +++ b/examples-runner/ci.x @@ -0,0 +1,10 @@ +MEMORY +{ + FLASH : ORIGIN = 0x20000000, LENGTH = 22K + RAM : ORIGIN = 0x20000000+22K, LENGTH = 10K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); diff --git a/ci/expected/big-struct-opt.run b/examples-runner/ci/expected/big-struct-opt.run similarity index 100% rename from ci/expected/big-struct-opt.run rename to examples-runner/ci/expected/big-struct-opt.run diff --git a/ci/expected/binds.run b/examples-runner/ci/expected/binds.run similarity index 100% rename from ci/expected/binds.run rename to examples-runner/ci/expected/binds.run diff --git a/ci/expected/cancel-reschedule.run b/examples-runner/ci/expected/cancel-reschedule.run similarity index 100% rename from ci/expected/cancel-reschedule.run rename to examples-runner/ci/expected/cancel-reschedule.run diff --git a/ci/expected/capacity.run b/examples-runner/ci/expected/capacity.run similarity index 100% rename from ci/expected/capacity.run rename to examples-runner/ci/expected/capacity.run diff --git a/ci/expected/cfg-whole-task.run b/examples-runner/ci/expected/cfg-whole-task.run similarity index 100% rename from ci/expected/cfg-whole-task.run rename to examples-runner/ci/expected/cfg-whole-task.run diff --git a/ci/expected/common.run b/examples-runner/ci/expected/common.run similarity index 100% rename from ci/expected/common.run rename to examples-runner/ci/expected/common.run diff --git a/ci/expected/complex.run b/examples-runner/ci/expected/complex.run similarity index 100% rename from ci/expected/complex.run rename to examples-runner/ci/expected/complex.run diff --git a/ci/expected/declared_locals.run b/examples-runner/ci/expected/declared_locals.run similarity index 100% rename from ci/expected/declared_locals.run rename to examples-runner/ci/expected/declared_locals.run diff --git a/ci/expected/destructure.run b/examples-runner/ci/expected/destructure.run similarity index 100% rename from ci/expected/destructure.run rename to examples-runner/ci/expected/destructure.run diff --git a/ci/expected/extern_binds.run b/examples-runner/ci/expected/extern_binds.run similarity index 100% rename from ci/expected/extern_binds.run rename to examples-runner/ci/expected/extern_binds.run diff --git a/ci/expected/extern_spawn.run b/examples-runner/ci/expected/extern_spawn.run similarity index 100% rename from ci/expected/extern_spawn.run rename to examples-runner/ci/expected/extern_spawn.run diff --git a/ci/expected/generics.run b/examples-runner/ci/expected/generics.run similarity index 100% rename from ci/expected/generics.run rename to examples-runner/ci/expected/generics.run diff --git a/ci/expected/hardware.run b/examples-runner/ci/expected/hardware.run similarity index 100% rename from ci/expected/hardware.run rename to examples-runner/ci/expected/hardware.run diff --git a/ci/expected/idle-wfi.run b/examples-runner/ci/expected/idle-wfi.run similarity index 100% rename from ci/expected/idle-wfi.run rename to examples-runner/ci/expected/idle-wfi.run diff --git a/ci/expected/idle.run b/examples-runner/ci/expected/idle.run similarity index 100% rename from ci/expected/idle.run rename to examples-runner/ci/expected/idle.run diff --git a/ci/expected/init.run b/examples-runner/ci/expected/init.run similarity index 100% rename from ci/expected/init.run rename to examples-runner/ci/expected/init.run diff --git a/ci/expected/locals.run b/examples-runner/ci/expected/locals.run similarity index 100% rename from ci/expected/locals.run rename to examples-runner/ci/expected/locals.run diff --git a/ci/expected/lock-free.run b/examples-runner/ci/expected/lock-free.run similarity index 100% rename from ci/expected/lock-free.run rename to examples-runner/ci/expected/lock-free.run diff --git a/ci/expected/lock.run b/examples-runner/ci/expected/lock.run similarity index 100% rename from ci/expected/lock.run rename to examples-runner/ci/expected/lock.run diff --git a/ci/expected/message.run b/examples-runner/ci/expected/message.run similarity index 100% rename from ci/expected/message.run rename to examples-runner/ci/expected/message.run diff --git a/ci/expected/message_passing.run b/examples-runner/ci/expected/message_passing.run similarity index 100% rename from ci/expected/message_passing.run rename to examples-runner/ci/expected/message_passing.run diff --git a/ci/expected/multilock.run b/examples-runner/ci/expected/multilock.run similarity index 100% rename from ci/expected/multilock.run rename to examples-runner/ci/expected/multilock.run diff --git a/ci/expected/not-sync.run b/examples-runner/ci/expected/not-sync.run similarity index 100% rename from ci/expected/not-sync.run rename to examples-runner/ci/expected/not-sync.run diff --git a/ci/expected/only-shared-access.run b/examples-runner/ci/expected/only-shared-access.run similarity index 100% rename from ci/expected/only-shared-access.run rename to examples-runner/ci/expected/only-shared-access.run diff --git a/examples-runner/ci/expected/periodic-at.run b/examples-runner/ci/expected/periodic-at.run new file mode 100644 index 000000000000..7be173d28e7b --- /dev/null +++ b/examples-runner/ci/expected/periodic-at.run @@ -0,0 +1,4 @@ +foo ticks: 0 +foo ticks: 100 +foo ticks: 200 +foo ticks: 300 diff --git a/examples-runner/ci/expected/periodic-at2.run b/examples-runner/ci/expected/periodic-at2.run new file mode 100644 index 000000000000..1fdce8c1c153 --- /dev/null +++ b/examples-runner/ci/expected/periodic-at2.run @@ -0,0 +1,7 @@ +foo ticks: 0 +bar ticks: 10 +foo ticks: 110 +bar ticks: 120 +foo ticks: 220 +bar ticks: 230 +foo ticks: 330 diff --git a/ci/expected/periodic.run b/examples-runner/ci/expected/periodic.run similarity index 100% rename from ci/expected/periodic.run rename to examples-runner/ci/expected/periodic.run diff --git a/ci/expected/peripherals-taken.run b/examples-runner/ci/expected/peripherals-taken.run similarity index 100% rename from ci/expected/peripherals-taken.run rename to examples-runner/ci/expected/peripherals-taken.run diff --git a/examples-runner/ci/expected/pool.run b/examples-runner/ci/expected/pool.run new file mode 100644 index 000000000000..128976523b6c --- /dev/null +++ b/examples-runner/ci/expected/pool.run @@ -0,0 +1,2 @@ +bar +foo diff --git a/ci/expected/preempt.run b/examples-runner/ci/expected/preempt.run similarity index 100% rename from ci/expected/preempt.run rename to examples-runner/ci/expected/preempt.run diff --git a/ci/expected/ramfunc.run b/examples-runner/ci/expected/ramfunc.run similarity index 100% rename from ci/expected/ramfunc.run rename to examples-runner/ci/expected/ramfunc.run diff --git a/ci/expected/ramfunc.run.grep.bar b/examples-runner/ci/expected/ramfunc.run.grep.bar similarity index 100% rename from ci/expected/ramfunc.run.grep.bar rename to examples-runner/ci/expected/ramfunc.run.grep.bar diff --git a/ci/expected/ramfunc.run.grep.foo b/examples-runner/ci/expected/ramfunc.run.grep.foo similarity index 100% rename from ci/expected/ramfunc.run.grep.foo rename to examples-runner/ci/expected/ramfunc.run.grep.foo diff --git a/ci/expected/resource-user-struct.run b/examples-runner/ci/expected/resource-user-struct.run similarity index 100% rename from ci/expected/resource-user-struct.run rename to examples-runner/ci/expected/resource-user-struct.run diff --git a/ci/expected/schedule.run b/examples-runner/ci/expected/schedule.run similarity index 100% rename from ci/expected/schedule.run rename to examples-runner/ci/expected/schedule.run diff --git a/ci/expected/shared.run b/examples-runner/ci/expected/shared.run similarity index 100% rename from ci/expected/shared.run rename to examples-runner/ci/expected/shared.run diff --git a/ci/expected/smallest.run b/examples-runner/ci/expected/smallest.run similarity index 100% rename from ci/expected/smallest.run rename to examples-runner/ci/expected/smallest.run diff --git a/ci/expected/spawn.run b/examples-runner/ci/expected/spawn.run similarity index 100% rename from ci/expected/spawn.run rename to examples-runner/ci/expected/spawn.run diff --git a/ci/expected/static.run b/examples-runner/ci/expected/static.run similarity index 100% rename from ci/expected/static.run rename to examples-runner/ci/expected/static.run diff --git a/ci/expected/t-binds.run b/examples-runner/ci/expected/t-binds.run similarity index 100% rename from ci/expected/t-binds.run rename to examples-runner/ci/expected/t-binds.run diff --git a/ci/expected/t-cfg-resources.run b/examples-runner/ci/expected/t-cfg-resources.run similarity index 100% rename from ci/expected/t-cfg-resources.run rename to examples-runner/ci/expected/t-cfg-resources.run diff --git a/ci/expected/t-htask-main.run b/examples-runner/ci/expected/t-htask-main.run similarity index 100% rename from ci/expected/t-htask-main.run rename to examples-runner/ci/expected/t-htask-main.run diff --git a/ci/expected/t-idle-main.run b/examples-runner/ci/expected/t-idle-main.run similarity index 100% rename from ci/expected/t-idle-main.run rename to examples-runner/ci/expected/t-idle-main.run diff --git a/ci/expected/t-late-not-send.run b/examples-runner/ci/expected/t-late-not-send.run similarity index 100% rename from ci/expected/t-late-not-send.run rename to examples-runner/ci/expected/t-late-not-send.run diff --git a/ci/expected/t-schedule.run b/examples-runner/ci/expected/t-schedule.run similarity index 100% rename from ci/expected/t-schedule.run rename to examples-runner/ci/expected/t-schedule.run diff --git a/ci/expected/t-spawn.run b/examples-runner/ci/expected/t-spawn.run similarity index 100% rename from ci/expected/t-spawn.run rename to examples-runner/ci/expected/t-spawn.run diff --git a/ci/expected/task.run b/examples-runner/ci/expected/task.run similarity index 100% rename from ci/expected/task.run rename to examples-runner/ci/expected/task.run diff --git a/examples-runner/examples_to_runner.sh b/examples-runner/examples_to_runner.sh new file mode 100644 index 000000000000..0bbbd6312801 --- /dev/null +++ b/examples-runner/examples_to_runner.sh @@ -0,0 +1,9 @@ + +# Convert old examples to CI runner +cp ../examples/* ./src/bin/ +sd "use panic_semihosting as _;" "use examples_runner as _;" src/bin/* +sd "lm3s6965" "examples_runner::pac" src/bin/* +sd "use cortex_m_semihosting::.*" "use examples_runner::{println, exit};" src/bin/* +sd "debug::exit.*" "exit();" src/bin/* +sd "hprintln" "println" src/bin/* +sd "\"\).unwrap\(\)" "\")" src/bin/* diff --git a/examples-runner/qemu.x b/examples-runner/qemu.x new file mode 100644 index 000000000000..6e14429c14ba --- /dev/null +++ b/examples-runner/qemu.x @@ -0,0 +1,13 @@ +MEMORY +{ + FLASH : ORIGIN = 0x00000000, LENGTH = 32K + RAM : ORIGIN = 0x20000000, LENGTH = 32K + # RAM only runner + # FLASH : ORIGIN = 0x20000000, LENGTH = 22K + # RAM : ORIGIN = 0x20000000+22K, LENGTH = 10K +} + +/* This is where the call stack will be allocated. */ +/* The stack is of the full descending type. */ +/* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ +_stack_start = ORIGIN(RAM) + LENGTH(RAM); diff --git a/examples/big-struct-opt.rs b/examples-runner/src/bin/big-struct-opt.rs similarity index 87% rename from examples/big-struct-opt.rs rename to examples-runner/src/bin/big-struct-opt.rs index bbc2535a3903..8ff7c2b8a16f 100644 --- a/examples/big-struct-opt.rs +++ b/examples-runner/src/bin/big-struct-opt.rs @@ -6,7 +6,7 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; /// Some big struct pub struct BigStruct { @@ -20,11 +20,11 @@ impl BigStruct { } } -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { use super::BigStruct; use core::mem::MaybeUninit; - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared { @@ -42,8 +42,6 @@ mod app { &mut *cx.local.bs.as_mut_ptr() }; - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - ( Shared { // assign the reference so we can use the resource @@ -54,6 +52,11 @@ mod app { ) } + #[idle] + fn idle(_: idle::Context) -> ! { + exit(); + } + #[task(binds = UART0, shared = [big_struct])] fn task(_: task::Context) {} } diff --git a/examples/binds.rs b/examples-runner/src/bin/binds.rs similarity index 65% rename from examples/binds.rs rename to examples-runner/src/bin/binds.rs index 56565cbec989..30aae4c8127e 100644 --- a/examples/binds.rs +++ b/examples-runner/src/bin/binds.rs @@ -5,13 +5,13 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; // `examples/interrupt.rs` rewritten to use `binds` -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::{println, exit}; + use examples_runner::pac::Interrupt; #[shared] struct Shared {} @@ -23,33 +23,28 @@ mod app { fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { rtic::pend(Interrupt::UART0); - hprintln!("init").unwrap(); + println!("init"); (Shared {}, Local {}, init::Monotonics()) } #[idle] fn idle(_: idle::Context) -> ! { - hprintln!("idle").unwrap(); + println!("idle"); rtic::pend(Interrupt::UART0); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - loop { - cortex_m::asm::nop(); - } + exit(); } #[task(binds = UART0, local = [times: u32 = 0])] fn foo(cx: foo::Context) { *cx.local.times += 1; - hprintln!( + println!( "foo called {} time{}", *cx.local.times, if *cx.local.times > 1 { "s" } else { "" } - ) - .unwrap(); + ); } } diff --git a/examples/cancel-reschedule.rs b/examples-runner/src/bin/cancel-reschedule.rs similarity index 80% rename from examples/cancel-reschedule.rs rename to examples-runner/src/bin/cancel-reschedule.rs index a38a9c4eae65..0f9398c4f824 100644 --- a/examples/cancel-reschedule.rs +++ b/examples-runner/src/bin/cancel-reschedule.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use systick_monotonic::*; #[monotonic(binds = SysTick, default = true)] @@ -28,7 +28,7 @@ mod app { // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) let mono = Systick::new(systick, 12_000_000); - hprintln!("init").ok(); + println!("init"); // Schedule `foo` to run 1 second in the future foo::spawn_after(1.secs()).unwrap(); @@ -42,7 +42,7 @@ mod app { #[task] fn foo(_: foo::Context) { - hprintln!("foo").ok(); + println!("foo"); // Schedule `bar` to run 2 seconds in the future (1 second after foo runs) let spawn_handle = baz::spawn_after(2.secs()).unwrap(); @@ -51,7 +51,7 @@ mod app { #[task] fn bar(_: bar::Context, baz_handle: baz::SpawnHandle, do_reschedule: bool) { - hprintln!("bar").ok(); + println!("bar"); if do_reschedule { // Reschedule baz 2 seconds from now, instead of the original 1 second @@ -61,13 +61,13 @@ mod app { } else { // Or cancel it baz_handle.cancel().unwrap(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } } #[task] fn baz(_: baz::Context) { - hprintln!("baz").ok(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + println!("baz"); + exit(); } } diff --git a/examples/capacity.rs b/examples-runner/src/bin/capacity.rs similarity index 69% rename from examples/capacity.rs rename to examples-runner/src/bin/capacity.rs index a617269869b0..46d8655f0827 100644 --- a/examples/capacity.rs +++ b/examples-runner/src/bin/capacity.rs @@ -5,12 +5,12 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::{println, exit}; + use examples_runner::pac::Interrupt; #[shared] struct Shared {} @@ -37,13 +37,13 @@ mod app { #[task(capacity = 4)] fn foo(_: foo::Context, x: u32) { - hprintln!("foo({})", x).unwrap(); + println!("foo({})", x); } #[task] fn bar(_: bar::Context) { - hprintln!("bar").unwrap(); + println!("bar"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } } diff --git a/examples/cfg-whole-task.rs b/examples-runner/src/bin/cfg-whole-task.rs similarity index 82% rename from examples/cfg-whole-task.rs rename to examples-runner/src/bin/cfg-whole-task.rs index f41866db476b..355785c00e5a 100644 --- a/examples/cfg-whole-task.rs +++ b/examples-runner/src/bin/cfg-whole-task.rs @@ -5,13 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0, QEI0])] mod app { - use cortex_m_semihosting::debug; - #[cfg(debug_assertions)] - use cortex_m_semihosting::hprintln; + use examples_runner::exit; #[shared] struct Shared { @@ -41,11 +39,11 @@ mod app { #[idle] fn idle(_: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - loop { - cortex_m::asm::nop(); - } + // loop { + // cortex_m::asm::nop(); + // } } #[task(capacity = 2, shared = [count])] @@ -84,11 +82,10 @@ mod app { #[cfg(debug_assertions)] #[task(capacity = 2)] fn log(_: log::Context, n: u32) { - hprintln!( + println!( "foo has been called {} time{}", n, if n == 1 { "" } else { "s" } - ) - .ok(); + ); } } diff --git a/examples/common.rs b/examples-runner/src/bin/common.rs similarity index 71% rename from examples/common.rs rename to examples-runner/src/bin/common.rs index 1fe671e61ac4..f161298985e4 100644 --- a/examples/common.rs +++ b/examples-runner/src/bin/common.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0, QEI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use systick_monotonic::*; // Implements the `Monotonic` trait // A monotonic timer to enable scheduling in RTIC @@ -31,12 +31,7 @@ mod app { } #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; - - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mono = Systick::new(systick, 12_000_000); - + fn init(_cx: init::Context) -> (Shared, Local, init::Monotonics) { // Spawn the task `foo` directly after `init` finishes foo::spawn().unwrap(); @@ -44,17 +39,17 @@ mod app { // by the `#[monotonic(..)]` above bar::spawn_after(1.secs()).unwrap(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - ( - // Initialization of shared resources - Shared { s1: 0, s2: 1 }, - // Initialization of task local resources - Local { l1: 2, l2: 3 }, - // Move the monotonic timer to the RTIC run-time, this enables - // scheduling - init::Monotonics(mono), - ) + exit(); + + // ( + // // Initialization of shared resources + // Shared { s1: 0, s2: 1 }, + // // Initialization of task local resources + // Local { l1: 2, l2: 3 }, + // // Move the monotonic timer to the RTIC run-time, this enables + // // scheduling + // init::Monotonics(mono), + // ) } // Background task, runs whenever no other tasks are running @@ -73,7 +68,7 @@ mod app { // This task is only spawned once in `init`, hence this task will run // only once - hprintln!("foo").ok(); + println!("foo"); } // Software task, also not bound to a hardware interrupt @@ -81,7 +76,7 @@ mod app { // The resources `s1` and `s2` are shared between all other tasks. #[task(shared = [s1, s2], local = [l2])] fn bar(_: bar::Context) { - hprintln!("bar").ok(); + println!("bar"); // Run `bar` once per second bar::spawn_after(1.secs()).unwrap(); @@ -97,6 +92,6 @@ mod app { // Note that RTIC does NOT clear the interrupt flag, this is up to the // user - hprintln!("UART0 interrupt!").ok(); + println!("UART0 interrupt!"); } } diff --git a/examples/complex.rs b/examples-runner/src/bin/complex.rs similarity index 63% rename from examples/complex.rs rename to examples-runner/src/bin/complex.rs index e5cf6dbea30c..f4b453a0b9db 100644 --- a/examples/complex.rs +++ b/examples-runner/src/bin/complex.rs @@ -5,13 +5,13 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::pac::Interrupt; + use examples_runner::{exit, println}; #[shared] struct Shared { @@ -25,7 +25,7 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - hprintln!("init").unwrap(); + println!("init"); ( Shared { @@ -40,37 +40,37 @@ mod app { #[idle(shared = [s2, s3])] fn idle(mut cx: idle::Context) -> ! { - hprintln!("idle p0 started").ok(); + println!("idle p0 started"); rtic::pend(Interrupt::GPIOC); cx.shared.s3.lock(|s| { - hprintln!("idle enter lock s3 {}", s).ok(); - hprintln!("idle pend t0").ok(); + println!("idle enter lock s3 {}", s); + println!("idle pend t0"); rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 3 - hprintln!("idle pend t1").ok(); + println!("idle pend t1"); rtic::pend(Interrupt::GPIOB); // t1 p3, with shared ceiling 3 - hprintln!("idle pend t2").ok(); + println!("idle pend t2"); rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing - hprintln!("idle still in lock s3 {}", s).ok(); + println!("idle still in lock s3 {}", s); }); - hprintln!("\nback in idle").ok(); + println!("\nback in idle"); cx.shared.s2.lock(|s| { - hprintln!("enter lock s2 {}", s).ok(); - hprintln!("idle pend t0").ok(); + println!("enter lock s2 {}", s); + println!("idle pend t0"); rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2 - hprintln!("idle pend t1").ok(); + println!("idle pend t1"); rtic::pend(Interrupt::GPIOB); // t1 p3, no sharing - hprintln!("idle pend t2").ok(); + println!("idle pend t2"); rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing - hprintln!("idle still in lock s2 {}", s).ok(); + println!("idle still in lock s2 {}", s); }); - hprintln!("\nidle exit").ok(); + println!("\nidle exit"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - loop { - cortex_m::asm::nop(); - } + // loop { + // cortex_m::asm::nop(); + // } } #[task(binds = GPIOA, priority = 2, local = [times: u32 = 0], shared = [s2, s3])] @@ -78,13 +78,12 @@ mod app { // Safe access to local `static mut` variable *cx.local.times += 1; - hprintln!( + println!( "t0 p2 called {} time{}", *cx.local.times, if *cx.local.times > 1 { "s" } else { "" } - ) - .ok(); - hprintln!("t0 p2 exit").ok(); + ); + println!("t0 p2 exit"); } #[task(binds = GPIOB, priority = 3, local = [times: u32 = 0], shared = [s3, s4])] @@ -92,23 +91,22 @@ mod app { // Safe access to local `static mut` variable *cx.local.times += 1; - hprintln!( + println!( "t1 p3 called {} time{}", *cx.local.times, if *cx.local.times > 1 { "s" } else { "" } - ) - .ok(); + ); cx.shared.s4.lock(|s| { - hprintln!("t1 enter lock s4 {}", s).ok(); - hprintln!("t1 pend t0").ok(); + println!("t1 enter lock s4 {}", s); + println!("t1 pend t0"); rtic::pend(Interrupt::GPIOA); // t0 p2, with shared ceiling 2 - hprintln!("t1 pend t2").ok(); + println!("t1 pend t2"); rtic::pend(Interrupt::GPIOC); // t2 p4, no sharing - hprintln!("t1 still in lock s4 {}", s).ok(); + println!("t1 still in lock s4 {}", s); }); - hprintln!("t1 p3 exit").ok(); + println!("t1 p3 exit"); } #[task(binds = GPIOC, priority = 4, local = [times: u32 = 0], shared = [s4])] @@ -116,17 +114,16 @@ mod app { // Safe access to local `static mut` variable *cx.local.times += 1; - hprintln!( + println!( "t2 p4 called {} time{}", *cx.local.times, if *cx.local.times > 1 { "s" } else { "" } - ) - .unwrap(); + ); cx.shared.s4.lock(|s| { - hprintln!("enter lock s4 {}", s).ok(); + println!("enter lock s4 {}", s); *s += 1; }); - hprintln!("t3 p4 exit").ok(); + println!("t3 p4 exit"); } } diff --git a/examples/declared_locals.rs b/examples-runner/src/bin/declared_locals.rs similarity index 78% rename from examples/declared_locals.rs rename to examples-runner/src/bin/declared_locals.rs index 52d354bc9a72..5873f2d59b48 100644 --- a/examples/declared_locals.rs +++ b/examples-runner/src/bin/declared_locals.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [UART0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [UART0])] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared {} @@ -22,9 +22,9 @@ mod app { // Locals in `#[init]` have 'static lifetime let _a: &'static mut u32 = cx.local.a; - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - (Shared {}, Local {}, init::Monotonics()) + // (Shared {}, Local {}, init::Monotonics()) } #[idle(local = [a: u32 = 0])] diff --git a/examples/destructure.rs b/examples-runner/src/bin/destructure.rs similarity index 71% rename from examples/destructure.rs rename to examples-runner/src/bin/destructure.rs index 6019c225cca3..7ecc47b84e3c 100644 --- a/examples/destructure.rs +++ b/examples-runner/src/bin/destructure.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [UART0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [UART0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared { @@ -31,8 +31,8 @@ mod app { #[idle] fn idle(_: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - loop {} + exit(); + // loop {} } // Direct destructure @@ -42,7 +42,7 @@ mod app { let b = cx.shared.b; let c = cx.shared.c; - hprintln!("foo: a = {}, b = {}, c = {}", a, b, c).unwrap(); + println!("foo: a = {}, b = {}, c = {}", a, b, c); } // De-structure-ing syntax @@ -50,6 +50,6 @@ mod app { fn bar(cx: bar::Context) { let bar::SharedResources { a, b, c } = cx.shared; - hprintln!("bar: a = {}, b = {}, c = {}", a, b, c).unwrap(); + println!("bar: a = {}, b = {}, c = {}", a, b, c); } } diff --git a/examples/extern_binds.rs b/examples-runner/src/bin/extern_binds.rs similarity index 62% rename from examples/extern_binds.rs rename to examples-runner/src/bin/extern_binds.rs index 4dc6633c5dee..efe02e88dace 100644 --- a/examples/extern_binds.rs +++ b/examples-runner/src/bin/extern_binds.rs @@ -5,19 +5,19 @@ #![no_main] #![no_std] -use cortex_m_semihosting::hprintln; -use panic_semihosting as _; +use examples_runner as _; +use examples_runner::println; // Free function implementing the interrupt bound task `foo`. fn foo(_: app::foo::Context) { - hprintln!("foo called").ok(); + println!("foo called"); } -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { use crate::foo; - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::pac::Interrupt; + use examples_runner::{exit, println}; #[shared] struct Shared {} @@ -29,22 +29,22 @@ mod app { fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { rtic::pend(Interrupt::UART0); - hprintln!("init").unwrap(); + println!("init"); (Shared {}, Local {}, init::Monotonics()) } #[idle] fn idle(_: idle::Context) -> ! { - hprintln!("idle").unwrap(); + println!("idle"); rtic::pend(Interrupt::UART0); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - loop { - cortex_m::asm::nop(); - } + // loop { + // cortex_m::asm::nop(); + // } } extern "Rust" { diff --git a/examples/extern_spawn.rs b/examples-runner/src/bin/extern_spawn.rs similarity index 72% rename from examples/extern_spawn.rs rename to examples-runner/src/bin/extern_spawn.rs index 7f9b5a5f9b3d..8342756e5c55 100644 --- a/examples/extern_spawn.rs +++ b/examples-runner/src/bin/extern_spawn.rs @@ -5,19 +5,19 @@ #![no_main] #![no_std] -use cortex_m_semihosting::{debug, hprintln}; -use panic_semihosting as _; +use examples_runner::{println, exit}; +use examples_runner as _; // Free function implementing the spawnable task `foo`. fn foo(_c: app::foo::Context, x: i32, y: u32) { - hprintln!("foo {}, {}", x, y).unwrap(); + println!("foo {}, {}", x, y); if x == 2 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } app::foo::spawn(2, 3).unwrap(); } -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { use crate::foo; diff --git a/examples/generics.rs b/examples-runner/src/bin/generics.rs similarity index 74% rename from examples/generics.rs rename to examples-runner/src/bin/generics.rs index 72b861ba919e..01fb399e4ad0 100644 --- a/examples/generics.rs +++ b/examples-runner/src/bin/generics.rs @@ -5,14 +5,14 @@ #![no_main] #![no_std] -use cortex_m_semihosting::hprintln; -use panic_semihosting as _; +use examples_runner as _; +use examples_runner::println; use rtic::Mutex; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::pac::Interrupt; + use examples_runner::{exit, println}; #[shared] struct Shared { @@ -32,19 +32,19 @@ mod app { #[task(binds = UART0, shared = [shared], local = [state: u32 = 0])] fn uart0(c: uart0::Context) { - hprintln!("UART0(STATE = {})", *c.local.state).unwrap(); + println!("UART0(STATE = {})", *c.local.state); // second argument has type `shared::shared` super::advance(c.local.state, c.shared.shared); rtic::pend(Interrupt::UART1); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } #[task(binds = UART1, priority = 2, shared = [shared], local = [state: u32 = 0])] fn uart1(c: uart1::Context) { - hprintln!("UART1(STATE = {})", *c.local.state).unwrap(); + println!("UART1(STATE = {})", *c.local.state); // second argument has type `shared::shared` super::advance(c.local.state, c.shared.shared); @@ -61,5 +61,5 @@ fn advance(state: &mut u32, mut shared: impl Mutex) { (old, *shared) }); - hprintln!("shared: {} -> {}", old, new).unwrap(); + println!("shared: {} -> {}", old, new); } diff --git a/examples/hardware.rs b/examples-runner/src/bin/hardware.rs similarity index 72% rename from examples/hardware.rs rename to examples-runner/src/bin/hardware.rs index 60632247fb9d..4b6662aa345b 100644 --- a/examples/hardware.rs +++ b/examples-runner/src/bin/hardware.rs @@ -5,12 +5,12 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::pac::Interrupt; + use examples_runner::{exit, println}; #[shared] struct Shared {} @@ -24,7 +24,7 @@ mod app { // `init` returns because interrupts are disabled rtic::pend(Interrupt::UART0); // equivalent to NVIC::pend - hprintln!("init").unwrap(); + println!("init"); (Shared {}, Local {}, init::Monotonics()) } @@ -33,15 +33,15 @@ mod app { fn idle(_: idle::Context) -> ! { // interrupts are enabled again; the `UART0` handler runs at this point - hprintln!("idle").unwrap(); + println!("idle"); rtic::pend(Interrupt::UART0); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - loop { - cortex_m::asm::nop(); - } + // loop { + // cortex_m::asm::nop(); + // } } #[task(binds = UART0, local = [times: u32 = 0])] @@ -49,11 +49,10 @@ mod app { // Safe access to local `static mut` variable *cx.local.times += 1; - hprintln!( + println!( "UART0 called {} time{}", *cx.local.times, if *cx.local.times > 1 { "s" } else { "" } - ) - .unwrap(); + ); } } diff --git a/examples/idle-wfi.rs b/examples-runner/src/bin/idle-wfi.rs similarity index 54% rename from examples/idle-wfi.rs rename to examples-runner/src/bin/idle-wfi.rs index 4a8a8dee2b49..b98e787caf2d 100644 --- a/examples/idle-wfi.rs +++ b/examples-runner/src/bin/idle-wfi.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -19,7 +19,7 @@ mod app { #[init] fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics) { - hprintln!("init").unwrap(); + println!("init"); // Set the ARM SLEEPONEXIT bit to go to sleep after handling interrupts // See https://developer.arm.com/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit @@ -33,15 +33,15 @@ mod app { // Locals in idle have lifetime 'static let _x: &'static mut u32 = cx.local.x; - hprintln!("idle").unwrap(); + println!("idle"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - loop { - // Now Wait For Interrupt is used instead of a busy-wait loop - // to allow MCU to sleep between interrupts - // https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/WFI - rtic::export::wfi() - } + // loop { + // // Now Wait For Interrupt is used instead of a busy-wait loop + // // to allow MCU to sleep between interrupts + // // https://developer.arm.com/documentation/ddi0406/c/Application-Level-Architecture/Instruction-Details/Alphabetical-list-of-instructions/WFI + // rtic::export::wfi() + // } } } diff --git a/examples/idle.rs b/examples-runner/src/bin/idle.rs similarity index 61% rename from examples/idle.rs rename to examples-runner/src/bin/idle.rs index 55d6b1535283..c74999e423a7 100644 --- a/examples/idle.rs +++ b/examples-runner/src/bin/idle.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -19,7 +19,7 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - hprintln!("init").unwrap(); + println!("init"); (Shared {}, Local {}, init::Monotonics()) } @@ -29,12 +29,12 @@ mod app { // Locals in idle have lifetime 'static let _x: &'static mut u32 = cx.local.x; - hprintln!("idle").unwrap(); + println!("idle"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - loop { - cortex_m::asm::nop(); - } + // loop { + // cortex_m::asm::nop(); + // } } } diff --git a/examples/init.rs b/examples-runner/src/bin/init.rs similarity index 66% rename from examples/init.rs rename to examples-runner/src/bin/init.rs index b8a5bc5b989e..dc8e572975a4 100644 --- a/examples/init.rs +++ b/examples-runner/src/bin/init.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, peripherals = true)] +#[rtic::app(device = examples_runner::pac, peripherals = true)] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -23,7 +23,7 @@ mod app { let _core: cortex_m::Peripherals = cx.core; // Device specific peripherals - let _device: lm3s6965::Peripherals = cx.device; + let _device: examples_runner::pac::Peripherals = cx.device; // Locals in `init` have 'static lifetime let _x: &'static mut u32 = cx.local.x; @@ -32,10 +32,10 @@ mod app { // to indicate that this is a critical seciton let _cs_token: bare_metal::CriticalSection = cx.cs; - hprintln!("init").unwrap(); + println!("init"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - (Shared {}, Local {}, init::Monotonics()) + // (Shared {}, Local {}, init::Monotonics()) } } diff --git a/examples/locals.rs b/examples-runner/src/bin/locals.rs similarity index 79% rename from examples/locals.rs rename to examples-runner/src/bin/locals.rs index aa5d0fee3061..93663d0e1eb6 100644 --- a/examples/locals.rs +++ b/examples-runner/src/bin/locals.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])] +#[rtic::app(device = examples_runner::pac, dispatchers = [UART0, UART1])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -45,9 +45,9 @@ mod app { let local_to_idle = cx.local.local_to_idle; *local_to_idle += 1; - hprintln!("idle: local_to_idle = {}", local_to_idle).unwrap(); + println!("idle: local_to_idle = {}", local_to_idle); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); // error: no `local_to_foo` field in `idle::LocalResources` // _cx.local.local_to_foo += 1; @@ -55,9 +55,9 @@ mod app { // error: no `local_to_bar` field in `idle::LocalResources` // _cx.local.local_to_bar += 1; - loop { - cortex_m::asm::nop(); - } + // loop { + // cortex_m::asm::nop(); + // } } // `local_to_foo` can only be accessed from this context @@ -69,7 +69,7 @@ mod app { // error: no `local_to_bar` field in `foo::LocalResources` // cx.local.local_to_bar += 1; - hprintln!("foo: local_to_foo = {}", local_to_foo).unwrap(); + println!("foo: local_to_foo = {}", local_to_foo); } // `local_to_bar` can only be accessed from this context @@ -81,6 +81,6 @@ mod app { // error: no `local_to_foo` field in `bar::LocalResources` // cx.local.local_to_foo += 1; - hprintln!("bar: local_to_bar = {}", local_to_bar).unwrap(); + println!("bar: local_to_bar = {}", local_to_bar); } } diff --git a/examples/lock-free.rs b/examples-runner/src/bin/lock-free.rs similarity index 74% rename from examples/lock-free.rs rename to examples-runner/src/bin/lock-free.rs index ea6ff1bf37bb..2281dd556743 100644 --- a/examples/lock-free.rs +++ b/examples-runner/src/bin/lock-free.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])] +#[rtic::app(device = examples_runner::pac, dispatchers = [GPIOA])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared { @@ -33,7 +33,7 @@ mod app { *c.shared.counter += 1; // <- no lock API required let counter = *c.shared.counter; - hprintln!(" foo = {}", counter).unwrap(); + println!(" foo = {}", counter); } #[task(shared = [counter])] // <- same priority @@ -42,8 +42,8 @@ mod app { *c.shared.counter += 1; // <- no lock API required let counter = *c.shared.counter; - hprintln!(" bar = {}", counter).unwrap(); + println!(" bar = {}", counter); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } } diff --git a/examples/lock.rs b/examples-runner/src/bin/lock.rs similarity index 76% rename from examples/lock.rs rename to examples-runner/src/bin/lock.rs index f1a16968ce6a..6ad0e2a0ccf1 100644 --- a/examples/lock.rs +++ b/examples-runner/src/bin/lock.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [GPIOA, GPIOB, GPIOC])] +#[rtic::app(device = examples_runner::pac, dispatchers = [GPIOA, GPIOB, GPIOC])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared { @@ -29,7 +29,7 @@ mod app { // when omitted priority is assumed to be `1` #[task(shared = [shared])] fn foo(mut c: foo::Context) { - hprintln!("A").unwrap(); + println!("A"); // the lower priority task requires a critical section to access the data c.shared.shared.lock(|shared| { @@ -39,7 +39,7 @@ mod app { // bar will *not* run right now due to the critical section bar::spawn().unwrap(); - hprintln!("B - shared = {}", *shared).unwrap(); + println!("B - shared = {}", *shared); // baz does not contend for `shared` so it's allowed to run now baz::spawn().unwrap(); @@ -47,9 +47,9 @@ mod app { // critical section is over: bar can now start - hprintln!("E").unwrap(); + println!("E"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } #[task(priority = 2, shared = [shared])] @@ -61,11 +61,11 @@ mod app { *shared }); - hprintln!("D - shared = {}", shared).unwrap(); + println!("D - shared = {}", shared); } #[task(priority = 3)] fn baz(_: baz::Context) { - hprintln!("C").unwrap(); + println!("C"); } } diff --git a/examples/message.rs b/examples-runner/src/bin/message.rs similarity index 69% rename from examples/message.rs rename to examples-runner/src/bin/message.rs index 76c5675aaa75..278b7d04f494 100644 --- a/examples/message.rs +++ b/examples-runner/src/bin/message.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -26,7 +26,7 @@ mod app { #[task(local = [count: u32 = 0])] fn foo(cx: foo::Context) { - hprintln!("foo").unwrap(); + println!("foo"); bar::spawn(*cx.local.count).unwrap(); *cx.local.count += 1; @@ -34,17 +34,17 @@ mod app { #[task] fn bar(_: bar::Context, x: u32) { - hprintln!("bar({})", x).unwrap(); + println!("bar({})", x); baz::spawn(x + 1, x + 2).unwrap(); } #[task] fn baz(_: baz::Context, x: u32, y: u32) { - hprintln!("baz({}, {})", x, y).unwrap(); + println!("baz({}, {})", x, y); if x + y > 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } foo::spawn().unwrap(); diff --git a/examples/message_passing.rs b/examples-runner/src/bin/message_passing.rs similarity index 71% rename from examples/message_passing.rs rename to examples-runner/src/bin/message_passing.rs index ffa95371270f..106c8e5a353d 100644 --- a/examples/message_passing.rs +++ b/examples-runner/src/bin/message_passing.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -29,9 +29,9 @@ mod app { #[task(capacity = 3)] fn foo(_c: foo::Context, x: i32, y: u32) { - hprintln!("foo {}, {}", x, y).unwrap(); + println!("foo {}, {}", x, y); if x == 2 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } } } diff --git a/examples/multilock.rs b/examples-runner/src/bin/multilock.rs similarity index 76% rename from examples/multilock.rs rename to examples-runner/src/bin/multilock.rs index d99bae695eb2..aba5884d7e35 100644 --- a/examples/multilock.rs +++ b/examples-runner/src/bin/multilock.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [GPIOA])] +#[rtic::app(device = examples_runner::pac, dispatchers = [GPIOA])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared { @@ -48,9 +48,9 @@ mod app { *s2 += 1; *s3 += 1; - hprintln!("Multiple locks, s1: {}, s2: {}, s3: {}", *s1, *s2, *s3).unwrap(); + println!("Multiple locks, s1: {}, s2: {}, s3: {}", *s1, *s2, *s3); }); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } } diff --git a/examples/not-sync.rs b/examples-runner/src/bin/not-sync.rs similarity index 81% rename from examples/not-sync.rs rename to examples-runner/src/bin/not-sync.rs index aa79ad5626d8..9ed19c223ac4 100644 --- a/examples/not-sync.rs +++ b/examples-runner/src/bin/not-sync.rs @@ -6,7 +6,7 @@ #![no_std] use core::marker::PhantomData; -use panic_semihosting as _; +use examples_runner as _; pub struct NotSync { _0: PhantomData<*const ()>, @@ -14,11 +14,11 @@ pub struct NotSync { unsafe impl Send for NotSync {} -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { use super::NotSync; use core::marker::PhantomData; - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared { @@ -30,8 +30,6 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - ( Shared { shared: NotSync { _0: PhantomData }, @@ -41,6 +39,11 @@ mod app { ) } + #[idle] + fn idle(_: idle::Context) -> ! { + exit(); + } + #[task(shared = [&shared])] fn foo(c: foo::Context) { let _: &NotSync = c.shared.shared; diff --git a/examples/only-shared-access.rs b/examples-runner/src/bin/only-shared-access.rs similarity index 65% rename from examples/only-shared-access.rs rename to examples-runner/src/bin/only-shared-access.rs index 8b0a77ef8c36..a28e7c0d9da0 100644 --- a/examples/only-shared-access.rs +++ b/examples-runner/src/bin/only-shared-access.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [UART0, UART1])] +#[rtic::app(device = examples_runner::pac, dispatchers = [UART0, UART1])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{exit, println}; #[shared] struct Shared { @@ -30,13 +30,13 @@ mod app { #[task(shared = [&key])] fn foo(cx: foo::Context) { let key: &u32 = cx.shared.key; - hprintln!("foo(key = {:#x})", key).unwrap(); + println!("foo(key = {:#x})", key); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } #[task(priority = 2, shared = [&key])] fn bar(cx: bar::Context) { - hprintln!("bar(key = {:#x})", cx.shared.key).unwrap(); + println!("bar(key = {:#x})", cx.shared.key); } } diff --git a/examples/periodic-at.rs b/examples-runner/src/bin/periodic-at.rs similarity index 80% rename from examples/periodic-at.rs rename to examples-runner/src/bin/periodic-at.rs index f9fd995fb061..8e235c23c3c0 100644 --- a/examples/periodic-at.rs +++ b/examples-runner/src/bin/periodic-at.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use systick_monotonic::*; #[monotonic(binds = SysTick, default = true)] @@ -35,11 +35,11 @@ mod app { #[task(local = [cnt: u32 = 0])] fn foo(cx: foo::Context, instant: fugit::TimerInstantU64<100>) { - hprintln!("foo {:?}", instant).ok(); + println!("foo ticks: {:?}", instant.ticks()); *cx.local.cnt += 1; if *cx.local.cnt == 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } // Periodic ever 1 seconds diff --git a/examples/periodic-at2.rs b/examples-runner/src/bin/periodic-at2.rs similarity index 83% rename from examples/periodic-at2.rs rename to examples-runner/src/bin/periodic-at2.rs index 879f709c651c..5071c430f666 100644 --- a/examples/periodic-at2.rs +++ b/examples-runner/src/bin/periodic-at2.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use systick_monotonic::*; #[monotonic(binds = SysTick, default = true)] @@ -36,11 +36,11 @@ mod app { // Using the explicit type of the timer implementation #[task(local = [cnt: u32 = 0])] fn foo(cx: foo::Context, instant: fugit::TimerInstantU64<100>) { - hprintln!("foo {:?}", instant).ok(); + println!("foo ticks: {:?}", instant.ticks()); *cx.local.cnt += 1; if *cx.local.cnt == 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } // Spawn a new message with 100 ms offset to spawned time @@ -52,7 +52,7 @@ mod app { // This remains agnostic to the timer implementation #[task(local = [cnt: u32 = 0])] fn bar(_cx: bar::Context, instant: ::Instant) { - hprintln!("bar {:?}", instant).ok(); + println!("bar ticks: {:?}", instant.ticks()); // Spawn a new message with 1s offset to spawned time let next_instant = instant + 1.secs(); diff --git a/examples/periodic.rs b/examples-runner/src/bin/periodic.rs similarity index 79% rename from examples/periodic.rs rename to examples-runner/src/bin/periodic.rs index 40c69257e744..e654820297b6 100644 --- a/examples/periodic.rs +++ b/examples-runner/src/bin/periodic.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use systick_monotonic::*; #[monotonic(binds = SysTick, default = true)] @@ -35,11 +35,11 @@ mod app { #[task(local = [cnt: u32 = 0])] fn foo(cx: foo::Context) { - hprintln!("foo").ok(); + println!("foo"); *cx.local.cnt += 1; if *cx.local.cnt == 4 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } // Periodic ever 1 seconds diff --git a/examples/peripherals-taken.rs b/examples-runner/src/bin/peripherals-taken.rs similarity index 58% rename from examples/peripherals-taken.rs rename to examples-runner/src/bin/peripherals-taken.rs index d542c0e64dfb..67742eb1c2c7 100644 --- a/examples/peripherals-taken.rs +++ b/examples-runner/src/bin/peripherals-taken.rs @@ -3,11 +3,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared {} @@ -18,8 +18,8 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { assert!(cortex_m::Peripherals::take().is_none()); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - (Shared {}, Local {}, init::Monotonics()) + // (Shared {}, Local {}, init::Monotonics()) } } diff --git a/examples/pool.rs b/examples-runner/src/bin/pool.rs similarity index 78% rename from examples/pool.rs rename to examples-runner/src/bin/pool.rs index d59bd91607e3..b8a23380f354 100644 --- a/examples/pool.rs +++ b/examples-runner/src/bin/pool.rs @@ -9,17 +9,17 @@ use heapless::{ pool, pool::singleton::{Box, Pool}, }; -use panic_semihosting as _; +use examples_runner as _; use rtic::app; // Declare a pool of 128-byte memory blocks pool!(P: [u8; 128]); -#[app(device = lm3s6965, dispatchers = [SSI0, QEI0])] +#[app(device = examples_runner::pac, dispatchers = [SSI0, QEI0])] mod app { use crate::{Box, Pool}; - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::{println, exit}; + use examples_runner::pac::Interrupt; // Import the memory pool into scope use super::P; @@ -56,17 +56,17 @@ mod app { #[task] fn foo(_: foo::Context, x: Box

) { - hprintln!("foo({:?})", x.as_ptr()).unwrap(); + println!("foo"); // explicitly return the block to the pool drop(x); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } #[task(priority = 2)] - fn bar(_: bar::Context, x: Box

) { - hprintln!("bar({:?})", x.as_ptr()).unwrap(); + fn bar(_: bar::Context, _x: Box

) { + println!("bar"); // this is done automatically so we can omit the call to `drop` // drop(x); diff --git a/examples/preempt.rs b/examples-runner/src/bin/preempt.rs similarity index 58% rename from examples/preempt.rs rename to examples-runner/src/bin/preempt.rs index d0c8cc7d3fd5..4b8b657f8970 100644 --- a/examples/preempt.rs +++ b/examples-runner/src/bin/preempt.rs @@ -3,12 +3,12 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; use rtic::app; -#[app(device = lm3s6965, dispatchers = [SSI0, QEI0])] +#[app(device = examples_runner::pac, dispatchers = [SSI0, QEI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -25,21 +25,21 @@ mod app { #[task(priority = 1)] fn foo(_: foo::Context) { - hprintln!("foo - start").unwrap(); + println!("foo - start"); baz::spawn().unwrap(); - hprintln!("foo - end").unwrap(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + println!("foo - end"); + exit(); } #[task(priority = 2)] fn bar(_: bar::Context) { - hprintln!(" bar").unwrap(); + println!(" bar"); } #[task(priority = 2)] fn baz(_: baz::Context) { - hprintln!(" baz - start").unwrap(); + println!(" baz - start"); bar::spawn().unwrap(); - hprintln!(" baz - end").unwrap(); + println!(" baz - end"); } } diff --git a/examples/ramfunc.rs b/examples-runner/src/bin/ramfunc.rs similarity index 77% rename from examples/ramfunc.rs rename to examples-runner/src/bin/ramfunc.rs index 54acd7e84ccc..32f885d35572 100644 --- a/examples/ramfunc.rs +++ b/examples-runner/src/bin/ramfunc.rs @@ -5,10 +5,10 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; #[rtic::app( - device = lm3s6965, + device = examples_runner::pac, dispatchers = [ UART0, #[link_section = ".data.UART1"] @@ -16,7 +16,7 @@ use panic_semihosting as _; ]) ] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -34,9 +34,9 @@ mod app { #[inline(never)] #[task] fn foo(_: foo::Context) { - hprintln!("foo").unwrap(); + println!("foo"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } // run this task from RAM diff --git a/examples/resource-user-struct.rs b/examples-runner/src/bin/resource-user-struct.rs similarity index 79% rename from examples/resource-user-struct.rs rename to examples-runner/src/bin/resource-user-struct.rs index ae1918d05ded..5051c1f999b7 100644 --- a/examples/resource-user-struct.rs +++ b/examples-runner/src/bin/resource-user-struct.rs @@ -5,12 +5,12 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; - use lm3s6965::Interrupt; + use examples_runner::{println, exit}; + use examples_runner::pac::Interrupt; #[shared] struct Shared { @@ -39,12 +39,12 @@ mod app { // `shared` cannot be accessed from this context #[idle] fn idle(_cx: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); // error: no `shared` field in `idle::Context` // _cx.shared.shared += 1; - loop {} + // loop {} } // `shared` can be accessed from this context @@ -55,7 +55,7 @@ mod app { *shared }); - hprintln!("UART0: shared = {}", shared).unwrap(); + println!("UART0: shared = {}", shared); } // `shared` can be accessed from this context @@ -66,6 +66,6 @@ mod app { *shared }); - hprintln!("UART1: shared = {}", shared).unwrap(); + println!("UART1: shared = {}", shared); } } diff --git a/examples/schedule.rs b/examples-runner/src/bin/schedule.rs similarity index 79% rename from examples/schedule.rs rename to examples-runner/src/bin/schedule.rs index 5bad5a30ade7..4242d7e5ff3d 100644 --- a/examples/schedule.rs +++ b/examples-runner/src/bin/schedule.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use systick_monotonic::*; #[monotonic(binds = SysTick, default = true)] @@ -28,7 +28,7 @@ mod app { // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) let mono = Systick::new(systick, 12_000_000); - hprintln!("init").ok(); + println!("init"); // Schedule `foo` to run 1 second in the future foo::spawn_after(1.secs()).unwrap(); @@ -42,7 +42,7 @@ mod app { #[task] fn foo(_: foo::Context) { - hprintln!("foo").ok(); + println!("foo"); // Schedule `bar` to run 2 seconds in the future (1 second after foo runs) bar::spawn_after(1.secs()).unwrap(); @@ -50,7 +50,7 @@ mod app { #[task] fn bar(_: bar::Context) { - hprintln!("bar").ok(); + println!("bar"); // Schedule `baz` to run 1 seconds from now, but with a specific time instant. baz::spawn_at(monotonics::now() + 1.secs()).unwrap(); @@ -58,7 +58,7 @@ mod app { #[task] fn baz(_: baz::Context) { - hprintln!("baz").ok(); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + println!("baz"); + exit(); } } diff --git a/examples/shared.rs b/examples-runner/src/bin/shared.rs similarity index 77% rename from examples/shared.rs rename to examples-runner/src/bin/shared.rs index d87dca5263e7..fa7bff02483e 100644 --- a/examples/shared.rs +++ b/examples-runner/src/bin/shared.rs @@ -5,13 +5,13 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use heapless::spsc::{Consumer, Producer, Queue}; - use lm3s6965::Interrupt; + use examples_runner::pac::Interrupt; #[shared] struct Shared { @@ -34,9 +34,9 @@ mod app { fn idle(mut c: idle::Context) -> ! { loop { if let Some(byte) = c.shared.c.lock(|c| c.dequeue()) { - hprintln!("received message: {}", byte).unwrap(); + println!("received message: {}", byte); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } else { rtic::pend(Interrupt::UART0); } diff --git a/examples/smallest.rs b/examples-runner/src/bin/smallest.rs similarity index 51% rename from examples/smallest.rs rename to examples-runner/src/bin/smallest.rs index b121fcff88c2..c5869d1e6ca1 100644 --- a/examples/smallest.rs +++ b/examples-runner/src/bin/smallest.rs @@ -3,12 +3,12 @@ #![no_main] #![no_std] -use panic_semihosting as _; // panic handler +use examples_runner as _; // panic handler use rtic::app; -#[app(device = lm3s6965)] +#[app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared {} @@ -18,7 +18,7 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - (Shared {}, Local {}, init::Monotonics()) + exit(); + // (Shared {}, Local {}, init::Monotonics()) } } diff --git a/examples/spawn.rs b/examples-runner/src/bin/spawn.rs similarity index 59% rename from examples/spawn.rs rename to examples-runner/src/bin/spawn.rs index 2db1ab8a28ec..ea63327f8368 100644 --- a/examples/spawn.rs +++ b/examples-runner/src/bin/spawn.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -19,7 +19,7 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - hprintln!("init").unwrap(); + println!("init"); foo::spawn().unwrap(); (Shared {}, Local {}, init::Monotonics()) @@ -27,8 +27,8 @@ mod app { #[task] fn foo(_: foo::Context) { - hprintln!("foo").unwrap(); + println!("foo"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } } diff --git a/examples/static.rs b/examples-runner/src/bin/static.rs similarity index 82% rename from examples/static.rs rename to examples-runner/src/bin/static.rs index c9aa6046b559..4563833be811 100644 --- a/examples/static.rs +++ b/examples-runner/src/bin/static.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [UART0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [UART0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; use heapless::spsc::{Consumer, Producer, Queue}; #[shared] @@ -37,11 +37,11 @@ mod app { loop { // Lock-free access to the same underlying queue! if let Some(data) = c.local.c.dequeue() { - hprintln!("received message: {}", data).unwrap(); + println!("received message: {}", data); // Run foo until data if data == 3 { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } else { foo::spawn().unwrap(); } diff --git a/examples/t-binds.rs b/examples-runner/src/bin/t-binds.rs similarity index 75% rename from examples/t-binds.rs rename to examples-runner/src/bin/t-binds.rs index 12479c0ad4be..59841e67b36f 100644 --- a/examples/t-binds.rs +++ b/examples-runner/src/bin/t-binds.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared {} @@ -19,9 +19,9 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - (Shared {}, Local {}, init::Monotonics()) + // (Shared {}, Local {}, init::Monotonics()) } // Cortex-M exception diff --git a/examples/t-cfg-resources.rs b/examples-runner/src/bin/t-cfg-resources.rs similarity index 74% rename from examples/t-cfg-resources.rs rename to examples-runner/src/bin/t-cfg-resources.rs index 99c97ba5e194..667b57becf5b 100644 --- a/examples/t-cfg-resources.rs +++ b/examples-runner/src/bin/t-cfg-resources.rs @@ -3,11 +3,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared { @@ -21,8 +21,6 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - ( Shared { #[cfg(feature = "feature_x")] @@ -35,8 +33,9 @@ mod app { #[idle] fn idle(_cx: idle::Context) -> ! { - loop { - cortex_m::asm::nop(); - } + exit(); + // loop { + // cortex_m::asm::nop(); + // } } } diff --git a/examples/t-htask-main.rs b/examples-runner/src/bin/t-htask-main.rs similarity index 63% rename from examples/t-htask-main.rs rename to examples-runner/src/bin/t-htask-main.rs index 37189faf7669..62030c8ad85c 100644 --- a/examples/t-htask-main.rs +++ b/examples-runner/src/bin/t-htask-main.rs @@ -3,11 +3,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared {} @@ -17,13 +17,13 @@ mod app { #[init] fn init(_: init::Context) -> (Shared, Local, init::Monotonics) { - rtic::pend(lm3s6965::Interrupt::UART0); + rtic::pend(examples_runner::pac::Interrupt::UART0); (Shared {}, Local {}, init::Monotonics()) } #[task(binds = UART0)] fn taskmain(_: taskmain::Context) { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } } diff --git a/examples/t-idle-main.rs b/examples-runner/src/bin/t-idle-main.rs similarity index 61% rename from examples/t-idle-main.rs rename to examples-runner/src/bin/t-idle-main.rs index 1adc9bf044f2..f92117a456ee 100644 --- a/examples/t-idle-main.rs +++ b/examples-runner/src/bin/t-idle-main.rs @@ -3,11 +3,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared {} @@ -22,9 +22,9 @@ mod app { #[idle] fn taskmain(_: taskmain::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - loop { - cortex_m::asm::nop(); - } + exit(); + // loop { + // cortex_m::asm::nop(); + // } } } diff --git a/examples/t-late-not-send.rs b/examples-runner/src/bin/t-late-not-send.rs similarity index 77% rename from examples/t-late-not-send.rs rename to examples-runner/src/bin/t-late-not-send.rs index 06aedaa2ee5d..f80d5f50e832 100644 --- a/examples/t-late-not-send.rs +++ b/examples-runner/src/bin/t-late-not-send.rs @@ -5,17 +5,17 @@ use core::marker::PhantomData; -use panic_semihosting as _; +use examples_runner as _; pub struct NotSend { _0: PhantomData<*const ()>, } -#[rtic::app(device = lm3s6965)] +#[rtic::app(device = examples_runner::pac)] mod app { use super::NotSend; use core::marker::PhantomData; - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared { @@ -40,9 +40,9 @@ mod app { #[idle(shared = [x, y])] fn idle(_: idle::Context) -> ! { - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - loop { - cortex_m::asm::nop(); - } + exit(); + // loop { + // cortex_m::asm::nop(); + // } } } diff --git a/examples/t-schedule.rs b/examples-runner/src/bin/t-schedule.rs similarity index 91% rename from examples/t-schedule.rs rename to examples-runner/src/bin/t-schedule.rs index 5ec420873d76..1f1d7fc6b824 100644 --- a/examples/t-schedule.rs +++ b/examples-runner/src/bin/t-schedule.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; use systick_monotonic::*; #[monotonic(binds = SysTick, default = true)] @@ -22,15 +22,10 @@ mod app { struct Local {} #[init] - fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { - let systick = cx.core.SYST; + fn init(_cx: init::Context) -> (Shared, Local, init::Monotonics) { + exit(); - // Initialize the monotonic (SysTick rate in QEMU is 12 MHz) - let mono = Systick::new(systick, 12_000_000); - - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator - - (Shared {}, Local {}, init::Monotonics(mono)) + // (Shared {}, Local {}, init::Monotonics(mono)) } #[idle] diff --git a/examples/t-spawn.rs b/examples-runner/src/bin/t-spawn.rs similarity index 86% rename from examples/t-spawn.rs rename to examples-runner/src/bin/t-spawn.rs index 2bd771d7f690..6455ac0cba25 100644 --- a/examples/t-spawn.rs +++ b/examples-runner/src/bin/t-spawn.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0])] mod app { - use cortex_m_semihosting::debug; + use examples_runner::exit; #[shared] struct Shared {} @@ -23,9 +23,9 @@ mod app { let _: Result<(), u32> = bar::spawn(0); let _: Result<(), (u32, u32)> = baz::spawn(0, 1); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); - (Shared {}, Local {}, init::Monotonics()) + // (Shared {}, Local {}, init::Monotonics()) } #[idle] diff --git a/examples/task.rs b/examples-runner/src/bin/task.rs similarity index 68% rename from examples/task.rs rename to examples-runner/src/bin/task.rs index 2c53aa235961..b6c69e53f363 100644 --- a/examples/task.rs +++ b/examples-runner/src/bin/task.rs @@ -5,11 +5,11 @@ #![no_main] #![no_std] -use panic_semihosting as _; +use examples_runner as _; -#[rtic::app(device = lm3s6965, dispatchers = [SSI0, QEI0])] +#[rtic::app(device = examples_runner::pac, dispatchers = [SSI0, QEI0])] mod app { - use cortex_m_semihosting::{debug, hprintln}; + use examples_runner::{println, exit}; #[shared] struct Shared {} @@ -26,31 +26,31 @@ mod app { #[task] fn foo(_: foo::Context) { - hprintln!("foo - start").unwrap(); + 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(); - hprintln!("foo - middle").unwrap(); + println!("foo - middle"); // spawns `baz` onto the task scheduler // `baz` has higher priority than `foo` so it immediately preempts `foo` baz::spawn().unwrap(); - hprintln!("foo - end").unwrap(); + println!("foo - end"); } #[task] fn bar(_: bar::Context) { - hprintln!("bar").unwrap(); + println!("bar"); - debug::exit(debug::EXIT_SUCCESS); // Exit QEMU simulator + exit(); } #[task(priority = 2)] fn baz(_: baz::Context) { - hprintln!("baz").unwrap(); + println!("baz"); } } diff --git a/examples-runner/src/lib.rs b/examples-runner/src/lib.rs new file mode 100644 index 000000000000..13b8c95435e1 --- /dev/null +++ b/examples-runner/src/lib.rs @@ -0,0 +1,60 @@ +#![no_std] + + +pub use embedded_ci_pac as pac; // memory layout + +#[cfg(feature = "embedded-ci")] +use core::sync::atomic::{AtomicUsize, Ordering}; + +#[cfg(feature = "qemu")] +use panic_semihosting as _; + +#[cfg(feature = "embedded-ci")] +use defmt_rtt as _; // global logger +#[cfg(feature = "embedded-ci")] +use panic_probe as _; + +#[cfg(feature = "embedded-ci")] +defmt::timestamp! {"{=u64}", { + static COUNT: AtomicUsize = AtomicUsize::new(0); + // NOTE(no-CAS) `timestamps` runs with interrupts disabled + let n = COUNT.load(Ordering::Relaxed); + COUNT.store(n + 1, Ordering::Relaxed); + n as u64 +} +} + +// same panicking *behavior* as `panic-probe` but doesn't print a panic message +// this prevents the panic message being printed *twice* when `defmt::panic` is invoked +#[cfg(feature = "embedded-ci")] +#[defmt::panic_handler] +fn panic() -> ! { + cortex_m::asm::udf() +} + +/// Generalize println for QEMU and defmt +#[cfg(feature = "embedded-ci")] +#[macro_export] +macro_rules! println { + ($($l:tt)*) => { + defmt::println!($($l)*); + } +} + +#[cfg(feature = "qemu")] +#[macro_export] +macro_rules! println { + ($($l:tt)*) => { + cortex_m_semihosting::hprintln!($($l)*).ok(); + } +} + +/// Terminates the application and makes `probe-run` exit with exit-code = 0 +pub fn exit() -> ! { + #[cfg(feature = "qemu")] + cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_SUCCESS); + + loop { + cortex_m::asm::bkpt(); + } +} diff --git a/xtask/Cargo.toml b/examples-runner/xtask/Cargo.toml similarity index 68% rename from xtask/Cargo.toml rename to examples-runner/xtask/Cargo.toml index 33e6b3ad60af..d45965d44fc0 100644 --- a/xtask/Cargo.toml +++ b/examples-runner/xtask/Cargo.toml @@ -6,4 +6,4 @@ edition = "2018" [dependencies] anyhow = "1.0.43" os_pipe = "0.9.2" -structopt = "0.3.22" +clap = { version = "3.1.5", features = ["derive"] } diff --git a/xtask/src/build.rs b/examples-runner/xtask/src/build.rs similarity index 100% rename from xtask/src/build.rs rename to examples-runner/xtask/src/build.rs diff --git a/xtask/src/command.rs b/examples-runner/xtask/src/command.rs similarity index 69% rename from xtask/src/command.rs rename to examples-runner/xtask/src/command.rs index 2f719bf5c9fb..38ddba72d096 100644 --- a/xtask/src/command.rs +++ b/examples-runner/xtask/src/command.rs @@ -1,4 +1,5 @@ use crate::{RunResult, TestRunError}; +use clap::ArgEnum; use core::fmt; use os_pipe::pipe; use std::{fs::File, io::Read, process::Command}; @@ -10,6 +11,12 @@ pub enum BuildMode { Debug, } +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)] +pub enum Runner { + Qemu, + EmbeddedCi, +} + #[derive(Debug)] pub enum CargoCommand<'a> { Run { @@ -17,6 +24,7 @@ pub enum CargoCommand<'a> { target: &'a str, features: Option<&'a str>, mode: BuildMode, + runner: Runner, }, BuildAll { target: &'a str, @@ -45,23 +53,43 @@ impl<'a> CargoCommand<'a> { target, features, mode, - } => { - let mut args = vec![self.name(), "--example", example, "--target", target]; - - if let Some(feature_name) = features { - args.extend_from_slice(&["--features", feature_name]); + runner, + } => match runner { + Runner::Qemu => { + let mut args = vec![self.name(), "--bin", example, "--target", target]; + + if let Some(feature_name) = features { + args.extend_from_slice(&["--features", feature_name]); + } + if let Some(flag) = mode.to_flag() { + args.push(flag); + } + args } - if let Some(flag) = mode.to_flag() { - args.push(flag); + Runner::EmbeddedCi => { + let mut args = vec![]; + if target.contains("thumbv6") { + args.extend_from_slice(&["--cores", "cortexm0plus"]) + } else if target.contains("thumbv7") { + args.extend_from_slice(&["--cores", "cortexm3,cortexm4,cortexm7"]) + } else { + panic!("Unknown target: {}", target); + } + let s = Box::new(format!("target/{target}/{mode}/{example}")); + let s = s.into_boxed_str(); + let s: &'static str = Box::leak(s); + + args.push(s); + + args } - args - } + }, CargoCommand::BuildAll { target, features, mode, } => { - let mut args = vec![self.name(), "--examples", "--target", target]; + let mut args = vec![self.name(), "--bins", "--target", target]; if let Some(feature_name) = features { args.extend_from_slice(&["--features", feature_name]); @@ -78,6 +106,16 @@ impl<'a> CargoCommand<'a> { pub fn command(&self) -> &str { match self { + CargoCommand::Run { + example: _, + target: _, + features: _, + mode: _, + runner, + } => match runner { + Runner::Qemu => "cargo", + Runner::EmbeddedCi => "embedded-ci-client", + }, // we need to cheat a little here: // `cargo size` can't be ran on multiple files, so we're using `rust-size` instead – // which isn't a command that starts wizh `cargo`. So we're sneakily swapping them out :) diff --git a/xtask/src/main.rs b/examples-runner/xtask/src/main.rs similarity index 87% rename from xtask/src/main.rs rename to examples-runner/xtask/src/main.rs index 76ce04bd4c92..459307ac8536 100644 --- a/xtask/src/main.rs +++ b/examples-runner/xtask/src/main.rs @@ -2,6 +2,7 @@ mod build; mod command; use anyhow::bail; +use clap::Parser; use core::fmt; use std::{ error::Error, @@ -11,20 +12,22 @@ use std::{ process::ExitStatus, str, }; -use structopt::StructOpt; use crate::{ build::init_build_dir, - command::{run_command, run_successful, BuildMode, CargoCommand}, + command::{run_command, run_successful, BuildMode, CargoCommand, Runner}, }; const ARMV6M: &str = "thumbv6m-none-eabi"; const ARMV7M: &str = "thumbv7m-none-eabi"; -#[derive(Debug, StructOpt)] +#[derive(Debug, Parser)] +#[clap(author, version, about, long_about = None)] struct Options { - #[structopt(short, long)] + #[clap(short, long)] target: String, + #[clap(short, long, arg_enum)] + runner: Runner, } #[derive(Debug, Clone)] @@ -86,24 +89,24 @@ fn main() -> anyhow::Result<()> { let targets = [ARMV7M, ARMV6M]; - let examples: Vec<_> = std::fs::read_dir("./examples")? + let examples: Vec<_> = std::fs::read_dir("./src/bin")? .filter_map(|path| { path.map(|p| p.path().file_stem().unwrap().to_str().unwrap().to_string()) .ok() }) .collect(); - let opts = Options::from_args(); + let opts = Options::parse(); let target = &opts.target; init_build_dir()?; if target == "all" { for t in targets { - run_test(t, &examples)?; + run_tests(t, opts.runner, &examples)?; } } else if targets.contains(&target.as_str()) { - run_test(&target, &examples)?; + run_tests(&target, opts.runner, &examples)?; } else { eprintln!( "The target you specified is not available. Available targets are:\ @@ -117,10 +120,15 @@ fn main() -> anyhow::Result<()> { Ok(()) } -fn run_test(target: &str, examples: &[String]) -> anyhow::Result<()> { +fn run_tests(target: &str, runner: Runner, examples: &[String]) -> anyhow::Result<()> { + let features = Some(match runner { + Runner::Qemu => "qemu", + Runner::EmbeddedCi => "embedded-ci", + }); + arm_example(&CargoCommand::BuildAll { target, - features: None, + features, mode: BuildMode::Release, })?; @@ -128,8 +136,9 @@ fn run_test(target: &str, examples: &[String]) -> anyhow::Result<()> { let cmd = CargoCommand::Run { example, target, - features: None, + features, mode: BuildMode::Release, + runner, }; arm_example(&cmd)?;