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:
1 parent
fb1b8af2d1
commit
f9a61a086f
211 files changed
+45657
-12740
No files matched your search
@@ -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",
|
||||
] }
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
};
|
||||
}
|
||||
@@ -9,10 +9,8 @@ version.workspace = true
|
||||
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",
|
||||
] }
|
||||
|
||||
@@ -1,110 +1,42 @@
|
||||
//! Declarative Kakute F7 Mini V3 board description.
|
||||
//!
|
||||
//! This module deliberately contains no MCU registers, RTIC concepts, unsafe
|
||||
//! code, interrupt names, DMA handling, or task scheduling. Those concerns
|
||||
//! belong to the STM32F7 platform crate.
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
use platform_stm32f7::kaptan_ports::{PortCatalog, PortDescriptor};
|
||||
use platform_stm32f7::{
|
||||
AccelerometerRange, DigitalLowPassFilter, F7Board, F722Hardware,
|
||||
F722ImmutableConfig as ImmutableConfig, GyroscopeRange, ImuMount, LevelFilter, Mavlink,
|
||||
Mpu6000, Mpu6000Config, Pa4, Pb0Pb1Pb4Pb5Low, Pd2ActiveLow, VerticalSensor,
|
||||
AccelerometerRange, DigitalLowPassFilter, F7Board, F722Hardware, F722ImmutableConfig,
|
||||
F722UserConfig, GyroscopeRange, ImuMount, MotorPins, Mpu6000Config, Mpu6000Spi1,
|
||||
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,
|
||||
#[config(
|
||||
id = 106,
|
||||
key = "telemetry.range_hz",
|
||||
unit = "Hz",
|
||||
range(min = 1, max = 100)
|
||||
)]
|
||||
range_hz: u8,
|
||||
#[config(
|
||||
id = 107,
|
||||
key = "telemetry.optical_flow_hz",
|
||||
unit = "Hz",
|
||||
range(min = 1, max = 100)
|
||||
)]
|
||||
optical_flow_hz: u8,
|
||||
}
|
||||
|
||||
/// Complete user-writable configuration advertised by this board.
|
||||
#[derive(Clone, kaptan_config::Config)]
|
||||
pub struct UserConfig {
|
||||
mavlink: MavlinkConfig,
|
||||
telemetry: TelemetryConfig,
|
||||
}
|
||||
|
||||
/// Holybro Kakute F7 Mini V3.
|
||||
pub struct KakuteF7MiniV3;
|
||||
|
||||
impl F7Board for KakuteF7MiniV3 {
|
||||
type UserConfig = UserConfig;
|
||||
type ImmutableConfig = ImmutableConfig;
|
||||
impl PortCatalog<5> for KakuteF7MiniV3 {
|
||||
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,
|
||||
range_hz: 20,
|
||||
optical_flow_hz: 20,
|
||||
},
|
||||
};
|
||||
const IMMUTABLE_CONFIG: ImmutableConfig = ImmutableConfig {
|
||||
impl F7Board for KakuteF7MiniV3 {
|
||||
type UserConfig = F722UserConfig<Self, 5>;
|
||||
type ImmutableConfig = F722ImmutableConfig<Mpu6000Spi1>;
|
||||
|
||||
const FACTORY_USER_CONFIG: Self::UserConfig = Self::UserConfig::FACTORY;
|
||||
const IMMUTABLE_CONFIG: Self::ImmutableConfig = F722ImmutableConfig {
|
||||
name: "Kakute F7 Mini V3",
|
||||
service_hz: 100,
|
||||
hardware: F722Hardware::new()
|
||||
.output_inhibit(Pb0Pb1Pb4Pb5Low)
|
||||
.imu(
|
||||
Mpu6000::on_spi1()
|
||||
.with_drdy(Pa4)
|
||||
.mounted(ImuMount::BodyAligned)
|
||||
.configured(Mpu6000Config {
|
||||
accelerometer: AccelerometerRange::PlusMinus4G,
|
||||
gyroscope: GyroscopeRange::PlusMinus500DegreesPerSecond,
|
||||
digital_low_pass_filter: DigitalLowPassFilter::Bandwidth42Hz,
|
||||
sample_rate_divider: 9,
|
||||
}),
|
||||
)
|
||||
.mavlink(Mavlink::on_usart1().baud(115_200))
|
||||
.vertical_sensor(VerticalSensor::mtf01_on_uart4().baud(115_200))
|
||||
.status_led(Pd2ActiveLow)
|
||||
.telemetry_only(),
|
||||
hardware: F722Hardware::new(
|
||||
Mpu6000Spi1 {
|
||||
mount: ImuMount::Yaw270,
|
||||
config: Mpu6000Config {
|
||||
accelerometer: AccelerometerRange::PlusMinus4G,
|
||||
gyroscope: GyroscopeRange::PlusMinus500DegreesPerSecond,
|
||||
digital_low_pass_filter: DigitalLowPassFilter::Bandwidth42Hz,
|
||||
sample_rate_divider: 9,
|
||||
},
|
||||
},
|
||||
SerialInventory::new(&Self::DESCRIPTORS),
|
||||
StatusLed::ActiveLowPd2,
|
||||
VerticalSensor::None,
|
||||
MotorPins::Six,
|
||||
),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user