Commit Graph

334 Commits

Author SHA1 Message Date
Ulf Magnusson 4c6ea2d160 scripts: edtlib: Skip fully loading bindings in more cases
As a slightly hairy but important optimization inherited from the old
scripts, the binding loading code only looks at binding files whose raw
text contains one of the compatible strings from the devicetree. For
such files, a second pass parses the file as YAML and tries to extract a
compatible string, and skips the file if it fails (e.g. due to spurious
text matches in 'include'd binding fragments).

Until now, the binding would always get fully loaded (have 'include'd
files merged in, checks run, etc.) if the second pass managed to extract
a compatible.

Do slightly better by only fully loading the binding if the extracted
compatible from the second pass appears in the devicetree. This gets rid
of unnecessary binding loading in rare cases.

Discovered by test-bindings/deprecated.yaml getting loaded even when
everything that referenced it in test.dts was commented out, because it
happened to mention 'child-binding' in a comment.

Also add a check for YAML errors in the second pass, to be slightly more
robust. Print a warning if a file that isn't valid YAML is found.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-22 09:17:53 -05:00
Ulf Magnusson 110526ec0e scripts: edtlib: Add a Device.children attribute with child Devices
API oversight. This was meant to be there all along together with
Device.parent, for navigating the devicetree, but since a need for it
never came up in gen_defines.py, it got overlooked.

Devices are just devicetree nodes augmented with binding information and
some interpretation of devicetree properties. I wonder if the name
should be changed to something like edtlib.Node to make that clearer.
Calling something like a flash partition a "device" is a bit weird, as
Galak pointed out.

I think I went with Device originally to avoid confusion with
dtlib.Node, but since edtlib users don't directly interact with dtlib,
it might not be that confusing in practice.

Piggyback some documentation clarifications.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-21 09:10:36 -05:00
Ulf Magnusson 2f2642d5f6 scripts: testedtlib.py: Generate SystemExit on test failures
The devicetree check in check_compliance.py in ci-tools expects the
dtlib/edtlib test suites to exit with sys.exit() (which raises
SystemExit) on test failures, and interprets Exception as an internal
error in the test suite.

testedtlib.py accidentally raised Exception on test failures, making
check_compliance.py error out and skipping the rest of the tests when
there were failures. Fix it.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-21 09:08:56 -05:00
Ulf Magnusson 0b1ab4ab09 scripts: dts: Replace 'sub-node:' with more general 'child-binding:'
Deprecate 'sub-node:' and add a more general 'child-binding:' mechanism
to bindings. Keep supporting 'sub-node:', but print a deprecation
warning when it's used.

Like 'sub-node:', 'child-binding:' gives a binding to child nodes, but
the binding is required to be a complete binding, and is treated (and
checked) like a normal binding.

'child-binding:' can in turn contain another 'child-binding:', up to any
number of levels. This is automatic from treating it like a normal
binding, and from the code initializing parent Devices before child
Devices.

This lets nodes give bindings to grandchildren.

For example, take this devicetree fragment:

    parent {
            compatible = "foo";
            child-1 {
                    grandchild-1 {
                            ...
                    };
                    grandchild-2 {
                            ...
                    };
            };
            child-2 {
                    grandchild-3 {
                            ...
                    };
            };
    };

The binding for 'foo' could provide bindings for grandchild-1/2/3 like
this:

    compatible: "foo"

    # Binding for children
    child-binding:
        title: ...
        description: ...

        ...

        # Binding for grandchildren
        child-binding:
            title: ...
            description: ...

            properties:
                ...

Due to implementation issues with the old devicetree scripts, only two
levels of 'child-binding:' is supported for now. This limitation will go
away in Zephyr 2.2.

Piggyback shortening 'description:' and 'title:' in some bindings that
provide child bindings. This makes the generated header a bit neater.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-19 08:39:22 -05:00
Ulf Magnusson 1ebe945643 scripts: dts: Change 'child/parent: bus: ...' to 'child/parent-bus:'
Instead of

    child:
        bus: foo

    parent:
        bus: bar

, have

    child-bus: foo

    parent-bus: bar

'bus' is the only key that ever appears under 'child' and 'parent'.

Support the old keys for backwards compatibility, with a deprecation
warning if they're used.

Also add 'child/parent-bus' tests to the edtlib test suite. It was
untested before.

I also considered putting more stuff under 'child' and 'parent', but
there's not much point when there's just a few keys I think. Top-level
stuff is cleaner and easier to read.

I'm planning to add a 'child-binding' key a bit later (like 'sub-node',
but more flexible), and child-* is consistent with that.

Also add an unrelated test-bindings/grandchild-3.yaml that was
accidentally left out earlier.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-17 14:37:43 -05:00
Kumar Gala 8ce0cf0126 kconfig: Convert device tree chosen properties to new kconfigfunctions
Convert how we get the various chosen properties like "zephyr,console"
to use the new kconfig functions like dt_chosen_to_label.

Because of how kconfig parses things we define a set of variables of the
form DT_CHOSEN_Z_<PROP> since comma's are parsed as field seperators in
macros.

This conversion allows us to remove code in gen_defines.py for the
following chosen properties:

zephyr,console
zephyr,shell-uart
zephyr,bt-uart
zephyr,uart-pipe
zephyr,bt-mon-uart
zephyr,uart-mcumgr
zephyr,bt-c2h-uart

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2019-09-13 11:42:34 -05:00
Peter A. Bigot be2a885d42 scripts/dts/gen_defines.py: exclude initializer lists from conf file
Things that parse generated_dts_board.conf can't deal with entries
like:

    DT_GPIO_KEYS_BUTTON_1_GPIOS={"GPIO_0", 14, 256}

so keep them from being added there.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
2019-09-12 15:51:08 -05:00
Peter A. Bigot f62ae3e8ef scripts/dts/gen_defines.py: generate initializers for phandle/val lists
When a phandle-array (compound) has multiple members generate a define
that says how many there are; generate an initializer for each
individual member; and generate an initializer for the sequence of
members.

This allows drivers that expect multiple values in a compound to process
them without horrendous conditional compilation code attempting to
detect the number of elements in the compound.

It also eliminates the need to repeat the long prefix when initializing
a structure with the fields of a single compound.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
2019-09-12 13:31:48 -05:00
Peter A. Bigot 392845b13f scripts/dts/gen_defines.py: return macro identifier in out functions
The lowest level output function is the one that determines the full
name of the macro, including DT_ prefix.  Return the name of the macro
that provides the value for an identifier so that it can be used in
higher layers of the generator.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
2019-09-12 13:31:48 -05:00
Peter A. Bigot e9a173120f scripts/dts/gen_defines.py: generalize string escape
Add str2str to make the conversion of a string into a C literal with all
necessary escapes and enclosing double quotes available outside a
function that emits a define.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
2019-09-12 13:31:48 -05:00
Ulf Magnusson 2845d8f404 scripts: edtlib: Make order irrelevant when including multiple files
When foo.yaml set some property 'required: true' and bar.yaml set the
same property 'required: false', the check for changing
'required: false' to 'required: true' would raise an error for

    include: [bar.yaml, foo.yaml]

(with that particular order due to implementation details).

The order files are included in shouldn't matter. To fix it, change the
logic so that 'required' values are ORed together between included files
(so that 'required: true' is always respected), and remove the
'required' true-to-false check when merging included files.

Keep the true-to-false check when merging the (merged) included files
into the main binding (the binding with the 'include:' in it). This
might give a good organization, and the old scripts do it too.

Piggyback two fixes/cleanups:

 - 'compatible' should be allowed to appear in included files

 - No need to allow an 'inherits' key in _check_binding(), because
   it has been removed before then, when merging bindings

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-11 07:50:30 -05:00
Ulf Magnusson a5f4ad8df3 scripts: dts: Fix wrong filename in 'include:' code in old scripts
The 'fname' parameter to merge_included_bindings(), giving the path to
the top-level binding file, was accidentally shadowed in the
'for fname in fnames:' loop. This could lead to the wrong filename being
used in error messages.

Discovered via this pylint warning:

    scripts/dts/extract_dts_includes.py:225:12: R1704: Redefining
    argument with the local name 'fname' (redefined-argument-from-local)

Improve naming a bit to fix it.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-10 11:34:03 -05:00
Ulf Magnusson b918e25921 dts: scripts: Require properties to be declared in bindings
Except for a few special properties like 'interrupts' and '#size-cells',
require all devicetree properties on nodes with bindings to be declared
in the binding.

This will help catch misspellings, and makes refactoring and cleanups
safer.

Suggested by Peter A. Bigot.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-10 07:42:02 -05:00
Kumar Gala c16537fbde scripts/dts: Generate IRQ values for multi-level IRQs
When we have multi-level (ie chained interrupt controllers) Zephyr has a
schemee to encode the multi-level and IRQ values along the level's into
a single 32-bit value.  This is the "IRQ" value expected by Zephyr APIs.

The encoding scheme is documented here:

doc/reference/kernel/other/interrupts.rst

Update the device tree generation to walk the interrupt levels and
generate the expected encoded value for the IRQ.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2019-09-10 07:34:57 -05:00
Olle Norelius 5a53e21966 scripts: dts: Fix generation of single-value phandle/value array
Put a type check in the offending method.
Now any scalar will be put in a list for
compatibility with following code.

Signed-off-by: Olle Norelius <norelius.olle@gmail.com>
2019-09-09 14:15:44 -05:00
Ulf Magnusson ff1f75293e dts: edtlib: Support giving missing properties a default value
For missing optional properties, it can be handy to generate a default
value instead of no value, to cut down on #ifdefs.

Allow a default value to be specified in the binding, via a new
'default: <default value>' setting for properties in bindings.
Defaults are supported for both scalar and array types. YAML arrays are
used to specify the value for array types.

'default:' also appears in json-schema, with the same meaning.

Include misc. sanity checks, like the 'default' value matching 'type'.

The documentation changes in binding-template.yaml explain the syntax.

Suggested by Peter A. Bigot in
https://github.com/zephyrproject-rtos/zephyr/issues/17829.

Fixes: #17829
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-09 08:47:49 -05:00
Ulf Magnusson a0fceff1a2 scripts: dts: Simplify and improve 'compatible' matching
Instead of

    properties:
        compatible:
            constraint: "foo"

, just have

    compatible: "foo"

at the top level of the binding.

For backwards compatibility, the old 'properties: compatible: ...' form
is still accepted for now, and is treated the same as a single-element
'compatible:'.

The old syntax was inspired by dt-schema (though it isn't
dt-schema-compatible), which is in turn a thin wrapper around
json-schema (the idea is to transform .dts files into YAML and then
verify them).

Maybe the idea was to gradually switch the syntax over to dt-schema and
then be able to use unmodified dt-schema bindings, but dt-schema is
really a different kind of tool (a completely standalone linter), and
works very differently from our stuff (see schemas/dt-core.yaml in the
dt-schema repo to get an idea of just how differently).

Better to keep it simple.

This commit also piggybacks some clarifications to the binding template
re. '#cells:'.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 1467480491 scripts: dts: Replace bare 'except's in old scripts
A bare 'except:' can do some annoying stuff like eat Ctrl-C (because it
catches KeyboardInterrupt). Better to use 'except Exception:' as a
catch-all.

Even better might be to catch some more specific exception, because even
'except Exception:' eats stuff like misspelled identifiers.

Fixes this pylint warning:

    W0702: No exception type(s) specified (bare-except)

Fixing pylint warnings for a CI check.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson cff38cf0ef scripts: edtlib: Fix bad block indentation
Reported by pylint.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 8f22529e74 scripts: edtlib: Make _binding_include() global to fix pylint warning
Doesn't use 'self'. Fixes this pylint warning:

    scripts/dts/edtlib.py:272:4: R0201: Method could be a function
    (no-self-use)

Fixing pylint warnings for a CI check.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 8d317bc665 scripts: edtlib: Add backwards compatibility for 'category:'
Having backwards compatibility for !include and 'constraint:' is silly
without also having backwards compatibility for 'category:', because
that forces a binding change anyway.

Add backwards compatibility for 'category:', and just print a
deprecation warning when it's used.

Also move tests for deprecated features into a dedicated
test-bindings/deprecated.yaml binding, instead of piggybacking on other
tests.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson ba76b82f5a scripts: dtlib: Suppress _init_tokens() pylint warning
Suppress this pylint warning so that it can be enabled in the upcoming
CI check. The code is safe.

    scripts/dts/dtlib.py:1904:13: W0631: Using possibly undefined loop
    variable 'i' (undefined-loop-variable)

Also add some more comments to clarify _init_tokens().

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson a67eb7825a scripts: dts: Remove unused variable in old scripts
Detected by pylint. Getting rid of pylint warnings for a CI check.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson c1f6fe85f7 scripts: dts: devicetree.py: Fix pylint warning for iffy \w escape
"\w" gives a two-character string, but is iffy, because it relies on \w
not being defined as an escape sequence. r"\w" is better.

Fixes this pylint warning:

    scripts/dts/devicetree.py:134:0: W1401: Anomalous backslash in
    string: '\w'. String constant might be missing an r prefix.
    (anomalous-backslash-in-string)

Wondering if I should exclude the old DTS scripts from the pylint CI
check, but doesn't hurt to fix it at least.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 6c6336af11 scripts: dtlib: Refactor to fix two no-self-use pylint warnings
Move some property fetching and node deletion code from the DT class
over to the Node class. Reads pretty nicely, and indirectly gets rid of
two unused 'self' arguments.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 88c5079a87 scripts: dts: Fix misc. pylint warnings in old scripts
Fix pylint warnings for bad indent, redundant len()s in conditionals,
tests that could be improved with 'in', methods that don't use 'self',
and type()s where isinstance() is more common.

Preparation for adding a CI check.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson d834b69bd9 scripts: dts: Improve syntax and code for including binding files
Have

    include: foo.dts
    include: [foo.dts, bar.dts]

instead of

    inherits:
        !include foo.dts

    inherits:
        !include [foo.dts, bar.dts]

This is a nicer and shorter and less cryptic syntax, and will make it
possible to get rid of the custom PyYAML constructor for '!include'
later.

'inherits: !include ...' is still supported for backwards compatibility
for now. Later on, I'm planning to mass-replace it, add a deprecation
warning if it's used, and document 'include:'. Then the '!include'
implementation can be removed a bit later.

'!include' has caused issues in the past (see the comment above the
add_constructor() call), gets iffy with multiple EDT instances, and
makes the code harder to follow.

I'm guessing '!include' might've been intended to be useful outside of
'inherits:' originally, but that's the only place where it's used. It's
undocumented that it's possible to put it elsewhere.

To implement the backwards compatibility, the code just transforms

    inherits:
        !include foo.dts

into

    inherits:
        - foo.dts

and treats 'inherits:' similarly to 'include:'. Previously, !include
inserted the contents of the included file instead.

Some more sanity checks for 'include:'/'inherits:' are included as well.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson fcd665a26c dts: bindings: Have 'required: true/false' instead of 'category: ...'
The 'category: required/optional' setting for properties is just a
yes/no thing. Using a boolean makes it clearer, so have
'required: true/false' instead.

Print a clear error when 'category:' is used:

    edtlib.EDTError: please put 'required: true' instead of 'category:
    required' in 'properties: foo: ...' in
    test-bindings/sub-node-parent.yaml - 'category' has been removed

The old scripts in scripts/dts/ ignore this setting, and only print a
warning if 'category: required' in an inherited binding is changed to
'category: optional'. Remove that code, since the new scripts already
have the same check.

The replacement was done with

    git ls-files 'dts/bindings/*.yaml' | xargs sed -i \
        -e 's/category:\s*required/required: true/' \
        -e 's/category:\s*optional/required: false/'

dts/binding-template.yaml is updated as well.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 929837a35f scripts: dtlib: Add test for untested /memreserve/ error
Also simplify the /memreserve/ code a biny bit and convert spaces to
tabs in a testcase.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 247ae982ed dts: gen_defines: Remove lots of code duplication for phandle/val lists
Add a write_phandle_val_list() function for handling GPIOs, PWMs, and IO
channels. The logic is the same in all cases.

This also indirectly makes pwm-names and io-channel-names work the same
as gpio-names. Previously, they were ignored.

Also add a long explanation with example output.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 14138c3b9b dts: edtlib: Improve how we get the compatible string from bindings
Use Galak's idea from
https://github.com/zephyrproject-rtos/zephyr/pull/18313 to read the
'properties: compatible: constraint: "foo"' string from bindings in a
more robust way.

First, check if any of the compatible strings are in the file (needed as
an optimization). If any of them are, do a more careful check for the
'properties: compatible: constraint: ...' value matching a compatible,
to filter out false positives from comments and the like.

This commit a no-op in itself besides making things a bit more robust,
but it'll make later work easier (supporting multiple compatibles for a
binding, in a dt-schema-like way).

Co-authored-by: Kumar Gala <kumar.gala@linaro.org>
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 1480ad9ce7 dts: edtlib: Sanity-check the final merged binding only
Sanity-checking each !included file separately was inherited from the
old scripts. It makes it messy to check that combinations of fields make
sense, e.g. to check 'const:' or 'default:' against 'type:', since those
fields might come from different files (this is handy, since it makes
sense to just add/change a 'const:' value, for example).

Drop the requirement that each !included file is a complete binding in
itself, and treat them as binding fragments instead. Only check the
final merged binding.

This also means that !included files no longer need to have a
'description:' or 'title:' (those have always been unused for !included
files), so remove those, and add comments that explain what the
fragments are for instead. That should demystify bindings a bit.

Also fix the descriptions of i2c.yaml, i2s.yaml, spi.yaml, and
uart.yaml. They're for controllers, not devices. These are copy-paste
error from the corresponding device .yaml files.

Piggyback some indentation consistency nits in binding-template.yaml.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 73df9dea34 dts: dtlib: Add an _err() helper for error reporting
Similar to edtlib._err(). Just saves a bunch of 'raise DTError'.

Also add tests for some errors from the global to_num() and to_nums()
functions that were untested.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 2282777ad1 dts: dtlib: Refactor to get rid of _is_parsing flag
The public DT.get_node() function was used during parsing to look up
paths in references like &{/foo/bar}, along with an ugly
'DT._is_parsing' flag to adapt its behavior (to not mention aliases in
error messages).

Split out common node lookup code needed during parsing and by
get_node() instead, and stop using get_node() during parsing. This
allows '_is_parsing' to be removed and untangles things a bit.

Piggyback some other small reference-related cleanups, and fix an issue
with the filename/linenr being given twice in some error messages.

This commit also removes the index of path components from error
messages, but just the string is probably good enough.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson a9e8f1a96c dts: dtlib: Remove unused Property._err_with_context() function
Leftover.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 378254ad13 dts: edtlib: Sanity-check 'ranges' assignment syntax
Require either type TYPE_EMPTY ('ranges;') or TYPE_NUMS
('ranges = < 1 2 ... >;').

Putting the check in _check_dt() means it will run for all nodes,
including nodes without bindings, which is handy.

The _split() function already gives a decent error message if 'ranges'
has unexpected length, so skip checking the length.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 165dde0df4 dts: edtlib: Add a Property.type field
Deriving the type from looking at Property.val gets awkward e.g. when
there are many types that make Property.val a list. Instead, save the
type as given in the binding in Property.type.

Let Property.type just be a string. This has typo potential, but is nice
and flexible (and easy to print), and errors will probably be pretty
obvious.

Show the type in Property.__repr__() as well. This automatically gives
some test coverage.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson c42873fbe7 dts: dtlib/edtlib: Add phandle and phandle+nums array types
Add two new type-checked property types 'phandles' and 'phandle-array'
to edtlib.

'phandles' is for pure lists of phandles, with no other data, like

    foo = < &bar &baz ... >

'phandle-array' is for lists of phandles and (possibly) numbers, like

    foo = < &bar 1 2 &baz 3 4 ... >

dt-schema also has the 'phandle-array' type.

Property.val (in edtlib) is set to an array of Device objects for the
'phandles' type.

For the 'phandle-array' type, no Property object is created. This type
is only used for type checking.

Also refactor how types that do not create a Property object
('phandle-array' and 'compound') are handled. Have _prop_val() return
None for them.

The new types are implemented with two new TYPE_PHANDLES and
TYPE_PHANDLES_AND_NUMS types at the dtlib level. There is also a new
Property.to_nodes() functions for fetching the Nodes for an array of
phandles, with type checking.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 11019549bf dts: dtlib: Ignore manually specified phandles in type checking
Previously, Property.to_node() would allow assignments like

    x = < 1 >;

as long as 1 happened to be a valid phandle. This was deliberate, but
might hide errors, and would make the planned 'phandles' (list of
phandles) and 'phandle-array' (list of phandles and numbers) types a bit
too similar to 'type: array'.

Change Property.to_node() to only accept

    x = < &foo >;

This is probably all we need, and if you really need to accept manually
specified phandles, it can be worked around in other ways.

Piggyback some consistency nits in error messages from the
Property.to_*() functions.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson e703b4954a dts: edtlib: Sanity-check contents of 'sub-node:'
The contents of 'sub-node:' was assigned as-is as the binding, bypassing
_check_binding(). This also hid an error in
test-bindings/sub-node-parent.yaml.

Require 'sub-node:' to just have 'properties:' in it, and sanity-check
the properties like for regular bindings.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Kumar Gala f80332543e scripts/dts/gen_defines.py: Ignore varions base properties
We don't want any defines generated for 'status', 'interrupt-parent',
and 'interrupts-extended' properties.  So skip them in write_props if
we see them.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2019-09-07 10:25:02 -05:00
Kumar Gala 3d14374c5e scripts/dts/edtlib.py: add 'const' support to bindings
Add a 'const' property to bindings for any properties that are expected
to have a specifi known value.  For example, #address-cells for an I2C
bus should always be '1'.  So we can do something like the following in
the I2C bus binding:

    "#address-cells":
      type: int
      category: required
      const: 1

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Kumar Gala cd72ce122b scripts/dts/edtlib.py: error check enum
Make sure 'enum' is a list in the binding.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2019-09-07 10:25:02 -05:00
Kumar Gala 62bf267bb2 scripts/dts/edtlib.py: Hoist enum checking before early out
Move the enum checking before we early out for '#' and '-map' properties
so they can benefit from it.  Also make the error messages for failed
'enum' check more informative by including the paths to the .dts file
and the binding for the node.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 10:25:02 -05:00
Ulf Magnusson 4cac371d43 scripts: Suppress/fix undefined variable pylint warnings
dtlib.py and guiconfig.py do some hackery to build token and image
variable names, which triggers spurious pylint warnings like

    scripts/dts/dtlib.py:243:28: E0602: Undefined variable '_T_LABEL'
    (undefined-variable)

Suppress the warning for those files. The generated names get used in
lots of places.

Also suppress some warnings in doc/conf.py ('tags' is from Sphinx), and
fix a legitimate issue in scripts/dts/testdtlib.py.

This pylint check is useful enough to want enabled in the upcoming CI
check.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-09-07 08:03:04 -04:00
Kumar Gala a0a576d384 scripts/dts/gen_defines.py: Fix generation for multiple IO Channels
If there is more than one IO Channel than generate a define with a
trailing index for the IO Channel.  This matches what we do for GPIOs
and PWMs.

So something like:
  DT_FOOBAR_IO_CHANNELS_CONTROLLER_0
  DT_FOOBAR_IO_CHANNELS_CONTROLLER_1
  ...
  DT_FOOBAR_IO_CHANNELS_CONTROLLER_<N>

Fixes #18352

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2019-08-19 14:48:44 -05:00
Ulf Magnusson c2d702b961 dts: dtlib: Fix parsing of character literals
This was allowed due to a misunderstanding:

    foo = 'x';

In reality, 'x' works like an integer literal, and is used like this:

    foo = < 'x' >;

Fix character literal parsing to match the C tools.

Also fix backslash escape parsing to match the C tools exactly
(get_escape_char() in util.c): \<char> should be turned into <char> if
<char> isn't recognized as a special escape character, instead of being
left alone. This fixes parsing of e.g. '\'' (a character literal with a
single quote in it).

Piggyback some more tests for weird property/node names.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-08-13 07:41:45 -05:00
Ulf Magnusson 7168118290 dts: edtlib: Fix outdated doc comment for _init_devices()
No longer takes the DT instance as a parameter.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-08-13 07:41:45 -05:00
Ulf Magnusson 06b746cc58 dts: dtlib/edtlib: Add a syntax-based type-checking system
Property type-checking has been pretty rudimentary until now, only
checking things like the length being divisible by 4 for 'type: array',
and strings being null-terminated. In particular, no checking was done
for 'type: uint8-array', letting

  jedec-id = < 0xc8 0x28 0x17 >;

slip through when

  jedec-id = [ 0xc8 0x28 0x17 ];

was intended.

Fix it by adding a syntax-based type checker:

  1. Add Property.type, which gives a high-level type for the property,
     derived from the markers added in the previous commit.

     This includes types like TYPE_EMPTY ('foo;'),
     TYPE_NUM ('foo = < 3 >;'), TYPE_BYTES ('foo = [ 01 02 ];'),
     TYPE_STRINGS ('foo = "bar", "baz"'),
     TYPE_PHANDLE ('foo = < &bar >;'), and TYPE_COMPOUND (everything not
     recognized).

     See the Property.type docstring in dtlib for more info.

  2. Use the high-level type in
     Property.to_num()/to_string()/to_node()/etc. to verify that the
     property was assigned in an expected way for the type.

     If the assignment looks bad, give a helpful error:

       expected property 'nums' on /foo/bar in some.dts to be assigned
       with 'nums = < (number) (number) ... >', not 'nums = "oops";'

Some other related changes are included as well:

  - There's a new Property.to_bytes() function that works like accessing
    Property.bytes, except with an added check for the value being
    assigned like 'foo = [ ... ]'.

    This function solves problems like the jedec-id one.

  - There's a new Property.to_path() function for fetching the
    referenced node for assignments like 'foo = &node;', with type
    checking. (Strings are accepted too, as long as they give the path
    to an existing node.)

    This function is used for /chosen and /aliases.

  - A new 'type: phandle' type can now be given in bindings, for
    properties that are assigned like 'foo = < &node >;'.

  - Property.__str__() now displays phandles and path references as they
    were written (e.g. '< &foo >' instead of '< 0x1 >', if the
    allocated phandle happened to be 1).

  - Property.to_num() and Property.to_nums() no longer take a 'length'
    parameter, because it makes no sense with the type checking.

  - The global dtlib.to_string() and dtlib.to_strings() functions were
    removed, because they're not that useful.

  - More tests were added, along with misc. minor cleanup in various
    places.

  - Probably other stuff I forgot.

The more strict type checking in dtlib indirectly makes some parts of
edtlib more strict as well (wherever Property.to_*() is used).

Fixes: #18131

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-08-13 07:41:45 -05:00
Ulf Magnusson c9ac5e60e3 dts: dtlib: Remember the format of assignments
Previously, dtlib just stored the raw 'bytes' value for each property,
along with some markers in Property._markers for phandle and path
references.

Extend Property._markers to also remember where different data blocks
start, so that e.g.

    foo = <1 2 3>, "bar", [00 01];

can be reproduced as written.

Use the new information to reproduce properties as written in
Property.__str__(). This gives good test coverage as well, since the
test suite checks literal __str__() output.

Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
2019-08-13 07:41:45 -05:00