Previously, dtlib would fail to parse the following:
/delete-node/ &{/};
This is accepted by dtc, so dtlib should be aligned.
The expected behavior is that the contents of the "deleted" root node
are emptied, but the node itself remains in the tree. This means that
it's possible to put that statement at the end of a DTS file and still
get a valid output. A small test case for this scenario is included.
Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
Make sure filters set by property-allowlist and property-blocklist
in an including binding are recursively applied to included bindings.
Signed-off-by: Christophe Dufaza <chris@openmarl.org>
Make sure the property specs answered by the Binding.prop2specs API
do not all claim (PropertySpec.path) they were last modified
by the top-level binding.
Signed-off-by: Christophe Dufaza <chris@openmarl.org>
The current EDT graph logic only use properties directly under a
specific node to add dependencies. For nodes properties in
child-bindings, this means that the child phandles are only linked by
the child node itself, which does have an ordinal but no corresponding
"sturct device" in the code, causing those dependencies to be silently
ignored by gen_handles.py.
Fix that by adding the recursive logic to visit child bindings when
present, which causes all child node property handles to be linked to
the parent node.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
Converting this to a dataclass will make it easier to type annotate.
Adding type annotations is incremental progress towards type checking
the entire module.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Converting this to a dataclass will make it easier to type annotate.
Adding type annotations is incremental progress towards type checking
the entire module.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Converting this to a dataclass will make it easier to type annotate.
Adding type annotations is incremental progress towards type checking
the entire module.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Converting this to a dataclass will make it easier to type annotate.
Adding type annotations is incremental progress towards type checking
the entire module.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Converting this to a dataclass will make it easier to type annotate.
Adding type annotations is incremental progress towards type checking
the entire module.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Just like we did for dtlib in 15e3e317f7
("dtlib: implement copy.deepcopy() for DT"), except this time it's for
EDT. This also can do no harm and will be useful for implementing
system devicetree support.
No functional changes expected under the assumption that no users are
relying on us having stashed the exact bindings_dirs list passed to
the constructor. This patch switches to making a defensive copy, which
is safer and makes implementing this a little cleaner.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This helper lets you place a node (really the entire subtree rooted at
that node) elsewhere in the devicetree. This will be useful when
adding system devicetree support, when we'll want to be able to, for
example, move the CPU cluster node selected by the current execution
domain to /cpus.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Introduce a context manager that will save some typing
when dealing with expected exceptions.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Add test coverage for the child-binding include feature. It includes
verification of included properties as well as usage of allow/blocklist.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The standard library copy module allows you to implement shallow and
deep copies of objects. See its documentation for more details on
these terms.
Implementing copy.deepcopy() support for DT objects will allow us to
"clone" devicetree objects in other classes. This in turn will enable
new features, such as native system devicetree support, within the
python-devicetree.
It is also a pure feature extension which can't harm anything and is
therefore safe to merge now, even if system devicetree is never
adopted in Zephyr.
Note that we are making use of the move from OrderedDict to regular
dict to make this implementation more convenient.
See https://github.com/devicetree-org/lopper/ for more information on
system devicetree. We want to add system devicetree support to dtlib
because it seems to be a useful way to model modern, heterogeneous
SoCs than traditional devicetree, which can really only model a single
CPU "cluster" within such an SoC.
In order to create 'regular' devicetrees from a system devicetree, we
will want a programming interface that does the following:
1. parse the system devicetree
2. receive the desired transformations on it
3. perform the desired transformations to make
a 'regular' devicetree
Step 3 can be done as a destructive modification on an object-oriented
representation of a system devicetree, and that's the approach we will
take in python-devicetree. It will therefore be convenient to have an
efficient deepcopy implementation to be able to preserve the original
system devicetree and the derived regular devicetree in memory in the
same python process.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Regular dicts are insertion-ordered since CPython 3.6 and Python 3.7.
Zephyr now requires Python 3.8, so it should be OK to replace
OrderedDict with regular dict now. This results in less typing and
more readable object representations.
A nitpicker could argue that this is a functional change, since if a
user is doing 'assert isinstance(node.props, OrderedDict)', that will
fail now, but:
1. nobody is doing something like that in the zephyr tree
2. that would be a silly thing to do
3. we don't currently make any API stability guarantees
for this module right now anyway
so it should be fine.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Attempts to define two nodes with the same name within a single set of
curly brackets should fail.
For example, this is invalid DTS according to dtc:
/ { foo {}; foo {}; };
By contrast, this is valid since the node named 'foo' appears twice in
two different sets of curly brackets:
/ { foo {}; };
/ { foo {}; };
Zephyr's dtlib currently does not error out on the invalid condition.
Now that Zephyr itself has been updated to not include such nodes (to
the best of my ability), we can fix this divergence from current dtc
behavior and add a regression test in dtlib.
Fixes: #49590
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
For a single bus that supports multiple protocols, e.g. I3C and I2C,
the single value "bus:" setting is no longer sufficient, as a I3C bus
cannot be matched to a device having "on-bus: I2C". This commit
extends the "bus:" setting so that it can accept a list of values.
This change allows corresponding devicetree macros to be generated
so that DT_ON_BUS() can work properly in this scenario.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Allow for having array types (array, uint8-array, string-array) be const.
This would allow for something like:
properties:
reg-names:
const: ["foo", "bar"]
To be supported.
Renamed function _check_prop_type_and_default to _check_prop_by_type
as part of this change and Moved the check for 'const' types into
_check_prop_by_type as its similar to the prop_type check and it was
easier to implement in _check_prop_by_type as we already extract
prop_type from the option in that function.
Signed-off-by: Kumar Gala <galak@kernel.org>
It can be useful to know what the index of a particular child is in
the list of nodes. Add a a helper for computing that and some test
cases.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This adds some tests in test_edtlib.py and test.dts to check all
common possible combination of ranges property usage and handling
by edtlib.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Currently all the *-names and *-cells properties are derived from the
name of the base <name>s property. This is a limitation because:
- It forces the base property name to be plural ending in -s
- It doesn't allow the english exception of plural words ending in -es
With this patch we add one additional property 'specifier-space' that
can be used to explicitly specify the base property name.
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
Suggested-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Node names are subject to the rules in table 2.1 of the devicetree
specification v0.3, while properties are subject to rules in table
2.2. These rules mean that some property names are invalid node names.
However, the same regular expression is being used to validate the
names of nodes and properties in dtlib. This leads to invalid node
names being allowed to pass. Fix this issue by moving the node name
handling code to the Node constructor and checking against the
characters in table 2.1.
The test cases claim that the existing behavior matches dtc. I can't
reproduce that. I get errors when I use invalid characters (like "?")
in a node name. For example:
foo.dts:3.8-11: ERROR (node_name_chars): /node?: Bad character '?' in
node name
Try to make the dtlib error message reminiscent of that.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
As a first step towards being more forgiving on invalid inputs, allow
string-valued aliases properties that do not point to valid nodes when
the user requests permissiveness.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Error out on compatible properties with invalid values. The regular
expression used to validate them matches what's used in dt-schema.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
The documentation says DT.__init__ takes any iterable for the
include_path, but this leads to bad results when you pass it something
other than a 'real' sequence (list/tuple/etc), like a generator:
>>> dt = DT('/tmp/foo.dts', (x for x in ['a', 'b', 'c']))
>>> repr(dt)
"DT(filename='/tmp/foo.dts', include_path=<generator object ...>)"
Make a copy in list form just to avoid things like this.
Add a test for this and relax the regular expression in the existing
test case related to this.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Instead of hard-coding constants, use an IntEnum.
These is still a subclass of 'int', but is both easier to import and
easier to read during debugging.
For example, compare:
>>> Type.BYTES
<Type.BYTES: 1>
with:
>>> TYPE_BYTES
1
However, 'Type.BYTES == 1' is still True, and the enum values
otherwise behave like you would expect.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Add the ability to filter which properties get imported when we do an
include. We add a new YAML form for this:
include:
- name: other.yaml
property-blocklist:
- prop-to-block
or
include:
- name: other.yaml
property-allowlist:
- prop-to-allow
These lists can intermix simple file names with maps, like:
include:
- foo.yaml
- name: bar.yaml
property-allowlist:
- prop-to-allow
And you can filter from child bindings like this:
include:
- name: bar.yaml
child-binding:
property-allowlist:
- child-prop-to-allow
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
We are now in the process of extracting edtlib and dtlib into a
standalone source code library that we intend to share with other
projects.
Links related to the work making this standalone:
https://pypi.org/project/devicetree/https://python-devicetree.readthedocs.io/en/latest/https://github.com/zephyrproject-rtos/python-devicetree
This standalone repo includes the same features as what we have in
Zephyr, but in its own 'devicetree' python package with PyPI
integration, etc.
To avoid making this a hard fork, move the code that's being made
standalone around in Zephyr into a new scripts/dts/python-devicetree
subdirectory, and handle the package and sys.path changes in the
various places in the tree that use it.
From now on, it will be possible to update the standalone repository
by just recursively copying scripts/dts/python-devicetree's contents
into it and committing the results.
This is an interim step; do NOT 'pip install devicetree' yet.
The code in the zephyr repository is still the canonical location.
(In the long term, people will get the devicetree package from PyPI
just like they do the 'yaml' package today, but that won't happen for
the foreseeable future.)
This commit is purely intended to avoid a hard fork for the standalone
code, and no functional changes besides the package structure and
location of the code itself are expected.
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>