-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
scripts: extract_dts_includes: Add simple defines for i2c/spi children #11886
Conversation
Here's a WIP commit to add generation of the defines for SPI & I2C devices. This is in relationship to the discussion in #11737 |
@pabigot patch needs cleaning up, better comments, etc. But it should at least accomplish the job on the generation side. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have absolutely no idea how these changes do what they do, but the generated_dts_board.h
looks right. Thanks!
Codecov Report
@@ Coverage Diff @@
## master #11886 +/- ##
=======================================
Coverage 48.27% 48.27%
=======================================
Files 295 295
Lines 44281 44281
Branches 10601 10601
=======================================
Hits 21376 21376
Misses 18636 18636
Partials 4269 4269 Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine to me, but maybe could be used to address my concern about #11854: we miss a way to instruct, with info coming from dts/bindings, if driver should be compiled with SPI or I2C version.
Since we don't need to care about sensor instance yet, it could be a boolean like:
#define DT_AMS_CCS811_BUS_I2C/SPI 1
So sensor driver could be compiled either for I2C or SPI variant.
I would like to review this PR, please give me some time to do it. |
@erwango agreed; that's what was proposed when we talked. It's not required for my short-term needs but for completeness it should be there if it's easy to do. |
This feels like we start going down the rabbit hole. It's a relatively dirty hack on top of another relatively dirty hack (the decorated alias defines). And it's likely going to be difficult to untangle it later. What's stopping us from providing a clean solution? |
I'm not sure what a "clean solution" is and if other people have an idea there's certainly no consensus on it. So that's stopping us. I don't see this as breaking anything that's already in master: it adds some defines to the generated header. If it, after being augmented with the ability to determine parent bus, gets merged then I can convert some sensor drivers to something closer to the goal state: device instances tied to configuration object instances, manually populated now but ultimately done automatically. In those PRs people would have a chance to see what it would look like eventually, which is really hard to perceive at this state. If there isn't consensus that this is an improvement, then the extra defines can be dropped and another approach tried. |
This is entirely decoupled from |
The cleaner solution is code generation, but that will be post 1.14. We need something simpler than the full code generation solution for 1.14 that makes it so that dts_fixup.h isn't need for a I2C/SPI client drivers. Since all the I2C/SPI client drivers only handle single instances figured this was a reasonable stop-gap. I'm open to any other ideas on how to not require modifications to dts_fixup.h for the I2C/SPI client drivers. |
@pabigot can you look at tests/drivers/i2c/i2c_slave_api. Seems like we have a case of 2 of the same device. |
@galak indeed, two instances of the same EEPROM on different buses. They happen to have different addresses too, but that's not a reliable distinguisher. This is the case we didn't think we had to handle. It works today because they have different If the only instance of problem is in test code we could work around it. One approach is to detect the collision and, if one exists, emit a diagnostic and drop both alias names, requiring the implementation to use the full identifiers. To do that you'd need an alias dictionary that covered all nodes. It might be worth having that anyway, as getting the diagnostic from the generator could be more informative than "redefined macro" at compile time. If we're not willing to work around it, then |
I have no issue if you want to figure out a working around in the sample. |
I could do that to the test case but the only way is to make the devices have different compatibility strings. Then I'd have to change my review to reject the patch because it's a valid test providing circumstantial evidence that multiple instances of the same device on different buses is a real thing. If we merged the change the diagnostic would just show up on those applications when their maintainers updated Zephyr. My Python skills are rusty and I don't understand the extract scripts well enough to implement the global registry prefix deconflict workaround instead. So it looks like relying on
and tacking on yet another just to get:
is gross so I'd probably just use the old alias prefix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Further experimentation suggests this approach is not unique, and has a good chance of breaking existing applications without significant work described in other comments.
That's the main problem with this PR, we're going for a quick win without working out the concept. Even if this PR worked it would introduce inconsistency. A few more PRs like this one and soon no one would understand which defines are generated when and what for. And DTS is a critical part of the infrastructure.
This PR is (re-)using part of the code which is responsible for generating aliases, i.e. it's relying on the fact that defines generated for aliases are prefixed with compatible string. If we changed that this PR would break. |
I don't disagree. Lacking sufficient information on the detailed design for code generation my goal is short-term relief of the dts_fixup pain we're already experiencing, so at least we get some shared experience with where we're heading before the tooling shows up.
No, this PR proposed adding a third prefix that did not include alias, just compatible. Since it won't work, we'd have to fall back to one of the two solutions that are already in the baseline: the legacy alias-only prefix that doesn't include |
336f31c
to
4c4157b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dislike the re-use here of cell-index
, which is a non-standard property still used in Linux primarily in Freescale device tree bindings, serving a poorly defined and possibly inconsistent role. Its use here to identify a device instance is too opaque. Use a property name that makes sense, like device-instance
, or one that's clearly documented somewhere official to provide the information that's needed (if such a property exists).
Support for multiple instances should be consistent, not added in an ad-hoc manner to specific devices based on whether we've seen more than one instance. Whatever property name is used it should default to zero, be present in the base device YAML file rather than added only to specific devices, and the generated symbols should always include the device instance.
I'm growing even more sympathetic with @mnkp's comment that we "keep going for a quick win without working out the concept". I don't like this "let's try this; no that doesn't work, how about this" development model. All of this should have been thought through before it started getting merged, or if that wasn't possible there should have been a commitment to and programmatic oversight of rapid evolution to an acceptable long-term solution.
On that basis, I'm inclined to stop trying to fix things and just live with the dts_fixup.h
files, disgusting as they are. At this time I won't approve or reject this, but will leave it to others to comment to see if a consensus can emerge.
scripts/dts/extract/globals.py
Outdated
dash = '' | ||
new_alias_label = new_alias_prefix + dash + old_alias_label | ||
print(reduced[node_address]['props']) | ||
cell_index = reduced[node_address]['props'].get('cell-index') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should default to 0 so that if a device (like eeprom) that supports multiple instances is used on a board that only populates one instance we don't have to fuss with mapping the unqualified names to the ones suffixed by the instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What exactly do you mean by default to 0. Are you saying that for cell-index 0 we should NOT do 0 in the defines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean move the property to the SPI and I2C base YAML descriptions, and either make it required so people have to specify the instance number, or allow absence of an instance to behave as if it was provided with a value 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, will add cell-index to the i2c-device & spi-device yaml files. That makes sense to me. If there is something more than that let me know.
4c4157b
to
a9636c6
Compare
The time for LTS, the clean solution is code generation that removes the need for the define generation and fixups. However we want to put something in place for the LTS/1.14 release. I agree this is paper taping over the issue. |
@erwango can you review this again. I want some solution for this release until we move to code gen after. |
a9636c6
to
62f976c
Compare
Add zephyr,index property for the rare cases that we have more than one instance of a device and can't distinquish it. We intend to only use this for end point devices not part of the SoC itself. Currently most drivers in Zephyr for SPI or I2C sensors don't support multiple instances, so this should rarely be used. Signed-off-by: Kumar Gala <[email protected]>
The dts overlay's introduce multiple i2c,eeprom on the same bus. We should use zephyr,index to allow enumeration of the instances. Signed-off-by: Kumar Gala <[email protected]>
To simply and reduce what one has to do in a fixup file for i2c & spi devices, we generate aliased defines based on just the compatible name. For the rare case that a driver supports more than one instance, than the 'zephyr,index' property should be utilized to tell the instances apart. Signed-off-by: Kumar Gala <[email protected]>
62f976c
to
651eb8e
Compare
If we are talking about creating defines following the pattern
that's actually a very interesting proposal. It's scalable, consistent and not that much different to how binary blobs work. I believe we do not need to introduce Such defines could also be used by SoC drivers. We know that at the moment we misuse aliases. With the above approach we wouldn't need to. One difference to our current way of working with DT is that it will not be possible any more to enable driver instances in Kconfig since there will be no direct relation between instance number as defined in datasheet and the define generated for this instance. This is actually for the better. |
This would have to be done very carefully to be robust in the case of somebody refactoring the device-tree source, e.g. moving the include for an overlay that describes one instance above or below a node that describes another instance. The instance number really should be explicit, with a default of 0 inferred when the corresponding property is absent which will be the most common case for SPI/I2C peripherals. We can also bike-shed the property name; I don't like |
Curious, why would moving / refactoring the DTS source impact what the ID was?
If I understand what @mnkp is suggesting, that we just enumerate the instances of a given compatible starting at 0. Let's say there are 3 instances for "i2c,eeprom". It should not mater which of those instances is 0, 1, or 2. Is there some case you can think of where it would mater?
Yeah, I'm open to whatever we want to call it if we go this direction. |
I can't think of a case where it wouldn't, unless there's some other indicator I can use in applications and board setup to determine which instance I'm using for a given operation. I am assuming that part of the product of this scheme would be For EEPROM, I might have a 4 kb one for configuration data, and a 64 Mb one for logs. For sensors I might have one that's on the board, and one that's connected through a cable. In either case, they are not interchangeable. Am I missing something here? |
zephyr,index: | ||
type: int | ||
category: optional | ||
description: Instance ID (Start at 0, used if system has more than one) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess starting at 0 is not mandatory, is it?
I'm fine with the change as it is. I don't think we should enumerate available instances because index should not be changed if .dts is reorganised (first instance in the file would get _0 while I expected _1 in my code) or as mentioned by @pabigot some overlay is used or not. |
I've been a bit fast on the approval: I've one minor concern which is is the constraint on numbering. |
Are we mixing how an application determines which device instance it wants from how a driver instantiates those instances? Let's use an example with the eeprom so we are talking about something concrete: Here's what the DTS would look like:
Here's what we'd generate:
Driver would look like:
Your application would do something like:
|
If in my example the generator looks like this: (change which instance was 0 and 1)
The driver code and application code stays identical and things work exactly the same. |
@galak was faster providing the code sample. I'll repeat the same in words (since I already wrote it). If we follow approach Since the application gets handle to the driver instance via _LABEL property it is always able to get the specific instance it needs. |
what do you mean by constraint on numbering? |
@galak you're right; I've been working from an idiom where I identified resources based on aliases, so I'd have done:
and referenced it by So I agree there's no reason to try to make sure the instance number is persistent. Then it isn't clear why we'd need an instance number in the bindings (source) at all so we might as well get rid of Unless I'm also wrong about #12226 (comment), though, we should try to avoid the concern described there ( |
Seems I was confused as well between application and driver. You and @mnkp made it clear now. |
Agreed, we don't need an explicit index
Agreed. |
Agreed, regardless of the number of instances, we would always just have |
So does it mean that all current bus slaves drivers should be reworked to use _0 instance then? |
I think "yes". When this is available I'll update #11977 so we can see how it looks in a couple cases before going through and updating everything. |
cc @anangl |
I pushed a new PR with the solution discussed here. The new PR is #12426. |
To simply and reduce what one has to do in a fixup file for i2c & spi
devices, we generate aliased defines based on just the compatible name.
For now we make the assumption that there is only one sensor of a given
compatible in the system (which is how all I2C & SPI client drivers are
currently).
Signed-off-by: Kumar Gala [email protected]