-
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
[RFC] Deferred device initialization #67335
Conversation
4d9ed48
to
cea07b7
Compare
include/zephyr/device.h
Outdated
@@ -149,6 +149,8 @@ typedef int16_t device_handle_t; | |||
#define DEVICE_DT_NAME(node_id) \ | |||
DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id)) | |||
|
|||
#define DEVICE_DT_DEFER(node_id) \ | |||
DT_PROP_OR(node_id, zephyr_deferred_init, false) |
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.
DT_PROP(node_id, zephyr_deferred_init)
(boolean prop, defaults to 0 if not defined)
kernel/init.c
Outdated
for (entry = __deferred_init_start; entry <= __deferred_init_end; entry++) { | ||
if (entry->dev == dev) { | ||
return do_device_init(entry); | ||
} | ||
} |
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.
please use iterable sections
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.
Yes - I can't remember the exact macro off the top of my head ITERABLE_SECTION_FOR_EACH()
maybe? There is likely an ALT version that should allow for pointer aliasing if necessary
cea07b7
to
81fea91
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.
Clever and useful. Dropping a +1 even though it'll probably respin for the macrobatic review comments.
v2:
|
include/zephyr/device.h
Outdated
@@ -149,6 +149,16 @@ typedef int16_t device_handle_t; | |||
#define DEVICE_DT_NAME(node_id) \ | |||
DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id)) | |||
|
|||
/** | |||
* @brief Deterimine if a devicetree node initialization should be deferred. |
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.
typo
81fea91
to
7361202
Compare
I still think it's not the right way. Whether it's a callback and/or a dts property (which is worse than the cb imo), because of the dependencies, because of shortcomings in the device driver model. But I won't block, there seems to be a consensus already. |
This proposal is pretty close to what I had mocked up for the Arduino-on-Zephyr PoC last year, but properly done - so it definitely gets my preference! 👍 While I also appreciate the extra runtime flexibilty given by the alternative PR, I think the subtle issues arising with such an early state callback (as nicely detailed in this comment's second point), are pretty difficult to convey to users. |
Architecture WG:
|
Currently, all devices are initialized at boot time (following their level and priority order). This patch introduces deferred initialization: by setting the property `zephyr,deferred-init` on a device on the devicetree, Zephyr will not initialized the device. To initialize such devices, one has to call `device_init()`. Deferred initialization is done by grouping all deferred devices on a different ELF section. In this way, there's no need to consume more memory to keep track of deferred devices. When `device_init()` is called, Zephyr will scan the deferred devices section and call the initialization function for the matching device. As this scanning is done only during deferred device initialization, its cost should be bearable. Signed-off-by: Ederson de Souza <[email protected]>
Ensure that devices are not ready before calling `device_init()`, but are after the call. Signed-off-by: Ederson de Souza <[email protected]>
ae1af21
3e054b7
to
ae1af21
Compare
v4:
|
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.
Not entirely happy with the result, but let's move on.
Following discussions at #64869, this PR implements Option 1 from #39896.
With this PR, a new devicetree property,
zephyr,deferred-init
can be used to make a device not be initialised during boot. The device can be initialised by callingdevice_init()
from the application.Under the hood, this PR achieves that by grouping the deferred devices intialisation code in a different ELF section. This way, there's no overhead during normal initialisation: neither memory nor processing penalty. Deferred initialisation however loops over the deferred devices and initialises the matching one, incurring some processing penalty, which is hopefully acceptable.
A new test helps showcase the new feature.
Opens
DEVICE_INIT(DT_PATH(some_node))
), but this seems way too ugly. Any ideas?