diff --git a/Cargo.lock b/Cargo.lock index 9b02294d4..abae724e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6995,6 +6995,18 @@ dependencies = [ "stm32h7", ] +[[package]] +name = "tests-grapefruit" +version = "0.1.0" +dependencies = [ + "build-util", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "kern", + "stm32h7", +] + [[package]] name = "tests-lpc55xpresso" version = "0.1.0" diff --git a/build/xtask/src/config.rs b/build/xtask/src/config.rs index cbea48452..0aff68a20 100644 --- a/build/xtask/src/config.rs +++ b/build/xtask/src/config.rs @@ -879,7 +879,7 @@ impl BuildConfig<'_> { let mut nightly_features = vec![]; // nightly features that we use: - nightly_features.extend(["emit_stack_sizes", "used_with_arg"]); + nightly_features.extend(["emit_stack_sizes"]); // nightly features that our dependencies use: nightly_features.extend([ "backtrace", diff --git a/test/test-suite/src/main.rs b/test/test-suite/src/main.rs index 8cf93854b..81b802545 100644 --- a/test/test-suite/src/main.rs +++ b/test/test-suite/src/main.rs @@ -18,7 +18,6 @@ //! //! The Idol server, `test-idol-server`, tests Idol-mediated IPC. It must be //! included in the image with the name `idol`, but its ID is immaterial. -#![feature(used_with_arg)] #![no_std] #![no_main] #![forbid(clippy::wildcard_imports)] @@ -47,15 +46,14 @@ ringbuf!(Trace, 64, Trace::None); /// secure fault, and a different constant will be required.) const BAD_ADDRESS: u32 = 0x0; -/// Helper macro for building a list of functions with their names. -/// We use the humility debug processing to get the name of each -/// test case and the total number of tests. The #[used(linker)] -/// is to ensure that this actually gets emitted as a symbol. +/// Helper macro for building a list of functions with their names. We use the +/// humility debug processing to get the name of each test case and the total +/// number of tests. The `unsafe(no_mangle)` and `pub static mut` are to ensure +/// that this actually gets emitted as a symbol. macro_rules! test_cases { ($($(#[$attr:meta])* $name:path,)*) => { #[unsafe(no_mangle)] - #[used(linker)] - static TESTS: &[(&str, &(dyn Fn() + Send + Sync))] = &[ + pub static mut TESTS: &[(&str, &(dyn Fn() + Send + Sync))] = &[ $( $(#[$attr])* (stringify!($name), &$name) @@ -1683,7 +1681,12 @@ fn main() -> ! { caller.reply(()); ringbuf_entry!(Trace::TestStart); - TESTS[idx].1(); + // SAFETY: this is single-threaded code. In addition, + // `TESTS` is only `pub static mut` to ensure that it's + // compiled into the binary; no one mutates it. + unsafe { + TESTS[idx].1(); + } let op = RunnerOp::TestComplete as u16; diff --git a/test/tests-grapefruit/Cargo.toml b/test/tests-grapefruit/Cargo.toml new file mode 100644 index 000000000..c6e978917 --- /dev/null +++ b/test/tests-grapefruit/Cargo.toml @@ -0,0 +1,28 @@ +[package] +edition = "2024" +name = "tests-grapefruit" +version = "0.1.0" + +[features] +h753 = ["stm32h7/stm32h753"] + +[dependencies] +cfg-if = { workspace = true } +cortex-m = { workspace = true } +cortex-m-rt = { workspace = true } +stm32h7 = { workspace = true, features = ["rt"] } + +kern = { path = "../../sys/kern" } + +[build-dependencies] +build-util = { path = "../../build/util" } + +[[bin]] +name = "tests-grapefruit" +path = "../../app/grapefruit/src/main.rs" +test = false +doctest = false +bench = false + +[lints] +workspace = true diff --git a/test/tests-grapefruit/app.toml b/test/tests-grapefruit/app.toml new file mode 100644 index 000000000..1cb217991 --- /dev/null +++ b/test/tests-grapefruit/app.toml @@ -0,0 +1,65 @@ +name = "tests-grapefruit" +target = "thumbv7em-none-eabihf" +board = "grapefruit-a" +chip = "../../chips/stm32h7" +default-ram = "dtcm" +stacksize = 2048 + +[kernel] +name = "grapefruit" +requires = {flash = 32768, ram = 4096} + +[tasks.runner] +name = "test-runner" +priority = 0 +max-sizes = {flash = 16384, ram = 4096} +start = true + +[tasks.suite] +name = "test-suite" +priority = 2 +max-sizes = {flash = 65536, ram = 4096} +start = true +task-slots = ["assist", "idol", "suite", "runner"]# this doesn't actually use SPI; we're just mapping that interrupt to test +# interrupt handling. chosen completely arbitrarily. +uses = ["spi1"] +notifications = ["test-irq"] +interrupts = {"spi1.irq" = "test-irq"} + +# This block is used to test the task_config macro +[tasks.suite.config] +foo = '"Hello, world"' +bar = 42 +baz = [1, 2, 3, 4] +tup = [[1, true], [2, true], [3, false]] + +[tasks.assist] +name = "test-assist" +priority = 1 +max-sizes = {flash = 16384, ram = 4096} +start = true + +[tasks.idol] +name = "test-idol-server" +priority = 1 +max-sizes = {flash = 4096, ram = 1024} +stacksize = 1024 +start = true + +[tasks.hiffy] +name = "task-hiffy" +priority = 3 +features = ["testsuite"] +max-sizes = {flash = 32768, ram = 16384 } +stacksize = 2048 +start = true +task-slots = ["suite", "runner"] +notifications = ["timer"] + +[tasks.idle] +name = "task-idle" +priority = 4 +max-sizes = {flash = 256, ram = 256} +stacksize = 256 +start = true +