7#ifndef ZEPHYR_INCLUDE_DEVICE_H_
8#define ZEPHYR_INCLUDE_DEVICE_H_
43#define Z_DEVICE_DEPS_SEP INT16_MIN
49#define Z_DEVICE_DEPS_ENDS INT16_MAX
52#define Z_DEVICE_IS_MUTABLE(node_id) \
53 COND_CODE_1(IS_ENABLED(CONFIG_DEVICE_MUTABLE), (DT_PROP(node_id, zephyr_mutable)), (0))
75#define DEVICE_HANDLE_NULL 0
96#define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
104#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
106#if defined(CONFIG_LLEXT_EXPORT_DEVICES)
108#define Z_DEVICE_EXPORT(node_id) EXPORT_SYMBOL(DEVICE_DT_NAME_GET(node_id))
141#define DEVICE_DEFINE(dev_id, name, init_fn, pm, data, config, level, prio, \
143 Z_DEVICE_STATE_DEFINE(dev_id); \
144 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, pm, data, \
145 config, level, prio, api, \
146 &Z_DEVICE_STATE_NAME(dev_id))
159#define DEVICE_DT_NAME(node_id) \
160 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
169#define DEVICE_DT_DEFER(node_id) \
170 DT_PROP(node_id, zephyr_deferred_init)
203#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \
205 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
206 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
207 DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
209 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
220#define DEVICE_DT_INST_DEFINE(inst, ...) \
221 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
237#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
254#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
265#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
283#define DEVICE_DT_GET_ANY(compat) \
284 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
285 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
304#define DEVICE_DT_GET_ONE(compat) \
305 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
306 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
307 (ZERO_OR_COMPILE_ERROR(0)))
319#define DEVICE_DT_GET_OR_NULL(node_id) \
320 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), \
321 (DEVICE_DT_GET(node_id)), (NULL))
333#define DEVICE_GET(dev_id) (&DEVICE_NAME_GET(dev_id))
349#define DEVICE_DECLARE(dev_id) \
350 static const struct device DEVICE_NAME_GET(dev_id)
359#define DEVICE_INIT_DT_GET(node_id) \
360 (&Z_INIT_ENTRY_NAME(DEVICE_DT_NAME_GET(node_id)))
369#define DEVICE_INIT_GET(dev_id) (&Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)))
398#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
399struct device_dt_metadata;
402#ifdef CONFIG_DEVICE_DEPS_DYNAMIC
403#define Z_DEVICE_DEPS_CONST
405#define Z_DEVICE_DEPS_CONST const
422#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
433#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
444#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
480static inline const struct device *
484 const struct device *dev = NULL;
489 if ((dev_handle > 0) && ((
size_t)dev_handle <= numdev)) {
496#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
545 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
546 (rv[i] != Z_DEVICE_DEPS_SEP)) {
582 while (region != 1) {
583 if (*rv == Z_DEVICE_DEPS_SEP) {
588 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
589 (rv[i] != Z_DEVICE_DEPS_SEP)) {
626 while (region != 2) {
627 if (*rv == Z_DEVICE_DEPS_SEP) {
636 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
745size_t z_device_get_all_static(
const struct device **devices);
791#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
798#define Z_DEVICE_STATE_DEFINE(dev_id) \
799 static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
800 __attribute__((__section__(".z_devstate")))
802#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
810#define Z_DEVICE_DEPS_NAME(dev_id) _CONCAT(__devicedeps_, dev_id)
817#define Z_DEVICE_EXTRA_DEPS(...) \
818 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
821#define Z_DEVICE_DEPS_SECTION \
822 __attribute__((__section__(".__device_deps_pass1")))
825#define Z_DEVICE_DEPS_EXTERN extern
827#define Z_DEVICE_DEPS_EXTERN
865#define Z_DEVICE_DEPS_DEFINE(node_id, dev_id, ...) \
866 extern Z_DEVICE_DEPS_CONST device_handle_t Z_DEVICE_DEPS_NAME( \
868 Z_DEVICE_DEPS_CONST Z_DECL_ALIGN(device_handle_t) \
869 Z_DEVICE_DEPS_SECTION Z_DEVICE_DEPS_EXTERN __weak \
870 Z_DEVICE_DEPS_NAME(dev_id)[] = { \
872 DT_NODE_EXISTS(node_id), \
873 (DT_DEP_ORD(node_id), DT_REQUIRES_DEP_ORDS(node_id)), \
874 (DEVICE_HANDLE_NULL,)) \
876 Z_DEVICE_EXTRA_DEPS(__VA_ARGS__) \
878 COND_CODE_1(DT_NODE_EXISTS(node_id), \
879 (DT_SUPPORTS_DEP_ORDS(node_id)), ()) \
883#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
887struct device_dt_nodelabels {
889 size_t num_nodelabels;
893 const char *nodelabels[];
903struct device_dt_metadata {
908 const struct device_dt_nodelabels *nl;
929__syscall
const struct device *device_get_by_dt_nodelabel(
const char *nodelabel);
936static inline const struct device_dt_nodelabels *
937device_get_dt_nodelabels(
const struct device *dev)
951#define Z_DEVICE_MAX_NODELABEL_LEN Z_DEVICE_MAX_NAME_LEN
957#define Z_DEVICE_DT_METADATA_NAME_GET(dev_id) UTIL_CAT(__dev_dt_meta_, dev_id)
963#define Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) UTIL_CAT(__dev_dt_nodelabels_, dev_id)
971#define Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id) \
972 static const struct device_dt_nodelabels \
973 Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) = { \
974 .num_nodelabels = DT_NUM_NODELABELS(node_id), \
975 .nodelabels = DT_NODELABEL_STRING_ARRAY(node_id), \
978 static const struct device_dt_metadata \
979 Z_DEVICE_DT_METADATA_NAME_GET(dev_id) = { \
980 .nl = &Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id), \
991#define Z_DEVICE_INIT_SUB_PRIO(node_id) \
992 COND_CODE_1(DT_NODE_EXISTS(node_id), \
993 (DT_DEP_ORD_STR_SORTABLE(node_id)), (0))
1001#define Z_DEVICE_MAX_NAME_LEN 48U
1008#define Z_DEVICE_NAME_CHECK(name) \
1009 BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN, \
1010 Z_STRINGIFY(name) " too long")
1025#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_, node_id_, \
1029 .config = (config_), \
1031 .state = (state_), \
1033 IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) \
1034 IF_ENABLED(CONFIG_PM_DEVICE, Z_DEVICE_INIT_PM_BASE(pm_)) \
1035 IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
1036 (IF_ENABLED(DT_NODE_EXISTS(node_id_), \
1037 (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET( \
1046#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100
1047# define Z_DEVICE_INIT_PM_BASE(pm_) ({ .pm_base = (pm_),},)
1049# define Z_DEVICE_INIT_PM_BASE(pm_) (.pm_base = (pm_),)
1058#define Z_DEVICE_SECTION_NAME(level, prio) \
1059 _CONCAT(INIT_LEVEL_ORD(level), _##prio)
1077#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \
1079 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
1080 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \
1081 STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
1082 device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
1083 Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
1084 Z_DEVICE_INIT(name, pm, data, config, api, state, deps, node_id, dev_id)
1091#define Z_DEVICE_CHECK_INIT_LEVEL(level) \
1092 COND_CODE_1(Z_INIT_PRE_KERNEL_1_##level, (), \
1093 (COND_CODE_1(Z_INIT_PRE_KERNEL_2_##level, (), \
1094 (COND_CODE_1(Z_INIT_POST_KERNEL_##level, (), \
1095 (ZERO_OR_COMPILE_ERROR(0)))))))
1107#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \
1108 Z_DEVICE_CHECK_INIT_LEVEL(level) \
1110 static const Z_DECL_ALIGN(struct init_entry) __used __noasan Z_INIT_ENTRY_SECTION( \
1111 level, prio, Z_DEVICE_INIT_SUB_PRIO(node_id)) \
1112 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
1113 .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
1115 Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id), \
1118#define Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_) \
1119 static const Z_DECL_ALIGN(struct init_entry) __used __noasan \
1120 __attribute__((__section__(".z_deferred_init"))) \
1121 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
1122 .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
1124 Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id), \
1132#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100
1133# define Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id) { Z_DEV_ENTRY_DEV(node_id, dev_id) }
1135# define Z_DEVICE_INIT_ENTRY_DEV(node_id, dev_id) Z_DEV_ENTRY_DEV(node_id, dev_id)
1138#define Z_DEV_ENTRY_DEV(node_id, dev_id) \
1139 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = &DEVICE_NAME_GET(dev_id)
1162#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
1163 level, prio, api, state, ...) \
1164 Z_DEVICE_NAME_CHECK(name); \
1166 IF_ENABLED(CONFIG_DEVICE_DEPS, \
1167 (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \
1169 IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
1170 (IF_ENABLED(DT_NODE_EXISTS(node_id), \
1171 (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
1173 Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
1174 prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
1175 COND_CODE_1(DEVICE_DT_DEFER(node_id), \
1176 (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, \
1178 (Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, \
1180 IF_ENABLED(CONFIG_LLEXT_EXPORT_DEVICES, \
1181 (IF_ENABLED(DT_NODE_EXISTS(node_id), \
1182 (Z_DEVICE_EXPORT(node_id);))))
1194#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \
1195 extern COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), \
1196 (const)) struct device DEVICE_DT_NAME_GET(node_id);
1201#define Z_DEVICE_API_TYPE(_class) _CONCAT(_class, _driver_api)
1211#define DEVICE_API(_class, _name) const STRUCT_SECTION_ITERABLE(Z_DEVICE_API_TYPE(_class), _name)
1221#define DEVICE_API_GET(_class, _dev) ((const struct Z_DEVICE_API_TYPE(_class) *)_dev->api)
1233#define DEVICE_API_IS(_class, _dev) \
1235 STRUCT_SECTION_START_EXTERN(Z_DEVICE_API_TYPE(_class)); \
1236 STRUCT_SECTION_END_EXTERN(Z_DEVICE_API_TYPE(_class)); \
1237 (DEVICE_API_GET(_class, _dev) < STRUCT_SECTION_END(Z_DEVICE_API_TYPE(_class)) && \
1238 DEVICE_API_GET(_class, _dev) >= STRUCT_SECTION_START(Z_DEVICE_API_TYPE(_class))); \
1245#include <zephyr/syscalls/device.h>
const struct device * device_get_binding(const char *name)
Get a device reference from its device::name field.
int16_t device_handle_t
Type used to represent a "handle" for a device.
Definition device.h:72
static const device_handle_t * device_required_handles_get(const struct device *dev, size_t *count)
Get the device handles for devicetree dependencies of this device.
Definition device.h:538
static const device_handle_t * device_supported_handles_get(const struct device *dev, size_t *count)
Get the set of handles that this device supports.
Definition device.h:618
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition device.h:457
#define DEVICE_HANDLE_NULL
Flag value used to identify an unknown device.
Definition device.h:75
int device_required_foreach(const struct device *dev, device_visitor_callback_t visitor_cb, void *context)
Visit every device that dev directly requires.
static const struct device * device_from_handle(device_handle_t dev_handle)
Get the device corresponding to a handle.
Definition device.h:481
int(* device_visitor_callback_t)(const struct device *dev, void *context)
Prototype for functions used when iterating over a set of devices.
Definition device.h:516
bool device_is_ready(const struct device *dev)
Verify that a device is ready for use.
static const device_handle_t * device_injected_handles_get(const struct device *dev, size_t *count)
Get the device handles for injected dependencies of this device.
Definition device.h:574
int device_init(const struct device *dev)
Initialize a device.
int device_supported_foreach(const struct device *dev, device_visitor_callback_t visitor_cb, void *context)
Visit every device that dev directly supports.
#define DT_FOREACH_STATUS_OKAY_NODE(fn)
Invokes fn for every status okay node in the tree.
Definition devicetree.h:2960
#define STRUCT_SECTION_START_EXTERN(struct_type)
iterable section extern for start symbol for a struct
Definition iterable_sections.h:159
#define STRUCT_SECTION_START(struct_type)
iterable section start symbol for a struct type
Definition iterable_sections.h:149
#define STRUCT_SECTION_COUNT(struct_type, dst)
Count elements in a section.
Definition iterable_sections.h:291
Definitions of various linker Sections.
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__INT16_TYPE__ int16_t
Definition stdint.h:73
Runtime device dynamic structure (in RAM) per driver instance.
Definition device.h:379
bool initialized
Indicates the device initialization function has been invoked.
Definition device.h:392
uint8_t init_res
Device initialization return code (positive errno value).
Definition device.h:387
Runtime device structure (in ROM) per driver instance.
Definition device.h:411
struct pm_device_base * pm_base
Definition device.h:439
const device_handle_t * deps
Optional pointer to dependencies associated with the device.
Definition device.h:431
struct pm_device_isr * pm_isr
Definition device.h:441
const char * name
Name of the device instance.
Definition device.h:413
struct pm_device * pm
Definition device.h:440
void * data
Address of the device instance private data.
Definition device.h:421
const void * api
Address of the API structure exposed by the device instance.
Definition device.h:417
struct device_state * state
Address of the common device state.
Definition device.h:419
const void * config
Address of device instance config information.
Definition device.h:415
const struct device_dt_metadata * dt_meta
Definition device.h:445
Device PM info.
Definition device.h:139
Runtime PM info for device with synchronous PM.
Definition device.h:185
Runtime PM info for device with generic PM.
Definition device.h:163
Linkable loadable extension symbol definitions.