-
Notifications
You must be signed in to change notification settings - Fork 8.2k
Description
For more information on Zephyr's Device Driver Mode, refer to http://docs.zephyrproject.org/devices/drivers/drivers.html
Current situation
- A generic struct device with a generic struct device_config
- Shared system with services initialization (init.h), device and service initialization are interleaved (levels/prio).
- Optionally, power management generic functions are present (in the config part)
- Each device is identified by a "name" (stored in the config part)
- Such name is "maintained" through 4 possibilities (Kconfig, dts, macro or hard-coded)
- The name is only used to get the device bindings at runtime
- A device is uniquely allocated in device driver code through DEVICE_DEFINE() or DEVICE_AND_API_INIT() or DEVICE_INIT(). It requires as many calls of one of these macros as there are devices then.
- device's variable name is not generated from the above name (you cannot un-stringify on preprocessor level), thus it requires a hard-coded unique and un-quoted name.
- Each device are static but not constant (same for their config part)
- Specific device settings can be set either via Kconfig, dts, macros or the 3 of them.
- Most of these settings are specific to each device driver (no generic way)
- No error reporting when device initialization fails besides local debugging
- IRQ connection are made at runtime
There are good reasons for all of it, mostly. When ramping up Zephyr, there was not dts yet, Kconfig was the only way.
All of it works just fine. But as we see more architectures, more SoCs, boards and thus more devices being ported: it starts to clutter the system a bit and can be somewhat confusing to new comers. Moreover when things could be simpler and better optimized.
This is a known problem, on-going work is already fixing some of it. Let's list issues/ideas on how to improve the Device Drivel Model.
Tooling
-
Refactor/rewrite extract_dts_includes.py
Issue: Cleaning up a bit dts scripts #6504 But there is still more to do -
Drop dtc C based compiler for the python version (PR Python replacement for DTC [DNM/WIP] #5615), this would help for the below changes probably (and maintaining current dtc for windows gives extra work)
Simplifications (S)
-
Move all boards (arch/soc/devices) to dts. Issue: All boards for all arch's should use DTS #4960
-
Remove Kconfig device specific settings and use dts only
Only generic support would survive (CONFIG_GPIO, CONFIG_IEEE802154, etc...) ? -
DEVICE_* macro call for each device should be externalized from device source code:
The idea would be to generate these automatically from dts.
Optimizations (O)
-
Reversing the actual device and config interdependency to gain a bit of space:
SYS_INIT would then take less space than currently (ok just 12 bytes less) -
Remove the 'name' attribute in struct device_init (aka device_config):
This will need many steps, but mostly requires S1 to be done in order to avoid messing up with Kconfig. I already tried quickly to hack around dts, and Kconfig, since not all boards are dts ready and it is very ugly. It was just a quick PoC. (see https://github.com/tbursztyka/zephyr/tree/dev_name_const).
Zephyr will gain some ROM space from it: no device name, and direct bindings (which also will improve boot time a tiny bit)
-
Remove drv_name in DEVICE_* macro, keep only dev_name (which is the semantically right name, there is no such thing à as "driver name" anywhere at runtime).
-
Make all devices constant:
Easy now that getting the bindings are made at built time. (const in DEVICE_ macro, extern const struct device ... in the generated file etc...) -
DTS can generate such unique name via node name, thus 'label' could be removed altogether. No need for any name maintenance then in dtsi/yaml files.
-
Revise how IRQ are connected: this would reduce runtime necessary calls for it and save some ROM space, while simplifying maintenance as well (connection could be generated automatically via the dts workflow)
-
Do not built/link built device drivers, and there relevant device instances, if none of these are used anywhere. I.e. even if gpio port C is requested to be built, but proven to be let alone then: do not embed it in the final image. Again saving ROM space relevantly.
Issues ordering
- S1, O2 in parallel (S1 is anyway going to take quite sometime)
- S4
- O3, O7
- O4
- O5, O6 in parallel
- O8
Let's discuss and update this issue accordingly