This repository contains the accompanying demo for the Safety-Critical Rust Development with Ferrocene workshop.
The following tools must be installed:
- Install criticalup
- Docker installed and usable (see OS specific instructions below)
- Optional: Rust toolchain via rustup.
See Ferrocene Setup on how to link Ferrocene with rustup. cargo install mantra --locked(This requires a modern native C compiler via the cc binary (usually clang or gcc))cargo install cargo-nextest --lockedcargo install grcov --lockedcargo install just --lockedcargo install embsinth --lockedprobe-rsfollowing the official installation section
To run docker container on macOS, you may install lima. Follow their documentation to use it as alias for docker commands:
limactl start --mount-writable template:docker
export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
# To verify if it worked, run:
docker run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpineNote: limactl start --mount-writable template:docker must only be run the first time. Afterwards, run limactl start docker.
WARN: Setting --mount-writable makes the home directory writable from the container.
This is needed to get raw LLVM coverage data during unit testing, but may pose security risks if other docker container are run.
Once Lima and Docker are installed, try building the Dockerfile of this repository as described in section QEMU Docker Container.
For Windows users, Docker should be configured to use WSL 2 as documented in the official docker documentation. Once Docker is installed, try building the Dockerfile of this repository as described in section QEMU Docker Container.
Ferrocene's Facade targets allow to run regular Rust unit tests in an emulator of the CPU architecture of the actual target.
For convenience, the Dockerfile in this repository provides the needed qemu-arm-static binary to run thumbv7em binaries.
To build the image locally, run:
docker buildx build --load -t ubuntu-qemu-arm .The workspace level .cargo/config.toml file is set up to use the Docker container as runner for the Facade target.
The default configuration works for Linux and macOS, but must be changed for Windows hosts due to filepath incompatibilities.
For Windows User: Uncomment the runner configuration for Windows and comment the one for Linux and macOS.
The Facade targets are special targets available with Ferrocene. Similar to rustup, we provide criticalup to manage Ferrocene installations.
Assuming criticalup is installed, authenticate and install Ferrocene via:
# This will ask you for an authentication token
criticalup auth set
# This will install Ferrocene as configured in 'criticalup.toml'
criticalup installThis repository has set ferrocene as default rustup channel in rust-toolchain.toml
to ensure Ferrocene is used for all Cargo commands.
To make Ferrocene available for rustup, run:
criticalup link createWith Docker and the container set up and the prerequisites installed, you should be able to run:
just rad-unit-testsThis will run all unit tests and collect code coverage data.
For manual and system testing, two NRF 52840 DK devices must be connected to your host machine.
Related Datasheets from Nordic:
The main device is referred to as RAD and is the one the main rad application is being flashed on.
For testing purpose, the second device referred to as SIM is used to simulate the environment the application is being used in.
The two boards are connected through pins P1.02 to P1.08 with P1.02 to P1.04 being RAD outputs and SIM inputs.
Mapping is done in a way that makes it easy to use two 4-pin male-to-male cables as shown in the HW-Setup.pdf schematic.
Note: Not all 8 pins are used, but using two 4-pin cables makes connecting the two boards easier.
The following lists show how the I/O pins, LEDs and buttons of the two boards are connected.
RAD:
- Outputs
- p1.01: Radiation Control
- Low: Start Radiation
- High: Stop Radiation
- p1.02: Mode Indicator
- Low: Operation
- High: Idle
- p1.03: Start-Stop Indicator
- Low: Start requested
- High: Stop requested
- p1.01: Radiation Control
- Inputs
- p1.05: Start-Stop Switch
- Low: Start
- High: Stop
- p1.06: Door Sensor
- Low: Closed
- High: Open
- p1.07: Confirmation Switch
- Low: Confirmed
- High: Unconfirmed
- p1.08: Radiation Sensor
- Low: Active
- High: Deactive
- p1.05: Start-Stop Switch
- LEDS
- 1: Mode Indicator (ON = Operation)
- 2: Door Sensor (ON = Closed)
- 3: Confirmation Switch (ON = Confirmed)
- 4: Radiation Relay (ON = Active)
SIM:
- Outputs
- p1.01: Start-Stop Switch
- Low: Start
- High: Stop
- p1.02: Door Sensor
- Low: Closed
- High: Open
- p1.03: Confirmation Switch
- Low: Confirmed
- High: Unconfirmed
- p1.04: Radiation
- Low: Active
- High: Deactive
- p1.01: Start-Stop Switch
- Inputs
- p1.05: Radiation Relay
- Low: On
- High: Off
- p1.06: RAD Mode
- Low: Operation
- High: Idle
- p1.07: Start Request Indicator
- Low: Start requested
- High: undefined
- p1.05: Radiation Relay
- LEDs
- 1: Start-Stop Switch (ON = Start)
- 2: Door Sensor (ON = Closed)
- 3: Confirmation Switch (ON = Confirmed)
- 4: Radiation State (ON = Active)
- Toggle Buttons
- 1: Start-Stop Switch
- 2: Door Sensor
- 3: Confirmation Switch
- 4: Radiation
Once both devices are connected to the host and the 4-pin cables are connected between the devices, the debug probe IDs must be updated to point to the actual attached devices. To get the serial numbers of the attached probes, look at the white sticker on the DK devices. The number at the bottom is the serial number. This can be confirmed by running:
probe-rs listThis should return a similar output to:
The following debug probes were found:
[0]: J-Link -- 1366:1051:001050286871 (J-Link)
[1]: J-Link -- 1366:1051:001050272949 (J-Link)
The output ID per probe is: <vendor ID>:<probe ID>:<serial number>
Since vendor and probe ID should be the same for all DK devices, only the serial numbers for the RAD and SIM devives must be replaced in:
rad/.cargo/config.tomlusing the number of the RADsim/.cargo/config.tomlusing the number of the SIMsystem-tests/src/lib.rschanging the two constants at the top
Follow the instructions documented in docs/reviews/phase_one/rad_hw.json5 to ensure both devices are connected successfully and I/O mapping is wired as outlined in the hardware setup.
With this working, you can now run all system tests via:
just rad-system-tests