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
@@ -1,11 +1,13 @@
|
||||
//! Non-blocking, chip-select-scoped SPI transfer contract.
|
||||
//!
|
||||
//! A selected device owns electrical chip-select behavior. A driver retains its
|
||||
//! transfer storage until a terminal completion event; implementations submit
|
||||
//! DMA or interrupt-driven work and never wait for a peripheral flag.
|
||||
//! A selected device owns electrical chip-select behavior and asynchronous
|
||||
//! transfer storage. Submission copies in; successful completion copies out.
|
||||
//! No caller borrow or caller address may survive either method call.
|
||||
|
||||
#![no_std]
|
||||
|
||||
pub mod dma;
|
||||
|
||||
/// Terminal outcome reported by a selected SPI device.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum SpiCompletion {
|
||||
@@ -17,28 +19,63 @@ pub enum SpiCompletion {
|
||||
TransferFault,
|
||||
}
|
||||
|
||||
/// Failure to accept and copy out a completed transfer. No receive bytes are
|
||||
/// changed on error.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CompletionError {
|
||||
/// No terminal event: leave the active transfer entirely untouched.
|
||||
NotPending,
|
||||
/// There is no submitted transfer to complete.
|
||||
NotActive,
|
||||
/// The destination length differs from the submitted length.
|
||||
InvalidLength,
|
||||
/// The transfer failed; no receive bytes are usable.
|
||||
TransferFault,
|
||||
/// Quiescence could not be proven. Storage and route are permanently held.
|
||||
Quarantined,
|
||||
}
|
||||
|
||||
/// Owns one chip-select-scoped, non-blocking SPI route.
|
||||
///
|
||||
/// `start_transfer` begins a complete transfer and returns without waiting for
|
||||
/// a peripheral status flag. The caller owns both buffers until the board
|
||||
/// reports a terminal `SpiCompletion`; `complete_transfer` releases the route
|
||||
/// after that terminal outcome.
|
||||
/// Moving, dropping, or forgetting the device or caller buffers during a
|
||||
/// transfer must be memory-safe. Hardware accesses only implementation-owned
|
||||
/// storage whose allocation outlives hardware activity, including cancellation.
|
||||
pub trait SpiDevice {
|
||||
/// Failure to submit a transfer.
|
||||
type StartError;
|
||||
|
||||
/// Starts one complete full-duplex transfer.
|
||||
///
|
||||
/// Implementations assert chip select before submitting and deassert it on
|
||||
/// every terminal completion or submission failure. `receive` receives one
|
||||
/// octet for each `transmit` octet; the two ranges must have equal length.
|
||||
fn start_transfer(
|
||||
&mut self,
|
||||
transmit: &[u8],
|
||||
receive: &mut [u8],
|
||||
) -> Result<(), Self::StartError>;
|
||||
/// Identifies a temporary admission rejection. No transfer was accepted.
|
||||
/// Drivers may retry the same pending operation within their deadline.
|
||||
fn is_busy(_error: &Self::StartError) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Releases transport ownership after a hardware ISR acknowledged a
|
||||
/// terminal completion. This must not poll or wait.
|
||||
fn complete_transfer(&mut self, completion: SpiCompletion);
|
||||
/// Copies `transmit` into bounded route-owned storage and starts one
|
||||
/// full-duplex transfer. Empty/oversized submissions must fail safely.
|
||||
///
|
||||
/// No pointer into `transmit` is retained. Chip select is asserted before
|
||||
/// submission; rejecting a concurrent submission must not disturb it.
|
||||
fn start_transfer(&mut self, transmit: &[u8]) -> Result<(), Self::StartError>;
|
||||
|
||||
/// On `Complete`, proves hardware quiescence before copying exactly the
|
||||
/// submitted number of bytes to an equally sized `receive` and releasing
|
||||
/// chip select. An interrupt notification alone is not proof of quiescence.
|
||||
///
|
||||
/// `NotPending` returns that error without aborting or changing anything.
|
||||
/// Faults cancel the transfer without copying out. Any bounded hardware
|
||||
/// shutdown that cannot prove quiescence must quarantine the route and its
|
||||
/// storage permanently, preventing reuse. No destination pointer is retained.
|
||||
/// Passing `TransferFault` also requests cancellation without an IRQ. It must
|
||||
/// perform the same bounded shutdown and return `TransferFault` only after
|
||||
/// quiescence, or `Quarantined` if that cannot be proved. No bytes are copied.
|
||||
///
|
||||
/// Providers must validate current hardware progress, not trust a notification
|
||||
/// from a previous transfer. Before reuse, drain old hardware flags/data. A
|
||||
/// delayed notification may fault a new incomplete transfer but must never
|
||||
/// publish old receive storage as a new result.
|
||||
fn complete_transfer(
|
||||
&mut self,
|
||||
completion: SpiCompletion,
|
||||
receive: &mut [u8],
|
||||
) -> Result<(), CompletionError>;
|
||||
}
|
||||
Reference in new issue
Block a user