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>
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>
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>
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>
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>
We should only assume a GPIO specifier is either named <FOO>-gpios or
gpios. Any other form like ngpios should not be considered a GPIO
specifier. especially since 'ngpios' is the standard property name for
the number of gpio's that are implemented.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
--deprecate-only sounded like a command to "only deprecate (something)"
to me at first. --deprecated-only might make it clearer that it's about
only generating deprecated stuff.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
No binding has anything but 'version: 0.1', and the code in scripts/dts/
never does anything with it except print a warning if it isn't there.
It's undocumented what it means.
I suspect it's overkill if it's meant to be the binding format version.
If we'd need to tell different versions from each other, we could change
some other minor thing in the format, and it probably won't be needed.
Remove the 'version' fields from the bindings and the warning from the
scripts/dts/ scripts.
The new device tree script will give an error when unknown fields appear
in bindings.
The deletion was done with
git ls-files 'dts/bindings/*.yaml' | xargs sed -i '/^\s*version: /d'
Some blank lines at the beginning of bindings were removed as well.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
* Remove dead code that referenced 'generation' but didn't do anything
with it
* Replace looking at 'generation' with a simple check for property
starting with # (for things like #address-cells, etc) or ending in
-map (for things like gpio-map) to skip
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Now that we've converted LED and SW to use DT_ prefix we can mark the
non-DT_ prefixed versions as deprecated.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Now that we've converted all _GPIO_ to _GPIOS_ we can mark the _GPIO_
form as deprecated (same for _PWM_ / _PWMS_).
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Add support so that we can flag any "defines" associated with a call to
either extract_cells or extract_controller as deprecated.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
We have 'use-prop-name' flag in the bindings which is specifically used
for GPIO properties to control if we get "GPIO" or "GPIOS" as the
generated define name.
Lets remove the inconsistancy and use "GPIOS" as the preferred name as
this matches the DTS property name. Towards that we will generate both
forms and remove support for 'use-prop-name'.
This also impacts "PWM" generation. So we'll have "PWM" and "PWMS"
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Several bindings have an expectation of sub-nodes that describe the
actual infomation. The sub-nodes don't have any compatiable so we can't
key on that.
So we can add the concept of a sub-node to the YAML to handle cases like
'gpio-keys', 'gpio-leds', 'pwm-leds', etc..
The sub-node in the YAML is effective the "binding" params that describe
what properties should exist in the sub-node.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Found a few annoying typos and figured I better run script and
fix anything it can find, here are the results...
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Its possible that the <INSTANCE> number could conflict with the register
number. This is shown to happen for a device like soc-nv-flash at
address 0.
So change naming convention to DT_INST_<INSTANCE>_<COMPAT>_<PROP> and
make DT_<COMPAT>_<INSTANCE>_<PROP> as deprecated.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Because of how generate defines for instances its possible that we have
a name conflict if the instance ID and reg addr space clash.
For example on qemu_x86 there are current two 'soc-nv-flash' nodes and
one is at reg addr 0, but instance id 1, the other is reg addr 0x1000
and instance id 0. We'd possibly get this conflict:
For the 'soc-nv-flash' at 0x1000 (instance 0):
(instance define)
#define DT_SOC_NV_FLASH_0_BASE_ADDRESS 0x1000
For the 'soc-nv-flash' at 0x0 (instance 1):
(address define)
#define DT_SOC_NV_FLASH_0_BASE_ADDRESS 0x0
To deal with this we make sure that the lower reg address is instance 0,
than things work out ok. To handle this case, if we sort the instance
IDs based on reg addr than if we have something at reg addr 0, it will
also than be an instand ID 0.
The longer term solution will be to deprecated the old defines and
remove the conflict between instance ID defines and normal DT defines.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
We generated some alias defines for children of a bus in which we had a
path alias for the bus node. We never used these defines, we don't
recommend they get used (child of busses should use instance defines)
and they were only generated in small handful of cases (for dts that had
path aliases to the bus node - i2c or spi).
Remove this as effectively dead code.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
Allow a device tree node to be child on one bus and parent on another
bus (e.g. an I2C slave device with multiple sub-devices).
Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
Discovered with pylint3.
Use the placeholder name '_' for unproblematic unused variables. It's
what I'm used to, and pylint knows not to flag it.
Also improve the naming a bit in devicetree.py. If a key/value is known
to be a specific thing (like a node), then it's helpful to call it that
instead of something generic like "value".
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
- Remove DTFlash.extract(), which was just dispatching to either
_extract_flash() or _extract_code_partition() depending on which
magic string was passed in. Call them directly instead.
- Fold constant and globally available parameter values into functions
- Remove DTFlash._flash_node. It's easy to derive wherever it's needed,
and it makes it clearer where it comes from (and means functions can
be called in any order).
- Remove DTFlash._flash_base_address, which is unused
- Remove various unused parameters to functions
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
PyYAML 5.1 was just released and it doesn't support !include as
previous versions do. This breaks our DTS bindings parsing.
Let's fix our extract_dts_include.py script to work with both
3.13 and 5.1.
Also, update the pyyaml requirement to >=3.13 to be sure we're
compatible.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/14496
Signed-off-by: Michael Scott <mike@foundries.io>
To reproduce the issue this addresses, run "cmake -B96b_nitrogen"
twice with Python 3.5. Observe the order of the flash partition table
changing in:
"build{1,2}/zephyr/include/generated/generated_dts_board.conf" and
"generated_dts_board_unfixed.h"
Dictionaries are iterated in a random order by Python 3.5 and before.
This could have caused "Unstable" CI in PR #13921 and maybe others.
Anyway we want builds to be determimistic by default. Explicit
randomness can be added for better coverage but not by default.
Signed-off-by: Marc Herbert <marc.herbert@intel.com>
If a binding specifies 'generate: define' for 'interrupt-names' (like
some bindings do), then that ought to generate #defines for it, but the
scripts/dts code currently hardcodes 'interrupt-names' to be ignored
(along with some other properties).
Maybe the 'generate: define' in those bindings is a mistake, but the
code still ought to respect it. That also gets rid of some mystery code.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Add some short doc comments at the beginning so that people can quickly
get an idea of what they're about.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
It's confusing that "address" is often used within the same function to
refer to both node paths and e.g. address cells.
Make things easier to understand by calling /foo/bar a path instead.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
extract_property() is meant to generate #defines for a single property,
like 'foo = <1 2 3>'. Currently, it also generates node-level #defines
related to parent buses.
That makes the intent of the code hard to understand, and also means
that identical node-level #defines get redundantly added multiple times
(once per property).
Generate the node-level bus #defines before processing properties, in
generate_node_defines(). Use a new generate_bus_defines() helper.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Due to the way the code was structured,
flash.extract_partition(node_path) was called multiple times for the
same 'node_path'.
That must've been a mistake to begin with (but was hard to spot before
the code was cleaned up). Move the generation of per-node #defines out
of the property loop.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
generate_node_defines() immediately returns if the node's 'compatible'
is not in the binding.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Derive 'node_compat' and 'prop_val' (the dictionary for the property
from the YAML binding) inside extract_property().
That gives it just two parameters and makes it clearer that it's just
generating #define's for a single device tree property. 'prop_val' was
only used to look up prop_val['type'].
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Moves it closer to where it's used, and will allow other simplifications
in generate_node_defines().
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
After lots of reverse-engineering, I understand why deepcopy() is used:
1) Various functions defined in scripts/dts/extract/* modify the list
of names in-place
2) A plain list.copy() won't work when the *-names property happens to
have a single name in it, because devicetree.py gives a string
instead of a list in that case
Using deepcopy() to solve (2) is very confusing (especially with no
comments), because no deep copying is actually needed.
Get rid of deepcopy(), add a helper function for fetching the names, and
some comments.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Turn
if a:
if b:
...
into
if a and b:
...
Simplify some error messages with .format() as well, and get rid of some
redundant str()s. '{0} {1} {1}'.format('foo', 'bar') gives
'foo bar bar'.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
- Reduce the indentation and remove the awkward line breaks. This is
possible now that there's no recursion.
- Be consistent with quotes
- Move some initialization closer to where it's used
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
The recursion was used to implement 'properties:' within 'properties:'
in binding files, which seems to be a dead leftover (and undocumented).
Removing it gets rid of code and makes things more transparent.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Use more descriptive naming, get rid of unused 'v' variable, and an
unnecessary None check (None won't appear in get_binding_compats()).
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
...to generate_node_defines().
More explicit. "extract node include info" can be read in many ways:
- Extract a node's "include info"
- Extract node and include info
- etc.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
That way it consistently generates all #define's.
Add some related clarifying comments to main() too.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>