diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 00e7da354f9..a1b3632fae2 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -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_, DT_NODE_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 hash */ +#define Z_DEVICE_EXPORT(node_id) \ + EXPORT_SYMBOL_NAMED(DEVICE_DT_NAME_GET(node_id), \ + DEVICE_NAME_GET(Z_DEVICE_DT_HASH(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 @@ -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 diff --git a/subsys/llext/Kconfig b/subsys/llext/Kconfig index 0e3ce5dd57d..5d98bf31e03 100644 --- a/subsys/llext/Kconfig +++ b/subsys/llext/Kconfig @@ -86,6 +86,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. Identifiers generated this + way are stable across rebuilds. + config LLEXT_EXPORT_BUILTINS_BY_SLID bool "Export built-in symbols to llexts via SLIDs" help diff --git a/tests/subsys/llext/testcase.yaml b/tests/subsys/llext/testcase.yaml index c7fe918444c..507c580fcf0 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -124,3 +124,21 @@ tests: - CONFIG_LLEXT_STORAGE_WRITABLE=y - CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y - CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID=y + + # Test the export device IDs by hash feature on a single architecture in + # both normal and SLID mode. + llext.devices_by_hash: + arch_allow: arm + filter: not CONFIG_MPU and not CONFIG_MMU + extra_conf_files: ['no_mem_protection.conf'] + extra_configs: + - CONFIG_LLEXT_STORAGE_WRITABLE=n + - CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH=y + llext.devices_by_hash_slid_linking: + arch_allow: arm + filter: not CONFIG_MPU and not CONFIG_MMU + extra_conf_files: ['no_mem_protection.conf'] + extra_configs: + - CONFIG_LLEXT_STORAGE_WRITABLE=n + - CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH=y + - CONFIG_LLEXT_EXPORT_BUILTINS_BY_SLID=y