diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 39cdd7de..11ac9ebc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,30 +2,159 @@ on:
pull_request:
merge_group:
workflow_dispatch:
+ schedule:
+ # Run every night at 8am UTC
+ - cron: '0 8 * * SAT'
name: cortex-m CI
jobs:
- ci-linux:
- runs-on: ubuntu-latest
- continue-on-error: ${{ matrix.experimental || false }}
+ # Test cortex-m
+ cortex-m-ci-linux:
+ runs-on: ubuntu-26.04
+ continue-on-error: true
strategy:
matrix:
- # All generated code should be running on stable now
- rust: [stable]
- test_cortex_m_types: [true]
+ rust: [nightly, stable, 1.85.0]
+ steps:
+ - uses: actions/checkout@v7
+ - uses: dtolnay/rust-toolchain@master
+ with:
+ toolchain: ${{ matrix.rust }}
+ - name: Run tests
+ run: cargo test --all --exclude cortex-m-rt --features cortex-m/critical-section-single-core
- include:
- # Test MSRV
- - rust: 1.85.0
+ # On x86_64-unknown-linux-gnu we can run our special testing shell script
+ cortex-m-rt-ci-linux:
+ runs-on: ubuntu-26.04
+ continue-on-error: true
+ strategy:
+ matrix:
+ rust: [nightly, stable, 1.85.0]
+ defaults:
+ run:
+ working-directory: cortex-m-rt
+ steps:
+ - uses: actions/checkout@v7
+ - uses: dtolnay/rust-toolchain@master
+ with:
+ toolchain: ${{ matrix.rust }}
+ targets: thumbv6m-none-eabi,thumbv7m-none-eabi,thumbv7em-none-eabi,thumbv7em-none-eabihf,thumbv8m.base-none-eabi,thumbv8m.main-none-eabi,thumbv8m.main-none-eabihf
+ - name: Install qemu and gcc
+ run: sudo apt-get update && sudo apt-get install qemu-system-arm gcc-arm-none-eabi
+ - name: Run CI script for x86_64-unknown-linux-gnu under ${{ matrix.rust }}
+ run: TARGET=x86_64-unknown-linux-gnu CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv6m-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv6m-none-eabi CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv7m-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv7m-none-eabi CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv7em-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv7em-none-eabi CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv7em-none-eabihf under ${{ matrix.rust }}
+ run: TARGET=thumbv7em-none-eabihf CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv8m.base-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv8m.base-none-eabi CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv8m.main-none-eabi under ${{ matrix.rust }}
+ run: TARGET=thumbv8m.main-none-eabi CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
+ - name: Run CI script for thumbv8m.main-none-eabihf under ${{ matrix.rust }}
+ run: TARGET=thumbv8m.main-none-eabihf CI_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- # Test nightly but don't fail
- - rust: nightly
- experimental: true
+ # On macOS and Windows, we at least make sure that all examples build and link.
+ cortex-m-rt-ci-other-os:
+ strategy:
+ matrix:
+ os: [macOS-latest, windows-latest]
+ rust: [nightly, stable, 1.85.0]
+ runs-on: ${{ matrix.os }}
+ continue-on-error: true
+ defaults:
+ run:
+ working-directory: cortex-m-rt
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
- - name: Run tests
- run: cargo test --all --exclude cortex-m-rt --exclude testsuite --features cortex-m/critical-section-single-core
+ targets: thumbv6m-none-eabi,thumbv7m-none-eabi,thumbv7em-none-eabi,thumbv7em-none-eabihf,thumbv8m.base-none-eabi,thumbv8m.main-none-eabi,thumbv8m.main-none-eabihf
+ - name: Remove examples that pass by failing
+ run: rm examples/data_overflow.rs
+ - name: Build examples for thumbv6m-none-eabi
+ run: cargo build --target=thumbv6m-none-eabi --examples
+ - name: Build examples for thumbv7m-none-eabi
+ run: cargo build --target=thumbv7m-none-eabi --examples
+ - name: Build examples for thumbv7em-none-eabi
+ run: cargo build --target=thumbv7em-none-eabi --examples
+ - name: Build examples for thumbv7em-none-eabihf
+ run: cargo build --target=thumbv7em-none-eabihf --examples
+ - name: Build examples for thumbv8m.base-none-eabi
+ run: cargo build --target=thumbv8m.base-none-eabi --examples
+ - name: Build examples for thumbv8m.main-none-eabi
+ run: cargo build --target=thumbv8m.main-none-eabi --examples
+ - name: Build examples for thumbv8m.main-none-eabihf
+ run: cargo build --target=thumbv8m.main-none-eabihf --examples
+ - name: Build crate for host OS
+ run: cargo build
+
+ # Run examples in QEMU
+ cortex-m-testsuite:
+ runs-on: ubuntu-26.04
+ continue-on-error: true
+ strategy:
+ matrix:
+ rust: [nightly, stable, 1.85.0]
+ steps:
+ - uses: actions/checkout@v7
+ - name: Install qemu-run
+ uses: taiki-e/cache-cargo-install-action@v3
+ with:
+ tool: qemu-run
+ - name: Install qemu
+ run: sudo apt-get update && sudo apt-get install qemu-system-arm
+ - uses: dtolnay/rust-toolchain@master
+ with:
+ toolchain: ${{ matrix.rust }}
+ targets: thumbv6m-none-eabi,thumbv7m-none-eabi,thumbv7em-none-eabi,thumbv7em-none-eabihf,thumbv8m.base-none-eabi,thumbv8m.main-none-eabi,thumbv8m.main-none-eabihf
+ - name: Run testsuite for thumbv8m.main-none-eabihf
+ run: |
+ cd testsuite && cargo test --features qemu --target thumbv8m.main-none-eabihf
+ - name: Run testsuite for thumbv8m.main-none-eabi
+ run: |
+ cd testsuite && cargo test --features qemu --target thumbv8m.main-none-eabi
+ - name: Run testsuite for thumbv8m.base-none-eabi
+ run: |
+ cd testsuite && cargo test --features qemu --target thumbv8m.base-none-eabi
+ - name: Run testsuite for thumbv7em-none-eabi
+ run: |
+ cd testsuite && cargo test --features qemu --target thumbv7em-none-eabi
+ - name: Run testsuite for thumbv7em-none-eabihf
+ run: |
+ cd testsuite && cargo test --features qemu --target thumbv7em-none-eabihf
+ - name: Run testsuite for thumbv7m-none-eabi
+ run: |
+ cd testsuite && cargo test --features qemu --target thumbv7m-none-eabi
+ - name: Run testsuite for thumbv6m-none-eabi
+ run: |
+ cd testsuite && cargo test --features qemu --target thumbv6m-none-eabi
+
+ report-issues:
+ runs-on: ubuntu-26.04
+ if: always()
+ needs: [cortex-m-ci-linux, cortex-m-rt-ci-other-os, cortex-m-rt-ci-linux, cortex-m-testsuite]
+ steps:
+ - name: Ensure all required jobs succeed
+ run: |
+ echo "Our needs:"
+ echo '${{ toJSON(needs) }}'
+ echo "Checking..."
+ echo '${{ toJSON(needs) }}' | jq -e 'to_entries | all(.value.result == "success")'
+ - uses: imjohnbo/issue-bot@v3
+ if: failure() && github.event_name == 'schedule'
+ with:
+ title: CI Failure
+ labels: ci
+ body: |
+ Scheduled CI run failed. Details:
+
+ https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml
index 036a01c8..526f5f27 100644
--- a/.github/workflows/clippy.yml
+++ b/.github/workflows/clippy.yml
@@ -3,18 +3,41 @@ on:
merge_group:
workflow_dispatch:
-name: Clippy check
+name: Clippy
+
jobs:
- clippy:
- runs-on: ubuntu-latest
+ clippy-host:
+ runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@1.85
with:
components: clippy
- run: cargo clippy --all --features cortex-m/critical-section-single-core -- -D warnings
+ clippy-target:
+ runs-on: ubuntu-26.04
+ continue-on-error: true
+ strategy:
+ matrix:
+ target:
+ - thumbv6m-none-eabi
+ - thumbv7m-none-eabi
+ - thumbv7em-none-eabi
+ - thumbv7em-none-eabihf
+ - thumbv8m.base-none-eabi
+ - thumbv8m.main-none-eabi
+ - thumbv8m.main-none-eabihf
+ steps:
+ - uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@1.85
with:
components: clippy
- targets: thumbv7em-none-eabihf
- - run: cd testsuite && cargo clippy --features qemu -- -D warnings
+ targets: ${{ matrix.target }}
+ - run: cd cortex-m && cargo clippy --target ${{ matrix.target }} --features critical-section-single-core -- -D warnings
+ - run: cd cortex-m-rt && cargo clippy --target ${{ matrix.target }} -- -D warnings
+ - run: cd testsuite && cargo clippy --target ${{ matrix.target }} --features qemu -- -D warnings
+ - run: cd testsuite && cargo clippy --target ${{ matrix.target }} --features hardware -- -D warnings
+ - run: cd cortex-m-semihosting && cargo clippy --target ${{ matrix.target }} -- -D warnings
+ - run: cd panic-semihosting && cargo clippy --target ${{ matrix.target }} -- -D warnings
+ - if: ${{ matrix.target != 'thumbv6m-none-eabi' && matrix.target != 'thumbv8m.base-none-eabi' }}
+ run: cd panic-itm && cargo clippy --target ${{ matrix.target }} -- -D warnings
diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml
deleted file mode 100644
index 436ba372..00000000
--- a/.github/workflows/cron.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-on:
- schedule:
- # Run every week at 8am UTC Saturday.
- - cron: '0 8 * * SAT'
- workflow_dispatch:
-
-name: Cron CI
-
-jobs:
- ci-linux:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v7
- - uses: dtolnay/rust-toolchain@stable
- - name: Run tests
- run: cargo test --all --exclude cortex-m-rt --exclude testsuite
- - uses: imjohnbo/issue-bot@v3
- if: failure()
- with:
- title: CI Failure
- labels: ci
- body: |
- Scheduled CI run failed. Details:
-
- https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- rt-ci-linux:
- runs-on: ubuntu-latest
- continue-on-error: ${{ matrix.experimental || false }}
- defaults:
- run:
- working-directory: cortex-m-rt
- steps:
- - uses: actions/checkout@v7
- - uses: dtolnay/rust-toolchain@stable
- - name: Install all Rust targets for stable
- run: rustup target install --toolchain=stable thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf thumbv8m.base-none-eabi thumbv8m.main-none-eabi thumbv8m.main-none-eabihf
- - name: Install qemu and gcc
- run: sudo apt-get update && sudo apt-get install qemu-system-arm gcc-arm-none-eabi
- - name: Run CI script for x86_64-unknown-linux-gnu under stable
- run: TARGET=x86_64-unknown-linux-gnu TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - name: Run CI script for thumbv6m-none-eabi under stable
- run: TARGET=thumbv6m-none-eabi TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - name: Run CI script for thumbv7m-none-eabi under stable
- run: TARGET=thumbv7m-none-eabi TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - name: Run CI script for thumbv7em-none-eabi under stable
- run: TARGET=thumbv7em-none-eabi TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - name: Run CI script for thumbv7em-none-eabihf under stable
- run: TARGET=thumbv7em-none-eabihf TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - name: Run CI script for thumbv8m.base-none-eabi under stable
- run: TARGET=thumbv8m.base-none-eabi TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - name: Run CI script for thumbv8m.main-none-eabi under stable
- run: TARGET=thumbv8m.main-none-eabi TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - name: Run CI script for thumbv8m.main-none-eabihf under stable
- run: TARGET=thumbv8m.main-none-eabihf TRAVIS_RUST_VERSION=stable bash ci/script.sh
- - uses: imjohnbo/issue-bot@v3
- if: failure()
- with:
- title: CI Failure
- labels: ci
- body: |
- Scheduled CI run failed. Details:
-
- https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/on-target.yml b/.github/workflows/on-target.yml
deleted file mode 100644
index 90aa552a..00000000
--- a/.github/workflows/on-target.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-on:
- pull_request:
- merge_group:
- # allows manual triggering
- workflow_dispatch:
-
-name: cortex-m on-target tests
-
-jobs:
-
- hil-qemu:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v7
- - name: Install qemu-run
- uses: taiki-e/cache-cargo-install-action@v3
- with:
- tool: qemu-run
- - name: Install QEMU Dependencies
- run: |
- sudo apt-get -y update
- sudo apt-get -y install libpixman-1-0 libfdt1 libglib2.0-0t64
- - name: Install custom QEMU into /opt
- run: |
- curl -sSL https://github.com/jonathanpallant/qemu9-for-ubuntu-2404/releases/download/qemu-9.2.3%2Bbuild0/qemu-9.2.3-ubuntu-24.04.tar.gz | sudo tar xvzf - -C /
- echo "/opt/qemu/bin" >> "$GITHUB_PATH"
- - name: Install toolchains
- uses: dtolnay/rust-toolchain@stable
- with:
- targets: thumbv7em-none-eabihf, thumbv6m-none-eabi
- - name: Run testsuite Cortex-M3
- run: |
- cd testsuite && cargo test --features qemu --target thumbv7em-none-eabihf
- - name: Run testsuite Cortex-M0
- run: |
- cd testsuite && cargo test --features qemu --target thumbv6m-none-eabi
diff --git a/.github/workflows/rt-ci.yml b/.github/workflows/rt-ci.yml
deleted file mode 100644
index 176edb74..00000000
--- a/.github/workflows/rt-ci.yml
+++ /dev/null
@@ -1,82 +0,0 @@
-on:
- pull_request:
- merge_group:
- workflow_dispatch:
-
-name: cortex-m-rt CI
-
-jobs:
- rt-ci-linux:
- runs-on: ubuntu-latest
- continue-on-error: ${{ matrix.experimental || false }}
- strategy:
- matrix:
- rust: [nightly, stable, 1.85.0]
-
- include:
- # Nightly is only for reference and allowed to fail
- - rust: nightly
- experimental: true
- defaults:
- run:
- working-directory: cortex-m-rt
- steps:
- - uses: actions/checkout@v7
- - uses: dtolnay/rust-toolchain@master
- with:
- toolchain: ${{ matrix.rust }}
- - name: Install all Rust targets for ${{ matrix.rust }}
- run: rustup target install --toolchain=${{ matrix.rust }} thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf thumbv8m.base-none-eabi thumbv8m.main-none-eabi thumbv8m.main-none-eabihf
- - name: Install qemu and gcc
- run: sudo apt-get update && sudo apt-get install qemu-system-arm gcc-arm-none-eabi
- - name: Run CI script for x86_64-unknown-linux-gnu under ${{ matrix.rust }}
- run: TARGET=x86_64-unknown-linux-gnu TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- - name: Run CI script for thumbv6m-none-eabi under ${{ matrix.rust }}
- run: TARGET=thumbv6m-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- - name: Run CI script for thumbv7m-none-eabi under ${{ matrix.rust }}
- run: TARGET=thumbv7m-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- - name: Run CI script for thumbv7em-none-eabi under ${{ matrix.rust }}
- run: TARGET=thumbv7em-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- - name: Run CI script for thumbv7em-none-eabihf under ${{ matrix.rust }}
- run: TARGET=thumbv7em-none-eabihf TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- - name: Run CI script for thumbv8m.base-none-eabi under ${{ matrix.rust }}
- run: TARGET=thumbv8m.base-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- - name: Run CI script for thumbv8m.main-none-eabi under ${{ matrix.rust }}
- run: TARGET=thumbv8m.main-none-eabi TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
- - name: Run CI script for thumbv8m.main-none-eabihf under ${{ matrix.rust }}
- run: TARGET=thumbv8m.main-none-eabihf TRAVIS_RUST_VERSION=${{ matrix.rust }} bash ci/script.sh
-
- # On macOS and Windows, we at least make sure that all examples build and link.
- rt-ci-other-os:
- strategy:
- matrix:
- os:
- - macOS-latest
- - windows-latest
- runs-on: ${{ matrix.os }}
- defaults:
- run:
- working-directory: cortex-m-rt
- steps:
- - uses: actions/checkout@v7
- - uses: dtolnay/rust-toolchain@stable
- - name: Install all Rust targets
- run: rustup target install thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf thumbv8m.base-none-eabi thumbv8m.main-none-eabi thumbv8m.main-none-eabihf
- - name: Remove examples that pass by failing
- run: rm examples/data_overflow.rs
- - name: Build examples for thumbv6m-none-eabi
- run: cargo build --target=thumbv6m-none-eabi --examples
- - name: Build examples for thumbv7m-none-eabi
- run: cargo build --target=thumbv7m-none-eabi --examples
- - name: Build examples for thumbv7em-none-eabi
- run: cargo build --target=thumbv7em-none-eabi --examples
- - name: Build examples for thumbv7em-none-eabihf
- run: cargo build --target=thumbv7em-none-eabihf --examples
- - name: Build examples for thumbv8m.base-none-eabi
- run: cargo build --target=thumbv8m.base-none-eabi --examples
- - name: Build examples for thumbv8m.main-none-eabi
- run: cargo build --target=thumbv8m.main-none-eabi --examples
- - name: Build examples for thumbv8m.main-none-eabihf
- run: cargo build --target=thumbv8m.main-none-eabihf --examples
- - name: Build crate for host OS
- run: cargo build
diff --git a/.github/workflows/rustfmt.yml b/.github/workflows/rustfmt.yml
index 25acbf20..4a2534c4 100644
--- a/.github/workflows/rustfmt.yml
+++ b/.github/workflows/rustfmt.yml
@@ -6,12 +6,12 @@ on:
name: Code formatting check
jobs:
- fmt:
- name: rustfmt
- runs-on: ubuntu-latest
+ rustfmt:
+ runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all -- --check
+ - run: cd testsuite && cargo fmt --all -- --check
diff --git a/cortex-m-rt/ci/script.sh b/cortex-m-rt/ci/script.sh
index b78e0f01..416603cd 100755
--- a/cortex-m-rt/ci/script.sh
+++ b/cortex-m-rt/ci/script.sh
@@ -2,18 +2,17 @@
set -euxo pipefail
-main() {
- cargo check --target "$TARGET"
+CARGO="cargo +${CI_RUST_VERSION}"
- cargo check --target "$TARGET" --features device
+main() {
+ $CARGO check --target "$TARGET"
- # A `critical_section` implementation is always needed.
- needed_features=
+ $CARGO check --target "$TARGET" --features device
- if [ "$TARGET" = x86_64-unknown-linux-gnu ] && [ "$TRAVIS_RUST_VERSION" = stable ]; then
- ( cd macros && cargo check && cargo test )
+ if [ "$TARGET" = x86_64-unknown-linux-gnu ] && [ "$CI_RUST_VERSION" = stable ]; then
+ ( cd macros && $CARGO check && $CARGO test )
- cargo test --features "device,${needed_features}" --test compiletest
+ $CARGO test --features "device" --test compiletest
fi
local examples=(
@@ -46,38 +45,36 @@ main() {
)
if [ "$TARGET" != x86_64-unknown-linux-gnu ]; then
# Only test on stable and nightly, not MSRV.
- if [ "$TRAVIS_RUST_VERSION" = stable ] || [ "$TRAVIS_RUST_VERSION" = nightly ]; then
- RUSTDOCFLAGS="-Cpanic=abort" cargo test --features "${needed_features}" --doc
+ if [ "$CI_RUST_VERSION" = stable ] || [ "$CI_RUST_VERSION" = nightly ]; then
+ RUSTDOCFLAGS="-Cpanic=abort" $CARGO test --doc
fi
for linker in "${linkers[@]}"; do
for ex in "${examples[@]}"; do
- cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" -- $linker
- cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" --release -- $linker
+ $CARGO rustc --target "$TARGET" --example "$ex" -- $linker
+ $CARGO rustc --target "$TARGET" --example "$ex" --release -- $linker
done
for ex in "${fail_examples[@]}"; do
- cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" -- $linker && exit 1
- cargo rustc --target "$TARGET" --example "$ex" --features "${needed_features}" --release -- $linker && exit 1
+ $CARGO rustc --target "$TARGET" --example "$ex" -- $linker && exit 1
+ $CARGO rustc --target "$TARGET" --example "$ex" --release -- $linker && exit 1
done
- cargo rustc --target "$TARGET" --example device --features "device,${needed_features}" -- $linker
- cargo rustc --target "$TARGET" --example device --features "device,${needed_features}" --release -- $linker
+ $CARGO rustc --target "$TARGET" --example device --features "device" -- $linker
+ $CARGO rustc --target "$TARGET" --example device --features "device" --release -- $linker
- cargo rustc --target "$TARGET" --example minimal --features "set-sp,${needed_features}" -- $linker
- cargo rustc --target "$TARGET" --example minimal --features "set-sp,${needed_features}" --release -- $linker
- cargo rustc --target "$TARGET" --example minimal --features "zero-init-ram,${needed_features}" -- $linker
- cargo rustc --target "$TARGET" --example minimal --features "zero-init-ram,${needed_features}" --release -- $linker
- cargo rustc --target "$TARGET" --example minimal --features "set-vtor,${needed_features}" -- $linker
- cargo rustc --target "$TARGET" --example minimal --features "set-vtor,${needed_features}" --release -- $linker
+ $CARGO rustc --target "$TARGET" --example minimal --features "set-sp" -- $linker
+ $CARGO rustc --target "$TARGET" --example minimal --features "set-sp" --release -- $linker
+ $CARGO rustc --target "$TARGET" --example minimal --features "zero-init-ram" -- $linker
+ $CARGO rustc --target "$TARGET" --example minimal --features "zero-init-ram" --release -- $linker
+ $CARGO rustc --target "$TARGET" --example minimal --features "set-vtor" -- $linker
+ $CARGO rustc --target "$TARGET" --example minimal --features "set-vtor" --release -- $linker
done
fi
case $TARGET in
thumbv6m-none-eabi|thumbv7m-none-eabi)
for linker in "${linkers[@]}"; do
- env RUSTFLAGS="$linker -C link-arg=-Tlink.x" cargo run \
- --target "$TARGET" --features "${needed_features}" --example qemu | grep "x = 42"
- env RUSTFLAGS="$linker -C link-arg=-Tlink.x" cargo run \
- --target "$TARGET" --features "${needed_features}" --example qemu --release | grep "x = 42"
+ env RUSTFLAGS="$linker -C link-arg=-Tlink.x" $CARGO run --target "$TARGET" --example qemu | grep "x = 42"
+ env RUSTFLAGS="$linker -C link-arg=-Tlink.x" $CARGO run --target "$TARGET" --example qemu --release | grep "x = 42"
done
;;
diff --git a/justfile b/justfile
index 0659b1e7..cd9882c7 100644
--- a/justfile
+++ b/justfile
@@ -1,7 +1,98 @@
+all: testsuite unit-test clippy clippy-test fmt-check
+
+testsuite: testsuite-thumbv8m-main-none-eabihf testsuite-thumbv8m-main-none-eabi testsuite-thumbv8m-base-none-eabi testsuite-thumbv7em-none-eabihf testsuite-thumbv7em-none-eabi testsuite-thumbv7m-none-eabi testsuite-thumbv6m-none-eabi
+
+# Run the on-target testsuite on QEMU on thumbv8m.main-none-eabihf
+[working-directory: "testsuite"]
+testsuite-thumbv8m-main-none-eabihf:
+ cargo test --features qemu --target thumbv8m.main-none-eabihf --release
+
+# Run the on-target testsuite on QEMU on thumbv8m.main-none-eabi
+[working-directory: "testsuite"]
+testsuite-thumbv8m-main-none-eabi:
+ cargo test --features qemu --target thumbv8m.main-none-eabi --release
+
+# Run the on-target testsuite on QEMU on thumbv8m.base-none-eabi
+[working-directory: "testsuite"]
+testsuite-thumbv8m-base-none-eabi:
+ cargo test --features qemu --target thumbv8m.base-none-eabi --release
+
+# Run the on-target testsuite on QEMU on thumbv7em-none-eabihf
+[working-directory: "testsuite"]
+testsuite-thumbv7em-none-eabihf:
+ cargo test --features qemu --target thumbv7em-none-eabihf --release
+
+# Run the on-target testsuite on QEMU on thumbv7em-none-eabi
+[working-directory: "testsuite"]
+testsuite-thumbv7em-none-eabi:
+ cargo test --features qemu --target thumbv7em-none-eabi --release
+
+# Run the on-target testsuite on QEMU on thumbv7m-none-eabi
[working-directory: "testsuite"]
-run-cortex-m3-test:
- cargo test --features qemu --target thumbv7em-none-eabihf
+testsuite-thumbv7m-none-eabi:
+ cargo test --features qemu --target thumbv7m-none-eabi --release
+# Run the on-target testsuite on QEMU on thumbv6m-none-eabi
[working-directory: "testsuite"]
-run-cortex-m0-test:
+testsuite-thumbv6m-none-eabi:
cargo test --features qemu --target thumbv6m-none-eabi --release
+
+# cortex-m-rt build tests
+build-tests: build-test-nightly build-test-stable build-test-msrv
+
+build-test-nightly: \
+ (build-test "thumbv6m-none-eabi" "nightly") \
+ (build-test "thumbv7m-none-eabi" "nightly") \
+ (build-test "thumbv7em-none-eabi" "nightly") \
+ (build-test "thumbv7em-none-eabihf" "nightly") \
+ (build-test "thumbv8m.base-none-eabi" "nightly") \
+ (build-test "thumbv8m.main-none-eabi" "nightly") \
+ (build-test "thumbv8m.main-none-eabihf" "nightly") \
+ (build-test "x86_64-unknown-linux-gnu" "nightly") \
+
+build-test-stable: \
+ (build-test "thumbv6m-none-eabi" "stable") \
+ (build-test "thumbv7m-none-eabi" "stable") \
+ (build-test "thumbv7em-none-eabi" "stable") \
+ (build-test "thumbv7em-none-eabihf" "stable") \
+ (build-test "thumbv8m.base-none-eabi" "stable") \
+ (build-test "thumbv8m.main-none-eabi" "stable") \
+ (build-test "thumbv8m.main-none-eabihf" "stable") \
+ (build-test "x86_64-unknown-linux-gnu" "stable") \
+
+build-test-msrv: \
+ (build-test "thumbv6m-none-eabi" "1.85") \
+ (build-test "thumbv7m-none-eabi" "1.85") \
+ (build-test "thumbv7em-none-eabi" "1.85") \
+ (build-test "thumbv7em-none-eabihf" "1.85") \
+ (build-test "thumbv8m.base-none-eabi" "1.85") \
+ (build-test "thumbv8m.main-none-eabi" "1.85") \
+ (build-test "thumbv8m.main-none-eabihf" "1.85") \
+ (build-test "x86_64-unknown-linux-gnu" "1.85") \
+
+[working-directory: "cortex-m-rt"]
+build-test target rust-version:
+ TARGET={{target}} CI_RUST_VERSION={{rust-version}} bash ci/script.sh
+
+# Run the unit tests
+unit-test:
+ cargo test --all --exclude cortex-m-rt --features cortex-m/critical-section-single-core
+
+# Run clippy on the testsuite
+[working-directory: "testsuite"]
+clippy-test:
+ cargo clippy --features qemu -- -D warnings
+
+# Run clippy on the workspace
+clippy:
+ cargo clippy --all --features cortex-m/critical-section-single-core -- -D warnings
+
+# Format all the code (the workspace and the testsuite)
+fmt:
+ cargo fmt --all
+ cd testsuite && cargo fmt --all
+
+# Check if the code is formatted correctly (the workspace and the testsuite)
+fmt-check:
+ cargo fmt --all -- --check
+ cd testsuite && cargo fmt --all -- --check
diff --git a/testsuite/.cargo/config.toml b/testsuite/.cargo/config.toml
index 4be2b8c6..96ead0a1 100644
--- a/testsuite/.cargo/config.toml
+++ b/testsuite/.cargo/config.toml
@@ -5,7 +5,23 @@ rustflags = [
"-C", "link-arg=-Tdefmt.x",
]
+[target.thumbv8m.base-none-eabi]
+# We don't have a Cortex-M23 machine, but this should work
+runner = "qemu-run --machine mps2-an505 --cpu cortex-m33"
+
+[target.thumbv8m.main-none-eabi]
+runner = "qemu-run --machine mps2-an505 --cpu cortex-m33"
+
+[target.thumbv8m.main-none-eabihf]
+runner = "qemu-run --machine mps2-an505 --cpu cortex-m33"
+
[target.thumbv7em-none-eabihf]
+runner = "qemu-run --machine lm3s6965evb --cpu cortex-m4"
+
+[target.thumbv7em-none-eabi]
+runner = "qemu-run --machine lm3s6965evb --cpu cortex-m4"
+
+[target.thumbv7m-none-eabi]
runner = "qemu-run --machine lm3s6965evb --cpu cortex-m3"
[target.thumbv6m-none-eabi]
diff --git a/testsuite/Cargo.toml b/testsuite/Cargo.toml
index 83ceb07c..6b628223 100644
--- a/testsuite/Cargo.toml
+++ b/testsuite/Cargo.toml
@@ -23,6 +23,9 @@ defmt = "1"
[dev-dependencies]
defmt-test = "0.4"
+[build-dependencies]
+arm-targets = "0.4.2"
+
# for the library crate (src/lib.rs)
[lib]
harness = false
@@ -39,3 +42,4 @@ cortex-m-rt = { path = "../cortex-m-rt" }
opt-level = "z" # Optimize for size
lto = true # Enable Link Time Optimization
codegen-units = 1 # Better optimization at cost of compile time
+debug = 2
diff --git a/testsuite/build.rs b/testsuite/build.rs
index 3d65b52a..d034aeed 100644
--- a/testsuite/build.rs
+++ b/testsuite/build.rs
@@ -1,66 +1,22 @@
+use arm_targets::Arch;
use std::{env, path::PathBuf};
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum MemorySelect {
- CortexM0,
- CortexM3,
-}
fn main() {
- let target = std::env::var("TARGET").unwrap();
-
- println!("cargo:rustc-check-cfg=cfg(armv6m)");
- println!("cargo:rustc-check-cfg=cfg(armv7m)");
- println!("cargo:rustc-check-cfg=cfg(armv7em)");
- println!("cargo:rustc-check-cfg=cfg(armv8m)");
- println!("cargo:rustc-check-cfg=cfg(armv8m_base)");
- println!("cargo:rustc-check-cfg=cfg(armv8m_main)");
-
- let mut memory_select = None;
- if target.starts_with("thumbv6m-") {
- memory_select = Some(MemorySelect::CortexM0);
- println!("cargo:rustc-cfg=armv6m");
- } else if target.starts_with("thumbv7m-") {
- memory_select = Some(MemorySelect::CortexM3);
- println!("cargo:rustc-cfg=armv7m");
- } else if target.starts_with("thumbv7em-") {
- memory_select = Some(MemorySelect::CortexM3);
- println!("cargo:rustc-cfg=armv7m");
- println!("cargo:rustc-cfg=armv7em"); // (not currently used)
- } else if target.starts_with("thumbv8m.base") {
- println!("cargo:rustc-cfg=armv8m");
- println!("cargo:rustc-cfg=armv8m_base");
- } else if target.starts_with("thumbv8m.main") {
- println!("cargo:rustc-cfg=armv8m");
- println!("cargo:rustc-cfg=armv8m_main");
- }
+ let target_info = arm_targets::process();
let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
- let memory_x_file = match memory_select {
- Some(MemorySelect::CortexM0) => {
- // Put `memory.x` in our output directory and ensure it's
- // on the linker search path.
- "memory_microbit.x"
- }
- Some(MemorySelect::CortexM3) => {
- // Put `memory.x` in our output directory and ensure it's
- // on the linker search path.
- "memory_m3.x"
- }
- // TODO: Copy memory.x if it exists?
- None => panic!("Unsupported target architecture: {}", target),
+ let memory_x_file = match target_info.arch() {
+ Some(Arch::Armv6M) => "memory_microbit.x",
+ Some(Arch::Armv7M) | Some(Arch::Armv7EM) => "memory_lm3s6965evb.x",
+ Some(Arch::Armv8MBase) | Some(Arch::Armv8MMain) => "memory_mps2_an505.x",
+ _ => panic!("Unsupported target architecture: {:?}", target_info),
};
+ println!("cargo:rerun-if-changed={}", memory_x_file);
let target_path = out.join("memory.x");
// Copy memory.x from parent directory only if it doesn't exist locally
- std::fs::copy(memory_x_file, &target_path)
- .unwrap_or_else(|e| panic!("Failed to copy memory.x: {}", e));
+ std::fs::copy(memory_x_file, &target_path).expect("Failed to copy memory.x for target");
+ // Tell linker to look where we just put the file
println!("cargo:rustc-link-search={}", out.display());
-
- // By default, Cargo will re-run a build script whenever
- // any file in the project changes. By specifying `memory.x`
- // here, we ensure the build script is only re-run when
- // `memory.x` is changed.
- println!("cargo:rerun-if-changed=memory_m3.x");
- println!("cargo:rerun-if-changed=memory_microbit.x");
}
diff --git a/testsuite/commands.gdb b/testsuite/commands.gdb
new file mode 100644
index 00000000..c5cd2564
--- /dev/null
+++ b/testsuite/commands.gdb
@@ -0,0 +1,7 @@
+target extended-remote :1234
+break main
+layout asm
+layout regs
+set logging file ./target/debug.log
+set logging enabled on
+stepi
diff --git a/testsuite/memory_m3.x b/testsuite/memory_lm3s6965evb.x
similarity index 100%
rename from testsuite/memory_m3.x
rename to testsuite/memory_lm3s6965evb.x
diff --git a/testsuite/memory_mps2_an505.x b/testsuite/memory_mps2_an505.x
new file mode 100644
index 00000000..9b39fa75
--- /dev/null
+++ b/testsuite/memory_mps2_an505.x
@@ -0,0 +1,7 @@
+/* Memory map for MPS2-AN505, using Non-Secure memory */
+MEMORY
+{
+ /* NOTE K = KiBi = 1024 bytes */
+ FLASH : ORIGIN = 0x10000000, LENGTH = 4M
+ RAM : ORIGIN = 0x28000000, LENGTH = 2M
+}
diff --git a/testsuite/src/lib.rs b/testsuite/src/lib.rs
index a684407f..3ec3c9a8 100644
--- a/testsuite/src/lib.rs
+++ b/testsuite/src/lib.rs
@@ -166,8 +166,8 @@ mod tests {
cortex_m::asm::semihosting_syscall(SYS_WRITE0, msg.as_ptr() as usize as u32);
}
}
-
- #[cfg(armv8m)]
+
+ #[cfg(any(arm_architecture = "v8-m.base", arm_architecture = "v8-m.main"))]
#[test]
fn sau_set_get_region(p: &mut cortex_m::Peripherals) {
use cortex_m::peripheral::sau::{SauRegion, SauRegionAttribute};
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 23c4aecb..2059a8c9 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -1,19 +1,43 @@
//! `cargo xtask` automation.
//!
//! Please refer to for an explanation of the concept.
-//!
-//! Also see the docs in `asm.rs`.
use std::process::Command;
-pub fn install_targets(targets: &mut dyn Iterator- , toolchain: Option<&str>) {
+/// List of all compilation targets we support.
+///
+/// This should generally list all of the bare-metal thumb targets starting at thumbv6.
+pub static ALL_TARGETS: &[&str] = &[
+ "thumbv6m-none-eabi",
+ "thumbv7m-none-eabi",
+ "thumbv7em-none-eabi",
+ "thumbv7em-none-eabihf",
+ "thumbv8m.base-none-eabi",
+ "thumbv8m.main-none-eabi",
+ "thumbv8m.main-none-eabihf",
+];
+
+/// Same as the list above, except with all "base" targets that have a reduced feature set removed.
+pub static NON_BASE_TARGETS: &[&str] = &[
+ "thumbv7m-none-eabi",
+ "thumbv7em-none-eabi",
+ "thumbv7em-none-eabihf",
+ "thumbv8m.main-none-eabi",
+ "thumbv8m.main-none-eabihf",
+];
+
+#[rustfmt::skip]
+pub static PACKAGE_FEATURES: &[(&str, &[&str], &[&str])] = &[
+ ("cortex-m", ALL_TARGETS, &["cm7-r0p1", "critical-section-single-core"]), // no `linker-plugin-lto` since it's experimental
+ ("cortex-m-semihosting", ALL_TARGETS, &["no-semihosting", "jlink-quirks"]),
+ ("panic-semihosting", ALL_TARGETS, &["exit", "jlink-quirks"]),
+ ("panic-itm", NON_BASE_TARGETS, &[]),
+];
+
+pub fn install_targets(targets: &[&str]) {
let mut rustup = Command::new("rustup");
rustup.arg("target").arg("add").args(targets);
- if let Some(toolchain) = toolchain {
- rustup.arg("--toolchain").arg(toolchain);
- }
-
let status = rustup.status().unwrap();
assert!(status.success(), "rustup command failed: {:?}", rustup);
}
@@ -38,3 +62,63 @@ pub fn check_host_side() {
assert!(a < b);
}
}
+
+pub fn check_crates_build(is_nightly: bool) {
+ // Build all crates for each supported target.
+ for (package, targets, all_features) in PACKAGE_FEATURES {
+ for target in *targets {
+ // Filters crate features, keeping only those that are supported.
+ // Relies on all crates in this repo to use the same convention.
+ let should_use_feature = |feat: &str| {
+ match feat {
+ // This is nightly-only, so don't use it on stable.
+ "inline-asm" => is_nightly,
+ // This only affects thumbv7em targets.
+ "cm7-r0p1" => target.starts_with("thumbv7em"),
+
+ _ => true,
+ }
+ };
+
+ // Every crate must build with the default feature set.
+ build(package, target, &[]);
+
+ let used_features = &*all_features
+ .iter()
+ .copied()
+ .filter(|feat| should_use_feature(feat))
+ .collect::>();
+
+ // (note: we don't test with default features disabled, since we don't use them yet)
+
+ // Every crate must build with each individual feature enabled.
+ for feat in used_features {
+ build(package, target, &[*feat]);
+ }
+
+ // Every crate must build with *all* features enabled.
+ build(package, target, used_features);
+
+ // (technically we should be checking the powerset of all features if we wanted to be
+ // *really* sure, but that takes too much time and isn't very easy to implement)
+ }
+ }
+}
+
+fn build(package: &str, target: &str, features: &[&str]) {
+ println!("building {} for {} {:?}", package, target, features);
+ let mut cargo = Command::new("cargo");
+ cargo.args(["build", "-p", package, "--target", target]);
+ for feat in features {
+ cargo.args(["--features", *feat]);
+ }
+
+ // Cargo features don't work right when invoked from the workspace root, so change to the
+ // package's directory when necessary.
+ if package != "cortex-m" {
+ cargo.current_dir(package);
+ }
+
+ let status = cargo.status().unwrap();
+ assert!(status.success(), "failed to execute: {:?}", cargo);
+}
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 224be3fe..ebc6b3bf 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -1,18 +1,29 @@
-use std::{env, process};
-use xtask::check_host_side;
+use xtask::{ALL_TARGETS, check_crates_build, check_host_side, install_targets};
+#[rustfmt::skip]
fn main() {
- let subcommand = env::args().nth(1);
+ let subcommand = std::env::args().nth(1);
match subcommand.as_deref() {
+ Some("install-targets") => install_targets(ALL_TARGETS),
Some("check-host-side") => check_host_side(),
+ Some("check-crates-build") => {
+ let output = std::process::Command::new("rustc")
+ .arg("-V")
+ .output()
+ .unwrap();
+ let is_nightly = std::str::from_utf8(&output.stdout).unwrap().contains("nightly");
+ check_crates_build(is_nightly)
+ }
_ => {
eprintln!("usage: cargo xtask ");
eprintln!();
eprintln!("subcommands:");
- eprintln!(
- " check-host-side Build the crate in a non-Cortex-M host application and check host side usage of certain types"
- );
- process::exit(1);
+ eprintln!(" check-host-side Build the crate in a non-Cortex-M host application and check host side usage of certain types");
+ eprintln!(" check-crates-build Check the workspace can be built for all known targets");
+ eprintln!(" install-targets Use rustup to install all the appropriate targets");
+ eprintln!();
+ eprintln!("You can also run 'cargo test' in the ./xtask directory");
+ std::process::exit(1);
}
}
}
diff --git a/xtask/tests/ci.rs b/xtask/tests/ci.rs
index 62530e29..6ecec6ee 100644
--- a/xtask/tests/ci.rs
+++ b/xtask/tests/ci.rs
@@ -1,108 +1,18 @@
use std::process::Command;
-use std::{env, str};
-use xtask::{check_host_side, install_targets};
-
-/// List of all compilation targets we support.
-///
-/// This should generally list all of the bare-metal thumb targets starting at thumbv6.
-static ALL_TARGETS: &[&str] = &[
- "thumbv6m-none-eabi",
- "thumbv7m-none-eabi",
- "thumbv7em-none-eabi",
- "thumbv7em-none-eabihf",
- "thumbv8m.base-none-eabi",
- "thumbv8m.main-none-eabi",
- "thumbv8m.main-none-eabihf",
-];
-
-/// Same as the list above, except with all "base" targets that have a reduced feature set removed.
-static NON_BASE_TARGETS: &[&str] = &[
- "thumbv7m-none-eabi",
- "thumbv7em-none-eabi",
- "thumbv7em-none-eabihf",
- "thumbv8m.main-none-eabi",
- "thumbv8m.main-none-eabihf",
-];
-
-fn build(package: &str, target: &str, features: &[&str]) {
- println!("building {} for {} {:?}", package, target, features);
- let mut cargo = Command::new("cargo");
- cargo.args(&["build", "-p", package, "--target", target]);
- for feat in features {
- cargo.args(&["--features", *feat]);
- }
-
- // Cargo features don't work right when invoked from the workspace root, so change to the
- // package's directory when necessary.
- if package != "cortex-m" {
- cargo.current_dir(package);
- }
-
- let status = cargo.status().unwrap();
- assert!(status.success(), "failed to execute: {:?}", cargo);
-}
-
-#[rustfmt::skip]
-static PACKAGE_FEATURES: &[(&str, &[&str], &[&str])] = &[
- ("cortex-m", ALL_TARGETS, &["cm7-r0p1", "critical-section-single-core"]), // no `linker-plugin-lto` since it's experimental
- ("cortex-m-semihosting", ALL_TARGETS, &["no-semihosting", "jlink-quirks"]),
- ("panic-semihosting", ALL_TARGETS, &["exit", "jlink-quirks"]),
- ("panic-itm", NON_BASE_TARGETS, &[]),
-];
-
-fn check_crates_build(is_nightly: bool, is_msrv: bool) {
- // Build all crates for each supported target.
- for (package, targets, all_features) in PACKAGE_FEATURES {
- for target in *targets {
- // Filters crate features, keeping only those that are supported.
- // Relies on all crates in this repo to use the same convention.
- let should_use_feature = |feat: &str| {
- match feat {
- // This is nightly-only, so don't use it on stable.
- "inline-asm" => is_nightly,
- // This only affects thumbv7em targets.
- "cm7-r0p1" => target.starts_with("thumbv7em"),
-
- _ => true,
- }
- };
-
- // Every crate must build with the default feature set.
- build(package, target, &[]);
-
- let used_features = &*all_features
- .iter()
- .copied()
- .filter(|feat| should_use_feature(*feat))
- .collect::>();
-
- // (note: we don't test with default features disabled, since we don't use them yet)
-
- // Every crate must build with each individual feature enabled.
- for feat in used_features {
- build(package, target, &[*feat]);
- }
-
- // Every crate must build with *all* features enabled.
- build(package, target, used_features);
-
- // (technically we should be checking the powerset of all features if we wanted to be
- // *really* sure, but that takes too much time and isn't very easy to implement)
- }
- }
-}
+use xtask::{ALL_TARGETS, check_crates_build, check_host_side, install_targets};
fn main() {
// Tests execute in the containing crate's root dir, `cd ..` so that we find `asm` etc.
- env::set_current_dir("..").unwrap();
+ std::env::set_current_dir("..").unwrap();
- install_targets(&mut ALL_TARGETS.iter().cloned(), None);
+ install_targets(ALL_TARGETS);
let output = Command::new("rustc").arg("-V").output().unwrap();
- let is_nightly = str::from_utf8(&output.stdout).unwrap().contains("nightly");
- let is_msrv = str::from_utf8(&output.stdout).unwrap().contains("1.59");
+ let is_nightly = std::str::from_utf8(&output.stdout)
+ .unwrap()
+ .contains("nightly");
- check_crates_build(is_nightly, is_msrv);
+ check_crates_build(is_nightly);
// Check host-side applications of the crate.
check_host_side();