Commit Graph

720 Commits

Author SHA1 Message Date
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
TOKITA Hiroshi
767d1ce5f6 devicetree: Adding UNQUOTED, TOKEN, and UPPERTOKEN variants of FULL_NAME
Like some other string properties, I will add a derived form
to FULL_NAME to make it easier to reference from macros.

Signed-off-by: TOKITA Hiroshi <tokita.hiroshi@gmail.com>
2024-10-08 06:01:10 -04:00
Joel Spadin
6edefd8f50 scripts: dts: properly escape string properties
Fixed escaping of double quotes, backslashes, and new line characters
so they can be used in string properties.

Previously, double quotes and backslashes were escaped in gen_defines.py
but not in gen_dts_cmake.py, and new lines were not escaped in either,
so using any of these characters would break the build.

Signed-off-by: Joel Spadin <joelspadin@gmail.com>
2024-10-04 13:26:51 -05: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
Benedikt Schmidt
fe3287a9ac scripts: dts: extract pickled EDT generation
Separate the pickled EDT generation from the C-Macro header
generation in gen_defines.py to have a more clear responsibility
of the scripts in the DTS parsing process.

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
Florian Grandel
945925bd8b scripts: dts: gen_defines: redundant sorting
Removes redundant sorting of nodes.

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
2024-09-25 13:46:32 -05:00
Florian Grandel
de846c7afa scripts: dts: gen_defines: type hints
Introduces type hints to all functions for improved static type checking
and IDE support.

Also equalizes spacing between functions as the lines are being touched
anyway.

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
Fin Maaß
fb8b30d8d0 dts: devicetree.h: add DT_REG_HAS_NAME
Add DT_REG_HAS_NAME,
DT_REG_ADDR_BY_NAME_OR,
DT_REG_SIZE_BY_NAME_OR,
DT_INST_REG_HAS_NAME,
DT_INST_REG_SIZE_BY_NAME_OR and
DT_INST_REG_ADDR_BY_NAME_OR.

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
2024-06-12 17:12:23 -05:00
Martí Bolívar
74abb2bf95 devicetree: add first-class node label helpers
Add the following new macros:

- DT_FOREACH_NODELABEL
- DT_FOREACH_NODELABEL_VARGS
- DT_INST_FOREACH_NODELABEL
- DT_INST_FOREACH_NODELABEL_VARGS

These are for-each helpers for iterating over the node labels of a
devicetree node. Since node labels are unique in the entire
devicetree, their token representations can be useful as unique IDs in
code as well.

As a first user of these, add:

- DT_NODELABEL_STRING_ARRAY
- DT_INST_NODELABEL_STRING_ARRAY

The motivating use case for these macros is to allow looking up a
struct device by devicetree node label in Zephyr shell utilities.
The work on the shells themselves is deferred to other patches.

To make working with the string array helpers easier, add:

- DT_NUM_NODELABELS
- DT_INST_NUM_NODELABELS

Signed-off-by: Martí Bolívar <mbolivar@amperecomputing.com>
2024-06-12 18:49:54 +02: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
Swift Tian
5871ff010b devicetree: Add DT/DT_INST_CHILD_NUM and DT/DT_INST_CHILD_NUM_STATUS_OKAY
Add a generated macro for the number of child nodes of a given node.
Add a generated macro for the number of child nodes of a given node which
children's status are "okay".

Signed-off-by: Swift Tian <swift.tian@ambiq.com>
2024-05-03 11:18:43 +02: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
Christophe Dufaza
70eaa61cb0 edtlib: test "last modified" semantic for included property specs
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>
2024-04-22 06:50:55 -07:00
Javan lacerda
dbfc1aaec6 scripts: dts: update pyyaml version
The currently used PyYaml version has some vulnerabilies as
described on the pull request description. It updates to
version 6.0, removing these supply chain vulnerabily.
The OSSF Scorecard was the tool used for discovering
 these vulnerabilties.

Signed-off-by: Javan lacerda <javanlacerda@google.com>
2024-03-29 09:03:34 -04:00
Yong Cong Sin
450a66fa36 gen_defines: output the interrupt level of a node
Currently it is tedious to know the level of an interrupt for
a node in C. One would have to go through a very complex and
error prone macros to check if there's a parent interrupt
controller & if the controller has an interrupt number and thus
not a pseudo interrupt controller like the one found in
`rv32m1`. The level of a node is required to encode the
Zephyr's multi-level interrupt number

Since it is easier to do it in the `gen_defines` script, let's
do the heavy lifting there so that we can introduce new DT
macros to get the interrupt level very easily later.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
2024-01-23 06:48:16 -05:00
Bjarki Arge Andreasen
08d6ff059e scripts: dts: gen_defines: Generate interrupt-controller macro
Extend the gen_defines.py write_interrupts(node) function to
generate macros to get the interrupt controller for an
interrupt specifier by idx and by name.

The information is already generated by edtlib.py and stored in
node.interrupts[].controller. This addition uses the node pointed
to by the controller member to generate the following example output

define DT_N_S_device1_IRQ_IDX_0_CONTROLLER \
       DT_N_S_gpio_800

define DT_N_S_device1_IRQ_NAME_test4_CONTROLLER \
       N_S_device1_IRQ_IDX_0_CONTROLLER

Signed-off-by: Bjarki Arge Andreasen <bjarki@arge-andreasen.me>
2024-01-17 13:18:00 +01:00
Yong Cong Sin
df2c0681d3 devicetree: encode multi-level interrupt number in C devicetree magic
The multi-level encoding of the interrupt number currently
happens in the `gen_defines.py`, which is called in the
`dts.cmake` module after `kconfig.cmake`. However, the number
of bits used by each level is defined in Kconfig and this means
that `gen_defines.py` will not be able to get that information
during build.

To fix this, do the multi-level encoding in C devicetree macro
magic instead of the python script. This ticks one of a
long-standing TODO item from the `gen_defines.py`.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
2023-10-30 11:43:39 -04:00
Fabio Baltieri
403640b75e edtlib: link child nodes to parent for nodes with child-bindings
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>
2023-10-25 18:39:31 -07:00
Gerard Marull-Paretas
7772cec6bd edtlib: always insert root node to the graph
When we have an empty Devicetree, ie,

```
/dts-v1/;

/ {

};
```

The node's dep_ordinal is never initialized because the node graph is
empty. This ends up with invalid ordinal tokens (-1) in
devicetree_generated.h which in turn produce some cryptic compiler
errors, see e.g.

```
error: pasting "dts_ord_" and "-" does not give a valid preprocessing
token
   95 | #define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_,
      DT_DEP_ORD(node_id))

...

include/zephyr/devicetree.h:2498:41:
note: in expansion of macro 'DT_FOREACH_OKAY_HELPER'
 2498 | #define DT_FOREACH_STATUS_OKAY_NODE(fn)
      DT_FOREACH_OKAY_HELPER(fn)
            |
	    ^~~~~~~~~~~~~~~~~~~~~~
include/zephyr/device.h:1022:1:
note: in expansion of macro 'DT_FOREACH_STATUS_OKAY_NODE'
     1022 |
	  DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL)

```

(devicetree_generated.h)

```
...
 #define DT_N_ORD -1
 #define DT_N_ORD_STR_SORTABLE 000-1
...
```

This patch makes sure root node is always inserted (without any target)
so that it gets initialized later.

Discovered as part of
https://github.com/zephyrproject-rtos/zephyr/pull/63696

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
2023-10-11 18:28:01 +03:00
Gerard Marull-Paretas
73b803ab4b edtlib: pinctrl properties are required in the binding
Consumers need to include `pinctrl-device.yaml` where this is defined.

Signed-off-by: Gerard Marull-Paretas <gerard@teslabs.com>
2023-09-27 13:58:28 +02:00
Grant Ramsay
5443703dc9 edtlib: Exclude PCI devices from some inapplicable checks
PCI devices are have some differences to regular nodes:
* node name specifies device/function e.g. "pcie@1,0"
* register address has a different meaning
* zero-sized register is allowed

This improves alignment with Linux DT for PCI devices

Signed-off-by: Grant Ramsay <gramsay@enphaseenergy.com>
2023-08-18 10:13:12 +02:00
Christophe Dufaza
ad48c51651 devicetree: edtlib: prefixes which are not vendors are NOT vendors
In Linux, checkpatch.pl relies on the vendor-prefixes.yaml file
to validate manufacturers in compatible strings.
In addition to the vendors defined in vendor-prefixes.txt,
the YAML file includes expressions for "prefixes which are not vendors":
these expressions do NOT define special manufacturers that may appear
in compatible strings, and are never involved as such in DTS files.
We can rather see them as bulk-definitions of JSON/YAML properties
suitable for the dt-schema tools.

OTHO, in Zephyr, checkpatch.pl relies on the vendor-prefixes.txt file,
which does not include these additional prefixes, but edtlib.EDT adds
them as hard-coded special values.

This is confusing, if not incorrect:

- the fact that edtlib.EDT (and thus its client code in the
zephyr/scripts directory) actually allows these vendors
in compatible strings is buried in the source code
- checkpatch.pl (with vendor-prefixes.txt) in Zephyr behaves neither like
checkpatch.pl (with vendor-prefixes.yaml) in Linux, nor like edtlib.EDT
(with _VENDOR_PREFIX_ALLOWED)
- Zephyr should not treat these "prefixes which are not vendors" as
valid manufacturers in compatible strings to begin with

Signed-off-by: Christophe Dufaza <chris@openmarl.org>
2023-08-16 14:50:26 +02:00
Grzegorz Swiderski
dcd8d60119 scripts: dts: Support DT_NODE_HAS_PROP(node_id, ranges)
This is a one-line fix for edtlib, which lets gen_defines.py indicate
whether the `ranges` property exists within a given node.

Although address translation through ranges is typically automatic,
users can choose to manually inspect ranges using DT_FOREACH_RANGE(),
DT_NUM_RANGES(), and other DT_RANGES_* macros. These can be used to
implement manual translation at runtime, which is currently done for
PCIe controllers.

The only thing missing is being able to check if a node contains an
empty `ranges;`, which signifies a 1:1 translation to the parent bus.
Checking DT_NUM_RANGES() is insufficient, because it returns zero
whether or not `ranges;` is present.

It should be possible to use DT_NODE_HAS_PROP(), but it was not working,
because edtlib ignores properties which are undeclared in bindings and
don't have a default type. Add a missing PropertySpec for `ranges` with
"compound" type; it can't be "array" because it can be empty-valued.

Signed-off-by: Grzegorz Swiderski <grzegorz.swiderski@nordicsemi.no>
2023-08-02 09:56:01 -07:00
Yasushi SHOJI
fb8f214f46 scripts: gen_defines.py: Update doc reference
interrupts.rst has been moved to doc/kernel/services/.

Signed-off-by: Yasushi SHOJI <yashi@spacecubics.com>
2023-08-01 08:20:24 +00:00
Jordan Yates
b6e03417c7 dts: gen_defines: generate _ORD_STR_SORTABLE
Generate a zero padded variant of `_ORD` that is suitable for use in
linker scripts with the `SORT` property, so that `6` is correctly placed
before `24`, and so on.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
2023-07-25 15:58:06 +00:00
Jordan Yates
f0958c62e4 Revert "dts: gen_defines: generate _ORD_STR_SORTABLE"
This reverts commit 9b77681473.
2023-07-25 14:17:11 +02:00
Jordan Yates
9b77681473 dts: gen_defines: generate _ORD_STR_SORTABLE
Generate a zero padded variant of `_ORD` that is suitable for use in
linker scripts with the `SORT` property, so that `6` is correctly placed
before `24`, and so on.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
2023-07-25 09:13:16 +02:00
Carlo Caione
935268ee64 devicetree.h: DT_FOREACH_NODE_VARGS, DT_FOREACH_STATUS_OKAY_NODE_VARGS
Add the _VARGS variant of DT_FOREACH_NODE and
DT_FOREACH_STATUS_OKAY_NODE for when we want to do some kind of
operation on all the nodes in the tree.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
2023-07-07 11:41:19 +02:00
Martí Bolívar
0c29e07e30 devicetree: better DT_PROP_BY_IDX()/DT_FOREACH_PROP_ELEM() support
Support use of these macros with properties of type phandle and
string by allowing iterating over:

- a phandle as if it were a phandles of length 1, for convenience and
  consistency with our ability to take its length (and getting 1)

- the non-null characters in a string: we exclude the null for
  consistency with the return value of DT_PROP_LEN() on string
  properties, which, like strlen(), does not include the null

With this and a previous patch expanding the usage of DT_PROP_LEN(),
there is now a relationship between being able to take a property's
logical length with DT_PROP_LEN() and being able to iterate over its
logical elements with DT_FOREACH_PROP_ELEM(). Explain this in the
documentation.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-05-16 18:14:26 +02:00
Martí Bolívar
8aa83f6ae8 devicetree: support DT_PROP_LEN() on phandle and string
It will be convenient to treat these respectively as degenerate cases
of 'phandles' and 'string-array'. Add support for this and regression
tests. (There's nothing to do in the case of 'phandle' beyond
documenting the guarantee.)

For the record, the other DT_PROP_LEN() tests for each type are in:

  type            test case              property
  ------------    --------------------   ------------
  array           test_arrays            a
  string-array    test_path_props        compatible
  uint8-array     test_arrays            b
  phandles        test_phandles          phs
  phandle-array   test_phandles          pha-gpios
  phandle         test_phandles          ph

Update docstrings and fix some issues in them.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-05-16 18:14:26 +02:00
Martí Bolívar
52043691e9 scripts: gen_defines: add some missing comments
We generally try to have comments in this file that show the form of
each generated macro. This is particularly important in the
write_vanilla_props() function, since that is called on every node in
the tree and handles generic macros that are widely applicable.

Various generated macros have been added over time that don't have
the corresponding comments; add these now.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-05-16 18:14:26 +02:00
Jordan Yates
59167e1888 scripts: dts: gen_defines: add ENUM_VAL_<val>_EXISTS define
Add a define of the form
`DT_N_<node-id>_P_<prop-id>_ENUM_VAL_<val>_EXISTS` for enumerated
devicetree properties. This enables the devicetree API to check whether
an enum is a given value directly, without resorting to error-prone
checks against the enum index.

Example generated defines (int and string):
	`#define DT_N_S_test_S_enum_4_P_val_ENUM_VAL_5_EXISTS 1`
	`#define DT_N_S_test_S_enum_6_P_val_ENUM_VAL_zero_EXISTS 1`

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
2023-05-15 09:03:37 -07:00
Martí Bolívar
5847890a18 edtlib: finish adding type annotations
This concludes the type annotations for the public API for the module,
along with the relevant internal state. It's not worth type annotating
the internal backwards compatibility shim for !include.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
3318380eaf edtlib: type annotate EDT
Incremental progress towards type annotating the entire module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
d89f974760 edtlib: type annotate Node
This requires adding a private constructor so that mypy
can tell what all the final instance state is going to be.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
cae8b6567d edtlib: make PinCtrl a type-annotated dataclass
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>
2023-04-17 08:58:14 -07:00
Martí Bolívar
83b6db2ec1 edtlib: make ControllerAndData a type-annotated dataclass
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>
2023-04-17 08:58:14 -07:00
Martí Bolívar
3a43e1b643 edtlib: make Range a type-annotated dataclass
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>
2023-04-17 08:58:14 -07:00
Martí Bolívar
b07f3ddd9f edtlib: clean up Range docstring
Fix grammar issues and typos.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
49c0d72234 edtlib: make Register a type-annotated dataclass
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>
2023-04-17 08:58:14 -07:00
Martí Bolívar
4415a29af2 edtlib: make Property a type-annotated dataclass
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>
2023-04-17 08:58:14 -07:00
Martí Bolívar
835a57ccfa edtlib: type annotate PropertySpec
Incremental progress towards type annotating the module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
1b6921965a edtlib: type annotate Binding
Incremental progress towards type annotating the whole module.
Annotate helper procedures used by the class as well.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
3d75f17d5e edtlib: improve error handling paths
Miscellaneous fixes discovered by inspection while type annotating the
module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
51d79808e4 edtlib: move Node
This is just moving the class definition higher in the file. I am
reordering the classes to make it possible to type annotate the module
in a more readable way.

Git might make the diff look bigger than it really is.
To verify this is just moving code, use 'git diff --minimal'.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
ba4b8a406e edtlib: move PinCtrl
This is just moving the class definition higher in the file
to make it easier to type annotate the module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
a5d82337b7 edtlib: move ControllerAndData
This is just moving the class definition higher in the file
to make it easier to type annotate the module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
ea4db57d90 edtlib: move Range
This is just moving the class definition higher in the file
to make it easier to type annotate the module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
da31368eed edtlib: move Register
This is just moving the class definition higher in the file
to make it easier to type annotate the module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
20731a3cab edtlib: move Property
This is just moving the class definition higher in the file
to make it easier to type annotate the module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
ff8c63c03b edtlib: move PropertySpec
This is just moving the class definition higher in the file
to make it easier to type annotate the module.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
bef3970573 edtlib: move Binding
This is just moving the class definition higher in the file. I am
reordering the classes to make it possible to type annotate the module
in a more readable way.

Git might make the diff look bigger than it really is.
To verify this is just moving code, use 'git diff --minimal'.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
cf9cfc31bd edtlib: implement copy.deepcopy() for EDT
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>
2023-04-17 08:58:14 -07:00
Martí Bolívar
f4b487aea2 edtlib: refactor some internals
Move all the initial settings of instance attributes to the
constructor, so we can keep track of them all more easily.

No functional changes expected.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
867dd1c84c devicetree: use c89 comments in test file
This is still the preferred style in a zephyr DTS.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
dcf1fc0592 dtlib: fix docstring
The reference is to an incorrect method.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-04-17 08:58:14 -07:00
Martí Bolívar
513e03ad68 edtlib: extract _slice() code to new helper module
This will make it more convenient to use it from multiple different
places, which we will have a need for in the future.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
c0a024253f edtlib: fix typo
Trivial fix.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
3bb1aaebd5 dtlib: fix pretty-printing in pdb
We need to have an _include_path attribute to pretty-print
this object from within pdb, for some reason. Add it.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
2d86e1b05d dtlib: add missing type annotations
This allows mypy to check the internal variable type annotations
within the function.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
78fca3c19c dtlib: fix comment header
The following section of code has nothing public inside.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
6ac19439b2 dtlib: remove dead code
There's no need for _parse_node() to return the Node instance that is
its sole argument. The only user of the return value is a dead store.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
5272e7f681 dtlib: add DT.move_node()
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>
2023-02-27 17:44:45 +01:00
Martí Bolívar
e479d3f7c6 dtlib: use new helper in test cases
Using dtlib_raises() throughout the test cases saves some typing.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
2063ddbc93 dtlib: add new test case helper
Introduce a context manager that will save some typing
when dealing with expected exceptions.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Martí Bolívar
faa7e530c2 dtlib: clean up a documentation string
The standard way we write this in the library is 'documentation
string', not 'docstring'.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2023-02-27 17:44:45 +01:00
Radosław Koppel
14a1b2ffec dts: Add _STRING_UNQUOTED string and string-array
This commit adds access to the string values without a quotes.

Signed-off-by: Radosław Koppel <r.koppel@k-el.com>
Co-authored-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
2023-02-20 09:49:00 +01:00
Allan Norgaard
23cacb3766 scripts: dts: gen_driver_kconfig_dts: Skip empty yaml files
The YAML parsing will currently return a None-type if no input data
is empty, and the subsequent check for a substring will cause an
exception.

Signed-off-by: Allan Norgaard <allannk@gmail.com>
2023-02-19 20:46:44 -05:00
Henrik Brix Andersen
28819152cb scripts: dts: add special tooling for handling GPIO hog nodes
GPIO hog nodes contain a "gpios" property, but unlike other "*-gpios"
properties, these are not phandle-arrays as they only carry the data part
(e.g. pin, flags) but lack the phandles to the (parent) GPIO controller.

Add special devicetree tooling to handle the "gpios" property of GPIO hog
nodes and generate special devicetree helper macros as if they were phandle
arrays.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2023-01-27 14:38:52 -08:00
Jamie McCrae
ec7044437e treewide: Disable automatic argparse argument shortening
Disables allowing the python argparse library from automatically
shortening command line arguments, this prevents issues whereby
a new command is added and code that wrongly uses the shortened
command of an existing argument which is the same as the new
command being added will silently change script behaviour.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2023-01-26 20:12:36 +09:00
Chris Duf
92897ef011 python-devicetree: bump version to 0.0.2
Inconsistency between python-devicetree version numbers
may be confusing:
- the last version at PyPI is 0.0.2
- zephyr-rtos/python-devicetree/setup.py sets the version
  to 0.0.2 (this is probably the setup file used when uploading
  to PyPI)
- zephyr-rtos/zephyr/scripts/dts/python-devicetree/setup.py sets
  the version to 0.0.1

This may suggest that the mirror repository, and PyPI, are more
up-to-date than zephyr-rtos/zephyr/scripts/dts/python-devicetree.

Repositories being otherwise mostly identical (1), also bumping
the python-devicetree's version here seems a sane option.

(1) Ignoring the doc directory (only at zephyr-rtos/python-devicetree).

Signed-off-by: Chris Duf <chris@openmarl.org>
2023-01-16 11:19:54 +00:00
Chris Duf
436616c66b python-devicetree: unpin types-PyYAML version
This is essentially a revert of PR #46311 "python-devicetree: CI hotfix",
assuming the original issue has been resolved, either upstream in
types-PyYAML or in Zephyr itself.

Tested with types-PyYAML 6.0.12.2 (current version at PyPI):

  $ python -m mypy --config-file=tox.ini --package=devicetree
  dtlib.py:962: note: By default the bodies of untyped functions [...]
  dtlib.py:964: note: By default the bodies of untyped functions [...]
  dtlib.py:965: note: By default the bodies of untyped functions [...]
  dtlib.py:967: note: By default the bodies of untyped functions [...]
  Success: no issues found in 4 source files

The "notes" above are harmless (use of type hinting to define local
variables while mypy won't "check the bodies of untyped functions").

References:
- python-devicetree tox run fails (issue #46286)
- python-devicetree: CI hotfix (PR #46311)
- python-devicetree: CI hotfix (commit f6a6843)

Signed-off-by: Chris Duf <chris@openmarl.org>
2023-01-16 11:19:54 +00:00
Moritz Fischer
7dd05967f7 scripts: dts: gen_driver_kconfig_dts: Use SafeLoader
Using SafeLoader is preferrable where possible.

Signed-off-by: Moritz Fischer <moritzf@google.com>
2023-01-04 07:38:56 -08:00
Fabio Baltieri
0daa3a78a9 yamllint: indentation: fix files in scripts/
Fix the YAML files indentation for files in scripts/.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
2023-01-04 14:23:53 +01:00
Gerard Marull-Paretas
537133fe44 devicetree: edtlib: tests: add coverage for child includes
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>
2022-11-17 06:57:46 -06:00
Martí Bolívar
a97295b6a2 edtlib: re-appease the linter
At some point in the past, we had to suppress a couple of false
positive pylint warnings to pass CI. But now the linter seems to have
figured out its original mistake and is complaining about a useless
supression. Sigh. Play along.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-11-07 19:00:31 +01:00
Martí Bolívar
15e3e317f7 dtlib: implement copy.deepcopy() for DT
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>
2022-11-07 19:00:31 +01:00
Martí Bolívar
3c976cc3b6 devicetree: stop using OrderedDict
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>
2022-11-07 19:00:31 +01:00
Martí Bolívar
c25dde3511 dtlib: fix Property.labels docstring
The value of the 'labels' attribute is a list, not a set.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-11-07 19:00:31 +01:00
Martí Bolívar
b64d5d6d19 dtlib: move some internal code around
Refactor the file parsing methods for readability by moving the
_parse_header() and _parse_memreserves() calls from _parse_dt() to
_parse_file(). The header and memreserves are not part of the 'tree'
part of the devicetree; now that we have a dedicated _parse_file()
helper, it makes more sense to me to have them there.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-11-07 19:00:31 +01:00
Martí Bolívar
c875cb0f94 dtlib: fix Property.type type annotation
Holy overloaded technical terms, Batman.

Here, 'property' and 'type' each mean two different things, which
we can distinguish like this:

- Property (capital P): dtlib.Property class, represents
  a property in a devicetree node
- @property: a Python property
- type(): an "@property" in the Property class, that returns
  a dtlib.Type value
- Type (capital T): dtlib.Type class, represents the devicetree
  type of a Property value (dtlib.Type.BYTES, etc.)

The type() @property in the Property class currently has an 'int' as
its Python return type annotation. It really returns a dtlib.Type,
which is an int (since it's an IntEnum), but that's not the same thing
as an int.

Change this to Type to be clear that not just any int can be returned
by this @property.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-11-07 19:00:31 +01:00
Martí Bolívar
cd18ffee22 dtlib: clean up Property initialization
Make attribute initialization order match the order that attributes
appear within the class docstring. Move the 'type' property definition
up by the constructor to make it more obvious that this 'attribute' is
a (Python) property. This is for readability.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-11-07 19:00:31 +01:00
Martí Bolívar
47789aa1fa dtlib: clean up Node initialization
Reorder attribute initialization to match the order that attributes
appear in the class level docstring. This is for readability.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-11-07 19:00:31 +01:00
Martí Bolívar
cb78a5c322 dtlib: clean up DT initialization
Initialize all the public API interface related attributes within the
constructor instead of scattering them throughout the implementation
of the class, and make sure they all have type annotations.

Move all the parsing code away from the init routines and public API
down to the main parsing block.

This is for readability and paves the way for later changes that
affect the way initialization happens.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-11-07 19:00:31 +01:00
Chris Duf
e067be5f0c Devicetree: edtlib: fix possible TypeError in Binding.__repr__()
Calling Binding.__repr__() when the attribute Binding.path is None
would raise TypeError: expected str, bytes or os.PathLike object,
not  NoneType.

Known bindings that may not have a path (Binding.path is None)
include bindings for properties such as 'compatible', 'reg', 'status'.

Signed-off-by: Chris Duf <chris@openmarl.org>

Co-authored-by: Gerard Marull-Paretas <gerard@teslabs.com>
2022-10-13 12:02:31 +02:00
Chris Duf
230c80e000 Devicetree: edtlib: fix possible AttributeError in Property.description
Attempting to access the property Property.description
when Property.spec.description is None would raise
AttributeError: 'NoneType' object has no attribute 'strip'.

Known properties that may not have a description
(Property.spec.description is None):
- 'compatible' for nodes such as / /soc /soc/timer@e000e010 /leds /pwmleds
- 'reg'        for nodes such as /soc/timer@e000e010
- 'status'     for nodes such as /soc/timer@e000e010
- 'gpios'      for nodes such as /leds/led_0 /buttons/button_0
- 'pwms'       for nodes such as /pwmleds/pwm_led_0

This patch checks the PropertySpec.description attribute before calling
strip(): will return None, and not raise AttributeError.

Signed-off-by: Chris Duf <chris@openmarl.org>

Co-authored-by: Gerard Marull-Paretas <gerard@teslabs.com>
2022-10-13 16:03:49 +09:00
Chris Duf
5abce9b8ec Devicetree: edtlib: fix possible KeyError in Binding.description
Attempting to access the Binding.description property
when the description is unavailable would raise KeyError: 'description'.

Known bindings that won't define a 'description' key in the
Binding.raw dictionary include the 'compatible' property's binding
of nodes such as /, /soc, /leds or /pwmleds.
Note that this may also occur when a proper YAML
binding file is available (e.g. pwmleds.yaml).

This patch simply substitutes the Binding.raw dictionary indexing
with the get() function: will return None and not raise KeyError.

Signed-off-by: Chris Duf <chris@openmarl.org>
2022-10-12 18:45:32 +09:00
Maureen Helm
e73c363346 scripts: edtlib: gen_defines: Add model name macros based on compat
Follow up to 5b5aa6ebba adding model name
and existence macros for all compatibles of a node that match an entry
in vendor prefixes.

Signed-off-by: Maureen Helm <maureen.helm@intel.com>
2022-10-07 11:48:02 -07:00
Gerard Marull-Paretas
fdea3c9a44 devicetree: add DT(_INST)_FOREACH_PROP_ELEM_SEP(_VARGS)
Add a new set of helpers for expanding property entries with a
separator. These macros complement DT(_INST)FOREACH_PROP_ELEM(_VARGS) by
adding the capability to expand with a custom separator between property
entries. This allows, in some cases, to re-use existing macros (e.g.
DT_PROP_BY_IDX) without creating an auxiliary macro that just appends a
separator. Example:

```dts
n: node {
	...
	my-gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>,
		   <&gpiob 1 GPIO_ACTIVE_HIGH>;
};
```

Before:

```c
 #define GPIO_DT_SPEC_BY_IDX_AND_COMMA(node_id, prop, idx) \
	GPIO_DT_SPEC_BY_IDX(node_id, prop, idx),

struct gpio_dt_spec specs[] = {
	DT_FOREACH_PROP_ELEM(DT_NODELABEL(n), my_gpios,
			     GPIO_DT_SPEC_BY_IDX_AND_COMMA)
};
```

After:

```c
struct gpio_dt_spec specs[] = {
	DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(n), my_gpios,
				 GPIO_DT_SPEC_BY_IDX, (,))
};
```

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-10-03 10:11:18 +02:00
Martí Bolívar
22012894c0 dtlib: error out on duplicate node names
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>
2022-09-21 07:55:40 -07:00
Daniel Leung
418c915f1b dts: add primitive support for multi-bus in bindings
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>
2022-09-09 17:42:33 -04:00
Martí Bolívar
7ef9c4b20e edtlib: remove python 3.5 workaround
Remove a yaml monkeypatch. It is no longer needed since we support 3.6
or later on Zephyr v2.7 LTS and 3.8 or later on what will become v3.2.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
2022-09-07 15:38:26 +02:00
Maureen Helm
5b5aa6ebba scripts: gen_defines: Add vendor name macros based on vendor prefixes
Adds vendor name and existence macros for all compatibles of a node that
match an entry in the vendor prefixes file.

Signed-off-by: Maureen Helm <maureen.helm@intel.com>
2022-09-01 14:53:55 -07:00
Maureen Helm
a1b0c39c37 scripts: edtlib: Add compat2vendor LUT constructed from vendor prefixes
Adds a new compat2vendor lookup table that maps compatibles to vendor
names, constructed from the vendor prefixes file. This approach is a
more scalable alternative to adding a vendor name property to devicetree
bindings, as was previously proposed.

Signed-off-by: Maureen Helm <maureen.helm@intel.com>
2022-09-01 14:53:55 -07:00
Gerard Marull-Paretas
fff9ecbc7f devicetree: add DT_(INST_)FOREACH_CHILD(_STATUS_OKAY)_SEP(_VARGS)
It is frequent to see in Devicetree code constructs like:

```c
 #define NAME_AND_COMMA(node_id) DT_NODE_FULL_NAME(node_id),

const char *child_names[] = {
	DT_FOREACH_CHILD(DT_NODELABEL(n), NAME_AND_COMMA)
};
```

That is, an auxiliary macro to append a separator character in
DT_FOREACH* macros. Non-DT API, e.g. FOR_EACH(), takes a separator
argument to avoid such intermediate macros.

This patch adds DT_FOREACH_CHILD_SEP (and instance/status okay/vargs
versions of it). They all take an extra argument: a separator. With this
change, the example above can be simplified to:

```c
const char *child_labels[] = {
	DT_FOREACH_CHILD(DT_NODELABEL(n), DT_NODE_FULL_NAME, (,))
};
```

Notes:
- Other DT_FOREACH* macros could/should be extended as well

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-08-30 16:19:57 +02:00
Gerard Marull-Paretas
d77f4e61de scripts: dts: gen_defines: add DT_DEBRACKET_INTERNAL helper
Add a utility macro used to remove brackets from around a single
argument. While __DEBRACKET exists in util_internal.h, this change makes
DT independent (otherwise we should include util_internal.h, which is
another option).

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-08-30 16:19:57 +02:00