-
Notifications
You must be signed in to change notification settings - Fork 6.6k
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
DTS metadata should be made available to Kconfig #7302
Comments
Tentatively added assignees in order to get feedback from them. |
There's an upcoming Kconfig feature (that I've had some input in) that might come in handy here. It's a kind of simple preprocessor (that runs during parsing), where you can do stuff like this:
After expansion, that would turn into e.g.
Things then work like they usually do. It turns out that things get super complex if you don't limit it to a simple preprocessor. It would also support a I'm waiting for it to get added to the C tools before I add it to Kconfiglib. We've been arguing some details. |
Is there an RFC or similair for this? I'm not too worried about the mechanism for injecting DTS symbols into Kconfig. That seems trivial to me, the biggest effort is going to be porting DTS sources to not rely on Kconfig as it does today. That effort is so large, that there must be broad agreement that this makes sense. If not we are just going to have to accept and work-around that Kconfig can not configure based on information in DTS. Workarounds could include; Keep information that we want Kconfig to have access to out of DTS sources (limit the scope of DTS). |
@SebastianBoe , can we consider shield case (#6837, even if not merged yet) in this discussion, where a Kconfig value that enable use of a particular shield (CONFIG_SHIELD_XXX=y) adds shield.overlay to board dts file ? |
The shield use-case will not be possible as it is implemented today. In the new architecture one would have to use another mechanism than Kconfig to attach shield description's to board descriptions. |
@SebastianBoe |
This issue re-appeared when @b0661 tried to use device tree data in #5799. When device tree is placed after Kconfig everything becomes backwards. Instead of using Device Tree to describe hardware, and Kconfig to configure SW we end up doing the opposite. E.g. an SoC might use KConfig to declare that SPI is supported CONFIG_SPI=y and an application might use a Device tree overlay to prune the SPI driver. I'm not able to describe this properly, but I'm convinced that there is something seriously wrong with IMHO we need to figure out what we are doing (by resolving #7230) and then figure out what we want to do. I suspect that we need to be more strict about what we put in DT. It is difficult to be sure, because it is difficult to understand what we are doing right now, but I suspect that if we use DeviceTree as a description language and Kconfig as a configuration language we will end up with a simpler |
Device Tree proposes a specification to describe hardware and is used in variety of projects (https://www.devicetree.org/specifications/). This might appear as a constraint, but I think on the contrary that it will help providing clear and objective guidelines on what should be in DT and what should go in Kconfig. |
ok, as long as this remains doable. |
"HW description should be SW agnostic and we should be able to work with dts files common with Linux for instance. So we should work with existing dts files and dts speficication. This might appear as a constraint, but I think on the contrary that it will help providing clear and objective guidelines on what should be in DT and what should go in Kconfig." I agree. We should include in our guidelines that DeviceTree should be application/SW agnostic. An example of what this would mean in practice is that these files should not exist: AFAICT those files are doing two things and both of those should be done with Kconfig. Enabling the UART driver, a software component. Configuring (not describing) the UART peripheral to use 1Mbit baud rate. Some might object that configuring peripheral address registers belongs to DeviceTree, because The contents of peripheral address registers are inherently application-specific, or else the IC-designer |
Something like that (very simplified)?
I dislike the preprocessor approach, this will just make things very complex. |
Similar to the UART example, the same applies to memory and flash size configuration, that what comes to mind right now but there is probably more, if we go this route, then we are back to square one, i.e. we will be downing in Kconfig hell again. I personally dislike the the DTS overlays as shown above in the example, it just introduces yet another way to configure the system, in the past we only had Kconfig now we have to deal with another syntax and format. So, we need somehow to meet in the middle here and see DTS as not a hardware description language, but also as the hardware configuration language that tells the system (and software components) via Kconfig (the proposal in this issue) what hardware is available, to enable/disable hardware dependent components (drivers for example). |
Agreed. Kconfig needs to know about available hardware and the HAS
Agreed. Except that shouldn't it suffice with 'present' AKA HAS? It
I am not familiar with the problems of square one or or drowning in |
I actually meant OS agnostic, my bad for this wrong choice of word which introduced ambiguity.
So this is actually something specified by device tree specification, I don't see a reason why we should not use it. One shade though: in Linux, this is used to enable the driver. Device is in the dt blob at runtime, it is just not activated. In zephyr, this is done slightly differently as device won't be compiled if stated as "disabled".
Again, current-speed (as clock-frequency) is part of device tree specification. I don't see a reason not using it.
I disagree, for instance external interrupt or pin-control configuration are done through registers and a useful part of device tree specification. I don't think this criteria is pertinent. To sum up, my view:
|
DT = What |
Describing HW and populating registers at boot time is fine. But in
Because DT is superior to Kconfig at being a hardware description Imagine this use-case. A user is developing a Zephyr product. During This subsystem requires a driver that was not in use before, so When configuration of what drivers are enabled is managed by The usability difference between these two scenarios is what forces us |
DT = immutable I don't see why we would want to use DeviceTree to configure HW peripherals. Peripheral configuration is done by SW, it depends on the requirements of SW, it is as soft as SW, |
Then he should not forget to describe this device related to the driver in device tree... He'll have to mess with device tree anyway. Only difference between Zephyr and Linux in Kconfig vs DT partition is that Zephyr uses DT at pre-compilation, I think we should focus on what this impacts. And I don't think it impacts HW configuration. |
"Then he should not forget to describe this device related to the driver in device tree... He'll have to mess with device tree anyway." He doesn't need to, because in this use-case, the driver in question is already implemented and supported in Zephyr. Just not enabled in his application. "Besides, I don't see why a Zephyr developer would face different issues as a Linux developer on the use case you described." This was describing an application developer, not a Zephyr developer. The linux kernel has a comparatively easy configuration problem to solve because they have more resources on-target and can therefore do more at runtime whereas we must do more at build time. Also, application's do not need to configure and prune the kernel. So the usability of the configuration system is not as important in Linux as it is in Zephyr. |
Also, application's do not need to configure and prune the kernel. So the usability of the configuration system is not as important in Linux as it is in Zephyr. Agreed. I understand that everything that will impact compilation should be in Kconfig, right. |
re the UART example, Baudrate is not something static that can only be configured one time and per board, someone might actually want to change the baudrate at runtime, same applies for various frequencies of peripherals. So there is a use case there, however, that does not mean it is an either or question. Baudrate could be set by DTS and reconfigured by the application if needed. |
Sure, I think @SebastianBoe and I both meant "boot time" configuration. Then application has the hand to do whatever it need. |
The only problem that I had in #5799 is device instantiation, and there only the DTS status = "disabled" case. All other DTS properties that I had to use did fit into the current Kconfig/ DTS scheme and were usefull at least for automatic boot time configuration. (1) So may be as @SebastianBoe suggested a warning/ error in case Kconfig requests a device (e.g. by CONFIG_GPIO) that is not activated in the DTS could be a good starting point. This will automatically happen if all devices of a given device type (eg. GPIO) are deactivated. A problem arises if only some are deactivated because in this case the driver gets all the necessary information from the DTS and can not detect that there is some missing (e.g. only GPIOA is deactivated). Here Kconfig would have to be more specific (e.g. CONFIG_GPIO_CONTROLLER_0 - corresponding to the first GPIO of the SoC, here GPIOA). (2) The other way round - Kconfig prunes a driver of a device that is activated in the DTS - is aready handled. The device driver will just not be compiled. If Kconfig prunes a device of a device type, but that device is activated in the DTS a warning/ error should be issued. Assumed situation with drivers that use DTS:
My Conclusion:
|
My ideal way to deal with that would be to introduce a new "status" in dt (then feed in Kconfig if required):
So of course, "available" value would be Zephyr specific (at least at first) and we need to see how to introduce it and stay compatible with generic device tree. One way to make it possible is to consider this value would be present only in boards dts files and these files would be only available in Zephyr tree. Only SoC .dtsi files being fully Linux compatible. This is only an idea and has to be digged more in detailed. By the way, just fyi, the rough way linux is dealing with all that is that there is a generic function in the driver that parses embedded dt blob, extract properties value and instantiate devices depending on the status. I think we should keep in mind that we have different constraints, but we're trying to achieve the same globally, in pre-compilation. |
"available" is application specific. So why not put it only in a prj.dts? |
I don't think we want to keep instance oriented Kconfig option. That is: anything like *_SPI_0, *_GPIO_3 etc... so definitely not something like HAS_SPI_1. DTS is the one that will generate the instances, Kconfig is the one that know about what general feature are enabled (so not per-instance). About this initialization stuff, that will require to adapt the device driver model. Currently, it's all initialized at boot time (following a certain level/prio). We could create a new level that would be UNINITIALIZED. (DTS could handle that relevantly as well) Then you would need to expose a function device_init(struct device *dev) for the app to initialize the device. That said, is there really a relevant use-case for that kind of delayed initialization? 99% of device init is basically doing super trivial stuff like connecting it's irq line, maybe setting some data to 0 or else. The only complicated ones are, for instance, Ethernet or 15.4 drivers where they start an internal coop thread (usually for handling rx stuff). |
You need a way for applications to select the instances to be created. By this you put all the burden to DTS. Is there a concept of a proj.dts to be created by e.g. menuconfig? |
"proj.dts to be created by e.g. menuconfig?" Wouldn't it be the other way around? Assuming DT is processed before Kconfig one could generate Kconfig from DT. EDIT: Or are you proposing a GUI-frontend to DT? |
@b0661 @SebastianBoe we discussed this yesterday with @erwango and @tbursztyka in the TSC call. I've also created #8499 to track this. Nothing is decided but the current thinking seems to go towards:
We still need discussion on the following I believe: |
@b0661 @SebastianBoe @erwango @tbursztyka, some more thoughts on the instancing in KConfig below. Continuing with issue b) from my previous comment. Once Device Tree is processed before Kconfig, and regarding the way to enable and configure instances by the user, I think there are 2 possible approaches here (as long as we discard b.1 as a real option since in general people seem to be against enabling software features with DT):
|
I kind of like the proposal 1 which, in turn, would enable changing DT generated instances settings via menuconfig. User would have a unique tool to tweak things. Even non-enabled instance in DT should appear there I think. That would solve the issue of having the user going to modify .dts file in addition of using menuconfig. Including them would not be too hard, as we could have something like that in, let's say, drivers/spi/Kconfig.stm32
The only drawback is templating/generating these Kconfig.*.dt |
I also agree on option1. For Kconfig.*.dt files generation, I think we should think of a new script using same database input as we think codegen should use. |
My preferred way would be (I asume this is also option 1):
and
Index just follows the number of activated nodes of given driver type (here GPIO). No relation to label to keep it generic.
This way the user (and driver) gets the config options with the expected instance names that he knows and that are also specific to the SoC. Kconfig only contains generic configurations:
|
Haven't followed the discussion closely, but as an FYI, a new Kconfig feature (that I had some input in) that might be relevant here has been merged into the C Kconfig tools now (in It adds a simple preprocessor to Kconfig that (among other things) allows you to get input via shell commands. For example, this sets
You can also check whether a command succeeds:
I've been waiting for it to stabilize before I add it to Kconfiglib, but I think it should be pretty close now. If you think it'd be useful here, I could focus on getting it in. |
After review of @erwango ´s proposal of a DTS database common to several tools (see #6762) I think the transfer from DTS to Kconfig should be done by a Kconfig.generated configuration file that is read by Kconfig. This file should contain configuration data for all activated device. No more DTS_HAS_* configuration variables but instead directly creating something like the following:
This is the general scheme from the review:
|
The preprocessor also supports macros btw, so could have something like |
We need a consistent view of the hardware, so we can't let Kconfig change hardware options from DT. For example, pins cfg can't be set by Kconfig, because other software like mcuboot, tfm, etc will not see a consistent view of the hardware. |
I've been working a bit on the new Kconfig preprocessor stuff (it's in The new preprocessor lets you write stuff like
It wouldn't be too hard to allow custom functions to be defined in Python in Kconfiglib, and that might make querying DTS less awkard compared to running shell commands. You could then have stuff like Any thoughts? |
I would like to extend a bit the statement from @galak. As we all know in a typical MCU pins are shared between multiple hardware modules thanks to the service provided by GPIO/pinmux block. However, on many architectures pin muxing is quite inflexible, e.g. on Atmel SAM E70 MCU enabling GMAC module renders USART2 useless. All these intricate dependencies should be correctly handled by the configuration system, i.e. when configuring driver instances user should expect that enabling two driver instances which are mutually exclusive is not possible. This is not practically implementable in Kconfig, while - as far as I know - should be doable in DTS. |
So from this I understand all available instances should be generated, then Kconfig can control what instances are compiled, is that correct? |
Right. So if this is the case, how do we allow users to enable/disable hardware and set boot-time configuration in a friendly manner? Do we then need to create a
It's more than just the instances, which is fine I think from a DTS perspective. It's the pin mappings and default baudrates and the rest of boot-time config that worries me. |
@galak @erwango @nashif @b0661 @SebastianBoe So after a quick chat with @galak on IRC and based on all the info and PRs I've looked at, for me the only solution that maintains DT as the only absolute truth for hardware description and boot-time configuration is to go DT all the way for hardware and peripherals, and not rely on Kconfig at all for those. So summarizing this new idea: a) DT runs first, before Kconfig |
Take a look at #9925 as a means to decouple dts from Kconfig. |
This should be resolved by PR #12108 |
Note that this is now one of the tasks listed in #8499.
The list of sub-tasks in this particular tasks, from my conversations (@SebastianBoe feel free to add others here):
CONFIG_HAS_HW_SPI
and Kconfig depends on it forCONFIG_SPI
Original description:
How your SW is configured and what SW is available is dependent on what your HW looks like. It is not the other way around, that your board's HW description depends on what kind of SW you want.
Therefore we need to move DTS processing from after Kconfig to before Kconfig. This requires a lot of effort and will break all manner of things. But I believe it will result in a simpler and better integrated configuration system in the end.
A configuration architecture that this would enable (if we also start feeding DTS information into Kconfig somehow):
Use DTS to express what HW is present and feed this immutable information into Kconfig.
Use a (HW-support pruned) Kconfig tree to express that the user can enable and configure SW according to the immutable constraints of the HW.
The idea of feeding HW-information into Kconfig is not new. It is currently being done with BOARD and ARCH. This proposal simply extends the amount of HW information that is imported to take greater advantage of DTS information. When DTS information is only available after all SW configuration has completed it's usefulness in the configuration system is very minimal.
The text was updated successfully, but these errors were encountered: