feat(firmware): validate configuration and migrate sensor-driven flight APIs

Validate configuration through its owning schemas and keep board
declarations separate from shared F722 resource ownership. Bound USB
transitions, isolate transport failures and retain restart-only activation.

Migrate navigation and flight consumers with the sensor and schema
contracts. Require explicit installation data and synchronous output
authority; board motor outputs remain inhibited.

Validation: assembled-prefix host tests, strict Clippy, platform/USB tests
and both ARM release builds. Final-source coverage and scoped Miri/Kani
evidence are retained separately from hardware qualification.
This commit is contained in:
Onur Özkan committed 2026-11-07 18:12:11 +03:00
1 parent fb1b8af2d1
commit f9a61a086f
211 files changed
+45657 -12740

No files matched your search

+1 -3
View File
@@ -10,10 +10,8 @@ build = "build.rs"
workspace = true
[dependencies]
kaptan-config = { path = "../../libs/kaptan-config" }
platform-stm32f7 = { path = "../../platforms/stm32f7" }
# RTIC's attribute expansion emits absolute `rtic` support paths in the final
# board crate; the task graph and all RTIC source remain platform-owned.
# RTIC's macro emits absolute `rtic` paths in the board crate.
rtic = { version = "2.3", default-features = false, features = [
"thumbv7-backend",
] }
+24 -68
View File
@@ -1,79 +1,35 @@
//! Declarative support for the GEPRC TAKER F722 BLS 60A V2 stack.
//! Declarative support for the GEPRC GEP-F722-HD V2.
#![forbid(unsafe_code)]
use platform_stm32f7::kaptan_ports::{PortCatalog, PortDescriptor};
use platform_stm32f7::{
F7Board, F722Hardware, F722ImmutableConfig as ImmutableConfig, Icm42688, ImuMount, LevelFilter,
Mavlink, Pa13ActiveHigh, Pb0Pb1Pb4Pb5Low, Pc3, VerticalSensor,
F7Board, F722Hardware, F722ImmutableConfig, F722UserConfig, Icm42688Spi3, ImuMount, MotorPins,
SerialInventory, StatusLed, UART1, UART2, UART3, UART4, UART6, VerticalSensor,
};
/// User-writable MAVLink endpoint policy.
#[derive(Clone, kaptan_config::Config)]
struct MavlinkConfig {
#[config(id = 101, key = "mavlink.system_id", unit = "id", range(min = 1))]
system_id: u8,
#[config(id = 102, key = "mavlink.component_id", unit = "id", range(min = 1))]
component_id: u8,
#[config(
enum,
id = 105,
key = "mavlink.logging.level_filter",
unit = "log_level"
)]
log_level_filter: LevelFilter,
}
/// User-writable telemetry publication policy.
#[derive(Clone, kaptan_config::Config)]
struct TelemetryConfig {
#[config(
id = 103,
key = "telemetry.imu_hz",
unit = "Hz",
range(min = 1, max = 100)
)]
imu_hz: u8,
#[config(
id = 104,
key = "telemetry.heartbeat_hz",
unit = "Hz",
range(min = 1, max = 10)
)]
heartbeat_hz: u8,
}
/// Complete user-writable configuration advertised by this board.
#[derive(Clone, kaptan_config::Config)]
pub struct UserConfig {
mavlink: MavlinkConfig,
telemetry: TelemetryConfig,
}
/// ICM-42688-P-based GEP-F722-HD V2 paired with the 60 A stack.
pub struct GeprcF722V2;
impl F7Board for GeprcF722V2 {
type UserConfig = UserConfig;
type ImmutableConfig = ImmutableConfig;
impl PortCatalog<5> for GeprcF722V2 {
const DESCRIPTORS: [PortDescriptor; 5] = [UART1, UART2, UART3, UART4, UART6];
}
const FACTORY_USER_CONFIG: UserConfig = UserConfig {
mavlink: MavlinkConfig {
system_id: 1,
component_id: 1,
log_level_filter: LevelFilter::Info,
},
telemetry: TelemetryConfig {
imu_hz: 20,
heartbeat_hz: 2,
},
};
const IMMUTABLE_CONFIG: ImmutableConfig = ImmutableConfig {
impl F7Board for GeprcF722V2 {
type UserConfig = F722UserConfig<Self, 5>;
type ImmutableConfig = F722ImmutableConfig<Icm42688Spi3>;
const FACTORY_USER_CONFIG: Self::UserConfig = Self::UserConfig::FACTORY;
const IMMUTABLE_CONFIG: Self::ImmutableConfig = F722ImmutableConfig {
name: "GEPRC TAKER F722 V2 (ICM-42688-P)",
service_hz: 100,
hardware: F722Hardware::new()
.output_inhibit(Pb0Pb1Pb4Pb5Low)
.imu(Icm42688::on_spi3().with_drdy(Pc3).mounted(ImuMount::Yaw180))
.mavlink(Mavlink::on_usart2().baud(115_200))
.vertical_sensor(VerticalSensor::none())
.status_led(Pa13ActiveHigh)
.telemetry_only(),
hardware: F722Hardware::new(
Icm42688Spi3 {
mount: ImuMount::Yaw180,
},
SerialInventory::new(&Self::DESCRIPTORS),
StatusLed::ActiveHighPa13,
VerticalSensor::None,
MotorPins::Four,
),
};
}