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_DEP_ORD(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
111#define Z_DEVICE_DT_HASH(node_id) _CONCAT(dts_, DT_NODE_HASH(node_id))
122#if defined(LL_EXTENSION_BUILD) && defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH)
123#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_HASH(node_id)
125#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_DEP_ORD(node_id)
128#if defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH)
130#define Z_DEVICE_EXPORT(node_id) \
131 EXPORT_GROUP_SYMBOL_NAMED(DEVICE, \
132 DEVICE_DT_NAME_GET(node_id), \
133 DEVICE_NAME_GET(Z_DEVICE_DT_HASH(node_id)))
136#define Z_DEVICE_EXPORT(node_id) \
137 EXPORT_GROUP_SYMBOL(DEVICE, DEVICE_DT_NAME_GET(node_id))
176#define DEVICE_DEINIT_DEFINE(dev_id, name, init_fn, deinit_fn, pm, data, \
177 config, level, prio, api) \
178 Z_DEVICE_STATE_DEFINE(dev_id); \
179 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, deinit_fn, 0U, \
180 pm, data, config, level, prio, api, \
181 &Z_DEVICE_STATE_NAME(dev_id))
188#define DEVICE_DEFINE(dev_id, name, init_fn, pm, data, config, level, prio, \
190 DEVICE_DEINIT_DEFINE(dev_id, name, init_fn, NULL, pm, data, config, \
204#define DEVICE_DT_NAME(node_id) \
205 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
243#define DEVICE_DT_DEINIT_DEFINE(node_id, init_fn, deinit_fn, pm, data, config, \
244 level, prio, api, ...) \
245 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
246 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
247 DEVICE_DT_NAME(node_id), init_fn, deinit_fn, \
248 Z_DEVICE_DT_FLAGS(node_id), pm, data, config, level, \
250 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
259#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \
261 DEVICE_DT_DEINIT_DEFINE(node_id, init_fn, NULL, pm, data, config, \
262 level, prio, api, __VA_ARGS__)
272#define DEVICE_DT_INST_DEINIT_DEFINE(inst, ...) \
273 DEVICE_DT_DEINIT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
283#define DEVICE_DT_INST_DEFINE(inst, ...) \
284 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
300#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
317#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
328#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
346#define DEVICE_DT_GET_ANY(compat) \
347 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
348 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
367#define DEVICE_DT_GET_ONE(compat) \
368 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
369 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
370 (ZERO_OR_COMPILE_ERROR(0)))
382#define DEVICE_DT_GET_OR_NULL(node_id) \
383 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), \
384 (DEVICE_DT_GET(node_id)), (NULL))
399#define DEVICE_DT_GET_BY_IDX(node_id, prop, idx) \
400 DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx))
412#define DEVICE_GET(dev_id) (&DEVICE_NAME_GET(dev_id))
428#define DEVICE_DECLARE(dev_id) \
429 static const struct device DEVICE_NAME_GET(dev_id)
438#define DEVICE_INIT_DT_GET(node_id) \
439 (&Z_INIT_ENTRY_NAME(DEVICE_DT_NAME_GET(node_id)))
448#define DEVICE_INIT_GET(dev_id) (&Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)))
477#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
478struct device_dt_metadata;
481#ifdef CONFIG_DEVICE_DEPS_DYNAMIC
482#define Z_DEVICE_DEPS_CONST
484#define Z_DEVICE_DEPS_CONST const
496#define DEVICE_FLAG_INIT_DEFERRED BIT(0)
504#ifdef CONFIG_DEVICE_DEINIT_SUPPORT
506 int (*deinit)(
const struct device *dev);
528#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
539#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
550#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
586static inline const struct device *
595 if ((dev_handle > 0) && ((
size_t)dev_handle <= numdev)) {
602#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
651 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
652 (rv[i] != Z_DEVICE_DEPS_SEP)) {
688 while (region != 1) {
689 if (*rv == Z_DEVICE_DEPS_SEP) {
694 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
695 (rv[i] != Z_DEVICE_DEPS_SEP)) {
732 while (region != 2) {
733 if (*rv == Z_DEVICE_DEPS_SEP) {
742 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
851size_t z_device_get_all_static(
const struct device **devices);
879#define LOG_WRN_DEVICE_NOT_READY(dev) \
880 LOG_WRN("%s device not ready", (dev) ? (dev)->name : "(null)")
890#define LOG_ERR_DEVICE_NOT_READY(dev) \
891 LOG_ERR("%s device not ready", (dev) ? (dev)->name : "(null)")
902#define LOG_INST_WRN_DEVICE_NOT_READY(_log_inst, dev) \
903 LOG_INST_WRN(_log_inst, "%s device not ready", (dev) ? (dev)->name : "(null)")
914#define LOG_INST_ERR_DEVICE_NOT_READY(_log_inst, dev) \
915 LOG_INST_ERR(_log_inst, "%s device not ready", (dev) ? (dev)->name : "(null)")
964#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
971#define Z_DEVICE_STATE_DEFINE(dev_id) \
972 static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
973 __attribute__((__section__(".z_devstate")))
980#define Z_DEVICE_DT_FLAGS(node_id) \
981 (DT_PROP_OR(node_id, zephyr_deferred_init, 0U) * DEVICE_FLAG_INIT_DEFERRED)
983#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
991#define Z_DEVICE_DEPS_NAME(dev_id) _CONCAT(__devicedeps_, dev_id)
998#define Z_DEVICE_EXTRA_DEPS(...) \
999 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
1002#define Z_DEVICE_DEPS_SECTION \
1003 __attribute__((__section__(".__device_deps_pass1")))
1006#define Z_DEVICE_DEPS_EXTERN extern
1008#define Z_DEVICE_DEPS_EXTERN
1046#define Z_DEVICE_DEPS_DEFINE(node_id, dev_id, ...) \
1047 extern Z_DEVICE_DEPS_CONST device_handle_t Z_DEVICE_DEPS_NAME( \
1049 Z_DEVICE_DEPS_CONST Z_DECL_ALIGN(device_handle_t) \
1050 Z_DEVICE_DEPS_SECTION Z_DEVICE_DEPS_EXTERN __weak \
1051 Z_DEVICE_DEPS_NAME(dev_id)[] = { \
1053 DT_NODE_EXISTS(node_id), \
1054 (DT_DEP_ORD(node_id), DT_REQUIRES_DEP_ORDS(node_id)), \
1055 (DEVICE_HANDLE_NULL,)) \
1056 Z_DEVICE_DEPS_SEP, \
1057 Z_DEVICE_EXTRA_DEPS(__VA_ARGS__) \
1058 Z_DEVICE_DEPS_SEP, \
1059 IF_ENABLED(DT_NODE_EXISTS(node_id), \
1060 (DT_SUPPORTS_DEP_ORDS(node_id))) \
1064#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
1068struct device_dt_nodelabels {
1070 size_t num_nodelabels;
1074 const char *nodelabels[];
1084struct device_dt_metadata {
1089 const struct device_dt_nodelabels *nl;
1110__syscall
const struct device *device_get_by_dt_nodelabel(
const char *nodelabel);
1117static inline const struct device_dt_nodelabels *
1118device_get_dt_nodelabels(
const struct device *dev)
1132#define Z_DEVICE_MAX_NODELABEL_LEN Z_DEVICE_MAX_NAME_LEN
1138#define Z_DEVICE_DT_METADATA_NAME_GET(dev_id) UTIL_CAT(__dev_dt_meta_, dev_id)
1144#define Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) UTIL_CAT(__dev_dt_nodelabels_, dev_id)
1152#define Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id) \
1153 static const struct device_dt_nodelabels \
1154 Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) = { \
1155 .num_nodelabels = DT_NUM_NODELABELS(node_id), \
1156 .nodelabels = DT_NODELABEL_STRING_ARRAY(node_id), \
1159 static const struct device_dt_metadata \
1160 Z_DEVICE_DT_METADATA_NAME_GET(dev_id) = { \
1161 .nl = &Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id), \
1172#define Z_DEVICE_INIT_SUB_PRIO(node_id) \
1173 COND_CODE_1(DT_NODE_EXISTS(node_id), \
1174 (DT_DEP_ORD_STR_SORTABLE(node_id)), (0))
1182#define Z_DEVICE_MAX_NAME_LEN 48U
1189#define Z_DEVICE_NAME_CHECK(name) \
1190 BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN, \
1191 Z_STRINGIFY(name) " too long")
1199#define Z_DEVICE_OPS(init_fn_, deinit_fn_) \
1201 .init = (init_fn_), \
1202 IF_ENABLED(CONFIG_DEVICE_DEINIT_SUPPORT, \
1203 (.deinit = (deinit_fn_),)) \
1222#define Z_DEVICE_INIT(name_, init_fn_, deinit_fn_, flags_, pm_, data_, config_, api_, \
1223 state_, deps_, node_id_, dev_id_) \
1226 .config = (config_), \
1228 .state = (state_), \
1230 .ops = Z_DEVICE_OPS(init_fn_, deinit_fn_), \
1231 .flags = (flags_), \
1232 IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) \
1233 IF_ENABLED(CONFIG_PM_DEVICE, Z_DEVICE_INIT_PM_BASE(pm_)) \
1234 IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
1235 (IF_ENABLED(DT_NODE_EXISTS(node_id_), \
1236 (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET( \
1245#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100
1246# define Z_DEVICE_INIT_PM_BASE(pm_) ({ .pm_base = (pm_),},)
1248# define Z_DEVICE_INIT_PM_BASE(pm_) (.pm_base = (pm_),)
1257#define Z_DEVICE_SECTION_NAME(level, prio) \
1258 _CONCAT(INIT_LEVEL_ORD(level), _##prio)
1279#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, pm, data, config, \
1280 level, prio, api, state, deps) \
1281 IF_DISABLED(DT_NODE_EXISTS(node_id), (static)) \
1282 IF_DISABLED(Z_DEVICE_IS_MUTABLE(node_id), (const)) \
1283 STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
1284 device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
1285 Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
1286 Z_DEVICE_INIT(name, init_fn, deinit_fn, flags, pm, data, config, api, state, deps, \
1294#define Z_DEVICE_CHECK_INIT_LEVEL(level) \
1295 COND_CASE_1(Z_INIT_PRE_KERNEL_1_##level, (), \
1296 Z_INIT_PRE_KERNEL_2_##level, (), \
1297 Z_INIT_POST_KERNEL_##level, (), \
1298 (ZERO_OR_COMPILE_ERROR(0)))
1309#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio) \
1310 Z_DEVICE_CHECK_INIT_LEVEL(level) \
1312 static const Z_DECL_ALIGN(struct init_entry) __used __noasan Z_INIT_ENTRY_SECTION( \
1313 level, prio, Z_DEVICE_INIT_SUB_PRIO(node_id)) \
1314 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
1316 .dev = (const struct device *)&DEVICE_NAME_GET(dev_id), \
1341#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, pm, \
1342 data, config, level, prio, api, state, ...) \
1343 Z_DEVICE_NAME_CHECK(name); \
1345 IF_ENABLED(CONFIG_DEVICE_DEPS, \
1346 (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \
1348 IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
1349 (IF_ENABLED(DT_NODE_EXISTS(node_id), \
1350 (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
1352 Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, \
1353 pm, data, config, level, prio, api, state, \
1354 Z_DEVICE_DEPS_NAME(dev_id)); \
1356 Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio); \
1358 IF_ENABLED(CONFIG_LLEXT, \
1359 (IF_ENABLED(DT_NODE_EXISTS(node_id), \
1360 (Z_DEVICE_EXPORT(node_id);))))
1372#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \
1373 extern IF_DISABLED(Z_DEVICE_IS_MUTABLE(node_id), (const)) \
1374 struct device DEVICE_DT_NAME_GET(node_id);
1379#define Z_DEVICE_API_TYPE(_class) _CONCAT(_class, _driver_api)
1382#define Z_DEVICE_API_GET(_class, _dev) ((const struct Z_DEVICE_API_TYPE(_class) *)_dev->api)
1385#define Z_DEVICE_API_EXT_END(_struct_type) CONCAT(_, _struct_type, _ext_end)
1395#define DEVICE_API(_class, _name) const STRUCT_SECTION_ITERABLE(Z_DEVICE_API_TYPE(_class), _name)
1414#define DEVICE_API_EXTENDS(_child, _parent, _member) \
1415 CONTAINER_OF_VALIDATE((struct Z_DEVICE_API_TYPE(_parent) *)0, \
1416 struct Z_DEVICE_API_TYPE(_child), _member) \
1417 BUILD_ASSERT(offsetof(struct Z_DEVICE_API_TYPE(_child), _member) == 0, \
1418 "Parent API struct must be the first member of child API struct")
1430#define DEVICE_API_IS(_class, _dev) \
1432 STRUCT_SECTION_START_EXTERN(Z_DEVICE_API_TYPE(_class)); \
1433 extern const uint8_t Z_DEVICE_API_EXT_END(Z_DEVICE_API_TYPE(_class))[]; \
1435 ((const uint8_t *)Z_DEVICE_API_GET(_class, _dev) < \
1436 Z_DEVICE_API_EXT_END(Z_DEVICE_API_TYPE(_class)) && \
1437 (const uint8_t *)Z_DEVICE_API_GET(_class, _dev) >= \
1438 (const uint8_t *)STRUCT_SECTION_START(Z_DEVICE_API_TYPE(_class))); \
1449#define DEVICE_API_GET(_class, _dev) \
1451 IF_ENABLED(CONFIG_DEVICE_API_ASSERT, ( \
1452 __ASSERT(_dev != NULL, "device is NULL"); \
1453 __ASSERT(DEVICE_API_IS(_class, _dev), "device API is not %s", STRINGIFY(_class)); \
1455 Z_DEVICE_API_GET(_class, _dev); \
1462#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:644
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:724
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition device.h:563
#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:587
int device_deinit(const struct device *dev)
De-initialize a device.
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:622
bool device_is_ready(const struct device *dev)
Verify that a device is ready for use.
uint8_t device_flags_t
Device flags.
Definition device.h:488
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:680
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:3296
#define STRUCT_SECTION_START_EXTERN(struct_type)
iterable section extern for start symbol for a struct
Definition iterable_sections.h:187
#define STRUCT_SECTION_START(struct_type)
iterable section start symbol for a struct type
Definition iterable_sections.h:177
#define STRUCT_SECTION_COUNT(struct_type, dst)
Count elements in a section.
Definition iterable_sections.h:348
#define NULL
Definition iar_missing_defs.h:20
Definitions of various linker Sections.
Header file for System Power Management state definitions.
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__INT16_TYPE__ int16_t
Definition stdint.h:73
Device operations.
Definition device.h:501
int(* init)(const struct device *dev)
Initialization function.
Definition device.h:503
Runtime device dynamic structure (in RAM) per driver instance.
Definition device.h:458
bool initialized
Indicates the device initialization function has been invoked.
Definition device.h:471
uint8_t init_res
Device initialization return code (positive errno value).
Definition device.h:466
Runtime device structure (in ROM) per driver instance.
Definition device.h:513
struct pm_device_base * pm_base
Definition device.h:545
const device_handle_t * deps
Optional pointer to dependencies associated with the device.
Definition device.h:537
struct pm_device_isr * pm_isr
Definition device.h:547
const char * name
Name of the device instance.
Definition device.h:515
struct pm_device * pm
Definition device.h:546
void * data
Address of the device instance private data.
Definition device.h:523
const void * api
Address of the API structure exposed by the device instance.
Definition device.h:519
device_flags_t flags
Device flags.
Definition device.h:527
struct device_ops ops
Device operations.
Definition device.h:525
struct device_state * state
Address of the common device state.
Definition device.h:521
const void * config
Address of device instance config information.
Definition device.h:517
const struct device_dt_metadata * dt_meta
Definition device.h:551
Device PM info.
Definition device.h:211
Runtime PM info for device with synchronous PM.
Definition device.h:259
Runtime PM info for device with generic PM.
Definition device.h:235
Linkable loadable extension symbol definitions.
Iterable sections helpers.