Zephyr API Documentation 4.5.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
device.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
12
13#ifndef ZEPHYR_INCLUDE_DEVICE_H_
14#define ZEPHYR_INCLUDE_DEVICE_H_
15
16#include <stdint.h>
17
18#include <zephyr/devicetree.h>
19#include <zephyr/init.h>
21#include <zephyr/pm/state.h>
24#include <zephyr/sys/util.h>
25#include <zephyr/toolchain.h>
26
27#ifdef CONFIG_LLEXT
28#include <zephyr/llext/symbol.h>
29#endif
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
42
44
49#define Z_DEVICE_DEPS_SEP INT16_MIN
50
55#define Z_DEVICE_DEPS_ENDS INT16_MAX
56
58#define Z_DEVICE_IS_MUTABLE(node_id) \
59 COND_CODE_1(IS_ENABLED(CONFIG_DEVICE_MUTABLE), (DT_PROP(node_id, zephyr_mutable)), (0))
60
62
79
81#define DEVICE_HANDLE_NULL 0
82
102#define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
103
104/* This macro synthesizes a unique dev_id from a devicetree node by using
105 * the node's dependency ordinal.
106 *
107 * The ordinal used in this name can be mapped to the path by
108 * examining zephyr/include/generated/zephyr/devicetree_generated.h.
109 */
110#define Z_DEVICE_DT_DEP_ORD(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
111
112/* Same as above, but uses the hash of the node path instead of the ordinal.
113 *
114 * The hash used in this name can be mapped to the path by
115 * examining zephyr/include/generated/zephyr/devicetree_generated.h.
116 */
117#define Z_DEVICE_DT_HASH(node_id) _CONCAT(dts_, DT_NODE_HASH(node_id))
118
119/* By default, device identifiers are obtained using the dependency ordinal.
120 * When LLEXT_EXPORT_DEV_IDS_BY_HASH is defined, the main Zephyr binary exports
121 * DT identifiers via EXPORT_GROUP_SYMBOL_NAMED as hashed versions of their
122 * paths. When matching extensions are built, that is what they need to look
123 * for.
124 *
125 * The ordinal or hash used in this name can be mapped to the path by
126 * examining zephyr/include/generated/zephyr/devicetree_generated.h.
127 */
128#if defined(LL_EXTENSION_BUILD) && defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH)
129#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_HASH(node_id)
130#else
131#define Z_DEVICE_DT_DEV_ID(node_id) Z_DEVICE_DT_DEP_ORD(node_id)
132#endif
133
134#if defined(CONFIG_LLEXT_EXPORT_DEV_IDS_BY_HASH)
135/* Export device identifiers by hash */
136#define Z_DEVICE_EXPORT(node_id) \
137 EXPORT_GROUP_SYMBOL_NAMED(DEVICE, \
138 DEVICE_DT_NAME_GET(node_id), \
139 DEVICE_NAME_GET(Z_DEVICE_DT_HASH(node_id)))
140#else
141/* Export device identifiers using the builtin name */
142#define Z_DEVICE_EXPORT(node_id) \
143 EXPORT_GROUP_SYMBOL(DEVICE, DEVICE_DT_NAME_GET(node_id))
144#endif
145
182#define DEVICE_DEINIT_DEFINE(dev_id, name, init_fn, deinit_fn, pm, data, \
183 config, level, prio, api) \
184 Z_DEVICE_STATE_DEFINE(dev_id); \
185 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, deinit_fn, 0U, \
186 pm, data, config, level, prio, api, \
187 &Z_DEVICE_STATE_NAME(dev_id))
188
194#define DEVICE_DEFINE(dev_id, name, init_fn, pm, data, config, level, prio, \
195 api) \
196 DEVICE_DEINIT_DEFINE(dev_id, name, init_fn, NULL, pm, data, config, \
197 level, prio, api)
198
210#define DEVICE_DT_NAME(node_id) \
211 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
212
249#define DEVICE_DT_DEINIT_DEFINE(node_id, init_fn, deinit_fn, pm, data, config, \
250 level, prio, api, ...) \
251 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
252 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
253 DEVICE_DT_NAME(node_id), init_fn, deinit_fn, \
254 Z_DEVICE_DT_FLAGS(node_id), pm, data, config, level, \
255 prio, api, \
256 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
257 __VA_ARGS__)
258
265#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \
266 ...) \
267 DEVICE_DT_DEINIT_DEFINE(node_id, init_fn, NULL, pm, data, config, \
268 level, prio, api, __VA_ARGS__)
269
278#define DEVICE_DT_INST_DEINIT_DEFINE(inst, ...) \
279 DEVICE_DT_DEINIT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
280
289#define DEVICE_DT_INST_DEFINE(inst, ...) \
290 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
291
306#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
307
323#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
324
335#define DEVICE_DT_GET_COMMA(node_id) DEVICE_DT_GET(node_id),
336
346#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
347
358#define DEVICE_DT_INST_GET_COMMA(inst) DEVICE_DT_INST_GET(inst),
359
376#define DEVICE_DT_GET_ANY(compat) \
377 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
378 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
379 (NULL))
380
397#define DEVICE_DT_GET_ONE(compat) \
398 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
399 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
400 (ZERO_OR_COMPILE_ERROR(0)))
401
412#define DEVICE_DT_GET_OR_NULL(node_id) \
413 COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(node_id), \
414 (DEVICE_DT_GET(node_id)), (NULL))
415
429#define DEVICE_DT_GET_BY_IDX(node_id, prop, idx) \
430 DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx))
431
442#define DEVICE_GET(dev_id) (&DEVICE_NAME_GET(dev_id))
443
458#define DEVICE_DECLARE(dev_id) \
459 static const struct device DEVICE_NAME_GET(dev_id)
460
468#define DEVICE_INIT_DT_GET(node_id) \
469 (&Z_INIT_ENTRY_NAME(DEVICE_DT_NAME_GET(node_id)))
470
478#define DEVICE_INIT_GET(dev_id) (&Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)))
479
497
501 bool initialized : 1;
502};
503
504struct pm_device_base;
505struct pm_device;
506struct pm_device_isr;
507#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
508struct device_dt_metadata;
509#endif
510
511#ifdef CONFIG_DEVICE_DEPS_DYNAMIC
512#define Z_DEVICE_DEPS_CONST
513#else
514#define Z_DEVICE_DEPS_CONST const
515#endif
516
519
524
526#define DEVICE_FLAG_INIT_DEFERRED BIT(0)
527
529
533 int (*init)(const struct device *dev);
534#ifdef CONFIG_DEVICE_DEINIT_SUPPORT
536 int (*deinit)(const struct device *dev);
537#endif /* CONFIG_DEVICE_DEINIT_SUPPORT */
538};
539
543struct device {
545 const char *name;
547 const void *config;
549 const void *api;
553 void *data;
558#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
567 Z_DEVICE_DEPS_CONST device_handle_t *deps;
568#endif /* CONFIG_DEVICE_DEPS */
569#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
574 union {
578 struct pm_device *pm;
581 };
582#endif
583#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
588 const struct device_dt_metadata *dt_meta;
589#endif /* CONFIG_DEVICE_DT_METADATA */
590};
591
600static inline device_handle_t device_handle_get(const struct device *dev)
601{
604
605 /* TODO: If/when devices can be constructed that are not part of the
606 * fixed sequence we'll need another solution.
607 */
608 if (dev != NULL) {
609 ret = 1 + (device_handle_t)(dev - STRUCT_SECTION_START(device));
610 }
611
612 return ret;
613}
614
623static inline const struct device *
625{
627 const struct device *dev = NULL;
628 size_t numdev;
629
631
632 if ((dev_handle > 0) && ((size_t)dev_handle <= numdev)) {
633 dev = &STRUCT_SECTION_START(device)[dev_handle - 1];
634 }
635
636 return dev;
637}
638
639#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
640
659typedef int (*device_visitor_callback_t)(const struct device *dev,
660 void *context);
661
680static inline const device_handle_t *
681device_required_handles_get(const struct device *dev, size_t *count)
682{
683 const device_handle_t *rv = dev->deps;
684
685 if (rv != NULL) {
686 size_t i = 0;
687
688 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
689 (rv[i] != Z_DEVICE_DEPS_SEP)) {
690 ++i;
691 }
692 *count = i;
693 }
694
695 return rv;
696}
697
716static inline const device_handle_t *
717device_injected_handles_get(const struct device *dev, size_t *count)
718{
719 const device_handle_t *rv = dev->deps;
720 size_t region = 0;
721 size_t i = 0;
722
723 if (rv != NULL) {
724 /* Fast forward to injected devices */
725 while (region != 1) {
726 if (*rv == Z_DEVICE_DEPS_SEP) {
727 region++;
728 }
729 rv++;
730 }
731 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
732 (rv[i] != Z_DEVICE_DEPS_SEP)) {
733 ++i;
734 }
735 *count = i;
736 }
737
738 return rv;
739}
740
760static inline const device_handle_t *
761device_supported_handles_get(const struct device *dev, size_t *count)
762{
763 const device_handle_t *rv = dev->deps;
764 size_t region = 0;
765 size_t i = 0;
766
767 if (rv != NULL) {
768 /* Fast forward to supporting devices */
769 while (region != 2) {
770 if (*rv == Z_DEVICE_DEPS_SEP) {
771 region++;
772 }
773 rv++;
774 }
775 /* Count supporting devices.
776 * Trailing NULL's can be injected by gen_device_deps.py due to
777 * CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM
778 */
779 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
780 (rv[i] != DEVICE_HANDLE_NULL)) {
781 ++i;
782 }
783 *count = i;
784 }
785
786 return rv;
787}
788
819int device_required_foreach(const struct device *dev,
820 device_visitor_callback_t visitor_cb,
821 void *context);
822
852int device_supported_foreach(const struct device *dev,
853 device_visitor_callback_t visitor_cb,
854 void *context);
855
856#endif /* CONFIG_DEVICE_DEPS */
857
878__syscall const struct device *device_get_binding(const char *name);
879
888size_t z_device_get_all_static(const struct device **devices);
889
906__syscall bool device_is_ready(const struct device *dev);
907
908static inline bool z_impl_device_is_ready(const struct device *dev)
909{
910 /*
911 * if an invalid device pointer is passed as argument, this call
912 * reports the `device` as not ready for usage.
913 */
914 if (dev == NULL) {
915 return false;
916 }
917
918 return dev->state->initialized;
919}
920
929#define LOG_WRN_DEVICE_NOT_READY(dev) \
930 LOG_WRN("%s device not ready", (dev) ? (dev)->name : "(null)")
931
940#define LOG_ERR_DEVICE_NOT_READY(dev) \
941 LOG_ERR("%s device not ready", (dev) ? (dev)->name : "(null)")
942
952#define LOG_INST_WRN_DEVICE_NOT_READY(_log_inst, dev) \
953 LOG_INST_WRN(_log_inst, "%s device not ready", (dev) ? (dev)->name : "(null)")
954
964#define LOG_INST_ERR_DEVICE_NOT_READY(_log_inst, dev) \
965 LOG_INST_ERR(_log_inst, "%s device not ready", (dev) ? (dev)->name : "(null)")
966
981__syscall int device_init(const struct device *dev);
982
1004__syscall int device_deinit(const struct device *dev);
1005
1009
1011
1016#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
1017
1023#define Z_DEVICE_STATE_DEFINE(dev_id) \
1024 static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
1025 __attribute__((__section__(".z_devstate")))
1026
1032#define Z_DEVICE_DT_FLAGS(node_id) \
1033 (DT_PROP_OR(node_id, zephyr_deferred_init, 0U) * DEVICE_FLAG_INIT_DEFERRED)
1034
1035#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
1036
1043#define Z_DEVICE_DEPS_NAME(dev_id) _CONCAT(__devicedeps_, dev_id)
1044
1050#define Z_DEVICE_EXTRA_DEPS(...) \
1051 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
1052
1054#define Z_DEVICE_DEPS_SECTION \
1055 __attribute__((__section__(".__device_deps_pass1")))
1056
1057#ifdef __cplusplus
1058#define Z_DEVICE_DEPS_EXTERN extern
1059#else
1060#define Z_DEVICE_DEPS_EXTERN
1061#endif
1062
1098#define Z_DEVICE_DEPS_DEFINE(node_id, dev_id, ...) \
1099 extern Z_DEVICE_DEPS_CONST device_handle_t Z_DEVICE_DEPS_NAME( \
1100 dev_id)[]; \
1101 Z_DEVICE_DEPS_CONST Z_DECL_ALIGN(device_handle_t) \
1102 Z_DEVICE_DEPS_SECTION Z_DEVICE_DEPS_EXTERN __weak \
1103 Z_DEVICE_DEPS_NAME(dev_id)[] = { \
1104 COND_CODE_1( \
1105 DT_NODE_EXISTS(node_id), \
1106 (DT_DEP_ORD(node_id), DT_REQUIRES_DEP_ORDS(node_id)), \
1107 (DEVICE_HANDLE_NULL,)) /**/ \
1108 Z_DEVICE_DEPS_SEP, \
1109 Z_DEVICE_EXTRA_DEPS(__VA_ARGS__) /**/ \
1110 Z_DEVICE_DEPS_SEP, \
1111 IF_ENABLED(DT_NODE_EXISTS(node_id), \
1112 (DT_SUPPORTS_DEP_ORDS(node_id))) /**/ \
1113 }
1114
1115#endif /* CONFIG_DEVICE_DEPS */
1116#if defined(CONFIG_DEVICE_DT_METADATA) || defined(__DOXYGEN__)
1120struct device_dt_nodelabels {
1121 /* @brief number of elements in the nodelabels array */
1122 size_t num_nodelabels;
1123 /* @brief array of node labels as strings, exactly as they
1124 * appear in the final devicetree
1125 */
1126 const char *nodelabels[];
1127};
1128
1136struct device_dt_metadata {
1141 const struct device_dt_nodelabels *nl;
1142};
1143
1162__syscall const struct device *device_get_by_dt_nodelabel(const char *nodelabel);
1163
1169static inline const struct device_dt_nodelabels *
1170device_get_dt_nodelabels(const struct device *dev)
1171{
1172 if (dev->dt_meta == NULL) {
1173 return NULL;
1174 }
1175 return dev->dt_meta->nl;
1176}
1177
1184#define Z_DEVICE_MAX_NODELABEL_LEN Z_DEVICE_MAX_NAME_LEN
1185
1190#define Z_DEVICE_DT_METADATA_NAME_GET(dev_id) UTIL_CAT(__dev_dt_meta_, dev_id)
1191
1196#define Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) UTIL_CAT(__dev_dt_nodelabels_, dev_id)
1197
1204#define Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id) \
1205 static const struct device_dt_nodelabels \
1206 Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id) = { \
1207 .num_nodelabels = DT_NUM_NODELABELS(node_id), \
1208 .nodelabels = DT_NODELABEL_STRING_ARRAY(node_id), \
1209 }; \
1210 \
1211 static const struct device_dt_metadata \
1212 Z_DEVICE_DT_METADATA_NAME_GET(dev_id) = { \
1213 .nl = &Z_DEVICE_DT_NODELABELS_NAME_GET(dev_id), \
1214 };
1215#endif /* CONFIG_DEVICE_DT_METADATA */
1216
1224#define Z_DEVICE_INIT_SUB_PRIO(node_id) \
1225 COND_CODE_1(DT_NODE_EXISTS(node_id), \
1226 (DT_DEP_ORD_STR_SORTABLE(node_id)), (0))
1227
1234#define Z_DEVICE_MAX_NAME_LEN 48U
1235
1241#define Z_DEVICE_NAME_CHECK(name) \
1242 BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN, \
1243 Z_STRINGIFY(name) " too long")
1244
1251#define Z_DEVICE_OPS(init_fn_, deinit_fn_) \
1252 { \
1253 .init = (init_fn_), \
1254 IF_ENABLED(CONFIG_DEVICE_DEINIT_SUPPORT, \
1255 (.deinit = (deinit_fn_),)) \
1256 }
1257
1274#define Z_DEVICE_INIT(name_, init_fn_, deinit_fn_, flags_, pm_, data_, config_, api_, \
1275 state_, deps_, node_id_, dev_id_) \
1276 { \
1277 .name = name_, \
1278 .config = (config_), \
1279 .api = (api_), \
1280 .state = (state_), \
1281 .data = (data_), \
1282 .ops = Z_DEVICE_OPS(init_fn_, deinit_fn_), \
1283 .flags = (flags_), \
1284 IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) /**/ \
1285 IF_ENABLED(CONFIG_PM_DEVICE, Z_DEVICE_INIT_PM_BASE(pm_)) /**/ \
1286 IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
1287 (IF_ENABLED(DT_NODE_EXISTS(node_id_), \
1288 (.dt_meta = &Z_DEVICE_DT_METADATA_NAME_GET( \
1289 dev_id_),)))) \
1290 }
1291
1292/*
1293 * Anonymous unions require C11. Some pre-C11 gcc versions have early support for anonymous
1294 * unions but they require these braces when combined with C99 designated initializers. For
1295 * more details see https://docs.zephyrproject.org/latest/develop/languages/cpp/
1296 */
1297#if defined(__STDC_VERSION__) && (__STDC_VERSION__) < 201100
1298# define Z_DEVICE_INIT_PM_BASE(pm_) ({ .pm_base = (pm_),},)
1299#else
1300# define Z_DEVICE_INIT_PM_BASE(pm_) (.pm_base = (pm_),)
1301#endif
1302
1309#define Z_DEVICE_SECTION_NAME(level, prio) \
1310 _CONCAT(INIT_LEVEL_ORD(level), _##prio)
1311
1331#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, pm, data, config, \
1332 level, prio, api, state, deps) \
1333 IF_DISABLED(DT_NODE_EXISTS(node_id), (static)) \
1334 IF_DISABLED(Z_DEVICE_IS_MUTABLE(node_id), (const)) \
1335 STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
1336 device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
1337 Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
1338 Z_DEVICE_INIT(name, init_fn, deinit_fn, flags, pm, data, config, api, state, deps, \
1339 node_id, dev_id)
1340
1346#define Z_DEVICE_CHECK_INIT_LEVEL(level) \
1347 COND_CASE_1(Z_INIT_PRE_KERNEL_1_##level, (), \
1348 Z_INIT_PRE_KERNEL_2_##level, (), \
1349 Z_INIT_POST_KERNEL_##level, (), \
1350 (ZERO_OR_COMPILE_ERROR(0)))
1351
1361#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio) \
1362 Z_DEVICE_CHECK_INIT_LEVEL(level) \
1363 \
1364 static const Z_DECL_ALIGN(struct init_entry) __used __noasan Z_INIT_ENTRY_SECTION( \
1365 level, prio, Z_DEVICE_INIT_SUB_PRIO(node_id)) \
1366 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
1367 .init_fn = NULL, \
1368 .dev = (const struct device *)&DEVICE_NAME_GET(dev_id), \
1369 }
1370
1393#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, pm, \
1394 data, config, level, prio, api, state, ...) \
1395 Z_DEVICE_NAME_CHECK(name); \
1396 \
1397 IF_ENABLED(CONFIG_DEVICE_DEPS, \
1398 (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \
1399 \
1400 IF_ENABLED(CONFIG_DEVICE_DT_METADATA, \
1401 (IF_ENABLED(DT_NODE_EXISTS(node_id), \
1402 (Z_DEVICE_DT_METADATA_DEFINE(node_id, dev_id);))))\
1403 \
1404 Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, init_fn, deinit_fn, flags, \
1405 pm, data, config, level, prio, api, state, \
1406 Z_DEVICE_DEPS_NAME(dev_id)); \
1407 \
1408 Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, level, prio); \
1409 \
1410 IF_ENABLED(CONFIG_LLEXT, \
1411 (IF_ENABLED(DT_NODE_EXISTS(node_id), \
1412 (Z_DEVICE_EXPORT(node_id);))))
1413
1424#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \
1425 extern IF_DISABLED(Z_DEVICE_IS_MUTABLE(node_id), (const)) \
1426 struct device DEVICE_DT_NAME_GET(node_id);
1427
1428DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL)
1429
1430
1431#define Z_DEVICE_API_TYPE(_class) _CONCAT(_class, _driver_api)
1432
1434#define Z_DEVICE_API_GET(_class, _dev) ((const struct Z_DEVICE_API_TYPE(_class) *)_dev->api)
1435
1437#define Z_DEVICE_API_EXT_END(_struct_type) CONCAT(_, _struct_type, _ext_end)
1438
1440
1447#define DEVICE_API(_class, _name) const STRUCT_SECTION_ITERABLE(Z_DEVICE_API_TYPE(_class), _name)
1448
1466#define DEVICE_API_EXTENDS(_child, _parent, _member) \
1467 CONTAINER_OF_VALIDATE((struct Z_DEVICE_API_TYPE(_parent) *)0, \
1468 struct Z_DEVICE_API_TYPE(_child), _member) \
1469 BUILD_ASSERT(offsetof(struct Z_DEVICE_API_TYPE(_child), _member) == 0, \
1470 "Parent API struct must be the first member of child API struct")
1471
1482#define DEVICE_API_IS(_class, _dev) \
1483 ({ \
1484 STRUCT_SECTION_START_EXTERN(Z_DEVICE_API_TYPE(_class)); \
1485 extern const uint8_t Z_DEVICE_API_EXT_END(Z_DEVICE_API_TYPE(_class))[]; \
1486 \
1487 ((const uint8_t *)Z_DEVICE_API_GET(_class, _dev) < \
1488 Z_DEVICE_API_EXT_END(Z_DEVICE_API_TYPE(_class)) && \
1489 (const uint8_t *)Z_DEVICE_API_GET(_class, _dev) >= \
1490 (const uint8_t *)STRUCT_SECTION_START(Z_DEVICE_API_TYPE(_class))); \
1491 })
1492
1501#define DEVICE_API_GET(_class, _dev) \
1502 ({ \
1503 IF_ENABLED(CONFIG_DEVICE_API_ASSERT, ( \
1504 __ASSERT(_dev != NULL, "device is NULL"); \
1505 __ASSERT(DEVICE_API_IS(_class, _dev), "device API is not %s", STRINGIFY(_class)); \
1506 )); \
1507 Z_DEVICE_API_GET(_class, _dev); \
1508 })
1509
1510#ifdef __cplusplus
1511}
1512#endif
1513
1514#include <zephyr/syscalls/device.h>
1515
1516#endif /* ZEPHYR_INCLUDE_DEVICE_H_ */
Devicetree main header.
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:78
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:681
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:761
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition device.h:600
#define DEVICE_HANDLE_NULL
Flag value used to identify an unknown device.
Definition device.h:81
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:624
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:659
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:518
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:717
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:3593
#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
Public APIs for the system initialization infrastructure.
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:531
int(* init)(const struct device *dev)
Initialization function.
Definition device.h:533
Runtime device dynamic structure (in RAM) per driver instance.
Definition device.h:488
bool initialized
Indicates the device initialization function has been invoked and succeeded.
Definition device.h:501
uint8_t init_res
Device initialization return code (positive errno value).
Definition device.h:496
Runtime device structure (in ROM) per driver instance.
Definition device.h:543
struct pm_device_base * pm_base
Info common to all device PM variants.
Definition device.h:576
const device_handle_t * deps
Optional pointer to dependencies associated with the device.
Definition device.h:567
struct pm_device_isr * pm_isr
Info for a device using synchronous PM.
Definition device.h:580
const char * name
Name of the device instance.
Definition device.h:545
struct pm_device * pm
Info for a device using generic PM.
Definition device.h:578
void * data
Address of the device instance private data.
Definition device.h:553
const void * api
Address of the API structure exposed by the device instance.
Definition device.h:549
device_flags_t flags
Device flags.
Definition device.h:557
struct device_ops ops
Device operations.
Definition device.h:555
struct device_state * state
Address of the common device state.
Definition device.h:551
const void * config
Address of device instance config information.
Definition device.h:547
const struct device_dt_metadata * dt_meta
Devicetree metadata associated with the device (only available if <code class='doxyxref' data-stype=...
Definition device.h:588
Device PM info.
Definition device.h:213
Runtime PM info for device with synchronous PM.
Definition device.h:261
Runtime PM info for device with generic PM.
Definition device.h:237
Linkable loadable extension symbol definitions.
Iterable sections helpers.
Misc utilities.
Macros to abstract toolchain specific capabilities.