120 lines
3.7 KiB
Rust
120 lines
3.7 KiB
Rust
use std::{fs, path::PathBuf};
|
|
|
|
fn platform_source(relative: &str) -> String {
|
|
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
fs::read_to_string(root.join(relative)).expect("platform source must exist")
|
|
}
|
|
|
|
#[test]
|
|
fn former_motor_pins_are_inhibited_before_all_other_initialization() {
|
|
let module = platform_source("src/f722/mod.rs");
|
|
let interlock = module
|
|
.find("motor_inhibit::inhibit_motor_pins")
|
|
.expect("F722 initialization must claim the former motor pins first");
|
|
let validation = module
|
|
.find("config.validate()")
|
|
.expect("F722 initialization must validate its board configuration");
|
|
let board_initialization = module
|
|
.find("board::initialize")
|
|
.expect("F722 initialization must subsequently claim telemetry I/O");
|
|
|
|
assert!(interlock < validation);
|
|
assert!(validation < board_initialization);
|
|
|
|
let interlock = platform_source("src/f722/motor_inhibit.rs");
|
|
let reset = interlock
|
|
.find("port.bsrr()")
|
|
.expect("interlock must reset the former motor-pin output latches");
|
|
let output_mode = interlock
|
|
.find("port.moder()")
|
|
.expect("interlock must configure the former motor pins as GPIO outputs");
|
|
assert!(
|
|
reset < output_mode,
|
|
"output latches must be low before GPIO output mode is selected"
|
|
);
|
|
for pin in ["br0", "br1", "br4", "br5"] {
|
|
assert!(interlock.contains(pin), "interlock must reset PB pin {pin}");
|
|
}
|
|
for pin in ["moder0", "moder1", "moder4", "moder5"] {
|
|
assert!(
|
|
interlock.contains(pin),
|
|
"interlock must configure PB pin {pin}"
|
|
);
|
|
}
|
|
for pin in ["ot0", "ot1", "ot4", "ot5"] {
|
|
assert!(
|
|
interlock.contains(pin),
|
|
"interlock must set PB pin {pin} push-pull"
|
|
);
|
|
}
|
|
for pin in ["ospeedr0", "ospeedr1", "ospeedr4", "ospeedr5"] {
|
|
assert!(
|
|
interlock.contains(pin),
|
|
"interlock must set PB pin {pin} low speed"
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn telemetry_platform_has_no_physical_actuator_peripheral_path() {
|
|
let sources = [
|
|
platform_source("src/lib.rs"),
|
|
platform_source("src/f722/mod.rs"),
|
|
platform_source("src/f722/board.rs"),
|
|
platform_source("src/f722/firmware.rs"),
|
|
platform_source("src/f722/interrupts.rs"),
|
|
]
|
|
.join("\n");
|
|
|
|
for forbidden in [
|
|
"mod actuator",
|
|
"MotorOutput",
|
|
"MotorRoute",
|
|
"MotorOutputs",
|
|
"TIM3",
|
|
"TIM5",
|
|
"Dshot",
|
|
"Pwm",
|
|
"device.TIM3",
|
|
"device.TIM5",
|
|
] {
|
|
assert!(
|
|
!sources.contains(forbidden),
|
|
"telemetry platform must not expose actuator path {forbidden}"
|
|
);
|
|
}
|
|
|
|
let manifest = platform_source("Cargo.toml");
|
|
assert!(
|
|
!manifest.contains("kaptan-actuator"),
|
|
"telemetry platform must not link the physical actuator crate"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn telemetry_has_no_inbound_command_authority() {
|
|
let board = platform_source("src/f722/board.rs");
|
|
let firmware = platform_source("src/f722/firmware.rs");
|
|
|
|
assert!(
|
|
!board.contains("MavlinkReceiver"),
|
|
"telemetry must not retain an inbound MAVLink dispatch path"
|
|
);
|
|
assert!(
|
|
!board.contains("ArmRequest"),
|
|
"telemetry must not decode arm commands"
|
|
);
|
|
assert!(
|
|
!board.contains("MAV_RESULT_ACCEPTED"),
|
|
"telemetry must not accept an arm command"
|
|
);
|
|
assert!(
|
|
!firmware.contains("shared = [mavlink, motors]"),
|
|
"the MAVLink worker must not share a motor resource"
|
|
);
|
|
assert!(
|
|
!firmware.contains("MAVLINK_EVENT_RECEIVED"),
|
|
"telemetry must not schedule a worker from an inbound command"
|
|
);
|
|
}
|