-
Notifications
You must be signed in to change notification settings - Fork 66
pr146a
Author: d3zd3z (David Brown) | Base: main | Size: 7 files, +184/−6 lines CI: passing ✓ (build + docs) Review-time: 2026-04-08
This PR makes the full devicetree visible to Rust application code at runtime by generating pub static RAW_<PROP> constants for every property on every DT node, using a new Value/Word enum representation. Within that representation, GPIO phandles are detected at build time (via gpio-controller and #gpio-cells) and emitted as a typed Word::Gpio variant instead of a bare phandle reference. To make the generated data usable, several internal types (NoStatic, GpioStatic) are widened from pub(crate) to pub, and a new unsafe fn raw_new() constructor is added on GpioPin. A separate bug fix prevents compile errors when a Parent augment references a disabled ancestor node.
| Area | Files | Purpose |
|---|---|---|
| Config | dt-rust.yaml |
New raw_properties augment rule (empty rules = all nodes) |
| Build/codegen | zephyr-build/src/devicetree.rs |
Value::to_tokens() — core serializer with GPIO detection logic |
| Build/codegen | zephyr-build/src/devicetree/augment.rs |
RawProperties action + Parent disabled-ancestor fix |
| Runtime types | zephyr/src/lib.rs |
Value and Word enums in devicetree module |
| Runtime API | zephyr/src/device.rs |
NoStatic visibility: pub(crate) → pub
|
| Runtime API | zephyr/src/device/gpio.rs |
GpioStatic visibility × 2, Debug for GpioPin, raw_new()
|
| C interop | zephyr-sys/wrapper.h |
GPIO_OUTPUT_INACTIVE constant |
Notable: The Parent disabled-ancestor fix is a separate bug fix bundled into a feature PR. The Debug impl on GpioPin is also orthogonal. Both would benefit from separate commits for bisectability.
-
to_tokens()GPIO iterator logic (zephyr-build/src/devicetree.rs): The lookahead-then-advance pattern (clone iterator, peek#gpio-cellswords, then advance real iterator) is the most complex new code. The logic is correct on inspection — the two loops stay in sync because the slice iterator length is known — but it is fragile and has no automated test coverage. Silent fallback paths (unresolved phandle, missing#gpio-cells, non-number trailing words) mean bugs would produce subtly wrong output rather than errors. -
unsafe fn raw_new()(zephyr/src/device/gpio.rs:321): New public unsafe constructor that bypasses theUniquesingle-instance guard. Missing a# Safetydoc section documenting preconditions. Thepin as gpio_pin_tcast silently truncatesu32→u8; ifpin >= 32the asyncGpioStaticpath would index out-of-bounds on thewakersarray. -
Parent ancestor walk (
zephyr-build/src/devicetree/augment.rs): If the walk overshoots the root (level > tree depth),ancestorbecomesNone, the status check is skipped, and the generated code will reference a non-existentsuper::path — producing a confusing compile error. A descriptivepanic!would be friendlier. -
RawPropertiesapplies to every node (dt-rust.yaml):rules: []means every DT node getsRAW_*statics. This will increase generated file size and compile time. Dead-code elimination should prevent binary bloat, but the compile-time cost deserves consideration. -
Visibility expansion:
NoStatic,GpioStatic, andget_static_raw()are now part of the public API surface. Combined withraw_new(), this creates a complete external path to constructGpioPinwithout theUniqueguard.
-
[concern]
raw_new()needs a# Safetysection: preconditions should document (a)devicemust be valid non-null initialized Zephyr device, (b)pin < 32for async builds, (c) caller must manage concurrent access. Standard practice forunsafe fn. -
[concern]
raw_new()is dead code — no caller exists in the tree. Its intended consumer (code that readsRAW_*properties and constructsGpioPin) isn't in this PR. Shipping an untested, undocumentedpub unsafe fnwithout a caller is a latent risk. -
[question] Should the GPIO detection logic live inside the general
Value::to_tokens(), or in a GPIO-specific augment action? Embedding peripheral-specific logic in the general value serializer couples layers that could be independent. -
[question] The build-time
Valueenum (inzephyr-build) and the runtimeValueenum (inzephyr/src/lib.rs) share a name but are different types. Will this cause confusion in docs or maintenance? -
[nit]
GPIO_OUTPUT_INACTIVEinwrapper.his not mentioned in the PR description. -
[nit] The
Debugimpl forGpioPinis orthogonal to the feature and could be a separate commit. -
[question] The manual test plan says "Build hello_world and verify DT property access" but
hello_world/src/lib.rsdoes not reference anyRAW_*constant. What actually validates that the generated data is correct? -
[concern] No automated test coverage for any of the new code. The
to_tokens()GPIO lookahead is precisely the kind of host-side logic that benefits from unit tests with synthetic DTS data, sincezephyr-buildruns on the host with no hardware dependency.
This is a well-structured foundational PR that opens up general-purpose DT property access for Rust applications — a meaningful capability gap being filled. The core logic (GPIO detection, parent walk) is correct on close inspection, and the generated-static-data approach is sound. The main concerns are operational: the unsafe raw_new() constructor lacks safety documentation and has a latent pin-bounds issue, the GPIO detection logic is complex enough to warrant unit tests, and the PR bundles an unrelated bug fix (disabled ancestors) that should ideally be a separate commit. None of these are blockers, but the safety docs and the ancestor-walk edge case are worth addressing before merge.