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
@@ -38,7 +38,7 @@ fn expand_scalars(
|
||||
checks: field_checks,
|
||||
} = expand_field(&crate_path, field)?;
|
||||
descriptors.push(descriptor);
|
||||
checks.extend(field_checks);
|
||||
checks.extend(field_checks.iter().cloned());
|
||||
let id = field.id.expect("scalar configuration fields have IDs");
|
||||
let ty = &field.ty;
|
||||
let field_ident = &field.ident;
|
||||
@@ -90,7 +90,11 @@ fn expand_scalars(
|
||||
};
|
||||
let previous = self.#field_ident;
|
||||
self.#field_ident = next;
|
||||
if let Err(violation) = self.__validate_local_configuration() {
|
||||
let validation = (|| -> Result<(), #crate_path::ConfigViolation> {
|
||||
#(#field_checks)*
|
||||
Ok(())
|
||||
})();
|
||||
if let Err(violation) = validation {
|
||||
self.#field_ident = previous;
|
||||
return Err(#crate_path::FieldWriteError::Violation(violation));
|
||||
}
|
||||
@@ -272,8 +276,35 @@ fn expand_field(crate_path: &syn::Path, field: &crate::parse::FieldModel) -> Res
|
||||
Check::Maximum(value) => Some(value),
|
||||
_ => None,
|
||||
});
|
||||
let finite = field
|
||||
.checks
|
||||
.iter()
|
||||
.any(|check| matches!(check, Check::Finite));
|
||||
let nonzero = field
|
||||
.checks
|
||||
.iter()
|
||||
.any(|check| matches!(check, Check::Nonzero));
|
||||
let float = matches!(&field.ty, syn::Type::Path(path)
|
||||
if path.path.is_ident("f32") || path.path.is_ident("f64"));
|
||||
if float && !finite && (minimum.is_some() || maximum.is_some()) {
|
||||
let field_ident = &field.ident;
|
||||
checks.push(quote! {
|
||||
if self.#field_ident.is_nan() {
|
||||
return Err(#crate_path::ConfigViolation::field(
|
||||
#crate_path::FieldId::new(#id),
|
||||
#crate_path::ValidationRule::Unordered,
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
for check in &field.checks {
|
||||
checks.push(expand_check(crate_path, &field.ident, id, check.clone()));
|
||||
checks.push(expand_check(
|
||||
crate_path,
|
||||
&field.ident,
|
||||
id,
|
||||
check.clone(),
|
||||
float,
|
||||
));
|
||||
}
|
||||
let key = field.display_key.as_ref().expect("id fields have a key");
|
||||
let unit = field.unit.as_ref().expect("id fields have a unit");
|
||||
@@ -302,6 +333,8 @@ fn expand_field(crate_path: &syn::Path, field: &crate::parse::FieldModel) -> Res
|
||||
maximum: #maximum,
|
||||
enum_options: #enum_options,
|
||||
unit: #unit,
|
||||
finite: #finite,
|
||||
nonzero: #nonzero,
|
||||
}
|
||||
},
|
||||
checks,
|
||||
@@ -344,7 +377,18 @@ fn config_value_constructor_tokens(crate_path: &syn::Path, ty: &syn::Type) -> Re
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn expand_check(crate_path: &syn::Path, field: &syn::Ident, id: u16, check: Check) -> TokenStream {
|
||||
fn expand_check(
|
||||
crate_path: &syn::Path,
|
||||
field: &syn::Ident,
|
||||
id: u16,
|
||||
check: Check,
|
||||
float: bool,
|
||||
) -> TokenStream {
|
||||
let zero = if float {
|
||||
quote! { 0.0 }
|
||||
} else {
|
||||
quote! { 0 }
|
||||
};
|
||||
match check {
|
||||
Check::Finite => quote! {
|
||||
if !self.#field.is_finite() {
|
||||
@@ -355,7 +399,7 @@ fn expand_check(crate_path: &syn::Path, field: &syn::Ident, id: u16, check: Chec
|
||||
}
|
||||
},
|
||||
Check::Nonzero => quote! {
|
||||
if self.#field == 0 {
|
||||
if self.#field == #zero {
|
||||
return Err(#crate_path::ConfigViolation::field(
|
||||
#crate_path::FieldId::new(#id),
|
||||
#crate_path::ValidationRule::Zero,
|
||||
|
||||
Reference in new issue
Block a user