Zephyr API Documentation  3.6.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
7#ifndef ZEPHYR_INCLUDE_DEVICE_H_
8#define ZEPHYR_INCLUDE_DEVICE_H_
9
10#include <stdint.h>
11
12#include <zephyr/devicetree.h>
13#include <zephyr/init.h>
17#include <zephyr/sys/util.h>
18#include <zephyr/toolchain.h>
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
36#define Z_DEVICE_DEPS_SEP INT16_MIN
37
42#define Z_DEVICE_DEPS_ENDS INT16_MAX
43
45#define Z_DEVICE_IS_MUTABLE(node_id) \
46 COND_CODE_1(IS_ENABLED(CONFIG_DEVICE_MUTABLE), (DT_PROP(node_id, zephyr_mutable)), (0))
47
66
68#define DEVICE_HANDLE_NULL 0
69
89#define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
90
91/* Node paths can exceed the maximum size supported by
92 * device_get_binding() in user mode; this macro synthesizes a unique
93 * dev_id from a devicetree node while staying within this maximum
94 * size.
95 *
96 * The ordinal used in this name can be mapped to the path by
97 * examining zephyr/include/generated/devicetree_generated.h.
98 */
99#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
100
131#define DEVICE_DEFINE(dev_id, name, init_fn, pm, data, config, level, prio, \
132 api) \
133 Z_DEVICE_STATE_DEFINE(dev_id); \
134 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, pm, data, \
135 config, level, prio, api, \
136 &Z_DEVICE_STATE_NAME(dev_id))
137
149#define DEVICE_DT_NAME(node_id) \
150 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
151
182#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \
183 ...) \
184 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
185 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
186 DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
187 level, prio, api, \
188 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
189 __VA_ARGS__)
190
199#define DEVICE_DT_INST_DEFINE(inst, ...) \
200 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
201
216#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
217
233#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
234
244#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
245
262#define DEVICE_DT_GET_ANY(compat) \
263 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
264 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
265 (NULL))
266
283#define DEVICE_DT_GET_ONE(compat) \
284 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
285 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
286 (ZERO_OR_COMPILE_ERROR(0)))
287
298#define DEVICE_DT_GET_OR_NULL(node_id) \
299 COND_CODE_1(DT_NODE_HAS_STATUS(node_id, okay), \
300 (DEVICE_DT_GET(node_id)), (NULL))
301
312#define DEVICE_GET(dev_id) (&DEVICE_NAME_GET(dev_id))
313
328#define DEVICE_DECLARE(dev_id) \
329 static const struct device DEVICE_NAME_GET(dev_id)
330
338#define DEVICE_INIT_DT_GET(node_id) \
339 (&Z_INIT_ENTRY_NAME(DEVICE_DT_NAME_GET(node_id)))
340
348#define DEVICE_INIT_GET(dev_id) (&Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)))
349
367
371 bool initialized : 1;
372};
373
374struct pm_device_base;
375struct pm_device;
376struct pm_device_isr;
377
378#ifdef CONFIG_DEVICE_DEPS_DYNAMIC
379#define Z_DEVICE_DEPS_CONST
380#else
381#define Z_DEVICE_DEPS_CONST const
382#endif
383
387struct device {
389 const char *name;
391 const void *config;
393 const void *api;
397 void *data;
398#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
407 Z_DEVICE_DEPS_CONST device_handle_t *deps;
408#endif /* CONFIG_DEVICE_DEPS */
409#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
414 union {
416 struct pm_device *pm;
418 };
419#endif
420};
421
430static inline device_handle_t device_handle_get(const struct device *dev)
431{
434
435 /* TODO: If/when devices can be constructed that are not part of the
436 * fixed sequence we'll need another solution.
437 */
438 if (dev != NULL) {
439 ret = 1 + (device_handle_t)(dev - STRUCT_SECTION_START(device));
440 }
441
442 return ret;
443}
444
453static inline const struct device *
455{
457 const struct device *dev = NULL;
458 size_t numdev;
459
461
462 if ((dev_handle > 0) && ((size_t)dev_handle <= numdev)) {
463 dev = &STRUCT_SECTION_START(device)[dev_handle - 1];
464 }
465
466 return dev;
467}
468
469#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
470
489typedef int (*device_visitor_callback_t)(const struct device *dev,
490 void *context);
491
510static inline const device_handle_t *
511device_required_handles_get(const struct device *dev, size_t *count)
512{
513 const device_handle_t *rv = dev->deps;
514
515 if (rv != NULL) {
516 size_t i = 0;
517
518 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
519 (rv[i] != Z_DEVICE_DEPS_SEP)) {
520 ++i;
521 }
522 *count = i;
523 }
524
525 return rv;
526}
527
546static inline const device_handle_t *
547device_injected_handles_get(const struct device *dev, size_t *count)
548{
549 const device_handle_t *rv = dev->deps;
550 size_t region = 0;
551 size_t i = 0;
552
553 if (rv != NULL) {
554 /* Fast forward to injected devices */
555 while (region != 1) {
556 if (*rv == Z_DEVICE_DEPS_SEP) {
557 region++;
558 }
559 rv++;
560 }
561 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
562 (rv[i] != Z_DEVICE_DEPS_SEP)) {
563 ++i;
564 }
565 *count = i;
566 }
567
568 return rv;
569}
570
590static inline const device_handle_t *
591device_supported_handles_get(const struct device *dev, size_t *count)
592{
593 const device_handle_t *rv = dev->deps;
594 size_t region = 0;
595 size_t i = 0;
596
597 if (rv != NULL) {
598 /* Fast forward to supporting devices */
599 while (region != 2) {
600 if (*rv == Z_DEVICE_DEPS_SEP) {
601 region++;
602 }
603 rv++;
604 }
605 /* Count supporting devices.
606 * Trailing NULL's can be injected by gen_device_deps.py due to
607 * CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM
608 */
609 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
610 (rv[i] != DEVICE_HANDLE_NULL)) {
611 ++i;
612 }
613 *count = i;
614 }
615
616 return rv;
617}
618
649int device_required_foreach(const struct device *dev,
650 device_visitor_callback_t visitor_cb,
651 void *context);
652
682int device_supported_foreach(const struct device *dev,
683 device_visitor_callback_t visitor_cb,
684 void *context);
685
686#endif /* CONFIG_DEVICE_DEPS */
687
708__syscall const struct device *device_get_binding(const char *name);
709
718size_t z_device_get_all_static(const struct device **devices);
719
734bool z_device_is_ready(const struct device *dev);
735
752__syscall bool device_is_ready(const struct device *dev);
753
754static inline bool z_impl_device_is_ready(const struct device *dev)
755{
756 return z_device_is_ready(dev);
757}
758
769#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
770
776#define Z_DEVICE_STATE_DEFINE(dev_id) \
777 static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
778 __attribute__((__section__(".z_devstate")))
779
780#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
781
788#define Z_DEVICE_DEPS_NAME(dev_id) _CONCAT(__devicedeps_, dev_id)
789
795#define Z_DEVICE_EXTRA_DEPS(...) \
796 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
797
799#define Z_DEVICE_DEPS_SECTION \
800 __attribute__((__section__(".__device_deps_pass1")))
801
802#ifdef __cplusplus
803#define Z_DEVICE_DEPS_EXTERN extern
804#else
805#define Z_DEVICE_DEPS_EXTERN
806#endif
807
843#define Z_DEVICE_DEPS_DEFINE(node_id, dev_id, ...) \
844 extern Z_DEVICE_DEPS_CONST device_handle_t Z_DEVICE_DEPS_NAME( \
845 dev_id)[]; \
846 Z_DEVICE_DEPS_CONST Z_DECL_ALIGN(device_handle_t) \
847 Z_DEVICE_DEPS_SECTION Z_DEVICE_DEPS_EXTERN __weak \
848 Z_DEVICE_DEPS_NAME(dev_id)[] = { \
849 COND_CODE_1( \
850 DT_NODE_EXISTS(node_id), \
851 (DT_DEP_ORD(node_id), DT_REQUIRES_DEP_ORDS(node_id)), \
852 (DEVICE_HANDLE_NULL,)) \
853 Z_DEVICE_DEPS_SEP, \
854 Z_DEVICE_EXTRA_DEPS(__VA_ARGS__) \
855 Z_DEVICE_DEPS_SEP, \
856 COND_CODE_1(DT_NODE_EXISTS(node_id), \
857 (DT_SUPPORTS_DEP_ORDS(node_id)), ()) \
858 }
859
860#endif /* CONFIG_DEVICE_DEPS */
861
869#define Z_DEVICE_INIT_SUB_PRIO(node_id) \
870 COND_CODE_1(DT_NODE_EXISTS(node_id), \
871 (DT_DEP_ORD_STR_SORTABLE(node_id)), (0))
872
879#define Z_DEVICE_MAX_NAME_LEN 48U
880
886#define Z_DEVICE_NAME_CHECK(name) \
887 BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN, \
888 Z_STRINGIFY(DEVICE_NAME_GET(name)) " too long")
889
901#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_) \
902 { \
903 .name = name_, \
904 .config = (config_), \
905 .api = (api_), \
906 .state = (state_), \
907 .data = (data_), \
908 IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) \
909 IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),)}) \
910 }
911
918#define Z_DEVICE_SECTION_NAME(level, prio) \
919 _CONCAT(INIT_LEVEL_ORD(level), _##prio)
920
937#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \
938 deps) \
939 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
940 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \
941 STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
942 device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
943 Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
944 Z_DEVICE_INIT(name, pm, data, config, api, state, deps)
945
946/* deprecated device initialization levels */
947#define Z_DEVICE_LEVEL_DEPRECATED_EARLY \
948 __WARN("EARLY device driver level is deprecated")
949#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_1
950#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_2
951#define Z_DEVICE_LEVEL_DEPRECATED_POST_KERNEL
952#define Z_DEVICE_LEVEL_DEPRECATED_APPLICATION \
953 __WARN("APPLICATION device driver level is deprecated")
954#define Z_DEVICE_LEVEL_DEPRECATED_SMP \
955 __WARN("SMP device driver level is deprecated")
956
962#define Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \
963 Z_DEVICE_LEVEL_DEPRECATED_##level
964
975#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \
976 Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \
977 \
978 static const Z_DECL_ALIGN(struct init_entry) __used __noasan Z_INIT_ENTRY_SECTION( \
979 level, prio, Z_DEVICE_INIT_SUB_PRIO(node_id)) \
980 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
981 .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
982 (init_fn_)}, \
983 { \
984 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
985 &DEVICE_NAME_GET(dev_id), \
986 }, \
987 }
988
1010#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
1011 level, prio, api, state, ...) \
1012 Z_DEVICE_NAME_CHECK(name); \
1013 \
1014 IF_ENABLED(CONFIG_DEVICE_DEPS, \
1015 (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \
1016 \
1017 Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
1018 prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
1019 \
1020 Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, level, prio)
1021
1032#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \
1033 extern COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), \
1034 (const)) struct device DEVICE_DT_NAME_GET(node_id);
1035
1036DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL)
1037
1038
1040#ifdef __cplusplus
1041}
1042#endif
1043
1044#include <syscalls/device.h>
1045
1046#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:65
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:511
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:591
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition: device.h:430
#define DEVICE_HANDLE_NULL
Flag value used to identify an unknown device.
Definition: device.h:68
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:454
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:489
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:547
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:2671
#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:358
bool initialized
Indicates the device initialization function has been invoked.
Definition: device.h:371
uint8_t init_res
Device initialization return code (positive errno value).
Definition: device.h:366
Runtime device structure (in ROM) per driver instance.
Definition: device.h:387
struct pm_device_base * pm_base
Definition: device.h:415
const device_handle_t * deps
Optional pointer to dependencies associated with the device.
Definition: device.h:407
struct pm_device_isr * pm_isr
Definition: device.h:417
const char * name
Name of the device instance.
Definition: device.h:389
struct pm_device * pm
Definition: device.h:416
void * data
Address of the device instance private data.
Definition: device.h:397
const void * api
Address of the API structure exposed by the device instance.
Definition: device.h:393
struct device_state * state
Address of the common device state.
Definition: device.h:395
const void * config
Address of device instance config information.
Definition: device.h:391
Device PM info.
Definition: device.h:141
Runtime PM info for device with synchronous PM.
Definition: device.h:187
Runtime PM info for device with generic PM.
Definition: device.h:165
Macros to abstract toolchain specific capabilities.
Misc utilities.