Skip to content

[Feature] add dtgen device tree compile-time code generator#40

Open
LuisRuisinger wants to merge 3 commits intomainfrom
feature/comptime_devicetree_gen
Open

[Feature] add dtgen device tree compile-time code generator#40
LuisRuisinger wants to merge 3 commits intomainfrom
feature/comptime_devicetree_gen

Conversation

@LuisRuisinger
Copy link

Adds dtgen, a code generator for that parses device tree (.dts) files and emits a typed, queryable rust file to be used during building.

  • parses .dts files via cpp, dtc and fdt crate into a raw ir
  • emits a static rust file containing all device tree nodes and peripherals
  • provides a query api for proc-macros and during runtime

dtgen has been added to the xtasks, however further usage and integration must be discussed.
xtasks/crates/dtgen/README.md provides deeper insights in usage, ir, types.

@github-actions
Copy link

github-actions bot commented Mar 17, 2026

LCOV of commit 5f029f9 during Osiris CI #326

Total coverage: 13.55%

lcov: WARNING: lcov: WARNING: RC option 'lcov_branch_coverage' is deprecated.  Consider using 'branch_coverage. instead.  (Backward-compatible support will be removed in the future
Summary coverage rate:
  lines......: 13.6% (232 of 1712 lines)
  functions..: 16.7% (39 of 233 functions)
  branches...: no data found

Files changed coverage rate: n/a

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new dtgen xtask crate that compiles a .dts into a .dtb, parses the DTB into an IR, and generates a static Rust source file exposing topology/peripheral data plus a small query API for use via include!().

Changes:

  • Introduce dtgen library + CLI, including a DTB parser and Rust code generator.
  • Add IR types (DeviceTree, Node, PropValue) and generated query helpers (peripheral lookups, aliases).
  • Add documentation and workspace lockfile updates for the new crate/dependencies.

Reviewed changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
xtasks/crates/dtgen/src/parser.rs Runs cpp/dtc and walks the DTB via fdt into an in-memory DeviceTree.
xtasks/crates/dtgen/src/ir.rs Defines the IR and convenience query helpers like model() / stdout_compat().
xtasks/crates/dtgen/src/codegen.rs Emits Rust source for static node/peripheral arrays and query functions.
xtasks/crates/dtgen/src/lib.rs Provides the dtgen::run() entrypoint.
xtasks/crates/dtgen/src/main.rs Adds a clap-based CLI wrapper around dtgen::run().
xtasks/crates/dtgen/README.md Documents generated types and query API usage.
xtasks/crates/dtgen/Cargo.toml Defines the new crate and its dependencies.
xtasks/crates/dtgen/Cargo.lock Adds a per-crate lockfile for dtgen’s dependencies.
Cargo.lock Adds dtgen and fdt to the workspace lockfile.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +20 to +28
fn emit_header(out: &mut String) {
out.push_str(
r#"// ================================
// GENERATED BY dtgen — DO NOT EDIT
// ================================

#![allow(dead_code)]

"#,
Comment on lines +306 to +311
r#"/// Find the first enabled peripheral whose compatible list exactly matches `c`.
pub fn peripheral_by_compatible(c: &str) -> Option<&'static Peripheral> {
PERIPHERALS.iter().find(|p| p.is_compatible(c) && p.is_enabled())
}

/// Iterate all enabled peripherals whose compatible list exactly matches `c`.
Comment on lines +139 to +141
let path = path.split(':').next()?;
// match by last path component
let name = path.split('/').last()?;
[package]
name = "dtgen"
version = "0.1.0"
edition = "2021"
Comment on lines +12 to +14
let preprocessed_path = dts_path.with_extension("preprocessed.dts");
let dtb_path = dts_path.with_extension("dtb");

Comment on lines +107 to +108
.chunks(4)
.map(|b| u32::from_be_bytes(b.try_into().unwrap()))
if let Some(ph) = phandle {
tree.by_phandle.insert(ph, idx);
}
tree.by_name.insert(name, idx);
Comment on lines +182 to +188
## `chosen` submodule

```rust
// resolves /chosen stdout-path to the target Peripheral
chosen::stdout_path() // Option<&'static Peripheral>
```

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an inconsistency between intended design and actual design. Further commits will address the intended design to access chosen-node attributes through the chosen module.

LuisRuisinger and others added 2 commits March 17, 2026 17:02
Passing &dtb_path to Command::arg directly to not trigger potential panic on non-utf8 paths

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Codegen for treenodes should output decimals as node indices rather than hex which would potentially not imply indexing but rather addressing.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants