├── .cargo └── config.toml ├── .github ├── ISSUE_TEMPLATE │ └── bug-report-or-problem.md └── workflows │ ├── changelog.yml │ └── ci.yml ├── .gitignore ├── .idea ├── .gitignore ├── embedded-test.iml ├── modules.xml ├── runConfigurations │ ├── Run_bin_target_stm32f767.xml │ ├── Test_esp32c6_defmt.xml │ ├── Test_esp32c6_log.xml │ ├── Test_stm32f767_defmt.xml │ └── Test_stm32f767_log.xml └── vcs.xml ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── README.md ├── build.rs ├── demo.gif ├── embedded-test.x ├── examples ├── esp32c6 │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── src │ │ ├── lib.rs │ │ └── main.rs │ └── tests │ │ └── example_test.rs ├── std │ ├── .cargo │ │ └── config.toml │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── src │ │ ├── lib.rs │ │ └── main.rs │ └── tests │ │ └── example_test.rs └── stm32f767 │ ├── .cargo │ └── config.toml │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── README.md │ ├── build.rs │ ├── memory.x │ ├── src │ ├── lib.rs │ └── main.rs │ └── tests │ └── example_test.rs ├── macros ├── .gitignore ├── Cargo.toml ├── README.md └── src │ └── lib.rs └── src ├── export.rs ├── fmt.rs ├── lib.rs ├── semihosting.rs └── std.rs /.cargo/config.toml: -------------------------------------------------------------------------------- 1 | 2 | [build] 3 | target = "riscv32imac-unknown-none-elf" -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report-or-problem.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report or Problem 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ### Before you start 11 | 12 | 1. Please check whether you're experiencing an issue listed in the [FAQ](https://github.com/probe-rs/embedded-test/wiki/FAQ-and-common-errors). 13 | 2. Issues related to the host-side of this project are kept in the probe-rs repository (tagged [`component:embedded-test`](https://github.com/probe-rs/probe-rs/issues?q=is%3Aissue%20state%3Aopen%20label%3Acomponent%3Aembedded-test)) . If you already know the issue is related to the host-side, feel free to open the issue over there and to tag the maintainer of embedded-test (@t-moe). 14 | 15 | Thank you! 16 | 17 | ------ 18 | 19 | **Describe the bug** 20 | A clear and concise description of what the bug is. 21 | 22 | **Version information** 23 | * `probe-rs --version` 24 | * the version of embedded test 25 | * Include the output of `cargo tree | grep "embassy" -C3` if you are facing issues with embassy 26 | 27 | **To Reproduce** 28 | Steps to reproduce the behavior: 29 | 1. Go to '...' 30 | 2. Click on '....' 31 | 3. Scroll down to '....' 32 | 4. See error 33 | 34 | **Expected behavior** 35 | A clear and concise description of what you expected to happen. 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/workflows/changelog.yml: -------------------------------------------------------------------------------- 1 | name: Changelog check 2 | 3 | on: 4 | pull_request: 5 | # We will not track changes for the following packages/directories. 6 | paths-ignore: 7 | - "/examples/" 8 | # Run on labeled/unlabeled in addition to defaults to detect 9 | # adding/removing skip-changelog labels. 10 | types: [opened, reopened, labeled, unlabeled, synchronize] 11 | 12 | jobs: 13 | changelog: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout sources 18 | uses: actions/checkout@v4 19 | 20 | - name: Check that changelog updated 21 | uses: dangoslen/changelog-enforcer@v3 22 | with: 23 | skipLabels: "skip-changelog" 24 | missingUpdateErrorMessage: "Please add a changelog entry in the CHANGELOG.md file." -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This action builds* all the pushes to master, staging and trying which are required for bors. 2 | # Additionally it builds* for each PR. 3 | # 4 | # * builds includes building, checking, testing, checking format and clippy, as well as the changelog. 5 | 6 | on: 7 | push: 8 | branches: [master, staging, trying] 9 | pull_request: 10 | merge_group: 11 | 12 | # Cancel any currently running workflows from the same PR, branch, or 13 | # tag when a new workflow is triggered. 14 | # 15 | # https://stackoverflow.com/a/66336834 16 | concurrency: 17 | cancel-in-progress: true 18 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 19 | 20 | name: Run CI 21 | 22 | jobs: 23 | check: 24 | name: Check 25 | strategy: 26 | matrix: 27 | toolchain: 28 | - stable 29 | - nightly 30 | #os: 31 | #- ubuntu-latest 32 | #- windows-latest 33 | #- macos-14 34 | log_kind: 35 | - log 36 | - defmt 37 | 38 | target_and_example: [ 39 | # RISC-V devices: 40 | { target: "riscv32imac-unknown-none-elf", example: "examples/esp32c6/Cargo.toml" }, 41 | # arm7 devices: 42 | { target: "thumbv7em-none-eabihf", example: "examples/stm32f767/Cargo.toml" }, 43 | ] 44 | 45 | 46 | runs-on: ubuntu-latest #${{ matrix.os }} 47 | 48 | env: 49 | VCPKGRS_DYNAMIC: 1 # Use dynamic linking on Windows build (vcpkg) 50 | 51 | steps: 52 | - name: Checkout sources 53 | uses: actions/checkout@v4 54 | 55 | - name: Install target 56 | uses: dtolnay/rust-toolchain@v1 57 | with: 58 | target: ${{ matrix.target_and_example.target}} 59 | toolchain: ${{ matrix.toolchain }} 60 | components: rust-src 61 | 62 | - name: Cache Dependencies 63 | uses: Swatinem/rust-cache@v2.7.5 64 | 65 | - name: Run cargo check for embedded-test 66 | run: cargo check --target ${{ matrix.target_and_example.target}} --features ${{matrix.log_kind}} --locked 67 | 68 | - name: Run cargo check for example 69 | run: cargo check --target ${{ matrix.target_and_example.target}} --no-default-features --features ${{matrix.log_kind}} --manifest-path ${{matrix.target_and_example.example}} --locked --all-targets 70 | 71 | fmt: 72 | name: Rustfmt 73 | runs-on: ubuntu-latest 74 | steps: 75 | - name: Checkout sources 76 | uses: actions/checkout@v4 77 | 78 | - name: Run cargo fmt 79 | run: cargo fmt --all -- --check 80 | 81 | clippy: 82 | name: Clippy 83 | runs-on: ubuntu-latest 84 | steps: 85 | - name: Checkout sources 86 | uses: actions/checkout@v4 87 | 88 | - name: Install riscv32imac-unknown-none-elf target 89 | run: rustup target add riscv32imac-unknown-none-elf 90 | 91 | - name: Cache Dependencies 92 | uses: Swatinem/rust-cache@v2.7.5 93 | 94 | - name: Run cargo clippy 95 | run: cargo clippy --locked -- -D warnings 96 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /embedded-test-example 3 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/embedded-test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Run_bin_target_stm32f767.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Test_esp32c6_defmt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Test_esp32c6_log.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Test_stm32f767_defmt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Test_stm32f767_log.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 20 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## Unreleased 9 | 10 | ## [0.6.1] 11 | 12 | ### Added 13 | 14 | - Support [Ariel OS](https://ariel-os.org). 15 | - Support to run test on the host/std for Ariel OS. 16 | 17 | ### Changed 18 | - Updated defmt 0.3.8 => 1 19 | 20 | 21 | ## [0.6.0] 22 | 23 | ### Added 24 | 25 | - `#[tests(default_timeout = )]` to configure a suite-wide default timeout. 26 | - `#[tests(setup = )]` to configure a suite-wide (log) setup function (e.g. `rtt_target::rtt_init_log()`). 27 | 28 | ### Removed 29 | 30 | - Breaking: Removed Features `init-log` and `init-rtt`. 31 | 32 | ### Changed 33 | 34 | - Breaking: Bump embassy-excecutor to 0.7.0 35 | 36 | ## [0.5.0] 37 | 38 | ### Changed 39 | 40 | - Breaking: Bump embassy-excecutor to 0.6.1 41 | 42 | ## [0.4.0] 43 | 44 | ### Added 45 | 46 | - Make it possible to bring your own Embassy executor (feature `external-executor`) 47 | - Added panic handler directly to this crate (enabled per default, feature `panic-handler`) 48 | - Added support for xtensa semihosting (feature `xtensa-semihosting`) 49 | - Added feature to initialize logging sink (feature `init-log`) 50 | - Breaking: Added a linker script, to ensure symbols like `EMBEDDED_TEST_VERSION` are kept 51 | 52 | ### Changed 53 | 54 | - Feature `rtt` renamed to `init-rtt` to better reflect its purpose. 55 | 56 | ## [0.3.0] 57 | 58 | ### Added 59 | 60 | - Added Feature `rtt` to initialize logging via `rtt-target` crate. 61 | 62 | ### Changed 63 | 64 | - Breaking: Bump embassy-excecutor to 0.5.0 65 | 66 | ## [0.2.3] 67 | 68 | ### Added 69 | 70 | - Show improved diagnostic when no executor feature is enabled on the embassy-executor crate. 71 | - Calculate the test list buffer size at compile time to avoid a too small buffer. 72 | 73 | ### Fixed 74 | 75 | - Macro produced invalid rust code when there was no #[init] function present. 76 | 77 | ## [0.2.2] 78 | 79 | ### Changed 80 | 81 | - Removed `#![feature(trait_alias)]` to allow usage of `embedded-test` in stable rust. 82 | 83 | ### Fixed 84 | 85 | - Updated `semihosting` dependency to fix failing build for cortex-m targets. 86 | 87 | ## [0.2.1] 88 | 89 | Initial release on crates.io 90 | 91 | [unreleased]: https://github.com/probe-rs/embedded-test/compare/v0.6.1...master 92 | 93 | [0.6.1]: https://github.com/probe-rs/embedded-test/compare/v0.6.0...v0.6.1 94 | 95 | [0.6.0]: https://github.com/probe-rs/embedded-test/compare/v0.5.0...v0.6.0 96 | 97 | [0.5.0]: https://github.com/probe-rs/embedded-test/compare/v0.4.0...v0.5.0 98 | 99 | [0.4.0]: https://github.com/probe-rs/embedded-test/compare/v0.3.0...v0.4.0 100 | 101 | [0.3.0]: https://github.com/probe-rs/embedded-test/compare/v0.2.3...v0.3.0 102 | 103 | [0.2.3]: https://github.com/probe-rs/embedded-test/compare/v0.2.2...v0.2.3 104 | 105 | [0.2.2]: https://github.com/probe-rs/embedded-test/compare/v0.2.1...v0.2.2 106 | 107 | [0.2.1]: https://github.com/probe-rs/embedded-test/releases/tag/v0.2.1 108 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "atomic-polyfill" 7 | version = "1.0.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" 10 | dependencies = [ 11 | "critical-section", 12 | ] 13 | 14 | [[package]] 15 | name = "autocfg" 16 | version = "1.4.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 19 | 20 | [[package]] 21 | name = "bitflags" 22 | version = "1.3.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 25 | 26 | [[package]] 27 | name = "byteorder" 28 | version = "1.5.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 31 | 32 | [[package]] 33 | name = "critical-section" 34 | version = "1.2.0" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" 37 | 38 | [[package]] 39 | name = "darling" 40 | version = "0.20.11" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 43 | dependencies = [ 44 | "darling_core", 45 | "darling_macro", 46 | ] 47 | 48 | [[package]] 49 | name = "darling_core" 50 | version = "0.20.11" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 53 | dependencies = [ 54 | "fnv", 55 | "ident_case", 56 | "proc-macro2", 57 | "quote", 58 | "strsim", 59 | "syn", 60 | ] 61 | 62 | [[package]] 63 | name = "darling_macro" 64 | version = "0.20.11" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 67 | dependencies = [ 68 | "darling_core", 69 | "quote", 70 | "syn", 71 | ] 72 | 73 | [[package]] 74 | name = "defmt" 75 | version = "1.0.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" 78 | dependencies = [ 79 | "bitflags", 80 | "defmt-macros", 81 | ] 82 | 83 | [[package]] 84 | name = "defmt-macros" 85 | version = "1.0.1" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" 88 | dependencies = [ 89 | "defmt-parser", 90 | "proc-macro-error2", 91 | "proc-macro2", 92 | "quote", 93 | "syn", 94 | ] 95 | 96 | [[package]] 97 | name = "defmt-parser" 98 | version = "1.0.0" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" 101 | dependencies = [ 102 | "thiserror", 103 | ] 104 | 105 | [[package]] 106 | name = "document-features" 107 | version = "0.2.11" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" 110 | dependencies = [ 111 | "litrs", 112 | ] 113 | 114 | [[package]] 115 | name = "embassy-executor" 116 | version = "0.7.0" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "90327bcc66333a507f89ecc4e2d911b265c45f5c9bc241f98eee076752d35ac6" 119 | dependencies = [ 120 | "critical-section", 121 | "document-features", 122 | "embassy-executor-macros", 123 | ] 124 | 125 | [[package]] 126 | name = "embassy-executor-macros" 127 | version = "0.6.2" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "3577b1e9446f61381179a330fc5324b01d511624c55f25e3c66c9e3c626dbecf" 130 | dependencies = [ 131 | "darling", 132 | "proc-macro2", 133 | "quote", 134 | "syn", 135 | ] 136 | 137 | [[package]] 138 | name = "embedded-test" 139 | version = "0.6.1" 140 | dependencies = [ 141 | "defmt", 142 | "embassy-executor", 143 | "embedded-test-macros", 144 | "heapless 0.8.0", 145 | "log", 146 | "semihosting", 147 | "serde", 148 | "serde-json-core", 149 | ] 150 | 151 | [[package]] 152 | name = "embedded-test-macros" 153 | version = "0.6.1" 154 | dependencies = [ 155 | "darling", 156 | "proc-macro2", 157 | "quote", 158 | "syn", 159 | ] 160 | 161 | [[package]] 162 | name = "fnv" 163 | version = "1.0.7" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 166 | 167 | [[package]] 168 | name = "hash32" 169 | version = "0.2.1" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" 172 | dependencies = [ 173 | "byteorder", 174 | ] 175 | 176 | [[package]] 177 | name = "hash32" 178 | version = "0.3.1" 179 | source = "registry+https://github.com/rust-lang/crates.io-index" 180 | checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" 181 | dependencies = [ 182 | "byteorder", 183 | ] 184 | 185 | [[package]] 186 | name = "heapless" 187 | version = "0.7.17" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" 190 | dependencies = [ 191 | "atomic-polyfill", 192 | "hash32 0.2.1", 193 | "rustc_version", 194 | "spin", 195 | "stable_deref_trait", 196 | ] 197 | 198 | [[package]] 199 | name = "heapless" 200 | version = "0.8.0" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" 203 | dependencies = [ 204 | "hash32 0.3.1", 205 | "stable_deref_trait", 206 | ] 207 | 208 | [[package]] 209 | name = "ident_case" 210 | version = "1.0.1" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 213 | 214 | [[package]] 215 | name = "litrs" 216 | version = "0.4.1" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 219 | 220 | [[package]] 221 | name = "lock_api" 222 | version = "0.4.12" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 225 | dependencies = [ 226 | "autocfg", 227 | "scopeguard", 228 | ] 229 | 230 | [[package]] 231 | name = "log" 232 | version = "0.4.27" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 235 | 236 | [[package]] 237 | name = "proc-macro-error-attr2" 238 | version = "2.0.0" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 241 | dependencies = [ 242 | "proc-macro2", 243 | "quote", 244 | ] 245 | 246 | [[package]] 247 | name = "proc-macro-error2" 248 | version = "2.0.1" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 251 | dependencies = [ 252 | "proc-macro-error-attr2", 253 | "proc-macro2", 254 | "quote", 255 | "syn", 256 | ] 257 | 258 | [[package]] 259 | name = "proc-macro2" 260 | version = "1.0.95" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 263 | dependencies = [ 264 | "unicode-ident", 265 | ] 266 | 267 | [[package]] 268 | name = "quote" 269 | version = "1.0.40" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 272 | dependencies = [ 273 | "proc-macro2", 274 | ] 275 | 276 | [[package]] 277 | name = "rustc_version" 278 | version = "0.4.1" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 281 | dependencies = [ 282 | "semver", 283 | ] 284 | 285 | [[package]] 286 | name = "ryu" 287 | version = "1.0.20" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 290 | 291 | [[package]] 292 | name = "scopeguard" 293 | version = "1.2.0" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 296 | 297 | [[package]] 298 | name = "semihosting" 299 | version = "0.1.20" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "c3e1c7d2b77d80283c750a39c52f1ab4d17234e8f30bca43550f5b2375f41d5f" 302 | 303 | [[package]] 304 | name = "semver" 305 | version = "1.0.26" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" 308 | 309 | [[package]] 310 | name = "serde" 311 | version = "1.0.219" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 314 | dependencies = [ 315 | "serde_derive", 316 | ] 317 | 318 | [[package]] 319 | name = "serde-json-core" 320 | version = "0.5.1" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "3c9e1ab533c0bc414c34920ec7e5f097101d126ed5eac1a1aac711222e0bbb33" 323 | dependencies = [ 324 | "heapless 0.7.17", 325 | "ryu", 326 | "serde", 327 | ] 328 | 329 | [[package]] 330 | name = "serde_derive" 331 | version = "1.0.219" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 334 | dependencies = [ 335 | "proc-macro2", 336 | "quote", 337 | "syn", 338 | ] 339 | 340 | [[package]] 341 | name = "spin" 342 | version = "0.9.8" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 345 | dependencies = [ 346 | "lock_api", 347 | ] 348 | 349 | [[package]] 350 | name = "stable_deref_trait" 351 | version = "1.2.0" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 354 | 355 | [[package]] 356 | name = "strsim" 357 | version = "0.11.1" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 360 | 361 | [[package]] 362 | name = "syn" 363 | version = "2.0.100" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 366 | dependencies = [ 367 | "proc-macro2", 368 | "quote", 369 | "unicode-ident", 370 | ] 371 | 372 | [[package]] 373 | name = "thiserror" 374 | version = "2.0.12" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 377 | dependencies = [ 378 | "thiserror-impl", 379 | ] 380 | 381 | [[package]] 382 | name = "thiserror-impl" 383 | version = "2.0.12" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 386 | dependencies = [ 387 | "proc-macro2", 388 | "quote", 389 | "syn", 390 | ] 391 | 392 | [[package]] 393 | name = "unicode-ident" 394 | version = "1.0.18" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 397 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embedded-test" 3 | version = "0.6.1" 4 | edition = "2021" 5 | repository = "https://github.com/probe-rs/embedded-test" 6 | license = "MIT OR Apache-2.0" 7 | keywords = ["embedded", "test", "testing", "test-runner", "test-framework"] 8 | description = "A test harness and runner for embedded devices" 9 | categories = ["embedded", "no-std", "development-tools::testing"] 10 | 11 | [package.metadata.docs.rs] 12 | default-target = "riscv32imac-unknown-none-elf" 13 | 14 | [dependencies] 15 | semihosting = { version = "0.1.7", features = ["args"], optional = true } 16 | embedded-test-macros = { version = "0.6.1", path = "./macros" } 17 | serde = { version = "1.0.193", default-features = false, features = ["derive"] } 18 | serde-json-core = { version = "0.5.1" } 19 | heapless = "0.8.0" 20 | 21 | # Optional dependencies 22 | defmt = { version = "1", optional = true } 23 | log = { version = "0.4.20", optional = true } 24 | embassy-executor = { version = "0.7.0", optional = true, default-features = false } 25 | 26 | 27 | [features] 28 | default = ["semihosting", "panic-handler"] 29 | 30 | # use semihosting (for embedded targets) 31 | semihosting = ["dep:semihosting"] 32 | 33 | # use std functionality 34 | std = [] 35 | 36 | # defines a panic-handler which will invoke `semihosting::process::abort()` on panic 37 | panic-handler = [] 38 | 39 | # prints testcase exit result to defmt 40 | defmt = ["dep:defmt"] 41 | 42 | # prints testcase exit result to log 43 | log = ["dep:log"] 44 | 45 | # Enables async test and init functions using embassy-executor. 46 | # Note: You need to enable at least one executor feature on embassy unless you are using the `external-executor` feature 47 | embassy = ["embedded-test-macros/embassy", "dep:embassy-executor"] 48 | 49 | # you will use your own executor by setting it via the `tasks` macro, e.g. `#[embedded_test::tests(executor = esp_hal::embassy::executor::thread::Executor::new())]` 50 | external-executor = ["embedded-test-macros/external-executor"] 51 | 52 | # Enables Ariel OS integration 53 | ariel-os = ["embedded-test-macros/ariel-os", "embassy"] 54 | 55 | # enables the xtensa-specific semihosting implementation 56 | xtensa-semihosting = ["semihosting/openocd-semihosting"] 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Embedded Test 2 | 3 | [![Crates.io](https://img.shields.io/crates/v/embedded-test?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/embedded-test) 4 | [![Documentation](https://docs.rs/embedded-test/badge.svg)](https://docs.rs/embedded-test) 5 | ![Crates.io](https://img.shields.io/crates/l/embedded-test?labelColor=1C2C2E&style=flat-square) 6 | 7 | The embedded-test library provides a test harness for embedded systems (riscv, arm and xtensa). 8 | Use this library on the target together with [probe-rs](https://probe.rs/) on the host to run integration tests on your 9 | embedded device. 10 | 11 | [probe-rs](https://probe.rs/) together with embedded-test provide a (libtest compatible) test runner, which will: 12 | 13 | 1. Flash all the tests to the device in one go (via the `probe-rs run` command) 14 | 2. Request information about all tests from the device (via semihosting SYS_GET_CMDLINE) 15 | 3. In turn for each testcase: 16 | - Reset the device 17 | - Signal to the device (via semihosting SYS_GET_CMDLINE) which test to run 18 | - Wait for the device to signal that the test completed successfully or with error (via semihosting SYS_EXIT) 19 | 4. Report the results 20 | 21 | Since the test runner (`probe-rs run`) is libtest compatible ( 22 | using [libtest-mimic](https://crates.io/crates/libtest-mimic)), you can use intellij or vscode to run individual tests 23 | with the click of a button. 24 | 25 | ![](./demo.gif) 26 | 27 | ## Features 28 | 29 | * Runs each test case individually, and resets the device between each test case 30 | * Supports an init function which will be called before each test case and can pass state to the test cases 31 | * Supports async test and init functions (needs feature `embassy`) 32 | * Support `#[should_panic]`, `#[ignore]` and `#[timeout()]` attributes for each test case 33 | 34 | ## Usage 35 | 36 | Add the following to your `Cargo.toml`: 37 | 38 | ```toml 39 | [dev-dependencies] 40 | embedded-test = { version = "0.6.0" } 41 | 42 | [[test]] 43 | name = "example_test" 44 | harness = false 45 | ``` 46 | 47 | Install the runner on your system: 48 | 49 | ```bash 50 | cargo install probe-rs-tools 51 | ``` 52 | 53 | Setup probe-rs as the runner in your `.cargo/config.toml`. For example: 54 | 55 | ```toml 56 | [target.thumbv7em-none-eabihf] 57 | runner = "probe-rs run --chip STM32F767ZITx" 58 | # `probe-rs run` will autodetect whether the elf to flash is a normal firmware or a test binary 59 | ``` 60 | 61 | Add the following to your `build.rs` file: 62 | 63 | ```rust 64 | fn main() { 65 | println!("cargo::rustc-link-arg-tests=-Tembedded-test.x"); 66 | } 67 | ``` 68 | 69 | Then you can run your tests with `cargo test --test example_test` or use the button in vscode/intellij. 70 | 71 | Having trouble setting up? Checkout out 72 | the [FAQ and common Errors](https://github.com/probe-rs/embedded-test/wiki/FAQ-and-common-Errors) Wiki page. 73 | 74 | ## Example Test (e.g. `tests/example_test.rs`) 75 | 76 | Check the [example folder](https://github.com/probe-rs/embedded-test/tree/master/examples) 77 | for a complete example project for stm32/esp32. 78 | 79 | ```rust 80 | #![no_std] 81 | #![no_main] 82 | 83 | #[cfg(test)] 84 | #[embedded_test::tests] 85 | mod tests { 86 | use stm32f7xx_hal::pac::Peripherals; 87 | 88 | // An optional init function which is called before every test 89 | // Asyncness is optional, so is the return value 90 | #[init] 91 | async fn init() -> Peripherals { 92 | Peripherals::take().unwrap() 93 | } 94 | 95 | // Tests can be async (needs feature `embassy`) 96 | // Tests can take the state returned by the init function (optional) 97 | #[test] 98 | async fn takes_state(_state: Peripherals) { 99 | assert!(true) 100 | } 101 | 102 | // Tests can be conditionally enabled (with a cfg attribute) 103 | #[test] 104 | #[cfg(feature = "log")] 105 | fn log() { 106 | rtt_target::rtt_init_log!(); 107 | log::info!("Hello, log!"); 108 | assert!(true) 109 | } 110 | 111 | // Tests can be ignored with the #[ignore] attribute 112 | #[test] 113 | #[ignore] 114 | fn it_works_ignored() { 115 | assert!(false) 116 | } 117 | 118 | // Tests can fail with a custom error message by returning a Result 119 | #[test] 120 | fn it_fails_with_err() -> Result<(), &'static str> { 121 | Err("It failed because ...") 122 | } 123 | 124 | // Tests can be annotated with #[should_panic] if they are expected to panic 125 | #[test] 126 | #[should_panic] 127 | fn it_passes() { 128 | assert!(false) 129 | } 130 | 131 | // Tests can be annotated with #[timeout()] to change the default timeout of 60s 132 | #[test] 133 | #[timeout(10)] 134 | fn it_timeouts() { 135 | loop {} // should run into the 10s timeout 136 | } 137 | } 138 | ``` 139 | 140 | ## Configuration features 141 | 142 | | Feature | Default? | Description | 143 | |----------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 144 | | `panic-handler` | Yes | Defines a panic-handler which will invoke `semihosting::process::abort()` on panic | 145 | | `defmt` | No | Prints testcase exit result to defmt. You'll need to setup your defmt `#[global_logger]` yourself (e.g. `#[embedded_test::tests(setup=rtt_target::rtt_init_defmt!())`) . | 146 | | `log` | No | Prints testcase exit result to log. You'll need to setup your logging sink yourself (e.g. `#[embedded_test::tests(setup=rtt_target::rtt_init_log!())`) | 147 | | `embassy` | No | Enables async test and init functions. Note: You need to enable at least one executor feature on the embassy-executor crate unless you are using the `external-executor` feature. | 148 | | `external-executor` | No | Allows you to bring your own embassy executor which you need to pass to the `#[tests]` macro (e.g. `#[embedded_test::tests(executor = esp_hal::embassy::executor::thread::Executor::new())]`) | 149 | | `xtensa-semihosting` | No | Enables semihosting for xtensa targets. | 150 | | `ariel-os` | No | Enables [Ariel OS](https://ariel-os.github.io/ariel-os/dev/docs/book/testing.html) integration. | 151 | 152 | Please also note the doc for 153 | the [Attribute Macro embedded_test::tests](https://docs.rs/embedded-test/latest/embedded-test/attr.tests.html). 154 | 155 | ## License 156 | 157 | Licensed under either of: 158 | 159 | - [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 160 | - [MIT license](http://opensource.org/licenses/MIT) 161 | 162 | at your option. 163 | 164 | ### Contribution 165 | 166 | Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in 167 | the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without 168 | any additional terms or conditions. 169 | 170 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::error::Error; 3 | use std::fs; 4 | use std::path::PathBuf; 5 | 6 | // Macros taken from: 7 | // https://github.com/TheDan64/inkwell/blob/36c3b10/src/lib.rs#L81-L110 8 | 9 | // Given some features, assert that AT MOST one of the features is enabled. 10 | macro_rules! assert_unique_features { 11 | () => {}; 12 | 13 | ( $first:tt $(,$rest:tt)* ) => { 14 | $( 15 | #[cfg(all(feature = $first, feature = $rest))] 16 | compile_error!(concat!("Features \"", $first, "\" and \"", $rest, "\" cannot be used together")); 17 | )* 18 | assert_unique_features!($($rest),*); 19 | }; 20 | } 21 | 22 | fn main() -> Result<(), Box> { 23 | assert_unique_features!("log", "defmt"); 24 | assert_unique_features!("ariel-os", "external-executor"); 25 | assert_unique_features!("std", "semihosting"); 26 | 27 | let out = &PathBuf::from(env::var("OUT_DIR")?); 28 | let linker_script = fs::read_to_string("embedded-test.x")?; 29 | fs::write(out.join("embedded-test.x"), linker_script)?; 30 | println!("cargo:rustc-link-search={}", out.display()); 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/probe-rs/embedded-test/3b00ef7ff0271e28f4770f68a7b2a46de9fe8533/demo.gif -------------------------------------------------------------------------------- /embedded-test.x: -------------------------------------------------------------------------------- 1 | # This linker script is needed to ensure our symbol EMBEDDED_TEST_VERSION is not optimized away 2 | # The symbol is needed by probe-rs to determine whether a binary contains embedded tests or not 3 | # At a later point we might also communicate the available testcases to probe-rs via the symbol table 4 | 5 | # Redirect/rename a function here, so that we can make sure the user has added the linker script to the RUSTFLAGS 6 | EXTERN (__embedded_test_start); 7 | PROVIDE(embedded_test_linker_file_not_added_to_rustflags = __embedded_test_start); 8 | 9 | # Define a section for the embedded tests and make sure it is not optimized away 10 | SECTIONS 11 | { 12 | .embedded_test 1 (INFO) : 13 | { 14 | KEEP(*(.embedded_test.*)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/esp32c6/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [env] 2 | ESP_LOG = "debug" 3 | DEFMT_LOG = "debug" 4 | 5 | [build] 6 | target = "riscv32imac-unknown-none-elf" 7 | 8 | [target.riscv32imac-unknown-none-elf] 9 | runner = "probe-rs run --chip esp32c6" # for running the tests with probe-rs 10 | 11 | # use the following to run the main binary and see the jtag-uart output of the esp32c6 12 | # runner = "espflash flash --monitor" 13 | 14 | rustflags = [ 15 | # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) 16 | # NOTE: May negatively impact performance of produced code 17 | "-C", 18 | "force-frame-pointers", 19 | ] 20 | -------------------------------------------------------------------------------- /examples/esp32c6/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/esp32c6/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "anyhow" 7 | version = "1.0.98" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 10 | 11 | [[package]] 12 | name = "atomic-polyfill" 13 | version = "1.0.3" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" 16 | dependencies = [ 17 | "critical-section", 18 | ] 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.4.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 25 | 26 | [[package]] 27 | name = "bare-metal" 28 | version = "1.0.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" 31 | 32 | [[package]] 33 | name = "basic-toml" 34 | version = "0.1.10" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" 37 | dependencies = [ 38 | "serde", 39 | ] 40 | 41 | [[package]] 42 | name = "bitfield" 43 | version = "0.17.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "f798d2d157e547aa99aab0967df39edd0b70307312b6f8bd2848e6abe40896e0" 46 | 47 | [[package]] 48 | name = "bitflags" 49 | version = "1.3.2" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 52 | 53 | [[package]] 54 | name = "bitflags" 55 | version = "2.9.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 58 | 59 | [[package]] 60 | name = "bytemuck" 61 | version = "1.22.0" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" 64 | 65 | [[package]] 66 | name = "byteorder" 67 | version = "1.5.0" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 70 | 71 | [[package]] 72 | name = "cfg-if" 73 | version = "1.0.0" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 76 | 77 | [[package]] 78 | name = "chrono" 79 | version = "0.4.40" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" 82 | dependencies = [ 83 | "num-traits", 84 | ] 85 | 86 | [[package]] 87 | name = "critical-section" 88 | version = "1.2.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" 91 | 92 | [[package]] 93 | name = "darling" 94 | version = "0.20.11" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 97 | dependencies = [ 98 | "darling_core", 99 | "darling_macro", 100 | ] 101 | 102 | [[package]] 103 | name = "darling_core" 104 | version = "0.20.11" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 107 | dependencies = [ 108 | "fnv", 109 | "ident_case", 110 | "proc-macro2", 111 | "quote", 112 | "strsim", 113 | "syn", 114 | ] 115 | 116 | [[package]] 117 | name = "darling_macro" 118 | version = "0.20.11" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 121 | dependencies = [ 122 | "darling_core", 123 | "quote", 124 | "syn", 125 | ] 126 | 127 | [[package]] 128 | name = "defmt" 129 | version = "0.3.100" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" 132 | dependencies = [ 133 | "defmt 1.0.1", 134 | ] 135 | 136 | [[package]] 137 | name = "defmt" 138 | version = "1.0.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" 141 | dependencies = [ 142 | "bitflags 1.3.2", 143 | "defmt-macros", 144 | ] 145 | 146 | [[package]] 147 | name = "defmt-macros" 148 | version = "1.0.1" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" 151 | dependencies = [ 152 | "defmt-parser", 153 | "proc-macro-error2", 154 | "proc-macro2", 155 | "quote", 156 | "syn", 157 | ] 158 | 159 | [[package]] 160 | name = "defmt-parser" 161 | version = "1.0.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" 164 | dependencies = [ 165 | "thiserror", 166 | ] 167 | 168 | [[package]] 169 | name = "delegate" 170 | version = "0.13.3" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "b9b6483c2bbed26f97861cf57651d4f2b731964a28cd2257f934a4b452480d21" 173 | dependencies = [ 174 | "proc-macro2", 175 | "quote", 176 | "syn", 177 | ] 178 | 179 | [[package]] 180 | name = "document-features" 181 | version = "0.2.11" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" 184 | dependencies = [ 185 | "litrs", 186 | ] 187 | 188 | [[package]] 189 | name = "embassy-embedded-hal" 190 | version = "0.2.0" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | checksum = "5794414bc20e0d750f145bc0e82366b19dd078e9e075e8331fb8dd069a1cb6a2" 193 | dependencies = [ 194 | "embassy-futures", 195 | "embassy-sync", 196 | "embassy-time", 197 | "embedded-hal 0.2.7", 198 | "embedded-hal 1.0.0", 199 | "embedded-hal-async", 200 | "embedded-storage", 201 | "embedded-storage-async", 202 | "nb 1.1.0", 203 | ] 204 | 205 | [[package]] 206 | name = "embassy-executor" 207 | version = "0.6.3" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "f64f84599b0f4296b92a4b6ac2109bc02340094bda47b9766c5f9ec6a318ebf8" 210 | dependencies = [ 211 | "critical-section", 212 | "document-features", 213 | "embassy-executor-macros", 214 | ] 215 | 216 | [[package]] 217 | name = "embassy-executor" 218 | version = "0.7.0" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "90327bcc66333a507f89ecc4e2d911b265c45f5c9bc241f98eee076752d35ac6" 221 | dependencies = [ 222 | "critical-section", 223 | "document-features", 224 | "embassy-executor-macros", 225 | ] 226 | 227 | [[package]] 228 | name = "embassy-executor-macros" 229 | version = "0.6.2" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "3577b1e9446f61381179a330fc5324b01d511624c55f25e3c66c9e3c626dbecf" 232 | dependencies = [ 233 | "darling", 234 | "proc-macro2", 235 | "quote", 236 | "syn", 237 | ] 238 | 239 | [[package]] 240 | name = "embassy-futures" 241 | version = "0.1.1" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" 244 | 245 | [[package]] 246 | name = "embassy-sync" 247 | version = "0.6.2" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049" 250 | dependencies = [ 251 | "cfg-if", 252 | "critical-section", 253 | "embedded-io-async", 254 | "futures-sink", 255 | "futures-util", 256 | "heapless 0.8.0", 257 | ] 258 | 259 | [[package]] 260 | name = "embassy-time" 261 | version = "0.3.2" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "158080d48f824fad101d7b2fae2d83ac39e3f7a6fa01811034f7ab8ffc6e7309" 264 | dependencies = [ 265 | "cfg-if", 266 | "critical-section", 267 | "document-features", 268 | "embassy-time-driver", 269 | "embassy-time-queue-driver", 270 | "embedded-hal 0.2.7", 271 | "embedded-hal 1.0.0", 272 | "embedded-hal-async", 273 | "futures-util", 274 | "heapless 0.8.0", 275 | ] 276 | 277 | [[package]] 278 | name = "embassy-time-driver" 279 | version = "0.1.0" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "6e0c214077aaa9206958b16411c157961fb7990d4ea628120a78d1a5a28aed24" 282 | dependencies = [ 283 | "document-features", 284 | ] 285 | 286 | [[package]] 287 | name = "embassy-time-queue-driver" 288 | version = "0.1.0" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" 291 | 292 | [[package]] 293 | name = "embedded-can" 294 | version = "0.4.1" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" 297 | dependencies = [ 298 | "nb 1.1.0", 299 | ] 300 | 301 | [[package]] 302 | name = "embedded-hal" 303 | version = "0.2.7" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" 306 | dependencies = [ 307 | "nb 0.1.3", 308 | "void", 309 | ] 310 | 311 | [[package]] 312 | name = "embedded-hal" 313 | version = "1.0.0" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" 316 | 317 | [[package]] 318 | name = "embedded-hal-async" 319 | version = "1.0.0" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" 322 | dependencies = [ 323 | "embedded-hal 1.0.0", 324 | ] 325 | 326 | [[package]] 327 | name = "embedded-hal-nb" 328 | version = "1.0.0" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" 331 | dependencies = [ 332 | "embedded-hal 1.0.0", 333 | "nb 1.1.0", 334 | ] 335 | 336 | [[package]] 337 | name = "embedded-io" 338 | version = "0.6.1" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" 341 | 342 | [[package]] 343 | name = "embedded-io-async" 344 | version = "0.6.1" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" 347 | dependencies = [ 348 | "embedded-io", 349 | ] 350 | 351 | [[package]] 352 | name = "embedded-storage" 353 | version = "0.3.1" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" 356 | 357 | [[package]] 358 | name = "embedded-storage-async" 359 | version = "0.4.1" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" 362 | dependencies = [ 363 | "embedded-storage", 364 | ] 365 | 366 | [[package]] 367 | name = "embedded-test" 368 | version = "0.6.1" 369 | dependencies = [ 370 | "defmt 1.0.1", 371 | "embassy-executor 0.7.0", 372 | "embedded-test-macros", 373 | "heapless 0.8.0", 374 | "log", 375 | "semihosting", 376 | "serde", 377 | "serde-json-core", 378 | ] 379 | 380 | [[package]] 381 | name = "embedded-test-example-for-esp32c6" 382 | version = "0.1.0" 383 | dependencies = [ 384 | "defmt 1.0.1", 385 | "embassy-executor 0.6.3", 386 | "embassy-time", 387 | "embedded-test", 388 | "esp-backtrace", 389 | "esp-hal", 390 | "esp-hal-embassy", 391 | "esp-println", 392 | "log", 393 | "rtt-target", 394 | ] 395 | 396 | [[package]] 397 | name = "embedded-test-macros" 398 | version = "0.6.1" 399 | dependencies = [ 400 | "darling", 401 | "proc-macro2", 402 | "quote", 403 | "syn", 404 | ] 405 | 406 | [[package]] 407 | name = "enum-as-inner" 408 | version = "0.6.1" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" 411 | dependencies = [ 412 | "heck", 413 | "proc-macro2", 414 | "quote", 415 | "syn", 416 | ] 417 | 418 | [[package]] 419 | name = "enumset" 420 | version = "1.1.5" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" 423 | dependencies = [ 424 | "enumset_derive", 425 | ] 426 | 427 | [[package]] 428 | name = "enumset_derive" 429 | version = "0.10.0" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" 432 | dependencies = [ 433 | "darling", 434 | "proc-macro2", 435 | "quote", 436 | "syn", 437 | ] 438 | 439 | [[package]] 440 | name = "equivalent" 441 | version = "1.0.2" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 444 | 445 | [[package]] 446 | name = "esp-backtrace" 447 | version = "0.14.2" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "cb7660d85e3e7b0e113aaeeffb1a155e64a09a5035d4104031875acdba4cb68e" 450 | dependencies = [ 451 | "esp-build", 452 | "esp-println", 453 | ] 454 | 455 | [[package]] 456 | name = "esp-build" 457 | version = "0.1.0" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "b94a4b8d74e7cc7baabcca5b2277b41877e039ad9cd49959d48ef94dac7eab4b" 460 | dependencies = [ 461 | "quote", 462 | "syn", 463 | "termcolor", 464 | ] 465 | 466 | [[package]] 467 | name = "esp-config" 468 | version = "0.2.0" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "f7584e4cd1dac06201fd92fff1c84b396be5458ac4d93e9457e7a89b1b42c60e" 471 | dependencies = [ 472 | "document-features", 473 | ] 474 | 475 | [[package]] 476 | name = "esp-hal" 477 | version = "0.22.0" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "1a5605e1518d63f7bf9fbd9885e61d2896060d2e4f28954736bdd74da911b676" 480 | dependencies = [ 481 | "basic-toml", 482 | "bitfield", 483 | "bitflags 2.9.0", 484 | "bytemuck", 485 | "cfg-if", 486 | "chrono", 487 | "critical-section", 488 | "delegate", 489 | "document-features", 490 | "embassy-embedded-hal", 491 | "embassy-futures", 492 | "embassy-sync", 493 | "embedded-can", 494 | "embedded-hal 0.2.7", 495 | "embedded-hal 1.0.0", 496 | "embedded-hal-async", 497 | "embedded-hal-nb", 498 | "embedded-io", 499 | "embedded-io-async", 500 | "enumset", 501 | "esp-build", 502 | "esp-config", 503 | "esp-hal-procmacros", 504 | "esp-metadata", 505 | "esp-riscv-rt", 506 | "esp32c6", 507 | "fugit", 508 | "nb 1.1.0", 509 | "paste", 510 | "portable-atomic", 511 | "rand_core", 512 | "riscv", 513 | "serde", 514 | "strum", 515 | "ufmt-write", 516 | "void", 517 | "xtensa-lx-rt", 518 | ] 519 | 520 | [[package]] 521 | name = "esp-hal-embassy" 522 | version = "0.5.0" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "c7d0f2537ea2ff9bea26a1c8bfe43ad580d4c89febf27189653a9cf95f1f7961" 525 | dependencies = [ 526 | "critical-section", 527 | "document-features", 528 | "embassy-executor 0.6.3", 529 | "embassy-time-driver", 530 | "esp-build", 531 | "esp-config", 532 | "esp-hal", 533 | "esp-hal-procmacros", 534 | "esp-metadata", 535 | "portable-atomic", 536 | "static_cell", 537 | ] 538 | 539 | [[package]] 540 | name = "esp-hal-procmacros" 541 | version = "0.15.0" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "69a9a8706b7d1182b56335d196e70eeb04e2b70f4b8db96432898bd3c2bdb91e" 544 | dependencies = [ 545 | "darling", 546 | "document-features", 547 | "litrs", 548 | "object", 549 | "proc-macro-crate", 550 | "proc-macro-error2", 551 | "proc-macro2", 552 | "quote", 553 | "syn", 554 | ] 555 | 556 | [[package]] 557 | name = "esp-metadata" 558 | version = "0.4.0" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "f9972bbb21dcafe430b87f92efc7a788978a2d17cf8f572d104beeb48602482a" 561 | dependencies = [ 562 | "anyhow", 563 | "basic-toml", 564 | "serde", 565 | "strum", 566 | ] 567 | 568 | [[package]] 569 | name = "esp-println" 570 | version = "0.12.0" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "ee38e87bc7e303c299047c0e9bcd0f8ccca7c7e70d1fd78bbb565db14f33beb6" 573 | dependencies = [ 574 | "critical-section", 575 | "esp-build", 576 | "log", 577 | "portable-atomic", 578 | ] 579 | 580 | [[package]] 581 | name = "esp-riscv-rt" 582 | version = "0.9.1" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "94aca65db6157aa5f42d9df6595b21462f28207ca4230b799aa3620352ef6a72" 585 | dependencies = [ 586 | "document-features", 587 | "riscv", 588 | "riscv-rt-macros", 589 | ] 590 | 591 | [[package]] 592 | name = "esp32c6" 593 | version = "0.17.0" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "8b98fcf7ae90ee4d55f06170dfeaaebbf2a1619bb38b4e14b9009b4d636b87e7" 596 | dependencies = [ 597 | "critical-section", 598 | "vcell", 599 | ] 600 | 601 | [[package]] 602 | name = "fnv" 603 | version = "1.0.7" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 606 | 607 | [[package]] 608 | name = "fugit" 609 | version = "0.3.7" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" 612 | dependencies = [ 613 | "gcd", 614 | ] 615 | 616 | [[package]] 617 | name = "futures-core" 618 | version = "0.3.31" 619 | source = "registry+https://github.com/rust-lang/crates.io-index" 620 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 621 | 622 | [[package]] 623 | name = "futures-sink" 624 | version = "0.3.31" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 627 | 628 | [[package]] 629 | name = "futures-task" 630 | version = "0.3.31" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 633 | 634 | [[package]] 635 | name = "futures-util" 636 | version = "0.3.31" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 639 | dependencies = [ 640 | "futures-core", 641 | "futures-task", 642 | "pin-project-lite", 643 | "pin-utils", 644 | ] 645 | 646 | [[package]] 647 | name = "gcd" 648 | version = "2.3.0" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" 651 | 652 | [[package]] 653 | name = "hash32" 654 | version = "0.2.1" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" 657 | dependencies = [ 658 | "byteorder", 659 | ] 660 | 661 | [[package]] 662 | name = "hash32" 663 | version = "0.3.1" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" 666 | dependencies = [ 667 | "byteorder", 668 | ] 669 | 670 | [[package]] 671 | name = "hashbrown" 672 | version = "0.15.2" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 675 | 676 | [[package]] 677 | name = "heapless" 678 | version = "0.7.17" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" 681 | dependencies = [ 682 | "atomic-polyfill", 683 | "hash32 0.2.1", 684 | "rustc_version", 685 | "spin", 686 | "stable_deref_trait", 687 | ] 688 | 689 | [[package]] 690 | name = "heapless" 691 | version = "0.8.0" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" 694 | dependencies = [ 695 | "hash32 0.3.1", 696 | "stable_deref_trait", 697 | ] 698 | 699 | [[package]] 700 | name = "heck" 701 | version = "0.5.0" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 704 | 705 | [[package]] 706 | name = "ident_case" 707 | version = "1.0.1" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 710 | 711 | [[package]] 712 | name = "indexmap" 713 | version = "2.9.0" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" 716 | dependencies = [ 717 | "equivalent", 718 | "hashbrown", 719 | ] 720 | 721 | [[package]] 722 | name = "litrs" 723 | version = "0.4.1" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 726 | dependencies = [ 727 | "proc-macro2", 728 | ] 729 | 730 | [[package]] 731 | name = "lock_api" 732 | version = "0.4.12" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 735 | dependencies = [ 736 | "autocfg", 737 | "scopeguard", 738 | ] 739 | 740 | [[package]] 741 | name = "log" 742 | version = "0.4.27" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 745 | 746 | [[package]] 747 | name = "memchr" 748 | version = "2.7.4" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 751 | 752 | [[package]] 753 | name = "minijinja" 754 | version = "2.9.0" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "98642a6dfca91122779a307b77cd07a4aa951fbe32232aaf5bad9febc66be754" 757 | dependencies = [ 758 | "serde", 759 | ] 760 | 761 | [[package]] 762 | name = "mutex-trait" 763 | version = "0.2.0" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "b4bb1638d419e12f8b1c43d9e639abd0d1424285bdea2f76aa231e233c63cd3a" 766 | 767 | [[package]] 768 | name = "nb" 769 | version = "0.1.3" 770 | source = "registry+https://github.com/rust-lang/crates.io-index" 771 | checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" 772 | dependencies = [ 773 | "nb 1.1.0", 774 | ] 775 | 776 | [[package]] 777 | name = "nb" 778 | version = "1.1.0" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" 781 | 782 | [[package]] 783 | name = "num-traits" 784 | version = "0.2.19" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 787 | dependencies = [ 788 | "autocfg", 789 | ] 790 | 791 | [[package]] 792 | name = "object" 793 | version = "0.36.7" 794 | source = "registry+https://github.com/rust-lang/crates.io-index" 795 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 796 | dependencies = [ 797 | "memchr", 798 | ] 799 | 800 | [[package]] 801 | name = "once_cell" 802 | version = "1.21.3" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 805 | dependencies = [ 806 | "critical-section", 807 | "portable-atomic", 808 | ] 809 | 810 | [[package]] 811 | name = "paste" 812 | version = "1.0.15" 813 | source = "registry+https://github.com/rust-lang/crates.io-index" 814 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 815 | 816 | [[package]] 817 | name = "pin-project-lite" 818 | version = "0.2.16" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 821 | 822 | [[package]] 823 | name = "pin-utils" 824 | version = "0.1.0" 825 | source = "registry+https://github.com/rust-lang/crates.io-index" 826 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 827 | 828 | [[package]] 829 | name = "portable-atomic" 830 | version = "1.11.0" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" 833 | 834 | [[package]] 835 | name = "proc-macro-crate" 836 | version = "3.3.0" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" 839 | dependencies = [ 840 | "toml_edit", 841 | ] 842 | 843 | [[package]] 844 | name = "proc-macro-error-attr2" 845 | version = "2.0.0" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 848 | dependencies = [ 849 | "proc-macro2", 850 | "quote", 851 | ] 852 | 853 | [[package]] 854 | name = "proc-macro-error2" 855 | version = "2.0.1" 856 | source = "registry+https://github.com/rust-lang/crates.io-index" 857 | checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 858 | dependencies = [ 859 | "proc-macro-error-attr2", 860 | "proc-macro2", 861 | "quote", 862 | "syn", 863 | ] 864 | 865 | [[package]] 866 | name = "proc-macro2" 867 | version = "1.0.95" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 870 | dependencies = [ 871 | "unicode-ident", 872 | ] 873 | 874 | [[package]] 875 | name = "quote" 876 | version = "1.0.40" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 879 | dependencies = [ 880 | "proc-macro2", 881 | ] 882 | 883 | [[package]] 884 | name = "r0" 885 | version = "1.0.0" 886 | source = "registry+https://github.com/rust-lang/crates.io-index" 887 | checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" 888 | 889 | [[package]] 890 | name = "rand_core" 891 | version = "0.6.4" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 894 | 895 | [[package]] 896 | name = "riscv" 897 | version = "0.12.1" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "5ea8ff73d3720bdd0a97925f0bf79ad2744b6da8ff36be3840c48ac81191d7a7" 900 | dependencies = [ 901 | "critical-section", 902 | "embedded-hal 1.0.0", 903 | "paste", 904 | "riscv-macros", 905 | "riscv-pac", 906 | ] 907 | 908 | [[package]] 909 | name = "riscv-macros" 910 | version = "0.1.0" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "f265be5d634272320a7de94cea15c22a3bfdd4eb42eb43edc528415f066a1f25" 913 | dependencies = [ 914 | "proc-macro2", 915 | "quote", 916 | "syn", 917 | ] 918 | 919 | [[package]] 920 | name = "riscv-pac" 921 | version = "0.2.0" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436" 924 | 925 | [[package]] 926 | name = "riscv-rt-macros" 927 | version = "0.2.2" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "30f19a85fe107b65031e0ba8ec60c34c2494069fe910d6c297f5e7cb5a6f76d0" 930 | dependencies = [ 931 | "proc-macro2", 932 | "quote", 933 | "syn", 934 | ] 935 | 936 | [[package]] 937 | name = "rtt-target" 938 | version = "0.6.1" 939 | source = "registry+https://github.com/rust-lang/crates.io-index" 940 | checksum = "4235cd78091930e907d2a510adb0db1369e82668eafa338f109742fa0c83059d" 941 | dependencies = [ 942 | "critical-section", 943 | "defmt 0.3.100", 944 | "log", 945 | "once_cell", 946 | "portable-atomic", 947 | "ufmt-write", 948 | ] 949 | 950 | [[package]] 951 | name = "rustc_version" 952 | version = "0.4.1" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 955 | dependencies = [ 956 | "semver", 957 | ] 958 | 959 | [[package]] 960 | name = "rustversion" 961 | version = "1.0.20" 962 | source = "registry+https://github.com/rust-lang/crates.io-index" 963 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 964 | 965 | [[package]] 966 | name = "ryu" 967 | version = "1.0.20" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 970 | 971 | [[package]] 972 | name = "scopeguard" 973 | version = "1.2.0" 974 | source = "registry+https://github.com/rust-lang/crates.io-index" 975 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 976 | 977 | [[package]] 978 | name = "semihosting" 979 | version = "0.1.20" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "c3e1c7d2b77d80283c750a39c52f1ab4d17234e8f30bca43550f5b2375f41d5f" 982 | 983 | [[package]] 984 | name = "semver" 985 | version = "1.0.26" 986 | source = "registry+https://github.com/rust-lang/crates.io-index" 987 | checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" 988 | 989 | [[package]] 990 | name = "serde" 991 | version = "1.0.219" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 994 | dependencies = [ 995 | "serde_derive", 996 | ] 997 | 998 | [[package]] 999 | name = "serde-json-core" 1000 | version = "0.5.1" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "3c9e1ab533c0bc414c34920ec7e5f097101d126ed5eac1a1aac711222e0bbb33" 1003 | dependencies = [ 1004 | "heapless 0.7.17", 1005 | "ryu", 1006 | "serde", 1007 | ] 1008 | 1009 | [[package]] 1010 | name = "serde_derive" 1011 | version = "1.0.219" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1014 | dependencies = [ 1015 | "proc-macro2", 1016 | "quote", 1017 | "syn", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "serde_spanned" 1022 | version = "0.6.8" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 1025 | dependencies = [ 1026 | "serde", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "spin" 1031 | version = "0.9.8" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1034 | dependencies = [ 1035 | "lock_api", 1036 | ] 1037 | 1038 | [[package]] 1039 | name = "stable_deref_trait" 1040 | version = "1.2.0" 1041 | source = "registry+https://github.com/rust-lang/crates.io-index" 1042 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1043 | 1044 | [[package]] 1045 | name = "static_cell" 1046 | version = "2.1.0" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" 1049 | dependencies = [ 1050 | "portable-atomic", 1051 | ] 1052 | 1053 | [[package]] 1054 | name = "strsim" 1055 | version = "0.11.1" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1058 | 1059 | [[package]] 1060 | name = "strum" 1061 | version = "0.26.3" 1062 | source = "registry+https://github.com/rust-lang/crates.io-index" 1063 | checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" 1064 | dependencies = [ 1065 | "strum_macros", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "strum_macros" 1070 | version = "0.26.4" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" 1073 | dependencies = [ 1074 | "heck", 1075 | "proc-macro2", 1076 | "quote", 1077 | "rustversion", 1078 | "syn", 1079 | ] 1080 | 1081 | [[package]] 1082 | name = "syn" 1083 | version = "2.0.100" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 1086 | dependencies = [ 1087 | "proc-macro2", 1088 | "quote", 1089 | "unicode-ident", 1090 | ] 1091 | 1092 | [[package]] 1093 | name = "termcolor" 1094 | version = "1.4.1" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 1097 | dependencies = [ 1098 | "winapi-util", 1099 | ] 1100 | 1101 | [[package]] 1102 | name = "thiserror" 1103 | version = "2.0.12" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 1106 | dependencies = [ 1107 | "thiserror-impl", 1108 | ] 1109 | 1110 | [[package]] 1111 | name = "thiserror-impl" 1112 | version = "2.0.12" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 1115 | dependencies = [ 1116 | "proc-macro2", 1117 | "quote", 1118 | "syn", 1119 | ] 1120 | 1121 | [[package]] 1122 | name = "toml" 1123 | version = "0.8.21" 1124 | source = "registry+https://github.com/rust-lang/crates.io-index" 1125 | checksum = "900f6c86a685850b1bc9f6223b20125115ee3f31e01207d81655bbcc0aea9231" 1126 | dependencies = [ 1127 | "serde", 1128 | "serde_spanned", 1129 | "toml_datetime", 1130 | "toml_edit", 1131 | ] 1132 | 1133 | [[package]] 1134 | name = "toml_datetime" 1135 | version = "0.6.9" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" 1138 | dependencies = [ 1139 | "serde", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "toml_edit" 1144 | version = "0.22.25" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "10558ed0bd2a1562e630926a2d1f0b98c827da99fabd3fe20920a59642504485" 1147 | dependencies = [ 1148 | "indexmap", 1149 | "serde", 1150 | "serde_spanned", 1151 | "toml_datetime", 1152 | "toml_write", 1153 | "winnow", 1154 | ] 1155 | 1156 | [[package]] 1157 | name = "toml_write" 1158 | version = "0.1.0" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "28391a4201ba7eb1984cfeb6862c0b3ea2cfe23332298967c749dddc0d6cd976" 1161 | 1162 | [[package]] 1163 | name = "ufmt-write" 1164 | version = "0.1.0" 1165 | source = "registry+https://github.com/rust-lang/crates.io-index" 1166 | checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" 1167 | 1168 | [[package]] 1169 | name = "unicode-ident" 1170 | version = "1.0.18" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1173 | 1174 | [[package]] 1175 | name = "vcell" 1176 | version = "0.1.3" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" 1179 | 1180 | [[package]] 1181 | name = "void" 1182 | version = "1.0.2" 1183 | source = "registry+https://github.com/rust-lang/crates.io-index" 1184 | checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 1185 | 1186 | [[package]] 1187 | name = "winapi-util" 1188 | version = "0.1.9" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 1191 | dependencies = [ 1192 | "windows-sys", 1193 | ] 1194 | 1195 | [[package]] 1196 | name = "windows-sys" 1197 | version = "0.59.0" 1198 | source = "registry+https://github.com/rust-lang/crates.io-index" 1199 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1200 | dependencies = [ 1201 | "windows-targets", 1202 | ] 1203 | 1204 | [[package]] 1205 | name = "windows-targets" 1206 | version = "0.52.6" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1209 | dependencies = [ 1210 | "windows_aarch64_gnullvm", 1211 | "windows_aarch64_msvc", 1212 | "windows_i686_gnu", 1213 | "windows_i686_gnullvm", 1214 | "windows_i686_msvc", 1215 | "windows_x86_64_gnu", 1216 | "windows_x86_64_gnullvm", 1217 | "windows_x86_64_msvc", 1218 | ] 1219 | 1220 | [[package]] 1221 | name = "windows_aarch64_gnullvm" 1222 | version = "0.52.6" 1223 | source = "registry+https://github.com/rust-lang/crates.io-index" 1224 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1225 | 1226 | [[package]] 1227 | name = "windows_aarch64_msvc" 1228 | version = "0.52.6" 1229 | source = "registry+https://github.com/rust-lang/crates.io-index" 1230 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1231 | 1232 | [[package]] 1233 | name = "windows_i686_gnu" 1234 | version = "0.52.6" 1235 | source = "registry+https://github.com/rust-lang/crates.io-index" 1236 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1237 | 1238 | [[package]] 1239 | name = "windows_i686_gnullvm" 1240 | version = "0.52.6" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1243 | 1244 | [[package]] 1245 | name = "windows_i686_msvc" 1246 | version = "0.52.6" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1249 | 1250 | [[package]] 1251 | name = "windows_x86_64_gnu" 1252 | version = "0.52.6" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1255 | 1256 | [[package]] 1257 | name = "windows_x86_64_gnullvm" 1258 | version = "0.52.6" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1261 | 1262 | [[package]] 1263 | name = "windows_x86_64_msvc" 1264 | version = "0.52.6" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1267 | 1268 | [[package]] 1269 | name = "winnow" 1270 | version = "0.7.7" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "6cb8234a863ea0e8cd7284fcdd4f145233eb00fee02bbdd9861aec44e6477bc5" 1273 | dependencies = [ 1274 | "memchr", 1275 | ] 1276 | 1277 | [[package]] 1278 | name = "xtensa-lx" 1279 | version = "0.9.0" 1280 | source = "registry+https://github.com/rust-lang/crates.io-index" 1281 | checksum = "e758f94e1a1f71758f94052a2766dcb12604998eb372b8b2e30576e3ab1ba1e6" 1282 | dependencies = [ 1283 | "bare-metal", 1284 | "mutex-trait", 1285 | ] 1286 | 1287 | [[package]] 1288 | name = "xtensa-lx-rt" 1289 | version = "0.17.2" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "5c0307d03dadbf95633942e13901984f2059df4c963367348168cbd21c962669" 1292 | dependencies = [ 1293 | "anyhow", 1294 | "bare-metal", 1295 | "document-features", 1296 | "enum-as-inner", 1297 | "minijinja", 1298 | "r0", 1299 | "serde", 1300 | "strum", 1301 | "toml", 1302 | "xtensa-lx", 1303 | "xtensa-lx-rt-proc-macros", 1304 | ] 1305 | 1306 | [[package]] 1307 | name = "xtensa-lx-rt-proc-macros" 1308 | version = "0.2.2" 1309 | source = "registry+https://github.com/rust-lang/crates.io-index" 1310 | checksum = "11277b1e4cbb7ffe44678c668518b249c843c81df249b8f096701757bc50d7ee" 1311 | dependencies = [ 1312 | "darling", 1313 | "proc-macro2", 1314 | "quote", 1315 | "syn", 1316 | ] 1317 | -------------------------------------------------------------------------------- /examples/esp32c6/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embedded-test-example-for-esp32c6" 3 | version = "0.1.0" 4 | edition = "2021" 5 | repository = "https://github.com/probe-rs/embedded-test" 6 | license = "MIT OR Apache-2.0" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | # dependencies when using the log/defmt feature 12 | log = { version = "0.4.20", optional = true } 13 | defmt = { version = "1", optional = true } 14 | rtt-target = { version="0.6.1", optional= true } 15 | 16 | # Esp32 related dependencies for main.rs. Note: embedded-test comes with its own panic handler and logging sink. 17 | esp-backtrace = { version = "0.14.2", features = [ 18 | "esp32c6", 19 | "exception-handler", 20 | "panic-handler", 21 | "println", 22 | ] } 23 | 24 | esp-hal = { version = "0.22.0", features = ["esp32c6"] } 25 | esp-println = { version = "0.12.0", features = ["esp32c6", "log"] } 26 | embassy-time = { version = "0.3.1", features = ["generic-queue-8"] } 27 | esp-hal-embassy = { version = "0.5.0", features = ["esp32c6"] } 28 | embassy-executor = { default-features = false, version = "0.6.0" } # TODO: update to 0.7.0 when esp-hal supports it 29 | 30 | [dev-dependencies] 31 | embedded-test = { version = "0.6.0", features = ["embassy", "external-executor"], path = "../.." } 32 | 33 | [features] 34 | default = ["log"] 35 | log = ["dep:log", "dep:rtt-target", "rtt-target/log", "embedded-test/log"] 36 | defmt = ["dep:defmt", "dep:rtt-target", "rtt-target/defmt", "embedded-test/defmt"] 37 | 38 | [[bin]] 39 | name = "embedded-test-example-for-esp32c6" 40 | test = false # To make plain `cargo test` work: Disable tests for the bin, because we are only using the intergration tests 41 | bench = false # To make `cargo check --all-targets` work. 42 | required-features = ["log"] 43 | 44 | [lib] 45 | test = false # Same as above, to make plain `cargo test` work instead of `cargo test --tests` 46 | bench = false 47 | 48 | [[test]] 49 | name = "example_test" 50 | harness = false # Important: As we bring our own test harness, we need to disable the default one 51 | 52 | [lints.rust] 53 | unexpected_cfgs = { level = "warn", check-cfg = ['cfg(abc)'] } 54 | -------------------------------------------------------------------------------- /examples/esp32c6/README.md: -------------------------------------------------------------------------------- 1 | # Embedded Test Example for the esp32c6 (riscv32) 2 | 3 | ## Platform-specific notes: 4 | - When using async-tests: 5 | - esp-rs provides an optimized embassy-executor, therefore the feature `custom-executor` must be enabled on embedded-test and the invocation of embedded test should be `#[embedded_test::tests(executor=esp_hal_embassy::Executor::new())]` 6 | -------------------------------------------------------------------------------- /examples/esp32c6/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | // esp-hal specific 5 | println!("cargo:rustc-link-arg=-Tlinkall.x"); 6 | 7 | // add linker script for embedded-test!! 8 | println!("cargo::rustc-link-arg-tests=-Tembedded-test.x"); 9 | 10 | // Check if the `defmt` feature is enabled, and if so link its linker script 11 | if env::var("CARGO_FEATURE_DEFMT").is_ok() { 12 | println!("cargo:rustc-link-arg=-Tdefmt.x"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/esp32c6/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | -------------------------------------------------------------------------------- /examples/esp32c6/src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | use embassy_executor::Spawner; 5 | use embassy_time::{Duration, Timer}; 6 | use esp_backtrace as _; 7 | use esp_hal::prelude::*; 8 | use log::info; 9 | 10 | /// ====> Look in the tests directory to see how embedded-test works <==== 11 | 12 | /// This file here is just a simple async main function that prints "Hello world!" every second, 13 | /// similar to the example generate by esp-generate. 14 | 15 | #[main] 16 | async fn main(_spawner: Spawner) -> ! { 17 | let peripherals = esp_hal::init({ 18 | let mut config = esp_hal::Config::default(); 19 | config.cpu_clock = CpuClock::max(); 20 | config 21 | }); 22 | 23 | esp_println::logger::init_logger_from_env(); // # prints to jtag/uart0 ! 24 | 25 | let timer0 = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER) 26 | .split::(); 27 | esp_hal_embassy::init(timer0.alarm0); 28 | 29 | loop { 30 | info!("Hello world!"); 31 | Timer::after(Duration::from_secs(1)).await; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/esp32c6/tests/example_test.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | struct Context { 5 | #[allow(dead_code)] 6 | i2c0: esp_hal::peripherals::I2C0, 7 | } 8 | 9 | /// Sets up the logging before entering the test-body, so that embedded-test internal logs (e.g. Running Test <...>) can also be printed. 10 | /// Note: you can also inline this method in the attribute. e.g. `#[embedded_test::tests(setup=rtt_target::rtt_init_log!())]` 11 | fn setup_log() { 12 | #[cfg(feature = "log")] 13 | rtt_target::rtt_init_log!(); 14 | #[cfg(feature = "defmt")] 15 | rtt_target::rtt_init_defmt!(); 16 | } 17 | 18 | #[cfg(test)] 19 | #[embedded_test::tests(executor=esp_hal_embassy::Executor::new(), setup=crate::setup_log())] 20 | mod tests { 21 | use super::*; 22 | use esp_hal::prelude::*; 23 | 24 | // Optional: A init function which is called before every test 25 | // asyncness of init fn is optional 26 | #[init] 27 | async fn init() -> Context { 28 | let peripherals = esp_hal::init({ 29 | let mut config = esp_hal::Config::default(); 30 | config.cpu_clock = CpuClock::max(); 31 | config 32 | }); 33 | 34 | let timer0 = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER) 35 | .split::(); 36 | esp_hal_embassy::init(timer0.alarm0); 37 | 38 | // The init function can return some state, which can be consumed by the testcases 39 | Context { 40 | i2c0: peripherals.I2C0, 41 | } 42 | } 43 | 44 | // A test which takes the state returned by the init function (optional) 45 | // asyncness of test fn's is optional 46 | #[test] 47 | async fn takes_state(_state: Context) { 48 | assert!(true) 49 | } 50 | 51 | // Example for a test which is conditionally enabled 52 | #[test] 53 | #[cfg(feature = "log")] 54 | fn log() { 55 | log::info!("Hello, log!"); 56 | assert!(true) 57 | } 58 | 59 | // Another example for a conditionally enabled test 60 | #[test] 61 | #[cfg(feature = "defmt")] 62 | fn defmt() { 63 | defmt::info!("Hello, defmt!"); 64 | assert!(true) 65 | } 66 | 67 | // A test which is cfg'ed out 68 | #[test] 69 | #[cfg(abc)] 70 | fn it_works_disabled() { 71 | assert!(false) 72 | } 73 | 74 | // Tests can be ignored with the #[ignore] attribute 75 | #[test] 76 | #[ignore] 77 | fn it_works_ignored() { 78 | assert!(false) 79 | } 80 | 81 | // A test that fails with a panic 82 | #[test] 83 | fn it_fails1() { 84 | assert!(false) 85 | } 86 | 87 | // A test that fails with a returned Err(&str) 88 | #[test] 89 | fn it_fails2() -> Result<(), &'static str> { 90 | Err("It failed because ...") 91 | } 92 | 93 | // Tests can be annotated with #[should_panic] if they are expected to panic 94 | #[test] 95 | #[should_panic] 96 | fn it_passes() { 97 | assert!(false) 98 | } 99 | 100 | // This test should panic, but doesn't => it fails 101 | #[test] 102 | #[should_panic] 103 | fn it_fails3() {} 104 | 105 | // Tests can be annotated with #[timeout()] to change the default timeout of 60s 106 | #[test] 107 | #[timeout(10)] 108 | fn it_timeouts() { 109 | loop {} // should run into the 10s timeout 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /examples/std/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | # The repository level `.cargo/config.toml` sets an embedded target, which we 3 | # want to override here. Unfortunately there is no `host target triple`, so 4 | # this is hard-coded to x86_64 Linux here. This needs changing on other 5 | # platforms. 6 | target = "x86_64-unknown-linux-gnu" 7 | [target."x86_64-unknown-linux-gnu"] 8 | runner = "embedded-test-std-runner" 9 | -------------------------------------------------------------------------------- /examples/std/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/std/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "atomic-polyfill" 7 | version = "1.0.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" 10 | dependencies = [ 11 | "critical-section", 12 | ] 13 | 14 | [[package]] 15 | name = "autocfg" 16 | version = "1.4.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 19 | 20 | [[package]] 21 | name = "byteorder" 22 | version = "1.5.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 25 | 26 | [[package]] 27 | name = "critical-section" 28 | version = "1.2.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" 31 | 32 | [[package]] 33 | name = "darling" 34 | version = "0.20.10" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 37 | dependencies = [ 38 | "darling_core", 39 | "darling_macro", 40 | ] 41 | 42 | [[package]] 43 | name = "darling_core" 44 | version = "0.20.10" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 47 | dependencies = [ 48 | "fnv", 49 | "ident_case", 50 | "proc-macro2", 51 | "quote", 52 | "strsim", 53 | "syn", 54 | ] 55 | 56 | [[package]] 57 | name = "darling_macro" 58 | version = "0.20.10" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 61 | dependencies = [ 62 | "darling_core", 63 | "quote", 64 | "syn", 65 | ] 66 | 67 | [[package]] 68 | name = "document-features" 69 | version = "0.2.11" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" 72 | dependencies = [ 73 | "litrs", 74 | ] 75 | 76 | [[package]] 77 | name = "embassy-executor" 78 | version = "0.7.0" 79 | source = "registry+https://github.com/rust-lang/crates.io-index" 80 | checksum = "90327bcc66333a507f89ecc4e2d911b265c45f5c9bc241f98eee076752d35ac6" 81 | dependencies = [ 82 | "critical-section", 83 | "document-features", 84 | "embassy-executor-macros", 85 | ] 86 | 87 | [[package]] 88 | name = "embassy-executor-macros" 89 | version = "0.6.2" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "3577b1e9446f61381179a330fc5324b01d511624c55f25e3c66c9e3c626dbecf" 92 | dependencies = [ 93 | "darling", 94 | "proc-macro2", 95 | "quote", 96 | "syn", 97 | ] 98 | 99 | [[package]] 100 | name = "embedded-test" 101 | version = "0.6.1" 102 | dependencies = [ 103 | "embassy-executor", 104 | "embedded-test-macros", 105 | "heapless 0.8.0", 106 | "log", 107 | "serde", 108 | "serde-json-core", 109 | ] 110 | 111 | [[package]] 112 | name = "embedded-test-example-for-std" 113 | version = "0.1.0" 114 | dependencies = [ 115 | "embassy-executor", 116 | "embedded-test", 117 | "log", 118 | ] 119 | 120 | [[package]] 121 | name = "embedded-test-macros" 122 | version = "0.6.1" 123 | dependencies = [ 124 | "darling", 125 | "proc-macro2", 126 | "quote", 127 | "syn", 128 | ] 129 | 130 | [[package]] 131 | name = "fnv" 132 | version = "1.0.7" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 135 | 136 | [[package]] 137 | name = "hash32" 138 | version = "0.2.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" 141 | dependencies = [ 142 | "byteorder", 143 | ] 144 | 145 | [[package]] 146 | name = "hash32" 147 | version = "0.3.1" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" 150 | dependencies = [ 151 | "byteorder", 152 | ] 153 | 154 | [[package]] 155 | name = "heapless" 156 | version = "0.7.17" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" 159 | dependencies = [ 160 | "atomic-polyfill", 161 | "hash32 0.2.1", 162 | "rustc_version", 163 | "spin", 164 | "stable_deref_trait", 165 | ] 166 | 167 | [[package]] 168 | name = "heapless" 169 | version = "0.8.0" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" 172 | dependencies = [ 173 | "hash32 0.3.1", 174 | "stable_deref_trait", 175 | ] 176 | 177 | [[package]] 178 | name = "ident_case" 179 | version = "1.0.1" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 182 | 183 | [[package]] 184 | name = "litrs" 185 | version = "0.4.1" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 188 | 189 | [[package]] 190 | name = "lock_api" 191 | version = "0.4.12" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 194 | dependencies = [ 195 | "autocfg", 196 | "scopeguard", 197 | ] 198 | 199 | [[package]] 200 | name = "log" 201 | version = "0.4.26" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" 204 | 205 | [[package]] 206 | name = "proc-macro2" 207 | version = "1.0.94" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" 210 | dependencies = [ 211 | "unicode-ident", 212 | ] 213 | 214 | [[package]] 215 | name = "quote" 216 | version = "1.0.40" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 219 | dependencies = [ 220 | "proc-macro2", 221 | ] 222 | 223 | [[package]] 224 | name = "rustc_version" 225 | version = "0.4.1" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 228 | dependencies = [ 229 | "semver", 230 | ] 231 | 232 | [[package]] 233 | name = "ryu" 234 | version = "1.0.20" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 237 | 238 | [[package]] 239 | name = "scopeguard" 240 | version = "1.2.0" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 243 | 244 | [[package]] 245 | name = "semver" 246 | version = "1.0.26" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" 249 | 250 | [[package]] 251 | name = "serde" 252 | version = "1.0.219" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 255 | dependencies = [ 256 | "serde_derive", 257 | ] 258 | 259 | [[package]] 260 | name = "serde-json-core" 261 | version = "0.5.1" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "3c9e1ab533c0bc414c34920ec7e5f097101d126ed5eac1a1aac711222e0bbb33" 264 | dependencies = [ 265 | "heapless 0.7.17", 266 | "ryu", 267 | "serde", 268 | ] 269 | 270 | [[package]] 271 | name = "serde_derive" 272 | version = "1.0.219" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 275 | dependencies = [ 276 | "proc-macro2", 277 | "quote", 278 | "syn", 279 | ] 280 | 281 | [[package]] 282 | name = "spin" 283 | version = "0.9.8" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 286 | dependencies = [ 287 | "lock_api", 288 | ] 289 | 290 | [[package]] 291 | name = "stable_deref_trait" 292 | version = "1.2.0" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 295 | 296 | [[package]] 297 | name = "strsim" 298 | version = "0.11.1" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 301 | 302 | [[package]] 303 | name = "syn" 304 | version = "2.0.100" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 307 | dependencies = [ 308 | "proc-macro2", 309 | "quote", 310 | "unicode-ident", 311 | ] 312 | 313 | [[package]] 314 | name = "unicode-ident" 315 | version = "1.0.18" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 318 | -------------------------------------------------------------------------------- /examples/std/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embedded-test-example-for-std" 3 | version = "0.1.0" 4 | edition = "2021" 5 | repository = "https://github.com/probe-rs/embedded-test" 6 | license = "MIT OR Apache-2.0" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | embassy-executor = { default-features = false, version = "0.7.0", features = ["arch-std", "executor-thread"] } 12 | # Note: You need to enable at least one executor feature on embassy 0.7.x 13 | 14 | # dependencies when using the log feature 15 | log = { version = "0.4.20", optional = true } 16 | 17 | [dev-dependencies] 18 | embedded-test = { version = "0.6.0", default-features = false, features = ["embassy", "std"], path = "../.." } 19 | 20 | [features] 21 | default = ["log"] 22 | log = ["dep:log", "embedded-test/log"] 23 | 24 | [[bin]] 25 | name = "embedded-test-example-for-std" 26 | test = false # To make plain `cargo test` work: Disable tests for the bin, because we are only using the intergration tests 27 | bench = false # To make `cargo check --all-targets` work. 28 | 29 | [lib] 30 | test = false # Same as above, to make plain `cargo test` work instead of `cargo test --tests` 31 | bench = false 32 | 33 | [[test]] 34 | name = "example_test" 35 | harness = false # Important: As we bring our own test harness, we need to disable the default one 36 | 37 | [lints.rust] 38 | unexpected_cfgs = { level = "warn", check-cfg = ['cfg(abc)'] } 39 | -------------------------------------------------------------------------------- /examples/std/README.md: -------------------------------------------------------------------------------- 1 | # Embedded Test Example for std mode 2 | 3 | Needs [`embedded-test-std-runner`][runner]. 4 | 5 | [runner]: https://github.com/kaspar030/embedded-test-std-runner 6 | -------------------------------------------------------------------------------- /examples/std/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | // add linker script for embedded-test!! 5 | println!("cargo::rustc-link-arg-tests=../../embedded-test.x"); 6 | 7 | // Check if the `defmt` feature is enabled, and if so link its linker script 8 | if env::var("CARGO_FEATURE_DEFMT").is_ok() { 9 | panic!("defmt not supported on std!"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/std/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | -------------------------------------------------------------------------------- /examples/std/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello fellow tester!"); 3 | } 4 | -------------------------------------------------------------------------------- /examples/std/tests/example_test.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | /// Sets up the logging before entering the test-body, so that embedded-test internal logs (e.g. Running Test <...>) can also be printed. 4 | /// Note: you can also inline this method in the attribute. e.g. `#[embedded_test::tests(setup=rtt_target::rtt_init_log!())]` 5 | fn setup_log() { 6 | println!("setup_log()"); 7 | } 8 | 9 | #[cfg(test)] 10 | #[embedded_test::tests(setup=crate::setup_log())] 11 | mod unit_tests { 12 | // Optional: A init function which is called before every test 13 | // async + return value are optional 14 | #[init] 15 | async fn init() -> u32 { 16 | 1234 17 | } 18 | 19 | // A test which takes the state returned by the init function (optional) 20 | // asyncness is optional and needs feature embassy 21 | #[test] 22 | async fn takes_state(_state: u32) { 23 | assert!(true) 24 | } 25 | 26 | // Example for a test which is conditionally enabled 27 | #[test] 28 | #[cfg(feature = "log")] 29 | fn log() { 30 | log::info!("Hello, log!"); 31 | assert!(true) 32 | } 33 | 34 | // A test which is cfg'ed out 35 | #[test] 36 | #[cfg(abc)] 37 | fn it_works_disabled() { 38 | assert!(false) 39 | } 40 | 41 | // Tests can be ignored with the #[ignore] attribute 42 | #[test] 43 | #[ignore] 44 | fn it_works_ignored() { 45 | assert!(false) 46 | } 47 | 48 | // A test that fails with a panic 49 | #[test] 50 | fn it_fails1() { 51 | assert!(false) 52 | } 53 | 54 | // A test that fails with a returned Err(&str) 55 | #[test] 56 | fn it_fails2() -> Result<(), &'static str> { 57 | Err("It failed because ...") 58 | } 59 | 60 | // Tests can be annotated with #[should_panic] if they are expected to panic 61 | #[test] 62 | #[should_panic] 63 | fn it_passes() { 64 | assert!(false) 65 | } 66 | 67 | // This test should panic, but doesn't => it fails 68 | #[test] 69 | #[should_panic] 70 | fn it_fails3() {} 71 | 72 | // Tests can be annotated with #[timeout()] to change the default timeout of 60s 73 | #[test] 74 | #[timeout(2)] 75 | fn it_timeouts() { 76 | loop {} // should run into the 10s timeout 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /examples/stm32f767/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [env] 2 | DEFMT_LOG="debug" 3 | 4 | [build] 5 | target = "thumbv7em-none-eabihf" 6 | 7 | [target.thumbv7em-none-eabihf] 8 | runner = "probe-rs run --chip STM32F767ZITx" 9 | -------------------------------------------------------------------------------- /examples/stm32f767/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /examples/stm32f767/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "as-slice" 7 | version = "0.2.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" 10 | dependencies = [ 11 | "stable_deref_trait", 12 | ] 13 | 14 | [[package]] 15 | name = "atomic-polyfill" 16 | version = "1.0.3" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" 19 | dependencies = [ 20 | "critical-section", 21 | ] 22 | 23 | [[package]] 24 | name = "autocfg" 25 | version = "1.4.0" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 28 | 29 | [[package]] 30 | name = "bare-metal" 31 | version = "0.2.5" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" 34 | dependencies = [ 35 | "rustc_version 0.2.3", 36 | ] 37 | 38 | [[package]] 39 | name = "bare-metal" 40 | version = "1.0.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" 43 | 44 | [[package]] 45 | name = "bitfield" 46 | version = "0.13.2" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" 49 | 50 | [[package]] 51 | name = "bitflags" 52 | version = "1.3.2" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 55 | 56 | [[package]] 57 | name = "bitflags" 58 | version = "2.9.0" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 61 | 62 | [[package]] 63 | name = "bxcan" 64 | version = "0.7.0" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80" 67 | dependencies = [ 68 | "bitflags 1.3.2", 69 | "embedded-hal", 70 | "nb 1.1.0", 71 | "vcell", 72 | ] 73 | 74 | [[package]] 75 | name = "byteorder" 76 | version = "1.5.0" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 79 | 80 | [[package]] 81 | name = "cast" 82 | version = "0.3.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" 85 | 86 | [[package]] 87 | name = "cortex-m" 88 | version = "0.7.7" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" 91 | dependencies = [ 92 | "bare-metal 0.2.5", 93 | "bitfield", 94 | "critical-section", 95 | "embedded-hal", 96 | "volatile-register", 97 | ] 98 | 99 | [[package]] 100 | name = "cortex-m-rt" 101 | version = "0.7.5" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" 104 | dependencies = [ 105 | "cortex-m-rt-macros", 106 | ] 107 | 108 | [[package]] 109 | name = "cortex-m-rt-macros" 110 | version = "0.7.5" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" 113 | dependencies = [ 114 | "proc-macro2", 115 | "quote", 116 | "syn", 117 | ] 118 | 119 | [[package]] 120 | name = "critical-section" 121 | version = "1.2.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" 124 | 125 | [[package]] 126 | name = "darling" 127 | version = "0.20.11" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" 130 | dependencies = [ 131 | "darling_core", 132 | "darling_macro", 133 | ] 134 | 135 | [[package]] 136 | name = "darling_core" 137 | version = "0.20.11" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" 140 | dependencies = [ 141 | "fnv", 142 | "ident_case", 143 | "proc-macro2", 144 | "quote", 145 | "strsim", 146 | "syn", 147 | ] 148 | 149 | [[package]] 150 | name = "darling_macro" 151 | version = "0.20.11" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" 154 | dependencies = [ 155 | "darling_core", 156 | "quote", 157 | "syn", 158 | ] 159 | 160 | [[package]] 161 | name = "defmt" 162 | version = "0.3.100" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" 165 | dependencies = [ 166 | "defmt 1.0.1", 167 | ] 168 | 169 | [[package]] 170 | name = "defmt" 171 | version = "1.0.1" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" 174 | dependencies = [ 175 | "bitflags 1.3.2", 176 | "defmt-macros", 177 | ] 178 | 179 | [[package]] 180 | name = "defmt-macros" 181 | version = "1.0.1" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" 184 | dependencies = [ 185 | "defmt-parser", 186 | "proc-macro-error2", 187 | "proc-macro2", 188 | "quote", 189 | "syn", 190 | ] 191 | 192 | [[package]] 193 | name = "defmt-parser" 194 | version = "1.0.0" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" 197 | dependencies = [ 198 | "thiserror", 199 | ] 200 | 201 | [[package]] 202 | name = "deranged" 203 | version = "0.4.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" 206 | dependencies = [ 207 | "powerfmt", 208 | ] 209 | 210 | [[package]] 211 | name = "document-features" 212 | version = "0.2.11" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" 215 | dependencies = [ 216 | "litrs", 217 | ] 218 | 219 | [[package]] 220 | name = "embassy-executor" 221 | version = "0.7.0" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "90327bcc66333a507f89ecc4e2d911b265c45f5c9bc241f98eee076752d35ac6" 224 | dependencies = [ 225 | "cortex-m", 226 | "critical-section", 227 | "document-features", 228 | "embassy-executor-macros", 229 | ] 230 | 231 | [[package]] 232 | name = "embassy-executor-macros" 233 | version = "0.6.2" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "3577b1e9446f61381179a330fc5324b01d511624c55f25e3c66c9e3c626dbecf" 236 | dependencies = [ 237 | "darling", 238 | "proc-macro2", 239 | "quote", 240 | "syn", 241 | ] 242 | 243 | [[package]] 244 | name = "embedded-hal" 245 | version = "0.2.7" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" 248 | dependencies = [ 249 | "nb 0.1.3", 250 | "void", 251 | ] 252 | 253 | [[package]] 254 | name = "embedded-test" 255 | version = "0.6.1" 256 | dependencies = [ 257 | "defmt 1.0.1", 258 | "embassy-executor", 259 | "embedded-test-macros", 260 | "heapless 0.8.0", 261 | "log", 262 | "semihosting", 263 | "serde", 264 | "serde-json-core", 265 | ] 266 | 267 | [[package]] 268 | name = "embedded-test-example-for-stm32f767" 269 | version = "0.1.0" 270 | dependencies = [ 271 | "cortex-m", 272 | "cortex-m-rt", 273 | "defmt 1.0.1", 274 | "embassy-executor", 275 | "embedded-test", 276 | "log", 277 | "rtt-target", 278 | "stm32f7xx-hal", 279 | ] 280 | 281 | [[package]] 282 | name = "embedded-test-macros" 283 | version = "0.6.1" 284 | dependencies = [ 285 | "darling", 286 | "proc-macro2", 287 | "quote", 288 | "syn", 289 | ] 290 | 291 | [[package]] 292 | name = "fnv" 293 | version = "1.0.7" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 296 | 297 | [[package]] 298 | name = "fugit" 299 | version = "0.3.7" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" 302 | dependencies = [ 303 | "gcd", 304 | ] 305 | 306 | [[package]] 307 | name = "fugit-timer" 308 | version = "0.1.3" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "d9607bfc4c388f9d629704f56ede4a007546cad417b3bcd6fc7c87dc7edce04a" 311 | dependencies = [ 312 | "fugit", 313 | "nb 1.1.0", 314 | ] 315 | 316 | [[package]] 317 | name = "gcd" 318 | version = "2.3.0" 319 | source = "registry+https://github.com/rust-lang/crates.io-index" 320 | checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" 321 | 322 | [[package]] 323 | name = "hash32" 324 | version = "0.2.1" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" 327 | dependencies = [ 328 | "byteorder", 329 | ] 330 | 331 | [[package]] 332 | name = "hash32" 333 | version = "0.3.1" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" 336 | dependencies = [ 337 | "byteorder", 338 | ] 339 | 340 | [[package]] 341 | name = "heapless" 342 | version = "0.7.17" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" 345 | dependencies = [ 346 | "atomic-polyfill", 347 | "hash32 0.2.1", 348 | "rustc_version 0.4.1", 349 | "spin", 350 | "stable_deref_trait", 351 | ] 352 | 353 | [[package]] 354 | name = "heapless" 355 | version = "0.8.0" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" 358 | dependencies = [ 359 | "hash32 0.3.1", 360 | "stable_deref_trait", 361 | ] 362 | 363 | [[package]] 364 | name = "ident_case" 365 | version = "1.0.1" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 368 | 369 | [[package]] 370 | name = "litrs" 371 | version = "0.4.1" 372 | source = "registry+https://github.com/rust-lang/crates.io-index" 373 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 374 | 375 | [[package]] 376 | name = "lock_api" 377 | version = "0.4.12" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 380 | dependencies = [ 381 | "autocfg", 382 | "scopeguard", 383 | ] 384 | 385 | [[package]] 386 | name = "log" 387 | version = "0.4.27" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 390 | 391 | [[package]] 392 | name = "micromath" 393 | version = "2.1.0" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" 396 | 397 | [[package]] 398 | name = "nb" 399 | version = "0.1.3" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" 402 | dependencies = [ 403 | "nb 1.1.0", 404 | ] 405 | 406 | [[package]] 407 | name = "nb" 408 | version = "1.1.0" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" 411 | 412 | [[package]] 413 | name = "num-conv" 414 | version = "0.1.0" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 417 | 418 | [[package]] 419 | name = "once_cell" 420 | version = "1.21.3" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 423 | dependencies = [ 424 | "critical-section", 425 | "portable-atomic", 426 | ] 427 | 428 | [[package]] 429 | name = "portable-atomic" 430 | version = "1.11.0" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" 433 | 434 | [[package]] 435 | name = "powerfmt" 436 | version = "0.2.0" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 439 | 440 | [[package]] 441 | name = "proc-macro-error-attr2" 442 | version = "2.0.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" 445 | dependencies = [ 446 | "proc-macro2", 447 | "quote", 448 | ] 449 | 450 | [[package]] 451 | name = "proc-macro-error2" 452 | version = "2.0.1" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" 455 | dependencies = [ 456 | "proc-macro-error-attr2", 457 | "proc-macro2", 458 | "quote", 459 | "syn", 460 | ] 461 | 462 | [[package]] 463 | name = "proc-macro2" 464 | version = "1.0.95" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 467 | dependencies = [ 468 | "unicode-ident", 469 | ] 470 | 471 | [[package]] 472 | name = "quote" 473 | version = "1.0.40" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 476 | dependencies = [ 477 | "proc-macro2", 478 | ] 479 | 480 | [[package]] 481 | name = "rand_core" 482 | version = "0.6.4" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 485 | 486 | [[package]] 487 | name = "rtt-target" 488 | version = "0.6.1" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "4235cd78091930e907d2a510adb0db1369e82668eafa338f109742fa0c83059d" 491 | dependencies = [ 492 | "critical-section", 493 | "defmt 0.3.100", 494 | "log", 495 | "once_cell", 496 | "portable-atomic", 497 | "ufmt-write", 498 | ] 499 | 500 | [[package]] 501 | name = "rustc_version" 502 | version = "0.2.3" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 505 | dependencies = [ 506 | "semver 0.9.0", 507 | ] 508 | 509 | [[package]] 510 | name = "rustc_version" 511 | version = "0.4.1" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 514 | dependencies = [ 515 | "semver 1.0.26", 516 | ] 517 | 518 | [[package]] 519 | name = "ryu" 520 | version = "1.0.20" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 523 | 524 | [[package]] 525 | name = "scopeguard" 526 | version = "1.2.0" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 529 | 530 | [[package]] 531 | name = "semihosting" 532 | version = "0.1.20" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "c3e1c7d2b77d80283c750a39c52f1ab4d17234e8f30bca43550f5b2375f41d5f" 535 | 536 | [[package]] 537 | name = "semver" 538 | version = "0.9.0" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 541 | dependencies = [ 542 | "semver-parser", 543 | ] 544 | 545 | [[package]] 546 | name = "semver" 547 | version = "1.0.26" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" 550 | 551 | [[package]] 552 | name = "semver-parser" 553 | version = "0.7.0" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 556 | 557 | [[package]] 558 | name = "serde" 559 | version = "1.0.219" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 562 | dependencies = [ 563 | "serde_derive", 564 | ] 565 | 566 | [[package]] 567 | name = "serde-json-core" 568 | version = "0.5.1" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "3c9e1ab533c0bc414c34920ec7e5f097101d126ed5eac1a1aac711222e0bbb33" 571 | dependencies = [ 572 | "heapless 0.7.17", 573 | "ryu", 574 | "serde", 575 | ] 576 | 577 | [[package]] 578 | name = "serde_derive" 579 | version = "1.0.219" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 582 | dependencies = [ 583 | "proc-macro2", 584 | "quote", 585 | "syn", 586 | ] 587 | 588 | [[package]] 589 | name = "spin" 590 | version = "0.9.8" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 593 | dependencies = [ 594 | "lock_api", 595 | ] 596 | 597 | [[package]] 598 | name = "stable_deref_trait" 599 | version = "1.2.0" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 602 | 603 | [[package]] 604 | name = "stm32-fmc" 605 | version = "0.3.2" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c" 608 | dependencies = [ 609 | "embedded-hal", 610 | ] 611 | 612 | [[package]] 613 | name = "stm32f7" 614 | version = "0.15.1" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "194f877786053e5797371d084cc9dd6dc5d70f45470550af944013a298e7db9f" 617 | dependencies = [ 618 | "bare-metal 1.0.0", 619 | "cortex-m", 620 | "cortex-m-rt", 621 | "vcell", 622 | ] 623 | 624 | [[package]] 625 | name = "stm32f7xx-hal" 626 | version = "0.8.0" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "864a474a57e6a9c51482358a239eef920752526aea85ce20adb1bb621c36b889" 629 | dependencies = [ 630 | "as-slice", 631 | "bare-metal 1.0.0", 632 | "bitflags 2.9.0", 633 | "bxcan", 634 | "cast", 635 | "cortex-m", 636 | "cortex-m-rt", 637 | "embedded-hal", 638 | "fugit", 639 | "fugit-timer", 640 | "micromath", 641 | "nb 1.1.0", 642 | "rand_core", 643 | "stm32-fmc", 644 | "stm32f7", 645 | "time", 646 | "void", 647 | ] 648 | 649 | [[package]] 650 | name = "strsim" 651 | version = "0.11.1" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 654 | 655 | [[package]] 656 | name = "syn" 657 | version = "2.0.100" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" 660 | dependencies = [ 661 | "proc-macro2", 662 | "quote", 663 | "unicode-ident", 664 | ] 665 | 666 | [[package]] 667 | name = "thiserror" 668 | version = "2.0.12" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 671 | dependencies = [ 672 | "thiserror-impl", 673 | ] 674 | 675 | [[package]] 676 | name = "thiserror-impl" 677 | version = "2.0.12" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 680 | dependencies = [ 681 | "proc-macro2", 682 | "quote", 683 | "syn", 684 | ] 685 | 686 | [[package]] 687 | name = "time" 688 | version = "0.3.41" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" 691 | dependencies = [ 692 | "deranged", 693 | "num-conv", 694 | "powerfmt", 695 | "time-core", 696 | ] 697 | 698 | [[package]] 699 | name = "time-core" 700 | version = "0.1.4" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" 703 | 704 | [[package]] 705 | name = "ufmt-write" 706 | version = "0.1.0" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" 709 | 710 | [[package]] 711 | name = "unicode-ident" 712 | version = "1.0.18" 713 | source = "registry+https://github.com/rust-lang/crates.io-index" 714 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 715 | 716 | [[package]] 717 | name = "vcell" 718 | version = "0.1.3" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" 721 | 722 | [[package]] 723 | name = "void" 724 | version = "1.0.2" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" 727 | 728 | [[package]] 729 | name = "volatile-register" 730 | version = "0.2.2" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" 733 | dependencies = [ 734 | "vcell", 735 | ] 736 | -------------------------------------------------------------------------------- /examples/stm32f767/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embedded-test-example-for-stm32f767" 3 | version = "0.1.0" 4 | edition = "2021" 5 | repository = "https://github.com/probe-rs/embedded-test" 6 | license = "MIT OR Apache-2.0" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | cortex-m = { version = "0.7", features = ["critical-section-single-core"] } 12 | cortex-m-rt = "0.7" 13 | stm32f7xx-hal = { version = "0.8", features = ["stm32f767"] } # replace the model of your microcontroller here 14 | 15 | embassy-executor = { default-features = false, version = "0.7.0", features = ["executor-thread", "arch-cortex-m"] } 16 | # Note: You need to enable at least one executor feature on embassy 0.7.x 17 | 18 | # dependencies when using the log/defmt feature 19 | log = { version = "0.4.20", optional = true } 20 | defmt = { version = "1", optional = true } 21 | rtt-target = { version="0.6.1", optional= true } 22 | 23 | [dev-dependencies] 24 | embedded-test = { version = "0.6.0", features = ["embassy"], path = "../.." } 25 | 26 | [features] 27 | default = ["log"] 28 | log = ["dep:log", "dep:rtt-target", "rtt-target/log", "embedded-test/log"] 29 | defmt = ["dep:defmt", "dep:rtt-target", "rtt-target/defmt", "embedded-test/defmt"] 30 | 31 | [[bin]] 32 | name = "embedded-test-example-for-stm32f767" 33 | test = false # To make plain `cargo test` work: Disable tests for the bin, because we are only using the intergration tests 34 | bench = false # To make `cargo check --all-targets` work. 35 | 36 | [lib] 37 | test = false # Same as above, to make plain `cargo test` work instead of `cargo test --tests` 38 | bench = false 39 | 40 | [[test]] 41 | name = "example_test" 42 | harness = false # Important: As we bring our own test harness, we need to disable the default one 43 | 44 | [lints.rust] 45 | unexpected_cfgs = { level = "warn", check-cfg = ['cfg(abc)'] } 46 | -------------------------------------------------------------------------------- /examples/stm32f767/README.md: -------------------------------------------------------------------------------- 1 | # Embedded Test Example for the stm32f767 (armv7) 2 | -------------------------------------------------------------------------------- /examples/stm32f767/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | // stm32 specific 5 | println!("cargo:rustc-link-arg=-Tlink.x"); 6 | 7 | // add linker script for embedded-test!! 8 | println!("cargo::rustc-link-arg-tests=-Tembedded-test.x"); 9 | 10 | // Check if the `defmt` feature is enabled, and if so link its linker script 11 | if env::var("CARGO_FEATURE_DEFMT").is_ok() { 12 | println!("cargo:rustc-link-arg=-Tdefmt.x"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/stm32f767/memory.x: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | /* NOTE K = KiBi = 1024 bytes */ 4 | FLASH : ORIGIN = 0x08000000, LENGTH = 128K 5 | RAM : ORIGIN = 0x20000000, LENGTH = 32K 6 | } 7 | 8 | /* This is where the call stack will be allocated. */ 9 | /* The stack is of the full descending type. */ 10 | /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ 11 | _stack_start = ORIGIN(RAM) + LENGTH(RAM); -------------------------------------------------------------------------------- /examples/stm32f767/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | -------------------------------------------------------------------------------- /examples/stm32f767/src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | #![no_std] 3 | 4 | /// ====> Look in the tests directory to see how embedded-test works <==== 5 | /// This file here is just a simple blinky example, as found in the examples of the stm32f7xx-hal crate. 6 | use core::panic::PanicInfo; 7 | use stm32f7xx_hal::gpio::GpioExt; 8 | use stm32f7xx_hal::pac; 9 | use stm32f7xx_hal::prelude::*; 10 | 11 | #[no_mangle] 12 | fn main() -> ! { 13 | if let (Some(dp), Some(cp)) = ( 14 | pac::Peripherals::take(), 15 | cortex_m::peripheral::Peripherals::take(), 16 | ) { 17 | // Set up the LED. On the Nucleo-144 it's connected to pin PB7. 18 | let gpiob = dp.GPIOB.split(); 19 | let mut led = gpiob.pb7.into_push_pull_output(); 20 | 21 | // Set up the system clock. We want to run at 48MHz for this one. 22 | let rcc = dp.RCC.constrain(); 23 | let clocks = rcc.cfgr.sysclk(48.MHz()).freeze(); 24 | 25 | // Create a delay abstraction based on SysTick 26 | let mut delay = cp.SYST.delay(&clocks); 27 | 28 | loop { 29 | // On for 1s, off for 1s. 30 | led.set_high(); 31 | delay.delay_ms(1000_u32); 32 | led.set_low(); 33 | delay.delay_ms(1000_u32); 34 | } 35 | } 36 | 37 | loop {} 38 | } 39 | 40 | #[panic_handler] 41 | fn panic(_panic: &PanicInfo<'_>) -> ! { 42 | loop {} 43 | } 44 | -------------------------------------------------------------------------------- /examples/stm32f767/tests/example_test.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | 4 | /// Sets up the logging before entering the test-body, so that embedded-test internal logs (e.g. Running Test <...>) can also be printed. 5 | /// Note: you can also inline this method in the attribute. e.g. `#[embedded_test::tests(setup=rtt_target::rtt_init_log!())]` 6 | fn setup_log() { 7 | #[cfg(feature = "log")] 8 | rtt_target::rtt_init_log!(); 9 | #[cfg(feature = "defmt")] 10 | rtt_target::rtt_init_defmt!(); 11 | } 12 | 13 | #[cfg(test)] 14 | #[embedded_test::tests(setup=crate::setup_log())] 15 | mod unit_tests { 16 | use stm32f7xx_hal::pac::Peripherals; 17 | 18 | // Optional: A init function which is called before every test 19 | // async + return value are optional 20 | #[init] 21 | async fn init() -> Peripherals { 22 | Peripherals::take().unwrap() 23 | } 24 | 25 | // A test which takes the state returned by the init function (optional) 26 | // asyncness is optional and needs feature embassy 27 | #[test] 28 | async fn takes_state(_state: Peripherals) { 29 | assert!(true) 30 | } 31 | 32 | // Example for a test which is conditionally enabled 33 | #[test] 34 | #[cfg(feature = "log")] 35 | fn log() { 36 | log::info!("Hello, log!"); 37 | assert!(true) 38 | } 39 | 40 | // Another example for a conditionally enabled test 41 | #[test] 42 | #[cfg(feature = "defmt")] 43 | fn defmt() { 44 | defmt::info!("Hello, defmt!"); 45 | assert!(true) 46 | } 47 | 48 | // A test which is cfg'ed out 49 | #[test] 50 | #[cfg(abc)] 51 | fn it_works_disabled() { 52 | assert!(false) 53 | } 54 | 55 | // Tests can be ignored with the #[ignore] attribute 56 | #[test] 57 | #[ignore] 58 | fn it_works_ignored() { 59 | assert!(false) 60 | } 61 | 62 | // A test that fails with a panic 63 | #[test] 64 | fn it_fails1() { 65 | assert!(false) 66 | } 67 | 68 | // A test that fails with a returned Err(&str) 69 | #[test] 70 | fn it_fails2() -> Result<(), &'static str> { 71 | Err("It failed because ...") 72 | } 73 | 74 | // Tests can be annotated with #[should_panic] if they are expected to panic 75 | #[test] 76 | #[should_panic] 77 | fn it_passes() { 78 | assert!(false) 79 | } 80 | 81 | // This test should panic, but doesn't => it fails 82 | #[test] 83 | #[should_panic] 84 | fn it_fails3() {} 85 | 86 | // Tests can be annotated with #[timeout()] to change the default timeout of 60s 87 | #[test] 88 | #[timeout(10)] 89 | fn it_timeouts() { 90 | loop {} // should run into the 10s timeout 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /macros/.gitignore: -------------------------------------------------------------------------------- 1 | target/ -------------------------------------------------------------------------------- /macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "embedded-test-macros" 3 | description = "proc-macros for the embedded-test crate" 4 | version = "0.6.1" 5 | edition = "2021" 6 | repository = "https://github.com/probe-rs/embedded-test" 7 | license = "MIT OR Apache-2.0" 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | 12 | [lib] 13 | proc-macro = true 14 | 15 | [dependencies] 16 | proc-macro2 = "1.0.79" 17 | quote = "1.0.35" 18 | syn = { version = "2.0.52", features = ["extra-traits", "full"] } 19 | darling = "0.20.8" 20 | 21 | [features] 22 | embassy = [] 23 | external-executor = [] 24 | ariel-os = [] 25 | 26 | [dev-dependencies] 27 | trybuild = "1" 28 | -------------------------------------------------------------------------------- /macros/README.md: -------------------------------------------------------------------------------- 1 | # Embedded Test Macros 2 | 3 | Macros for the [embedded-test](https://crates.io/crates/embedded-test) crate. 4 | 5 | Note: Do not use this crate directly, the macros are reexported by the `embedded-test` crate. -------------------------------------------------------------------------------- /macros/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copied from https://github.com/knurling-rs/defmt/blob/main/firmware/defmt-test/macros/src/lib.rs 2 | extern crate proc_macro; 3 | 4 | use darling::{ast::NestedMeta, FromMeta}; 5 | use proc_macro::TokenStream; 6 | use quote::{format_ident, quote}; 7 | use syn::{parse, spanned::Spanned, Attribute, Item, ItemFn, ItemMod, ReturnType, Type}; 8 | 9 | /// Attribute to be placed on the test suite's module. 10 | /// 11 | /// ## Arguments 12 | /// - `default-timeout`: The default timeout in seconds for all tests in the suite. This can be overridden on a per-test basis. If not specified here or on a per-test basis, the default timeout is 60 seconds. 13 | /// - `executor`: The custom executor to use for running async tests. This is only required if the features `embassy` and `external-executor` are enabled. 14 | /// - `setup`: A function that will be called before running the tests. This can be used to setup logging or other global state. 15 | /// 16 | /// ## Examples 17 | /// 18 | /// Define a test suite with a single test: 19 | /// 20 | /// ```rust,no_run 21 | /// #[embedded_test::tests] 22 | /// mod tests { 23 | /// #[init] 24 | /// fn init() { 25 | /// // Initialize the hardware 26 | /// } 27 | /// 28 | /// #[test] 29 | /// fn test() { 30 | /// // Test the hardware 31 | /// } 32 | /// } 33 | /// ``` 34 | /// 35 | /// Define a test suite and customize everything: 36 | /// 37 | /// ```rust,no_run 38 | /// #[embedded_test::tests(default_timeout = 10, executor = embassy::executor::Executor::new(), setup = rtt_target::rtt_init_log!())] 39 | /// mod tests { 40 | /// #[init] 41 | /// fn init() { 42 | /// // Initialize the hardware 43 | /// } 44 | /// 45 | /// #[test] 46 | /// fn test() { 47 | /// log::info("Start....") 48 | /// // Test the hardware 49 | /// } 50 | /// 51 | /// #[test] 52 | /// #[timeout(5)] 53 | /// fn test2() { 54 | /// // Test the hardware 55 | /// } 56 | /// } 57 | /// ``` 58 | #[proc_macro_attribute] 59 | pub fn tests(args: TokenStream, input: TokenStream) -> TokenStream { 60 | match tests_impl(args, input) { 61 | Ok(ts) => ts, 62 | Err(e) => e.to_compile_error().into(), 63 | } 64 | } 65 | 66 | fn tests_impl(args: TokenStream, input: TokenStream) -> parse::Result { 67 | #[derive(Debug, FromMeta)] 68 | struct MacroArgs { 69 | executor: Option, 70 | default_timeout: Option, 71 | setup: Option, 72 | } 73 | 74 | let attr_args = match NestedMeta::parse_meta_list(args.into()) { 75 | Ok(v) => v, 76 | Err(e) => { 77 | return Ok(TokenStream::from(darling::Error::from(e).write_errors())); 78 | } 79 | }; 80 | 81 | let macro_args = match MacroArgs::from_list(&attr_args) { 82 | Ok(v) => v, 83 | Err(e) => { 84 | return Ok(TokenStream::from(e.write_errors())); 85 | } 86 | }; 87 | 88 | #[cfg(not(all(feature = "embassy", feature = "external-executor")))] 89 | if macro_args.executor.is_some() { 90 | return Err(parse::Error::new( 91 | proc_macro2::Span::call_site(), 92 | "`#[embedded_test::tests]` attribute doesn't take an executor unless the features `embassy` and `external-executor` are enabled", 93 | )); 94 | } 95 | 96 | let module: ItemMod = syn::parse(input)?; 97 | 98 | let items = if let Some(content) = module.content { 99 | content.1 100 | } else { 101 | return Err(parse::Error::new( 102 | module.span(), 103 | "module must be inline (e.g. `mod foo {}`)", 104 | )); 105 | }; 106 | 107 | let mut init = None; 108 | let mut tests = vec![]; 109 | let mut untouched_tokens = vec![]; 110 | for item in items { 111 | match item { 112 | Item::Fn(mut f) => { 113 | let mut test_kind = None; 114 | let mut should_panic = false; 115 | let mut ignore = false; 116 | let mut timeout = None; 117 | 118 | f.attrs.retain(|attr| { 119 | if attr.path().is_ident("init") { 120 | test_kind = Some(Attr::Init); 121 | false 122 | } else if attr.path().is_ident("test") { 123 | test_kind = Some(Attr::Test); 124 | false 125 | } else if attr.path().is_ident("should_panic") { 126 | should_panic = true; 127 | false 128 | } else if attr.path().is_ident("ignore") { 129 | ignore = true; 130 | false 131 | } else if attr.path().is_ident("timeout") { 132 | timeout = Some(attr.clone()); 133 | false 134 | } else { 135 | true 136 | } 137 | }); 138 | 139 | let timeout = if let Some(attr) = timeout { 140 | match attr.parse_args::() { 141 | Ok(TimeoutAttribute { value }) => Some(value), 142 | Err(e) => { 143 | return Err(parse::Error::new( 144 | attr.span(), 145 | format!("failed to parse `timeout` attribute. Must be of the form #[timeout(10)] where 10 is the timeout in seconds. Error: {}", e) 146 | )); 147 | } 148 | } 149 | } else { 150 | None 151 | }; 152 | 153 | let attr = match test_kind { 154 | Some(it) => it, 155 | None => { 156 | return Err(parse::Error::new( 157 | f.span(), 158 | "function requires `#[init]` or `#[test]` attribute", 159 | )); 160 | } 161 | }; 162 | 163 | match attr { 164 | Attr::Init => { 165 | if init.is_some() { 166 | return Err(parse::Error::new( 167 | f.sig.ident.span(), 168 | "only a single `#[init]` function can be defined", 169 | )); 170 | } 171 | 172 | if should_panic { 173 | return Err(parse::Error::new( 174 | f.sig.ident.span(), 175 | "`#[should_panic]` is not allowed on the `#[init]` function", 176 | )); 177 | } 178 | 179 | if ignore { 180 | return Err(parse::Error::new( 181 | f.sig.ident.span(), 182 | "`#[ignore]` is not allowed on the `#[init]` function", 183 | )); 184 | } 185 | 186 | if timeout.is_some() { 187 | return Err(parse::Error::new( 188 | f.sig.ident.span(), 189 | "`#[timeout]` is not allowed on the `#[init]` function", 190 | )); 191 | } 192 | 193 | if check_fn_sig(&f.sig).is_err() || !f.sig.inputs.is_empty() { 194 | return Err(parse::Error::new( 195 | f.sig.ident.span(), 196 | "`#[init]` function must have signature `async fn() [-> Type]` (async/return type are optional)", 197 | )); 198 | } 199 | 200 | #[cfg(not(feature = "embassy"))] 201 | if f.sig.asyncness.is_some() { 202 | return Err(parse::Error::new( 203 | f.sig.ident.span(), 204 | "`#[init]` function can only be async if an async executor is enabled via feature", 205 | )); 206 | } 207 | 208 | let state = match &f.sig.output { 209 | ReturnType::Default => None, 210 | ReturnType::Type(.., ty) => Some(ty.clone()), 211 | }; 212 | let asyncness = f.sig.asyncness.is_some(); 213 | init = Some(Init { 214 | func: f, 215 | state, 216 | asyncness, 217 | }); 218 | } 219 | 220 | Attr::Test => { 221 | if check_fn_sig(&f.sig).is_err() || f.sig.inputs.len() > 1 { 222 | return Err(parse::Error::new( 223 | f.sig.ident.span(), 224 | "`#[test]` function must have signature `async fn(state: &mut Type)` (async/parameter are optional)", 225 | )); 226 | } 227 | 228 | #[cfg(not(feature = "embassy"))] 229 | if f.sig.asyncness.is_some() { 230 | return Err(parse::Error::new( 231 | f.sig.ident.span(), 232 | "`#[test]` function can only be async if an async executor is enabled via feature", 233 | )); 234 | } 235 | 236 | let input = if f.sig.inputs.len() == 1 { 237 | let arg = &f.sig.inputs[0]; 238 | 239 | // NOTE we cannot check the argument type matches `init.state` at this 240 | // point 241 | if let Some(ty) = get_arg_type(arg).cloned() { 242 | Some(Input { ty }) 243 | } else { 244 | // was not `&mut T` 245 | return Err(parse::Error::new( 246 | arg.span(), 247 | "parameter must be of the type that init() returns", 248 | )); 249 | } 250 | } else { 251 | None 252 | }; 253 | 254 | let asyncness = f.sig.asyncness.is_some(); 255 | tests.push(Test { 256 | cfgs: extract_cfgs(&f.attrs), 257 | func: f, 258 | asyncness, 259 | input, 260 | should_panic, 261 | ignore, 262 | timeout: timeout.or(macro_args.default_timeout), 263 | }); 264 | } 265 | } 266 | } 267 | 268 | _ => { 269 | untouched_tokens.push(item); 270 | } 271 | } 272 | } 273 | 274 | let krate = format_ident!("embedded_test"); 275 | let ident = module.ident; 276 | let mut state_ty = None; 277 | let (init_fn, init_expr, init_is_async) = if let Some(ref init) = init { 278 | let init_func = &init.func; 279 | let init_ident = &init.func.sig.ident; 280 | state_ty = init.state.clone(); 281 | 282 | ( 283 | Some(quote!(#init_func)), 284 | invoke(init_ident, vec![], init.asyncness), 285 | init.asyncness, 286 | ) 287 | } else { 288 | (None, quote!(()), false) 289 | }; 290 | 291 | let mut unit_test_calls = vec![]; 292 | let mut test_function_invokers = vec![]; 293 | 294 | for test in &tests { 295 | let should_panic = test.should_panic; 296 | let ignore = test.ignore; 297 | let ident = &test.func.sig.ident; 298 | let ident_invoker = format_ident!("__{}_invoker", ident); 299 | let span = test.func.sig.ident.span(); 300 | 301 | let timeout = match test.timeout { 302 | Some(timeout) => quote!(Some(#timeout)), 303 | None => quote!(None), 304 | }; 305 | 306 | //TODO: if init func returns something, all functions must accept it as input? 307 | let mut args = vec![]; 308 | 309 | if let Some(input) = test.input.as_ref() { 310 | if let Some(state) = &state_ty { 311 | if input.ty != **state { 312 | return Err(parse::Error::new( 313 | input.ty.span(), 314 | format!( 315 | "this type must match `#[init]`s return type: {}", 316 | type_ident(state) 317 | ), 318 | )); 319 | } 320 | args.push(quote!(state)); 321 | } else { 322 | return Err(parse::Error::new( 323 | span, 324 | "no state was initialized by `#[init]`; signature must be `fn()`", 325 | )); 326 | } 327 | } 328 | 329 | let run_call = invoke(ident, args, test.asyncness); 330 | 331 | let init_run_and_check = quote!( 332 | { 333 | let outcome; 334 | { 335 | let state = #init_expr; // either init() or init().await or () 336 | outcome = #run_call; // either test(state), test(state).await, test(), or test().await 337 | } 338 | #krate::export::check_outcome(outcome); 339 | } 340 | ); 341 | 342 | let task_path = if cfg!(feature = "ariel-os") { 343 | quote!(ariel_os::task) 344 | } else { 345 | quote!(#krate::export::task) 346 | }; 347 | 348 | // The closure that will be called, if the test should be runned. 349 | // This closure has the signature () -> !, so it will never return. 350 | // The closure will signal the test result via semihosting exit/abort instead 351 | let entrypoint = if test.asyncness || init_is_async { 352 | // We need a utility function, so that embassy can create a task for us 353 | let cfgs = &test.cfgs; 354 | test_function_invokers.push(quote!( 355 | #(#cfgs)* 356 | #[#task_path] 357 | async fn #ident_invoker() { 358 | #init_run_and_check 359 | } 360 | )); 361 | 362 | if cfg!(feature = "ariel-os") { 363 | quote!(|| { 364 | ariel_os::asynch::spawner().must_spawn(#ident_invoker()); 365 | ariel_os::thread::park(); 366 | unreachable!(); 367 | }) 368 | } else { 369 | let executor = if let Some(executor) = ¯o_args.executor { 370 | quote! { 371 | #executor 372 | } 373 | } else { 374 | quote! { 375 | #krate::export::Executor::new() 376 | } 377 | }; 378 | 379 | quote!(|| { 380 | let mut executor = #executor; 381 | let executor = unsafe { __make_static(&mut executor) }; 382 | executor.run(|spawner| { 383 | spawner.must_spawn(#ident_invoker()); 384 | }) 385 | }) 386 | } 387 | } else { 388 | quote!(|| { 389 | #init_run_and_check 390 | }) 391 | }; 392 | 393 | unit_test_calls.push(quote! { 394 | const FULLY_QUALIFIED_FN_NAME: &str = concat!(module_path!(), "::", stringify!(#ident)); 395 | test_funcs.push(#krate::export::Test{name: FULLY_QUALIFIED_FN_NAME, ignored: #ignore, should_panic: #should_panic, function: #entrypoint, timeout: #timeout}).unwrap(); 396 | }); 397 | } 398 | 399 | let test_functions = tests.iter().map(|test| &test.func); 400 | let test_cfgs = tests.iter().map(|test| &test.cfgs); 401 | let test_count = { 402 | let test_cfgs = test_cfgs.clone(); 403 | quote!( 404 | { 405 | let mut counter = 0; 406 | #( 407 | #(#test_cfgs)* 408 | { counter += 1; } 409 | )* 410 | counter 411 | } 412 | ) 413 | }; 414 | 415 | let test_names_strlen = { 416 | let test_cfgs = test_cfgs.clone(); 417 | let test_names = tests.iter().map(|test| test.func.sig.ident.clone()); 418 | quote!( 419 | { 420 | // The idea of this code is to calculate the overall string length of all test names, 421 | // so that inside `run_tests` we can allocate a json buffer of the right size, 422 | // without doing a heap allocation (requiring a global allocator) 423 | let mut counter = 0; 424 | #( 425 | #(#test_cfgs)* 426 | { 427 | const FULLY_QUALIFIED_FN_NAME: &str = concat!(module_path!(), "::", stringify!(#test_names)); 428 | counter += FULLY_QUALIFIED_FN_NAME.len(); 429 | } 430 | )* 431 | counter 432 | } 433 | ) 434 | }; 435 | let setup = macro_args.setup; 436 | 437 | let (thread_start, maybe_export_name) = if cfg!(feature = "ariel-os") { 438 | ( 439 | quote!( 440 | // TODO: make stack size configurable 441 | #[ariel_os::thread(autostart, stacksize = 16384)] 442 | fn embedded_test_thread() { 443 | unsafe { __embedded_test_entry() } 444 | } 445 | ), 446 | quote!(), 447 | ) 448 | } else { 449 | (quote!(), quote!(#[export_name = "main"])) 450 | }; 451 | 452 | Ok(quote!( 453 | #[cfg(test)] 454 | mod #ident { 455 | #(#untouched_tokens)* 456 | 457 | // Used by probe-rs to detect that the binary runs embedded-test 458 | #[used] 459 | #[no_mangle] 460 | #[link_section = ".embedded_test.meta"] 461 | static EMBEDDED_TEST_VERSION: usize = 0; 462 | 463 | unsafe fn __make_static(t: &mut T) -> &'static mut T { 464 | ::core::mem::transmute(t) 465 | } 466 | 467 | #thread_start 468 | 469 | #maybe_export_name 470 | unsafe extern "C" fn __embedded_test_entry() -> ! { 471 | // The linker file will redirect this call to the function below. 472 | // This trick ensures that we get a compile error, if the linker file was not added to the rustflags. 473 | #krate::export::ensure_linker_file_was_added_to_rustflags(); 474 | } 475 | 476 | #[no_mangle] 477 | unsafe extern "C" fn __embedded_test_start() -> ! { 478 | { 479 | #setup 480 | } 481 | 482 | const TEST_COUNT : usize = #test_count; 483 | const TEST_NAMES_STRLEN : usize = #test_names_strlen; 484 | let mut test_funcs: #krate::export::Vec<#krate::export::Test, TEST_COUNT> = #krate::export::Vec::new(); 485 | 486 | #( 487 | #(#test_cfgs)* 488 | { 489 | #unit_test_calls // pushes Test to test_funcs 490 | } 491 | )* 492 | 493 | const JSON_SIZE_TOTAL : usize = #krate::export::JSON_SIZE_HEADER + TEST_NAMES_STRLEN + #krate::export::JSON_SIZE_PER_TEST_WITHOUT_TESTNAME * TEST_COUNT; 494 | 495 | #krate::export::run_tests::(&mut test_funcs[..]); 496 | } 497 | 498 | #init_fn 499 | 500 | #( 501 | #test_functions 502 | )* 503 | 504 | #( 505 | #test_function_invokers 506 | )* 507 | }) 508 | .into()) 509 | } 510 | 511 | #[derive(Clone, Copy)] 512 | enum Attr { 513 | Init, 514 | Test, 515 | } 516 | 517 | struct Init { 518 | func: ItemFn, 519 | state: Option>, 520 | asyncness: bool, 521 | } 522 | 523 | struct Test { 524 | func: ItemFn, 525 | cfgs: Vec, 526 | input: Option, 527 | should_panic: bool, 528 | ignore: bool, 529 | asyncness: bool, 530 | timeout: Option, 531 | } 532 | 533 | struct Input { 534 | ty: Type, 535 | } 536 | 537 | struct TimeoutAttribute { 538 | value: u32, 539 | } 540 | 541 | impl syn::parse::Parse for TimeoutAttribute { 542 | fn parse(input: syn::parse::ParseStream) -> syn::Result { 543 | let value_lit: syn::LitInt = input.parse()?; 544 | let value = value_lit.base10_parse::()?; 545 | 546 | Ok(TimeoutAttribute { value }) 547 | } 548 | } 549 | 550 | // NOTE doesn't check the parameters or the return type 551 | fn check_fn_sig(sig: &syn::Signature) -> Result<(), ()> { 552 | if sig.constness.is_none() 553 | && sig.unsafety.is_none() 554 | && sig.abi.is_none() 555 | && sig.generics.params.is_empty() 556 | && sig.generics.where_clause.is_none() 557 | && sig.variadic.is_none() 558 | { 559 | Ok(()) 560 | } else { 561 | Err(()) 562 | } 563 | } 564 | 565 | fn get_arg_type(arg: &syn::FnArg) -> Option<&Type> { 566 | if let syn::FnArg::Typed(pat) = arg { 567 | match &*pat.ty { 568 | syn::Type::Reference(_) => None, 569 | _ => Some(&pat.ty), 570 | } 571 | } else { 572 | None 573 | } 574 | } 575 | 576 | fn extract_cfgs(attrs: &[Attribute]) -> Vec { 577 | let mut cfgs = vec![]; 578 | 579 | for attr in attrs { 580 | if attr.path().is_ident("cfg") { 581 | cfgs.push(attr.clone()); 582 | } 583 | } 584 | 585 | cfgs 586 | } 587 | 588 | fn type_ident(ty: impl AsRef) -> String { 589 | let mut ident = String::new(); 590 | let ty = ty.as_ref(); 591 | let ty = format!("{}", quote!(#ty)); 592 | ty.split_whitespace().for_each(|t| ident.push_str(t)); 593 | ident 594 | } 595 | 596 | fn invoke( 597 | func: &proc_macro2::Ident, 598 | args: Vec, 599 | asyncness: bool, 600 | ) -> proc_macro2::TokenStream { 601 | if asyncness { 602 | quote!(#func(#(#args),*).await) 603 | } else { 604 | quote!(#func(#(#args),*)) 605 | } 606 | } 607 | -------------------------------------------------------------------------------- /src/export.rs: -------------------------------------------------------------------------------- 1 | use crate::TestOutcome; 2 | 3 | pub use heapless::Vec; 4 | 5 | #[cfg_attr(feature = "std", path = "std.rs")] 6 | #[cfg_attr(not(feature = "std"), path = "semihosting.rs")] 7 | mod hosting; 8 | 9 | pub fn ensure_linker_file_was_added_to_rustflags() -> ! { 10 | // Try to access a symbol which we provide in the embedded-test.x linker file. 11 | // This will trigger a linker error if the linker file has not been added to the rustflags 12 | extern "C" { 13 | fn embedded_test_linker_file_not_added_to_rustflags() -> !; 14 | } 15 | unsafe { embedded_test_linker_file_not_added_to_rustflags() } 16 | } 17 | 18 | // Reexport the embassy stuff 19 | #[cfg(all(feature = "embassy", not(feature = "ariel-os")))] 20 | pub use embassy_executor::task; 21 | #[cfg(all( 22 | feature = "embassy", 23 | not(feature = "external-executor"), 24 | not(feature = "ariel-os") 25 | ))] 26 | pub use embassy_executor::Executor; // Please activate the `executor-thread` or `executor-interrupt` feature on the embassy-executor crate (v0.7.x)! 27 | 28 | const VERSION: u32 = 1; //Format version of our protocol between probe-rs and target running embedded-test 29 | 30 | // Constants ahead that are used by proc macros to calculate the needed json buffer size 31 | pub const JSON_SIZE_HEADER: usize = r#"{"version:12,tests:[]}"#.len(); 32 | pub const JSON_SIZE_PER_TEST_WITHOUT_TESTNAME: usize = 33 | r#"{"name":"","should_panic":false,ignored:false,timeout:1234567890},"#.len(); 34 | 35 | /// Struct which will be serialized as JSON and sent to probe-rs when it requests the available tests 36 | // NOTE: Update the const's above if you change something here 37 | #[derive(Debug, serde::Serialize)] 38 | pub struct Tests<'a> { 39 | pub version: u32, 40 | pub tests: &'a [Test], 41 | } 42 | 43 | /// Struct which describes a single test to probe-rs 44 | // NOTE: Update the const's above if you change something here 45 | #[derive(Debug, serde::Serialize)] 46 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] 47 | pub struct Test { 48 | pub name: &'static str, 49 | #[serde(skip)] 50 | pub function: fn() -> !, 51 | pub should_panic: bool, 52 | pub ignored: bool, 53 | pub timeout: Option, 54 | } 55 | 56 | pub fn run_tests(tests: &mut [Test]) -> ! { 57 | for test in tests.iter_mut() { 58 | test.name = &test.name[test.name.find("::").unwrap() + 2..]; 59 | } 60 | 61 | let args = &hosting::args().expect("Failed to get cmdline via semihosting"); 62 | 63 | // this is an iterator already with semihosting, not on std 64 | let mut args = args.into_iter(); 65 | 66 | let command = match args.next() { 67 | Some(c) => c.expect("command to run contains non-utf8 characters"), 68 | None => { 69 | error!("Received no arguments via semihosting. Please communicate with the target with the embedded-test runner."); 70 | hosting::abort(); 71 | } 72 | }; 73 | 74 | match command { 75 | "list" => { 76 | info!("tests available: {:?}", tests); 77 | let tests = Tests { 78 | version: VERSION, 79 | tests, 80 | }; 81 | 82 | hosting::print_test_list::(&tests); 83 | 84 | hosting::exit(0); 85 | } 86 | "run" => { 87 | let test_name = args.next().expect("test name missing"); 88 | 89 | let test_name = test_name.expect("test name contains non-utf8 character"); 90 | 91 | let test = tests 92 | .iter_mut() 93 | .find(|t| t.name == test_name) 94 | .expect("test to run not found"); 95 | info!("Running test: {:?}", test); 96 | (test.function)(); 97 | } 98 | _ => { 99 | error!("Unknown command: {}", command); 100 | hosting::abort(); 101 | } 102 | } 103 | } 104 | 105 | pub fn check_outcome(outcome: T) -> ! { 106 | if outcome.is_success() { 107 | info!("Test exited with () or Ok(..)"); 108 | hosting::exit(0); 109 | } else { 110 | info!("Test exited with Err(..): {:?}", outcome); 111 | hosting::abort(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/fmt.rs: -------------------------------------------------------------------------------- 1 | #![macro_use] 2 | #![allow(unused_macros)] 3 | 4 | macro_rules! trace { 5 | ($s:literal $(, $x:expr)* $(,)?) => { 6 | { 7 | #[cfg(feature = "log")] 8 | ::log::trace!($s $(, $x)*); 9 | #[cfg(feature = "defmt")] 10 | ::defmt::trace!($s $(, $x)*); 11 | #[cfg(not(any(feature = "log", feature="defmt")))] 12 | let _ = ($( & $x ),*); 13 | } 14 | }; 15 | } 16 | 17 | macro_rules! debug { 18 | ($s:literal $(, $x:expr)* $(,)?) => { 19 | { 20 | #[cfg(feature = "log")] 21 | ::log::debug!($s $(, $x)*); 22 | #[cfg(feature = "defmt")] 23 | ::defmt::debug!($s $(, $x)*); 24 | #[cfg(not(any(feature = "log", feature="defmt")))] 25 | let _ = ($( & $x ),*); 26 | } 27 | }; 28 | } 29 | 30 | macro_rules! info { 31 | ($s:literal $(, $x:expr)* $(,)?) => { 32 | { 33 | #[cfg(feature = "log")] 34 | ::log::info!($s $(, $x)*); 35 | #[cfg(feature = "defmt")] 36 | ::defmt::info!($s $(, $x)*); 37 | #[cfg(not(any(feature = "log", feature="defmt")))] 38 | let _ = ($( & $x ),*); 39 | } 40 | }; 41 | } 42 | 43 | macro_rules! warn { 44 | ($s:literal $(, $x:expr)* $(,)?) => { 45 | { 46 | #[cfg(feature = "log")] 47 | ::log::warn!($s $(, $x)*); 48 | #[cfg(feature = "defmt")] 49 | ::defmt::warn!($s $(, $x)*); 50 | #[cfg(not(any(feature = "log", feature="defmt")))] 51 | let _ = ($( & $x ),*); 52 | } 53 | }; 54 | } 55 | 56 | macro_rules! error { 57 | ($s:literal $(, $x:expr)* $(,)?) => { 58 | { 59 | #[cfg(feature = "log")] 60 | ::log::error!($s $(, $x)*); 61 | #[cfg(feature = "defmt")] 62 | ::defmt::error!($s $(, $x)*); 63 | #[cfg(not(any(feature = "log", feature="defmt")))] 64 | let _ = ($( & $x ),*); 65 | } 66 | }; 67 | } 68 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copied from https://github.com/knurling-rs/defmt/blob/main/firmware/defmt-test/src/lib.rs 2 | 3 | #![cfg_attr(not(feature = "std"), no_std)] 4 | #![allow(clippy::needless_doctest_main)] 5 | #![cfg_attr(not(doctest), doc = include_str!("../README.md"))] 6 | 7 | mod fmt; 8 | 9 | pub use embedded_test_macros::tests; 10 | 11 | #[cfg(all(feature = "panic-handler", not(feature = "ariel-os")))] 12 | #[panic_handler] 13 | fn panic(info: &core::panic::PanicInfo) -> ! { 14 | error!("====================== PANIC ======================"); 15 | 16 | #[cfg(not(feature = "defmt"))] 17 | error!("{}", info); 18 | 19 | #[cfg(feature = "defmt")] 20 | error!("{}", defmt::Display2Format(info)); 21 | 22 | semihosting::process::abort() 23 | } 24 | 25 | /// Private implementation details used by the proc macro. 26 | /// WARNING: This API is not stable and may change at any time. 27 | #[doc(hidden)] 28 | pub mod export; 29 | 30 | mod sealed { 31 | pub trait Sealed {} 32 | impl Sealed for () {} 33 | impl Sealed for Result {} 34 | } 35 | 36 | /// Indicates whether a test succeeded or failed. 37 | /// 38 | /// This is comparable to the `Termination` trait in libstd, except stable and tailored towards the 39 | /// needs of embedded-test. It is implemented for `()`, which always indicates success, and `Result`, 40 | /// where `Ok` indicates success. 41 | #[cfg(feature = "defmt")] 42 | pub trait TestOutcome: defmt::Format + sealed::Sealed { 43 | fn is_success(&self) -> bool; 44 | } 45 | 46 | /// Indicates whether a test succeeded or failed. 47 | /// 48 | /// This is comparable to the `Termination` trait in libstd, except stable and tailored towards the 49 | /// needs of embedded-test. It is implemented for `()`, which always indicates success, and `Result`, 50 | /// where `Ok` indicates success. 51 | #[cfg(feature = "log")] 52 | pub trait TestOutcome: core::fmt::Debug + sealed::Sealed { 53 | fn is_success(&self) -> bool; 54 | } 55 | 56 | /// Indicates whether a test succeeded or failed. 57 | /// 58 | /// This is comparable to the `Termination` trait in libstd, except stable and tailored towards the 59 | /// needs of embedded-test. It is implemented for `()`, which always indicates success, and `Result`, 60 | /// where `Ok` indicates success. 61 | #[cfg(all(not(feature = "log"), not(feature = "defmt")))] 62 | pub trait TestOutcome: sealed::Sealed { 63 | fn is_success(&self) -> bool; 64 | } 65 | 66 | impl TestOutcome for () { 67 | fn is_success(&self) -> bool { 68 | true 69 | } 70 | } 71 | 72 | #[cfg(feature = "log")] 73 | impl TestOutcome for Result { 74 | fn is_success(&self) -> bool { 75 | self.is_ok() 76 | } 77 | } 78 | 79 | #[cfg(feature = "defmt")] 80 | impl TestOutcome for Result { 81 | fn is_success(&self) -> bool { 82 | self.is_ok() 83 | } 84 | } 85 | 86 | #[cfg(all(not(feature = "log"), not(feature = "defmt")))] 87 | impl TestOutcome for Result { 88 | fn is_success(&self) -> bool { 89 | self.is_ok() 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/semihosting.rs: -------------------------------------------------------------------------------- 1 | use semihosting::experimental::env::Args; 2 | use semihosting::io; 3 | use semihosting::sys::arm_compat::syscall::ParamRegR; 4 | use semihosting::sys::arm_compat::syscall::{syscall_readonly, OperationNumber}; 5 | 6 | use crate::export::Tests; 7 | 8 | pub fn args() -> io::Result> { 9 | semihosting::experimental::env::args::<1024>() 10 | } 11 | 12 | pub fn abort() -> ! { 13 | semihosting::process::abort() 14 | } 15 | 16 | pub fn exit(code: i32) -> ! { 17 | semihosting::process::exit(code) 18 | } 19 | 20 | pub fn print_test_list(tests: &Tests<'_>) { 21 | let mut buf = [0u8; JSON_SIZE_TOTAL]; 22 | let size = serde_json_core::to_slice(&tests, &mut buf) 23 | .expect("Buffer to store list of test was too small"); 24 | let args = [ParamRegR::ptr(buf.as_ptr()), ParamRegR::usize(size)]; 25 | let ret = unsafe { 26 | syscall_readonly( 27 | OperationNumber::user_defined(0x100), 28 | ParamRegR::block(&args), 29 | ) 30 | }; 31 | if ret.usize() != 0 { 32 | error!("syscall failed: {}", ret.usize()); 33 | abort(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/std.rs: -------------------------------------------------------------------------------- 1 | use core::convert::Infallible; 2 | use std::sync::LazyLock; 3 | 4 | use crate::export::Tests; 5 | 6 | type Args = Vec>; 7 | 8 | pub fn args() -> Result { 9 | // We want to return an Iterator over `Result<&'static str, Error>` in order to 10 | // match the API of semihosting's `args()` / `Args`. 11 | // `std` has `String` args, so let's make those `'static`. 12 | // We also skip `argv[0]`, which on `std` contains the binary name. 13 | static ARGS: LazyLock> = LazyLock::new(|| std::env::args().skip(1).collect()); 14 | 15 | Ok(ARGS 16 | .iter() 17 | .map(|s| Ok(s.as_str())) 18 | .collect::>>()) 19 | } 20 | 21 | pub fn abort() -> ! { 22 | std::process::abort() 23 | } 24 | 25 | pub fn exit(code: i32) -> ! { 26 | std::process::exit(code) 27 | } 28 | 29 | pub fn print_test_list(tests: &Tests<'_>) { 30 | let tests_json = 31 | serde_json_core::to_string::<_, JSON_SIZE_TOTAL>(tests).expect("conversion to json"); 32 | 33 | println!("{tests_json}"); 34 | } 35 | --------------------------------------------------------------------------------