Open johnkjellberg opened 2 years ago
You do realise that in Zephyr, the devicetree is not part of the produced binary at all? The devicetree is parsed and a set of C defines are produced, which are used as compile-time constants?
What you are suggesting is a totally different approach more alike what Linux does (where the devicetree is compiled to a devicetree blob, which is parsed at run-time).
You do realise that in Zephyr, the devicetree is not part of the produced binary at all? The devicetree is parsed and a set of C defines are produced, which are used as compile-time constants?
Yes. I'm talking about the result that is generated from the tree. For example the arrays used to initialize the drivers. That part should not be that hard, but there might be other things that is generated that I'm not aware of. I'm open to other suggestions to solve the described problem.
Food for thought; I have a similar use case where a board has GPIO revision indicators.
As already mentioned, it's not an easy task to support multiple devicetrees, but it should be possible to allow some "runtime customization" in a single dts
file.
My idea was to extend the hwinfo
API, since it's single instance, with int hwinfo_get_device_revision(uint32_t *rev)
. Adding a compatible that would implement such a function could look like:
gpio_revision {
compatible = "zephyr,gpio-revision";
gpios = <&gpio1 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>,
<&gpio1 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>,
<&gpio1 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
};
And create a dependency with other devices, example for i2c
address change:
&i2c0 {
sensor_old: some_sensor@0 {
compatible = "vendor,chip";
reg = <0x00>;
hwinfo-revision = <0x01>;
};
sensor_new: some_sensor@1 {
compatible = "vendor,chip";
reg = <0x01>;
hwinfo-revision = <0x02>, <0x03>, <0x04>;
};
}
Note that this would also require modifications to the device initialization.
I've created an example branch for the zephyr,gpio-revision
driver here.
General runtime device tree will be very hard with the way Zephyr turns the dts into C macros. Consider this:
#if DT_INST_NODE_HAS_PROP(0, target_speed)
In order to support two device trees, one with target-speed
and one without, it would be necessary to compile both branches of the #if
and select at runtime. How could that ever be done?
What might be a possibility is support for drivers that access the device tree solely through values placed into their device->config
struct. Many drivers do, or could, work this way.
Both dts nodes need to be present and enabled. Both are parsed into C macros. The driver instantiation macro, i.e. DEVICE_DT_DEFINE
, needs to create both struct device
objects, one for each possible device. Then at run time, the driver's init function is only called on one of the struct device
objects.
A problem that comes up is when the device affects other devices. For instance, it uses a GPIO for its chipselect and that is contained in the parent SPI bus device. Or it has pinctrl nodes. Enabling the device at runtime doesn't just mean the driver's init function is called or not called. It also means the pin controller was configured for the device and that might have been compiled in directly into the pinctrl code.
Hi @galak,
This issue, marked as an Feature Request, was opened a while ago and did not get any traction. It was just assigned to you based on the labels. If you don't consider yourself the right person to address this issue, please re-assing it to the right person.
Please take a moment to review if the issue is still relevant to the project. If it is, please provide feedback and direction on how to move forward. If it is not, has already been addressed, is a duplicate, or is no longer relevant, please close it with a short comment explaining the reason.
@johnkjellberg you are also encouraged to help moving this issue forward by providing additional information and confirming this request/issue is still relevant to you.
Thanks!
Since it is quite common that components need to be replaced it is must be possible to support different hw revisions. The current Zephyr model handles this by having different BOARD definitions and build separate binaries for each hardware revision. This is not very convenient, since it might just be a small LED driver, I2C address or other minor difference that have changed for example.
I would like to be able to define multiple device trees in one binary that can be selected runtime during boot (by for example checking version pins connected to GPIO).
Edit: I'm not suggesting to include the actual tree to be parsed during runtime. I'm suggesting that what is generated is generated and separated in such a way that it can be selected at runtime. Such as the list of drivers used by 'device.c'