Skip to content

Commit

Permalink
device: add CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH option
Browse files Browse the repository at this point in the history
This new option allows to generate device names from the hash of the
devicetree node path, instead of the device's ordinal number. The
resulting names are stable across rebuilds.

Add a new test case to test this new option.

Signed-off-by: Luca Burelli <l.burelli@arduino.cc>
  • Loading branch information
pillo79 committed Sep 25, 2024
1 parent 16ba0e3 commit cf49b3d
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
36 changes: 31 additions & 5 deletions include/zephyr/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,35 @@ typedef int16_t device_handle_t;
* The ordinal used in this name can be mapped to the path by
* examining zephyr/include/generated/zephyr/devicetree_generated.h.
*/
#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
#define Z_DEVICE_DT_DEP_ORD(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))

#if defined(CONFIG_LLEXT_EXPORT_DEVICES)
/* Same as above, but uses the hash of the node path instead of the ordinal.
*
* The hash used in this name can be mapped to the path by
* examining zephyr/include/generated/zephyr/devicetree_generated.h.
*/
#define Z_DEVICE_DT_HASH(node_id) _CONCAT(dts_hash_, DT_HASH(node_id))

/* By default, device identifiers are obtained using the dependency ordinal.
* When LLEXT_EXPORT_DEV_IDS_BY_HASH is defined, the main Zephyr binary exports
* DT identifiers via EXPORT_SYMBOL_NAMED as hashed versions of their paths.
* When matching extensions are built, that is what they need to look for.
*
* The ordinal or hash used in this name can be mapped to the path by
* examining zephyr/include/generated/zephyr/devicetree_generated.h.
*/
#if defined(LL_EXTENSION_BUILD) && defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH)
#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_HASH(node_id)
#else
#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_DEP_ORD(node_id)
#endif

#if defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH)
/* Export device identifiers by their hash */
#define Z_DEVICE_EXPORT(node_id) \
EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \
STRINGIFY(DEVICE_NAME_GET(Z_DEVICE_DT_HASH(node_id))))

Check notice on line 131 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:131 -#define Z_DEVICE_EXPORT(node_id) \ - EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \ +#define Z_DEVICE_EXPORT(node_id) \ + EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \

Check notice on line 131 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:131 -#define Z_DEVICE_EXPORT(node_id) \ - EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \ +#define Z_DEVICE_EXPORT(node_id) \ + EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \

Check notice on line 131 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:131 -#define Z_DEVICE_EXPORT(node_id) \ - EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \ +#define Z_DEVICE_EXPORT(node_id) \ + EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \

Check notice on line 131 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:131 -#define Z_DEVICE_EXPORT(node_id) \ - EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \ +#define Z_DEVICE_EXPORT(node_id) \ + EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \
#elif defined(CONFIG_LLEXT_EXPORT_DEVICES)
/* Export device identifiers using the builtin name */
#define Z_DEVICE_EXPORT(node_id) EXPORT_SYMBOL(DEVICE_DT_NAME_GET(node_id))
#endif
Expand Down Expand Up @@ -175,8 +201,8 @@ typedef int16_t device_handle_t;
*
* This macro defines a @ref device that is automatically configured by the
* kernel during system initialization. The global device object's name as a C
* identifier is derived from the node's dependency ordinal. @ref device.name is
* set to `DEVICE_DT_NAME(node_id)`.
* identifier is derived from the node's dependency ordinal or hash.
* @ref device.name is set to `DEVICE_DT_NAME(node_id)`.
*
* The device is declared with extern visibility, so a pointer to a global
* device object can be obtained with `DEVICE_DT_GET(node_id)` from any source
Expand Down Expand Up @@ -208,7 +234,7 @@ typedef int16_t device_handle_t;
level, prio, api, \
&Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
__VA_ARGS__) \
IF_ENABLED(CONFIG_LLEXT_EXPORT_DEVICES, (; Z_DEVICE_EXPORT(node_id))) \
IF_ENABLED(CONFIG_LLEXT_EXPORT_DEVICES, (; Z_DEVICE_EXPORT(node_id)))

Check notice on line 237 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:237 -#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \ - ...) \ - Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ - Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \ - DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \ - level, prio, api, \ - &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \ - __VA_ARGS__) \ +#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, ...) \ + Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ + Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), DEVICE_DT_NAME(node_id), init_fn, \ + pm, data, config, level, prio, api, \ + &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), __VA_ARGS__) \

Check notice on line 237 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:237 -#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \ - ...) \ - Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ - Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \ - DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \ - level, prio, api, \ - &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \ - __VA_ARGS__) \ +#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, ...) \ + Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ + Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), DEVICE_DT_NAME(node_id), init_fn, \ + pm, data, config, level, prio, api, \ + &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), __VA_ARGS__) \

Check notice on line 237 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:237 -#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \ - ...) \ - Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ - Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \ - DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \ - level, prio, api, \ - &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \ - __VA_ARGS__) \ +#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, ...) \ + Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ + Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), DEVICE_DT_NAME(node_id), init_fn, \ + pm, data, config, level, prio, api, \ + &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), __VA_ARGS__) \

Check notice on line 237 in include/zephyr/device.h

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

include/zephyr/device.h:237 -#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \ - ...) \ - Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ - Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \ - DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \ - level, prio, api, \ - &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \ - __VA_ARGS__) \ +#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, ...) \ + Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \ + Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), DEVICE_DT_NAME(node_id), init_fn, \ + pm, data, config, level, prio, api, \ + &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), __VA_ARGS__) \

/**
* @brief Like DEVICE_DT_DEFINE(), but uses an instance of a `DT_DRV_COMPAT`
Expand Down
8 changes: 8 additions & 0 deletions subsys/llext/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ config LLEXT_EXPORT_DEVICES
When enabled, all Zephyr devices defined in the device tree are
made available to llexts via the standard DT_ / DEVICE_* macros.

config LLEXT_EXPORT_DEV_IDS_BY_HASH
bool "Use hash of device path in device name"
depends on LLEXT_EXPORT_DEVICES
help
When enabled, exported device names are generated from a hash of
the node path instead of an ordinal number. The resulting names
are stable across rebuilds.

config LLEXT_EXPORT_BUILTINS_BY_SLID
bool "Export built-in symbols to llexts via SLIDs"
help
Expand Down
8 changes: 8 additions & 0 deletions tests/subsys/llext/simple/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ tests:
- qemu_cortex_a53 # ARM Cortex-A53 (ARMv8-A ISA)
extra_configs:
- CONFIG_LLEXT_STORAGE_WRITABLE=n
llext.simple.devices_by_hash:
arch_allow: arm # Xtensa needs writable storage
filter: not CONFIG_MPU and not CONFIG_MMU and not CONFIG_SOC_SERIES_S32ZE
extra_configs:
- arch:arm:CONFIG_ARM_MPU=n
- arch:arm:CONFIG_ARM_AARCH32_MMU=n
- CONFIG_LLEXT_STORAGE_WRITABLE=n
- CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH=y
llext.simple.writable:
arch_allow: arm xtensa
integration_platforms:
Expand Down

0 comments on commit cf49b3d

Please sign in to comment.