Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Device Tree Support #15

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open

Device Tree Support #15

wants to merge 25 commits into from

Conversation

d3zd3z
Copy link
Collaborator

@d3zd3z d3zd3z commented Oct 16, 2024

Built on top of #5, this adds support for the devicetree.

This is definitely a WIP (hence draft), but shows the basics of generating the devicetree.

@d3zd3z d3zd3z changed the base branch from main to kobj October 18, 2024 22:22
@d3zd3z d3zd3z mentioned this pull request Oct 18, 2024
@d3zd3z d3zd3z force-pushed the dt branch 2 times, most recently from d4754e1 to c15b549 Compare October 24, 2024 17:07
@d3zd3z d3zd3z force-pushed the kobj branch 4 times, most recently from aa1e082 to d78650f Compare October 25, 2024 16:46
@d3zd3z d3zd3z changed the base branch from kobj to main October 25, 2024 17:24
@d3zd3z d3zd3z marked this pull request as ready for review October 25, 2024 17:24
@d3zd3z d3zd3z force-pushed the dt branch 2 times, most recently from 9fb4c7b to 9f25f08 Compare October 28, 2024 16:12
@d3zd3z d3zd3z force-pushed the dt branch 2 times, most recently from e640970 to 7e8a847 Compare November 21, 2024 20:27
@d3zd3z d3zd3z changed the base branch from main to logging November 21, 2024 20:27
Base automatically changed from logging to main November 23, 2024 14:46
@d3zd3z d3zd3z force-pushed the dt branch 2 times, most recently from abe1608 to 96f0740 Compare December 11, 2024 23:21
samples/blinky/Cargo.toml Outdated Show resolved Hide resolved
samples/blinky/build.rs Show resolved Hide resolved
samples/blinky/sample.yaml Show resolved Hide resolved
zephyr-build/src/lib.rs Outdated Show resolved Hide resolved
zephyr/src/device.rs Outdated Show resolved Hide resolved
zephyr-build/src/devicetree.rs Show resolved Hide resolved
zephyr-build/src/devicetree.rs Outdated Show resolved Hide resolved
zephyr-build/src/devicetree.rs Show resolved Hide resolved
zephyr-build/src/devicetree.rs Outdated Show resolved Hide resolved
zephyr-build/src/devicetree.rs Outdated Show resolved Hide resolved
Comment on lines +59 to +60
loop {
}
Copy link

Choose a reason for hiding this comment

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

Suggested change
loop {
}
loop {}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This should get fixed when I do a rustfmt cleanup.

samples/blinky/src/main.c Outdated Show resolved Hide resolved
/// The root of the tree.
root: Rc<Node>,
/// All of the labels.
labels: BTreeMap<String, Rc<Node>>,
Copy link

Choose a reason for hiding this comment

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

Any reason why this is not a HashMap? Do we want it to be sorted? https://doc.rust-lang.org/std/collections/index.html#use-a-btreemap-when

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Probably habit, honestly. There is some benefit to having the generated files always be the same, though.

Copy link

Choose a reason for hiding this comment

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

That's a good reason. Maybe you can add a comment to mention that BTreeMap keeps its values sorted, so the output in the generated files is always deterministic.

zephyr-build/src/devicetree.rs Outdated Show resolved Hide resolved
Copy link

Choose a reason for hiding this comment

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

The file contains an Apache-2.0 SPDX header but the code is Apache-2.0 OR MIT according to the cargo manifest

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch. I think what I'm going for is to make the Rust contributions Apache-2.0 OR MIT, and the Zephyr contributions just Apache-2.0. When I first wrote it, this was in the main zephyr tree, so it was less clear.

@d3zd3z
Copy link
Collaborator Author

d3zd3z commented Dec 13, 2024

From another comment, it looks like getting rustfmt setup, and clippy as well. Given the size of this change, I'd suggest making these something I do after this change merges, otherwise I'll be spending a bunch of time just resolving merge conflicts when I rebase this change.

This code parses the DTS file generated by the Zephyr build, along with a
few entries from the generated header file, to build a representation of
the device tree.  There is a notion of "augments" that add various
methods.  This is currently just hard-coded.

Signed-off-by: David Brown <[email protected]>
Blinky is a rust port of the samples/blinky application from the main
zephyr repo.  It performs the same function, but using the DT and GPIO
abstractions provided in the zephyr::sys module.

Signed-off-by: David Brown <[email protected]>
Create two modules with wrappers for Zephyr gpio and flash devices.
These have no methods, but allow the DT generated code to compile, with
`get_instance` methods that return these values.

Signed-off-by: David Brown <[email protected]>
The is_ready method on both `Gpio` and `GpioPin` will ultimately call
the underlying `device_is_ready` entry.

Signed-off-by: David Brown <[email protected]>
Create wrappers for config and pin toggle on the gpios.  This is enough
to allow the blink app to work.

Signed-off-by: David Brown <[email protected]>
Move the module declaration for the device tree up into `lib.rs` to
allow insertion of allow directives to eliminate documentation warnings
on the generated devicetree.

Signed-off-by: David Brown <[email protected]>
Instead of hardcoding all of the augments in the code, put these
augments into a data structure.  Load the actual rules from a yaml file
(with a future ability to extend this with per-app or per-module defined
augments.

Convert all of the existing hardcoded augment rules into the initial
augment file.
Add constructors to the individual device types.  These are unsafe, and
are all referenced from the generated devicetree code.
Move all of the device implementations into a `zephyr::device` module.

In this module, add a `Unique` type that supports the constructors on
the device requiring a unique instance.

The device tree augmentation code adds a declaration for these
uniqueness markers for each instance, passing it into the constructor.

Signed-off-by: David Brown <[email protected]>
Gpios in Zephyr are inherently unsafe.  There is a shared controller
that is not just used by the pins defined here, but extensively across
various drivers.

As such, make all of the gpio pin operations themselves unsafe.

We can help, a little bit, to at least enforce uniqueness with the
Rust drivers that use gpios by requiring them to take a mutable instance
of `GpioToken`, which has a singleton getter.

Signed-off-by: David Brown <[email protected]>
The hard-coded augments in augment.rs are no long used, so remove them
all, and move the config version into this file to avoid needing a
separate module, just for the trait.

Signed-off-by: David Brown <[email protected]>
Generate a full list of nodes that are present in the given device tree,
and provide a tool that build.rs in the app can use to make these
active.  This will allow conditionals like:

    #[cfg(dt = "aliases::led")]

to be used, which will make it possible to handle nodes being present or
not in the DTS.

See a subsequent patch to the blinky sample for an example of usage.

Signed-off-by: David Brown <[email protected]>
Show how an application can be conditional based on the presence of a
node in the devicetree.

Signed-off-by: David Brown <[email protected]>
Move this code out of the device.rs file, and into separate files for
each module.

Signed-off-by: David Brown <[email protected]>
The gpio device tree entries for the mps2 are defined with a
`#gpio-cells` value of 1, despite these values not being interpreted by
the driver, but by the devicetree code.  I'm not sure if these actually
work with any of the demos, as it is unclear what the macros would do
with this.  It doesn't give us a value to use for dt_flags.

If someone wants to put in some effort to fix this, feel free.  But I
don't think the problem is on the Rust side.

Signed-off-by: David Brown <[email protected]>
Prevents a warning on boards where there are no gpios or flash
controllers are defined.

Signed-off-by: David Brown <[email protected]>
This allows a build on the nrf51, preventing an error when the
partitions are detected, but the controller wasn't.

Signed-off-by: David Brown <[email protected]>
This fixes a weird issue with bindgen missing the `__device_dts_ord_nn`
declarations in some circumstances.  It is unclear when this was
occuring, and hopefully it doesn't return at some point.

Signed-off-by: David Brown <[email protected]>
Instead of trying to hand off data through a file between the build of
different crates, which was causing build failures in applications that
need to use cfgs based on the presence of DT nodes, instead, just parse
the DT again, and recalculate the node tree from it.

This should fix build issues with the all nodes txt file missing.

Signed-off-by: David Brown <[email protected]>
Several things have become unsafe, so use those in unsafe blocks.
The GPIO driver now has a token that must be passed to each action, to
enforce single threadded use.

Signed-off-by: David Brown <[email protected]>
Add a `#[allow(dead_code)]` annotation to `Gpio::new`, as not all
devices necessarily will have a Gpio device (or it could be disable).

Signed-off-by: David Brown <[email protected]>
Apply some clarifications and minor code changes based on github review
comments.

Signed-off-by: David Brown <[email protected]>
Change the AtomicUsize to an AtomicBool to clarify the use.  The flag is
still stored inverted, so false is the correct initializer, and we will
still initialize from zero-initted memory.

Signed-off-by: David Brown <[email protected]>
Apply various minor fixes.  None of these should affect the code
execution itself.

Signed-off-by: David Brown <[email protected]>
With the doc generation basically duplicated, the added entries to build
the DT are missing, causing doc generation to fail. Add those to the doc
generation rule as well.

Signed-off-by: David Brown <[email protected]>
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.

3 participants