Merge #136 136: Create syscall recorder for tests r=Woyten a=torfmaster # Content of the PR This PR contains an "event recorder" which enables to write unit tests which invoke syscalls. The idea is to capture all syscalls and record them to assert which syscalls occur. The return value for a syscall can also be set. # Help needed Comments are very welcome. The mock syscall implementation is very crude because it is good enough to cover the only existing test case. Ideas for meaningful tests are very welcome so I can elaborate which infrastructure is needed to create these tests. Ideas would be * test the set alarm retry mechanism of the alarm implementation * test non-trivial callbacks (i.e. temperature) Co-authored-by: torfmaster <briefe@kebes.de>
diff --git a/.cargo/config b/.cargo/config index 98ba621..6849bb7 100644 --- a/.cargo/config +++ b/.cargo/config
@@ -1,33 +1,19 @@ -# Target configuration for the example apps on the nRF52-DK -[target.thumbv7em-none-eabi] -rustflags = [ - "-C", "link-arg=-Tnrf52_layout.ld", - "-C", "relocation-model=static", - "-D", "warnings", -] +[alias] +rriscv32iamc = "run --release --target=riscv32iamc-unknown-none-elf --example" +rrv32iamc = "rriscv32iamc" +rriscv32imc = "run --release --target=riscv32imc-unknown-none-elf --example" +rrv32imc = "rriscv32imc" +rthumbv7em = "run --release --target=thumbv7em-none-eabi --example" +rtv7em = "rthumbv7em" -[target.riscv32imac-unknown-none-elf] -rustflags = [ - "-C", "link-arg=-Triscv32_layout.ld", - "-C", "relocation-model=static", - "-D", "warnings", -] +# Deny warnings on all architectures. build.rustflags cannot be used here as the lower section would override its effect. +[target.'cfg(all())'] +rustflags = ["-D", "warnings"] -[target.riscv32imc-unknown-none-elf] +# Common settings for all embedded targets +[target.'cfg(any(target_arch = "arm", target_arch = "riscv32"))'] rustflags = [ - "-C", "link-arg=-Topentitan_layout.ld", - "-C", "relocation-model=static", - "-D", "warnings", + "-C", "relocation-model=static", + "-C", "link-arg=-Tlayout.ld", ] - -# Target configuration for the travis CI Linux build -[target.x86_64-unknown-linux-gnu] -rustflags = [ - "-D", "warnings", -] - -# Target configuration for the travis CI OS-X build -[target.x86_64-apple-darwin] -rustflags = [ - "-D", "warnings", -] +runner = "./flash.sh"
diff --git a/.gitignore b/.gitignore index 3a78405..da66475 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,3 +1,4 @@ -target Cargo.lock +layout.ld +platform target
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ab5997..9325962 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -36,6 +36,9 @@ ### Miscellaneous +- Flashing examples is no longer restricted to the nRF52 DK board + - `./run_example.sh` has been deleted + - Instead, use `PLATFORM=<platform> cargo r<arch> <your_app>`. This will build the app for your CPU architecture and platform-specific memory layout and flash it via J-Link to your board - Targets without support for atomics can be built ## a8bb4fa9be504517d5533511fd8e607ea61f1750 (0.1.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aa9d1fb..dd09bf1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md
@@ -15,9 +15,13 @@ ## Compilation -`libtock-rs` currently has two compilation targets: `riscv32imac-unknown-none-elf` -and `thumbv7em-none-eabi`. You can build the library and the examples -using the script `build_examples.sh`. +`libtock-rs` currently has the following compilation targets + +- `riscv32imac-unknown-none-elf` +- `riscv32imc-unknown-none-elf` +- `thumbv7em-none-eabi` + +You can trigger a test build of the library and the examples using the script `build_examples.sh`. ## Unit Testing and Linting @@ -26,14 +30,12 @@ ## Integration tests -If you have a `nRF52-dk` you can run the integration tests as follows. -The pins P0.03 and P0.04 need to be connected (on a nRF52-DK). Then do the following: +If you have an nRF52 DK you can run the integration tests as follows. +The pins P0.03 and P0.04 need to be connected (on an nRF52 DK). Then do the following: - connect your device to your computer - open a console, e.g. `tockloader listen` -- run the tests `./run_hardware_test.sh - -The desired test output is: +- run the tests: `PLATFORM=nrf52 cargo rtv7em hardware_test` The expected output on the UART console will be as follows.
diff --git a/Cargo.toml b/Cargo.toml index 6b78136..53da413 100644 --- a/Cargo.toml +++ b/Cargo.toml
@@ -7,7 +7,7 @@ [dependencies] core = { package = "async-support", path = "async-support" } -linked_list_allocator = { version = "0.6.4", default-features = false } +linked_list_allocator = { version = "=0.6.5", default-features = false } libtock_codegen = { path = "codegen" } [dev-dependencies]
diff --git a/README.md b/README.md index b1e1202..e58223e 100644 --- a/README.md +++ b/README.md
@@ -26,44 +26,40 @@ 1. Ensure you have [rustup](https://www.rustup.rs/) installed. -1. Clone the repository. +1. Clone the repository: ```bash git clone https://github.com/tock/libtock-rs cd libtock-rs ``` -1. Install `elf2tab`. +1. Install `elf2tab`: ```bash cargo install -f elf2tab --version 0.4.0 ``` -1. Add dependencies for cross-compilation. +1. Add dependencies for cross-compilation. Currently, only few platforms have been configured, e.g.: ```bash - rustup target add thumbv7em-none-eabi + rustup target add thumbv7em-none-eabi # For an nRF52 DK board ``` -1. Use the `run_example` script to compile and run the example app you want - to use: - ```bash - ./run_example.sh blink + rustup target add riscv32imc-unknown-none-elf # For an OpenTitan board ``` - Due to bug #28 this will currently only work if you are using the nRF52-DK platform. +1. Use `cargo r<arch>` to compile and run an example app. The full command is platform dependent and looks as follows for the `blink` example: - If you have a nRF52840-DK you must change `link-arg=-Tnrf52_layout.ld` in - `.cargo/config` to `link-arg=-Tnrf52840_layout.ld` + ```bash + PLATFORM=nrf52 cargo rthumbv7em blink # For an nRF52 DK board + ``` - If you have a hail board you can flash your device as follows: + ```bash + PLATFORM=opentitan cargo rriscv32imc blink # For an OpenTitan board + ``` - - set the environment variable `hail` to `1` - - change `link-arg=-Tnrf52_layout.ld` in `.cargo/config` to `link-arg=-Thail_layout.ld` - - run `run_example.sh` as above. - - For other platforms, you may have to create your own memory layout definition. + For an unknown platform, you may have to create your own memory layout definition. Place the layout definition file at `layout_<platform>.ld` and do not forget to enhance the `tockloader_flags` dispatching section in `flash.sh`. You are welcome to create a PR, s.t. the number of supported platforms grows. ## Using libtock-rs @@ -92,14 +88,20 @@ To run on the code on your board you can use ```bash -./run_example.sh <your app> +PLATFORM=<platform> cargo r<arch> <your_app> ``` This script does the following steps for you: - cross-compile your program - create a TAB (tock application bundle) -- if you have a nRF52-DK board connected: flash this TAB to your board (using tockloader) +- if you have a J-Link compatible board connected: flash this TAB to your board (using tockloader) + +Instead of specifying an environment variable each time you can permanently configure your platform by writing its name into a file named `platform`, e.g. + +```bash +echo nrf52 > platform +``` ## License
diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..8cdb6ae --- /dev/null +++ b/build.rs
@@ -0,0 +1,55 @@ +use std::env; +use std::fs; +use std::fs::File; +use std::io::BufRead; +use std::io::BufReader; +use std::path::Path; +use std::process; + +fn main() { + static ENV_VAR: &str = "PLATFORM"; + static FILE_NAME: &str = "platform"; + + println!("cargo:rerun-if-env-changed={}", ENV_VAR); + println!("cargo:rerun-if-changed={}", FILE_NAME); + + let platform_name = + read_board_name_from_env_var(ENV_VAR).or_else(|| read_board_name_from_file(FILE_NAME)); + if let Some(platform_name) = platform_name { + println!("cargo:rustc-env={}={}", ENV_VAR, platform_name); + copy_linker_file(&platform_name.trim()); + } else { + println!( + "cargo:warning=No platform specified. \ + Remember to manually specify a linker file.", + ); + } +} + +fn read_board_name_from_env_var(env_var: &str) -> Option<String> { + env::var_os(env_var).map(|os_string| os_string.into_string().unwrap()) +} + +fn read_board_name_from_file(file_name: &str) -> Option<String> { + let path = Path::new(file_name); + if !path.exists() { + return None; + } + + let board_file = File::open(path).unwrap(); + let mut board_name = String::new(); + BufReader::new(board_file) + .read_line(&mut board_name) + .unwrap(); + Some(board_name) +} + +fn copy_linker_file(platform_name: &str) { + let linker_file_name = format!("layout_{}.ld", platform_name); + let path = Path::new(&linker_file_name); + if !path.exists() { + println!("Cannot find layout file {:?}", path); + process::exit(1); + } + fs::copy(linker_file_name, "layout.ld").unwrap(); +}
diff --git a/build_examples.sh b/build_examples.sh index dbaeb56..c094db9 100755 --- a/build_examples.sh +++ b/build_examples.sh
@@ -2,5 +2,5 @@ set -eux -cargo build --release --target=thumbv7em-none-eabi --examples -cargo build --release --target=riscv32imc-unknown-none-elf --examples # Important for tests: This target does not support atomics +PLATFORM=nrf52 cargo build --release --target=thumbv7em-none-eabi --examples +PLATFORM=riscv32 cargo build --release --target=riscv32imc-unknown-none-elf --examples # Important for testing: This target does not support atomics
diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..b13b751 --- /dev/null +++ b/doc/README.md
@@ -0,0 +1,7 @@ +# Available flash commands + +- `cargo rriscv32iamc`/`cargo rrv32iamc`: Use the `riscv32iamc-unknown-none-elf` target +- `cargo rriscv32imc`/`cargo rrv32imc`: Use the `riscv32imc-unknown-none-elf` target +- `cargo rthumbv7em`/`cargo rtv7em`: Use the `thumbv7em-none-eabi` target + +Before flashing, write your board name to the environment variable `PLATFORM` or to a file named `platform` \ No newline at end of file
diff --git a/flash.sh b/flash.sh new file mode 100755 index 0000000..a67312c --- /dev/null +++ b/flash.sh
@@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +set -eux + +artifact="$(basename $1)" +rust_target_folder="$(readlink -f $(dirname $1)/../..)" +libtock_target_path="${rust_target_folder}/tab/${PLATFORM}/${artifact}" +elf_file_name="${libtock_target_path}/cortex-m4.elf" +tab_file_name="${libtock_target_path}.tab" + +mkdir -p "${libtock_target_path}" +cp "$1" "${elf_file_name}" + +elf2tab -n "${artifact}" -o "${tab_file_name}" "${elf_file_name}" --stack 2048 --app-heap 1024 --kernel-heap 1024 --protected-region-size=64 + +case "${PLATFORM}" in + "nrf52"|"nrf52840") + tockloader_flags="--jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52" + ;; + "hail") + tockloader_flags="" + ;; + *) + echo "Tockloader flags unknown for platform \"${PLATFORM}\"" + exit 1 + ;; +esac + +tockloader uninstall ${tockloader_flags} || true +tockloader install ${tockloader_flags} "${tab_file_name}"
diff --git a/layout.ld b/layout_generic.ld similarity index 100% rename from layout.ld rename to layout_generic.ld
diff --git a/hail_layout.ld b/layout_hail.ld similarity index 93% rename from hail_layout.ld rename to layout_hail.ld index 786548c..f5473ee 100644 --- a/hail_layout.ld +++ b/layout_hail.ld
@@ -14,4 +14,4 @@ MPU_MIN_ALIGN = 8K; -INCLUDE layout.ld +INCLUDE layout_generic.ld
diff --git a/nrf52_layout.ld b/layout_nrf52.ld similarity index 93% rename from nrf52_layout.ld rename to layout_nrf52.ld index 7c96869..419a0bc 100644 --- a/nrf52_layout.ld +++ b/layout_nrf52.ld
@@ -14,4 +14,4 @@ MPU_MIN_ALIGN = 8K; -INCLUDE layout.ld +INCLUDE layout_generic.ld
diff --git a/nrf52840_layout.ld b/layout_nrf52840.ld similarity index 93% rename from nrf52840_layout.ld rename to layout_nrf52840.ld index 0ac2b5c..d99efa0 100644 --- a/nrf52840_layout.ld +++ b/layout_nrf52840.ld
@@ -14,4 +14,4 @@ MPU_MIN_ALIGN = 8K; -INCLUDE layout.ld +INCLUDE layout_generic.ld
diff --git a/opentitan_layout.ld b/layout_opentitan.ld similarity index 93% rename from opentitan_layout.ld rename to layout_opentitan.ld index d2d09ba..ab475fc 100644 --- a/opentitan_layout.ld +++ b/layout_opentitan.ld
@@ -14,4 +14,4 @@ MPU_MIN_ALIGN = 1K; -INCLUDE layout.ld +INCLUDE layout_generic.ld
diff --git a/riscv32_layout.ld b/layout_riscv32.ld similarity index 93% rename from riscv32_layout.ld rename to layout_riscv32.ld index b7067fd..e3aba2c 100644 --- a/riscv32_layout.ld +++ b/layout_riscv32.ld
@@ -14,4 +14,4 @@ MPU_MIN_ALIGN = 1K; -INCLUDE layout.ld +INCLUDE layout_generic.ld
diff --git a/run_all_checks.sh b/run_all_checks.sh index 7d96180..c445608 100755 --- a/run_all_checks.sh +++ b/run_all_checks.sh
@@ -2,6 +2,8 @@ set -eux +export PLATFORM=nrf52 # The specific platform doesn't matter for tests + cargo fmt --all -- --check cargo test --workspace cargo clippy --workspace --all-targets
diff --git a/run_example.sh b/run_example.sh deleted file mode 100755 index 92bd574..0000000 --- a/run_example.sh +++ /dev/null
@@ -1,38 +0,0 @@ -#!/usr/bin/env bash - -# Examples only run on a nRF52-DK board - -set -eux - -cargo build --release --target=thumbv7em-none-eabi --example "$1" - - -elf_file_name="target/tab/$1/cortex-m4.elf" -tab_file_name="target/tab/$1.tab" - -# Default value for nRF52-DK -tockloader_flags="--jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52" - -hail_defined=${hail:-} -if [ -n "$hail_defined" ] -then - tockloader_flags="" -fi - -mkdir -p "target/tab/$1" -cp "target/thumbv7em-none-eabi/release/examples/$1" "$elf_file_name" - -elf2tab -n "$1" -o "$tab_file_name" "$elf_file_name" --stack 2048 --app-heap 1024 --kernel-heap 1024 --protected-region-size=64 - -if [ "$#" -ge "2" ] -then - if [ "$2" = "--dont-clear-apps" ] - then - echo "do not delete apps from board." - else - tockloader uninstall $tockloader_flags || true - fi -else - tockloader uninstall $tockloader_flags || true -fi -tockloader install $tockloader_flags "$tab_file_name"
diff --git a/run_hardware_test.sh b/run_hardware_test.sh deleted file mode 100755 index 70fdc75..0000000 --- a/run_hardware_test.sh +++ /dev/null
@@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -# Tests only run on a nRF52-DK board - -set -eux - -yes 0|tockloader uninstall --jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52 || true - -./run_example.sh hardware_test --dont-clear-apps
diff --git a/src/entry_point/start_item_riscv32.rs b/src/entry_point/start_item_riscv32.rs index c107f36..cabfd66 100644 --- a/src/entry_point/start_item_riscv32.rs +++ b/src/entry_point/start_item_riscv32.rs
@@ -93,8 +93,8 @@ jal rust_start" : // No output operands : - : "memory", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "ra" // Clobbers + : "memory", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", + "x5", "x6", "x7", "x28", "x29", "x30", "x31", "x1" // Clobbers : "volatile" // Options ); hint::unreachable_unchecked();
diff --git a/src/syscalls/platform_riscv32.rs b/src/syscalls/platform_riscv32.rs index 88ddeec..f7d1858 100644 --- a/src/syscalls/platform_riscv32.rs +++ b/src/syscalls/platform_riscv32.rs
@@ -8,8 +8,8 @@ ecall" : : - : "memory", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "ra" + : "memory", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", + "x5", "x6", "x7", "x28", "x29", "x30", "x31", "x1" : "volatile"); }