Commit graph

163 commits

Author SHA1 Message Date
Luca Burelli
ed7f2e0833 scripts: dts: dtlib: preserve order of properties in DTS output
Ensure that the order of properties in the output DTS file matches the
order in which they are defined in the DTS source files by moving props
to the end of the dictionary when they are accessed.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-06-05 15:18:40 -05:00
Luca Burelli
0a4e2e383f scripts: dts: dtlib: improve formatting of long arrays
Split long arrays into multiple lines to improve readability of the
output DTS file. A new line is started when the array data exceeds
80 characters.

Add a few test entries to verify the new behavior.

Note: the F821 linter suppression prevents flagging 'array_start' and
'array_newline' as undefined variables. This is because these variables
are initialized when an opening brace is output, which is necessarily
before any element in a byte or prop array. A sequence of markers not
following this pattern would indicate a bug in the DTS parsing code.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-06-05 15:18:40 -05:00
Luca Burelli
fe7f71ba16 dtlib: add test for lineno/filename comments
Tweak the existing filename_and_lineno test to also check the generated
comments in the string representation of the devicetree match expected
contents and alignment.

Using tmpdir as the base directory simplifies the comparison by avoiding
directory separator issues.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-16 09:38:35 +02:00
Luca Burelli
c1603b3163 gen_edt: use workspace dir as base for relative paths in comments
This commit allows comments to reference files with paths that are relative
to the Zephyr workspace root. This is done by adding a new argument
'--workspace-dir' to the 'gen_edt.py' script, which is passed to the
'EDT' and 'DT' classes and used instead of the current working directory.

The workspace directory is set to WEST_TOPDIR if West is in use,
otherwise it is set to the parent directory of ZEPHYR_BASE so that
Zephyr files have a 'zephyr/' prefix.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-16 09:38:35 +02:00
Luca Burelli
a63cb8e74d dtlib: fix double empty line before root node
The root node is the first node in the DTS string representation, and is
currently separated from the headers by two empty lines.

Adjust the spacing so that only one line is printed in all situations. A
small adjustment is added to the test suite to keep the current expected
outputs unchanged.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-16 09:38:35 +02:00
Benjamin Cabé
afdb62d1e2 dtlib: add lineno/filename to string representation of a DT
Output lineno/filename as comments in the string representation of a DT
to help with debugging DT issues. Also, remove the added comments when
comparing the string representation of a DT to a reference string in the
DT testsuite.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-16 09:38:35 +02:00
Luca Burelli
6b325daa2a dtlib: wrap array properties in string representation
List each element of a property array in a different line to improve
the readability of the generated DTS file.
Update the test suite's expected outputs accordingly.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-16 09:38:35 +02:00
Luca Burelli
4b8be385c0 dtlib: fix 'phandle' property's filename and line number
The phandle property is auto-generated when parsing the DTS, so there is
no 'source information'. This commit sets the filename and line number
of the phandle property to be the same as the first reference to the
target node.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-05-16 09:38:35 +02:00
Aksel Skauge Mellbye
73b8d1b637 edtlib: Expose binding title in node class
Make the binding title available from the node the same way
the binding description is propagated.

Signed-off-by: Aksel Skauge Mellbye <aksel.mellbye@silabs.com>
2025-05-02 09:15:50 +02:00
James Roy
285b8ac933 style: edtlib: Use a more efficient expression
Replaced nested loops with a list comprehension
to improve performance. Execution time improved
from 0.0046203136444s to 0.0040774345397s

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-04-09 22:05:22 +02:00
James Roy
ee17657ad3 edtlib: binding: Add a title keyword
Add a 'title' keyword to the binding to provide a short
description of the binding, while 'description' serves as
the long description.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-04-02 12:54:24 +02:00
James Roy
9b795840f9 style: edtlib: Remove the redundant keys() method
Remove the redundant keys method when using the
in statement on a dict to fix the Ruff SIM118
warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
8a2cde9688 style: edtlib: Use from to chain the exception
Use the from keyword to chain exceptions in
order to fix the Ruff B904 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
826ddaed97 style: edtlib: Use the more readable not-equal operator
Replace 'not xx == xx' with 'xx != xx' to
fix the Ruff SIM201 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
b543c26548 style: edtlib: Reorganize the single-line if statement block
Move the statement in the single-line if block
to a new line to fix the Ruff E701 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
8bf5fd9668 style: edtlib: Remove the redundant call arguments
Remove the redundant positional argument in
open function to fix the Ruff UP015 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
7207e91972 style: edtlib: Merge redundant if statements
Merge redundant if statements to fix the Ruff
SIM102 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
20d8a47ad1 style: edtlib: Use a more readable not in statement
Replace 'not xx in xx' with the more readable
'xx not in xx' syntax to fix the Ruff E713 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
8b142ded55 style: edtlib: Sort the import statements
Sort the import statements to fix the
Ruff I001 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
f2eb205d6d style: edtlib: Add an explicit strict argument to the zip
Add an explicit strict parameter to the zip
function to fix the Ruff B905 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
9e46536a1f style: edtlib: Remove deprecated packages
Remove imported deprecated packages and replace
with new packages to fix Ruff UP035 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
James Roy
1425de54e7 style: edtlib: Remove unnecessary quotes
Remove unnecessary quotes from deferred type
annotations to fix the Ruff UP037 warning.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-03-28 12:22:00 +01:00
Benjamin Cabé
529656e2be devicetree: Add filename and line number tracking for nodes & properties
This change enhances the devicetree library by adding support for tracking
the source filename and line number for nodes and properties.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2025-02-26 22:02:39 +00:00
Benjamin Cabé
3352c402fb scripts: fix spelling of "below"
s/bellow/below/

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2025-02-19 18:51:13 +01:00
Christophe Dufaza
ad22d34d16 edtlib: amend Node.props API documentation
Node properties are not created for all properties defined
by the node's binding (Binding.prop2specs),
only for those that actually have a value.

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2025-01-30 18:29:28 +01:00
Christophe Dufaza
c6e3de296d edtlib: amend PropertySpec.path API documentation
PropertySpec.path does NOT tell "the file where the property
was last modified", but instead the binding file specifying
the devicetree node of which this is a property.

See: #65135

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2025-01-30 18:29:28 +01:00
Luca Burelli
16d71d0598 edtlib: add "hash" attribute to nodes
Add a new "hash" attribute to all Devicetree EDT nodes. The hash is
calculated on the full path of the node; this means that its value
remains stable across rebuilds.
The hash is checked for uniqueness among nodes in the same EDT.

This computed token is then added to `devicetree_generated.h` and made
accessible to Zephyr code via a new DT_NODE_HASH(node_id) macro.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
2025-01-22 15:49:10 +01:00
James Roy
34bc4c3e3e style: edtlib: Use a better format string
Use f-strings as recommended by PEP-8
instead of the .format() method.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-01-10 18:57:39 +01:00
Christophe Dufaza
ee5c520326 edtlib: tests: refine coverage of Binding objects initialization
Add a series of unit tests which try to cover somewhat systematically
the possible inputs and what we finally get at the exit
of the Binding constructor.

Running the assumption that any (valid) YAML binding file is
something we can make a Binding instance with:
- check which properties are defined at which level (binding,
  child-binding, grandchild-binding, etc) and their specifications
  once the binding is initialized
- check how including bindings are permitted to specialize
  the specifications of inherited properties
- check the rules applied when overwriting a binding's description
  or compatible string (at the binding, child-binding, etc, levels)

Some tests covering known issues are disabled by default:
- this permits to document these issues
- while not causing CI errors (when running the python-devicetree
  unit tests)
- enabling these tests without causing errors should allow us
  to consider the related issues are fixed

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2025-01-08 19:17:51 +01:00
James Roy
c99a61ada4 style: edtlib: Use a better type Annotations
Use built-in types for annotations instead
of types from the typing module.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-01-08 03:26:58 +01:00
James Roy
802eac71f0 style: edtlib: Use a better line continuation operator
Replace backslashes('\') with PEP-8 recommended
parentheses('( )') as the line continuation operator.

Signed-off-by: James Roy <rruuaanng@outlook.com>
2025-01-04 14:15:37 +01:00
Grzegorz Swiderski
f0646d3da4 edtlib: Express Node.matching_compat and Node.binding_path as @property
This simplifies the code and makes it clearer that both properties are
defined in terms of the Binding object matched to a given DT node.

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
2024-11-25 08:31:18 +01:00
Pieter De Gendt
f05deb1aa4 python: Format trivial files where only newlines were missing
Apply formatting on files that only needed adding newlines.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
2024-11-21 20:10:51 +01:00
Florian Grandel
becd9e5b92 scripts: dts: edtlib: fix type docs
The return type of 'uint8-array' properties was not yet documented.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
2024-11-18 19:30:57 -05:00
Florian Grandel
be4acee09a scripts: dts: edtlib: type hints
Adds type hints to functions that were not yet typed.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
2024-11-18 19:30:57 -05:00
Florian Grandel
0f1549c575 scripts: dts: edtlib: simplification
Small refactorings to simplify code and improve method encapsulation.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
2024-11-18 19:30:57 -05:00
Florian Grandel
4bd584cf21 scripts: dts: edtlib: improve Node encapsulation
Moves several node-specific operations inside the Node class to improve
its encapsulation, remove a monkey patch and access to internal methods
and fields.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
2024-11-18 19:30:57 -05:00
Christophe Dufaza
b0b278503f Revert "edtlib: fix "last modified" semantic for included ... specs"
[1] was introduced to get more valuable answers from
the PropertySpec.path API, which is supposed to tell
in which file the property's specification was "last modfied".

Further work on related issues [2] showed that the
approach chosen in [1] is dead end: we need to first rethink
how bindings (and especially child-bindings) are initialized.

[1] edtlib: fix last modified semantic in included property specs
[2] edtlib: Preserve paths of properties from included child bindings

See also: #65221, #78095

This reverts commit b3b5ad8156.

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2024-11-06 14:43:19 -06:00
Christophe Dufaza
c58d6761bc edtlib: tests: cover basics of filtering inherited properties
Use-case "B includes I includes X":
- X is a base binding file, specifying common properties
- I is an intermediary binding file, which includes X
  without modification nor filter
- B includes I, filtering the properties it chooses
  to inherit with an allowlist or a blocklist

Check that the properties inherited from X via I
are actually filtered as B intends to,
up to the grandchild-binding level.

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2024-11-06 14:43:19 -06:00
Christophe Dufaza
0b946dfc01 Revert "edtlib: test "last modified" semantic for ... specs"
This unit test was added to cover the change introduced by [1].

Further work on related issues [2] showed that the chosen approach
is dead end.
We're reverting all changes made in [1].

[1] edtlib: fix last modified semantic in included property specs
[2] edtlib: Preserve paths of properties from included child bindings

See also: #65221, #78095

This reverts commit 70eaa61cb0.

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2024-11-06 14:43:19 -06:00
Christophe Dufaza
308b568219 Revert "edtlib: test filters set by including bindings"
This unit test was added specifically to cover a regression
reported by the CI while working on [1].

Further work on related issues [2] showed that:
- [1] and [2] are dead end: we need to first rethink
  how bindings (and especially child-bindings) are initialized
- the inclusion mechanism supported by Zephyr deserves more systematic
  testing in edtlib if we want to work with confidence

The approach we choose is to:
- revert all changes made in [1]
- from there, systematically add unit tests as we address
  the issues we identified (or the additional features we need)
  one after the other

[1] edtlib: fix last modified semantic in included property specs
[2] edtlib: Preserve paths of properties from included child bindings

See also: #65221, #78095

This reverts commit 33bb3b60d9.

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2024-11-06 14:43:19 -06:00
Joel Hirsbrunner
7454cb984b Devicetree: Devicetree Bindings: Adjust python tests
Adjust existing tests to support the changes and add new tests to test
the newly added feature.

Signed-off-by: Joel Hirsbrunner <jhirsbrunner@baumer.com>
2024-10-15 04:11:36 -04:00
Joel Hirsbrunner
8b02bc9392 Devicetree: Devicetree Bindings: Support enums for array like dt props
It is currently impossible to use enum with any array like type (i.e.
string-array and array, these are the only ones that make sense) in the
devicetree and dt-bindings.
However, there is no such remark in the dt-bindings section of the docs.
Since this is a feature that comes in very handy and is implemented
fairly easily, I adjusted the scripts for this.

It is now possible to do something like this.
```yaml
compatible = "enums"

properties:
  array-enum:
    type: string-array
    enum:
      - bar
      - foo
      - baz
      - zoo
```
```dts
/ {
	enums {
		compatible = "enums";
		array-enum = "foo", "bar";
	};
};
```

Signed-off-by: Joel Hirsbrunner <jhirsbrunner@baumer.com>
2024-10-15 04:11:36 -04:00
Benedikt Schmidt
e7bf414f15 scripts: dts: devicetree: edtlib: Use insertion sort for compat2nodes
Sort the elements in the lists of compat2nodes already during insertion.

Signed-off-by: Benedikt Schmidt <benedikt.schmidt@embedded-solutions.at>
2024-09-25 13:46:32 -05:00
Florian Grandel
a575c769f8 scripts: dts: gen_defines/edtlib: improve encapsulation
Moves node sorting concern into EDT.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
2024-09-25 13:46:32 -05:00
Reto Schneider
371a48ac16 edtlib: Remove unreachable code
This fixes the following error reported by
./scripts/ci/check_compliance.py:

> 1 checks failed
> ERROR   : Test Pylint failed:
> W0101:Unreachable code (unreachable)
> File:scripts/dts/python-devicetree/src/devicetree/edtlib.py
> Line:2271
> Column:16
>
> Complete results in compliance.xml

Signed-off-by: Reto Schneider <reto.schneider@husqvarnagroup.com>
2024-09-17 14:58:25 -04:00
Lingao Meng
302422ad9d everywhere: replace double words
import os
import re

common_words = set([
    'about', 'after', 'all', 'also', 'an', 'and',
     'any', 'are', 'as', 'at',
    'be', 'because', 'but', 'by', 'can', 'come',
    'could', 'day', 'do', 'even',
    'first', 'for', 'get', 'give', 'go', 'has',
    'have', 'he', 'her',
    'him', 'his', 'how', 'I', 'in', 'into', 'it',
    'its', 'just',
    'know', 'like', 'look', 'make', 'man', 'many',
    'me', 'more', 'my', 'new',
    'no', 'not', 'now', 'of', 'one', 'only', 'or',
    'other', 'our', 'out',
    'over', 'people', 'say', 'see', 'she', 'so',
    'some', 'take', 'tell', 'than',
    'their', 'them', 'then', 'there', 'these',
    'they', 'think',
    'this', 'time', 'two', 'up', 'use', 'very',
    'want', 'was', 'way',
    'we', 'well', 'what', 'when', 'which', 'who',
    'will', 'with', 'would',
    'year', 'you', 'your'
])

valid_extensions = set([
    'c', 'h', 'yaml', 'cmake', 'conf', 'txt', 'overlay',
    'rst', 'dtsi',
    'Kconfig', 'dts', 'defconfig', 'yml', 'ld', 'sh', 'py',
    'soc', 'cfg'
])

def filter_repeated_words(text):
    # Split the text into lines
    lines = text.split('\n')

    # Combine lines into a single string with unique separator
    combined_text = '/*sep*/'.join(lines)

    # Replace repeated words within a line
    def replace_within_line(match):
        return match.group(1)

    # Regex for matching repeated words within a line
    within_line_pattern =
	re.compile(r'\b(' +
		'|'.join(map(re.escape, common_words)) +
		r')\b\s+\b\1\b')
    combined_text = within_line_pattern.
		sub(replace_within_line, combined_text)

    # Replace repeated words across line boundaries
    def replace_across_lines(match):
        return match.group(1) + match.group(2)

    # Regex for matching repeated words across line boundaries
    across_lines_pattern = re.
		compile(r'\b(' + '|'.join(
			map(re.escape, common_words)) +
			r')\b(\s*[*\/\n\s]*)\b\1\b')
    combined_text = across_lines_pattern.
		sub(replace_across_lines, combined_text)

    # Split the text back into lines
    filtered_text = combined_text.split('/*sep*/')

    return '\n'.join(filtered_text)

def process_file(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        text = file.read()

    new_text = filter_repeated_words(text)

    with open(file_path, 'w', encoding='utf-8') as file:
        file.write(new_text)

def process_directory(directory_path):
    for root, dirs, files in os.walk(directory_path):
        dirs[:] = [d for d in dirs if not d.startswith('.')]
        for file in files:
            # Filter out hidden files
            if file.startswith('.'):
                continue
            file_extension = file.split('.')[-1]
            if
	file_extension in valid_extensions:  # 只处理指定后缀的文件
                file_path = os.path.join(root, file)
                print(f"Processed file: {file_path}")
                process_file(file_path)

directory_to_process = "/home/mi/works/github/zephyrproject/zephyr"
process_directory(directory_to_process)

Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
2024-06-25 06:05:35 -04:00
Grzegorz Swiderski
46572f797f dtlib: Allow deleting the root node
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>
2024-06-06 00:42:10 -07:00
Christophe Dufaza
33bb3b60d9 edtlib: test filters set by including bindings
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>
2024-04-22 06:50:55 -07:00
Christophe Dufaza
b3b5ad8156 edtlib: fix "last modified" semantic for included property specs
Although the PropertySpec.path attribute is documented as
"the file where the property was last modified",
all property specs in Binding.prop2specs will claim
they were last modified by the top-level binding itself.

Consider:
- I1 is a base binding that specifies properties x and y
- I2 is an "intermediate" binding that includes I1,
  modifying the specification for property x
- B is a top-level bindings that includes I2,
  and specifies an additional property p

When enumerating the properties of B,
we expect the values of PropertySpec.path to tell us:
- y was last modified by I1
- x was last modified by I2
- p was last modified by B

However, the Binding constructor:
- first merges all included bindings into the top-level one
- eventually initializes specifications for all the defined properties

As a consequence, all defined properties claim they were last modified
by the top-level binding file.

We should instead:
- first, take into account their own specifications for the
  included properties
- eventually update these specifications with the properties
  the top-level binding adds or modifies

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2024-04-22 06:50:55 -07:00