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
38#define Z_DEVICE_DEPS_SEP INT16_MIN
39
44#define Z_DEVICE_DEPS_ENDS INT16_MAX
45
47#define Z_DEVICE_IS_MUTABLE(node_id) \
48 COND_CODE_1(IS_ENABLED(CONFIG_DEVICE_MUTABLE), (DT_PROP(node_id, zephyr_mutable)), (0))
49
68
70#define DEVICE_HANDLE_NULL 0
71
91#define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
92
93/* Node paths can exceed the maximum size supported by
94 * device_get_binding() in user mode; this macro synthesizes a unique
95 * dev_id from a devicetree node while staying within this maximum
96 * size.
97 *
98 * The ordinal used in this name can be mapped to the path by
99 * examining zephyr/include/generated/devicetree_generated.h.
100 */
101#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
102
133#define DEVICE_DEFINE(dev_id, name, init_fn, pm, data, config, level, prio, \
134 api) \
135 Z_DEVICE_STATE_DEFINE(dev_id); \
136 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, pm, data, \
137 config, level, prio, api, \
138 &Z_DEVICE_STATE_NAME(dev_id))
139
151#define DEVICE_DT_NAME(node_id) \
152 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
153
161#define DEVICE_DT_DEFER(node_id) \
162 DT_PROP(node_id, zephyr_deferred_init)
163
194#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \
195 ...) \
196 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
197 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
198 DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
199 level, prio, api, \
200 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
201 __VA_ARGS__)
202
211#define DEVICE_DT_INST_DEFINE(inst, ...) \
212 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
213
228#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
229
245#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
246
256#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
257
274#define DEVICE_DT_GET_ANY(compat) \
275 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
276 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
277 (NULL))
278
295#define DEVICE_DT_GET_ONE(compat) \
296 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
297 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
298 (ZERO_OR_COMPILE_ERROR(0)))
299
310#define DEVICE_DT_GET_OR_NULL(node_id) \
311 COND_CODE_1(DT_NODE_HAS_STATUS(node_id, okay), \
312 (DEVICE_DT_GET(node_id)), (NULL))
313
324#define DEVICE_GET(dev_id) (&DEVICE_NAME_GET(dev_id))
325
340#define DEVICE_DECLARE(dev_id) \
341 static const struct device DEVICE_NAME_GET(dev_id)
342
350#define DEVICE_INIT_DT_GET(node_id) \
351 (&Z_INIT_ENTRY_NAME(DEVICE_DT_NAME_GET(node_id)))
352
360#define DEVICE_INIT_GET(dev_id) (&Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)))
361
379
383 bool initialized : 1;
384};
385
386struct pm_device_base;
387struct pm_device;
388struct pm_device_isr;
389
390#ifdef CONFIG_DEVICE_DEPS_DYNAMIC
391#define Z_DEVICE_DEPS_CONST
392#else
393#define Z_DEVICE_DEPS_CONST const
394#endif
395
399struct device {
401 const char *name;
403 const void *config;
405 const void *api;
409 void *data;
410#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
419 Z_DEVICE_DEPS_CONST device_handle_t *deps;
420#endif /* CONFIG_DEVICE_DEPS */
421#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
426 union {
428 struct pm_device *pm;
430 };
431#endif
432};
433
442static inline device_handle_t device_handle_get(const struct device *dev)
443{
446
447 /* TODO: If/when devices can be constructed that are not part of the
448 * fixed sequence we'll need another solution.
449 */
450 if (dev != NULL) {
451 ret = 1 + (device_handle_t)(dev - STRUCT_SECTION_START(device));
452 }
453
454 return ret;
455}
456
465static inline const struct device *
467{
469 const struct device *dev = NULL;
470 size_t numdev;
471
473
474 if ((dev_handle > 0) && ((size_t)dev_handle <= numdev)) {
475 dev = &STRUCT_SECTION_START(device)[dev_handle - 1];
476 }
477
478 return dev;
479}
480
481#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
482
501typedef int (*device_visitor_callback_t)(const struct device *dev,
502 void *context);
503
522static inline const device_handle_t *
523device_required_handles_get(const struct device *dev, size_t *count)
524{
525 const device_handle_t *rv = dev->deps;
526
527 if (rv != NULL) {
528 size_t i = 0;
529
530 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
531 (rv[i] != Z_DEVICE_DEPS_SEP)) {
532 ++i;
533 }
534 *count = i;
535 }
536
537 return rv;
538}
539
558static inline const device_handle_t *
559device_injected_handles_get(const struct device *dev, size_t *count)
560{
561 const device_handle_t *rv = dev->deps;
562 size_t region = 0;
563 size_t i = 0;
564
565 if (rv != NULL) {
566 /* Fast forward to injected devices */
567 while (region != 1) {
568 if (*rv == Z_DEVICE_DEPS_SEP) {
569 region++;
570 }
571 rv++;
572 }
573 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
574 (rv[i] != Z_DEVICE_DEPS_SEP)) {
575 ++i;
576 }
577 *count = i;
578 }
579
580 return rv;
581}
582
602static inline const device_handle_t *
603device_supported_handles_get(const struct device *dev, size_t *count)
604{
605 const device_handle_t *rv = dev->deps;
606 size_t region = 0;
607 size_t i = 0;
608
609 if (rv != NULL) {
610 /* Fast forward to supporting devices */
611 while (region != 2) {
612 if (*rv == Z_DEVICE_DEPS_SEP) {
613 region++;
614 }
615 rv++;
616 }
617 /* Count supporting devices.
618 * Trailing NULL's can be injected by gen_device_deps.py due to
619 * CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM
620 */
621 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
622 (rv[i] != DEVICE_HANDLE_NULL)) {
623 ++i;
624 }
625 *count = i;
626 }
627
628 return rv;
629}
630
661int device_required_foreach(const struct device *dev,
662 device_visitor_callback_t visitor_cb,
663 void *context);
664
694int device_supported_foreach(const struct device *dev,
695 device_visitor_callback_t visitor_cb,
696 void *context);
697
698#endif /* CONFIG_DEVICE_DEPS */
699
720__syscall const struct device *device_get_binding(const char *name);
721
730size_t z_device_get_all_static(const struct device **devices);
731
746bool z_device_is_ready(const struct device *dev);
747
764__syscall bool device_is_ready(const struct device *dev);
765
766static inline bool z_impl_device_is_ready(const struct device *dev)
767{
768 return z_device_is_ready(dev);
769}
770
785__syscall int device_init(const struct device *dev);
786
797#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
798
804#define Z_DEVICE_STATE_DEFINE(dev_id) \
805 static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
806 __attribute__((__section__(".z_devstate")))
807
808#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
809
816#define Z_DEVICE_DEPS_NAME(dev_id) _CONCAT(__devicedeps_, dev_id)
817
823#define Z_DEVICE_EXTRA_DEPS(...) \
824 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
825
827#define Z_DEVICE_DEPS_SECTION \
828 __attribute__((__section__(".__device_deps_pass1")))
829
830#ifdef __cplusplus
831#define Z_DEVICE_DEPS_EXTERN extern
832#else
833#define Z_DEVICE_DEPS_EXTERN
834#endif
835
871#define Z_DEVICE_DEPS_DEFINE(node_id, dev_id, ...) \
872 extern Z_DEVICE_DEPS_CONST device_handle_t Z_DEVICE_DEPS_NAME( \
873 dev_id)[]; \
874 Z_DEVICE_DEPS_CONST Z_DECL_ALIGN(device_handle_t) \
875 Z_DEVICE_DEPS_SECTION Z_DEVICE_DEPS_EXTERN __weak \
876 Z_DEVICE_DEPS_NAME(dev_id)[] = { \
877 COND_CODE_1( \
878 DT_NODE_EXISTS(node_id), \
879 (DT_DEP_ORD(node_id), DT_REQUIRES_DEP_ORDS(node_id)), \
880 (DEVICE_HANDLE_NULL,)) \
881 Z_DEVICE_DEPS_SEP, \
882 Z_DEVICE_EXTRA_DEPS(__VA_ARGS__) \
883 Z_DEVICE_DEPS_SEP, \
884 COND_CODE_1(DT_NODE_EXISTS(node_id), \
885 (DT_SUPPORTS_DEP_ORDS(node_id)), ()) \
886 }
887
888#endif /* CONFIG_DEVICE_DEPS */
889
897#define Z_DEVICE_INIT_SUB_PRIO(node_id) \
898 COND_CODE_1(DT_NODE_EXISTS(node_id), \
899 (DT_DEP_ORD_STR_SORTABLE(node_id)), (0))
900
907#define Z_DEVICE_MAX_NAME_LEN 48U
908
914#define Z_DEVICE_NAME_CHECK(name) \
915 BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN, \
916 Z_STRINGIFY(DEVICE_NAME_GET(name)) " too long")
917
929#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_) \
930 { \
931 .name = name_, \
932 .config = (config_), \
933 .api = (api_), \
934 .state = (state_), \
935 .data = (data_), \
936 IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) \
937 IF_ENABLED(CONFIG_PM_DEVICE, ({ .pm_base = (pm_),)}) \
938 }
939
946#define Z_DEVICE_SECTION_NAME(level, prio) \
947 _CONCAT(INIT_LEVEL_ORD(level), _##prio)
948
965#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \
966 deps) \
967 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
968 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \
969 STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \
970 device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \
971 Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \
972 Z_DEVICE_INIT(name, pm, data, config, api, state, deps)
973
974/* deprecated device initialization levels */
975#define Z_DEVICE_LEVEL_DEPRECATED_EARLY \
976 __WARN("EARLY device driver level is deprecated")
977#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_1
978#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_2
979#define Z_DEVICE_LEVEL_DEPRECATED_POST_KERNEL
980#define Z_DEVICE_LEVEL_DEPRECATED_APPLICATION \
981 __WARN("APPLICATION device driver level is deprecated")
982#define Z_DEVICE_LEVEL_DEPRECATED_SMP \
983 __WARN("SMP device driver level is deprecated")
984
990#define Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \
991 Z_DEVICE_LEVEL_DEPRECATED_##level
992
1003#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \
1004 Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \
1005 \
1006 static const Z_DECL_ALIGN(struct init_entry) __used __noasan Z_INIT_ENTRY_SECTION( \
1007 level, prio, Z_DEVICE_INIT_SUB_PRIO(node_id)) \
1008 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
1009 .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
1010 (init_fn_)}, \
1011 { \
1012 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
1013 &DEVICE_NAME_GET(dev_id), \
1014 }, \
1015 }
1016
1017#define Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_) \
1018 static const Z_DECL_ALIGN(struct init_entry) __used __noasan \
1019 __attribute__((__section__(".z_deferred_init"))) \
1020 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
1021 .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
1022 (init_fn_)}, \
1023 { \
1024 COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \
1025 &DEVICE_NAME_GET(dev_id), \
1026 }, \
1027 }
1028
1050#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
1051 level, prio, api, state, ...) \
1052 Z_DEVICE_NAME_CHECK(name); \
1053 \
1054 IF_ENABLED(CONFIG_DEVICE_DEPS, \
1055 (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \
1056 \
1057 Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
1058 prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
1059 \
1060 COND_CODE_1(DEVICE_DT_DEFER(node_id), \
1061 (Z_DEFER_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, \
1062 init_fn)), \
1063 (Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, \
1064 level, prio)));
1065
1076#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \
1077 extern COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), \
1078 (const)) struct device DEVICE_DT_NAME_GET(node_id);
1079
1080DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL)
1081
1082
1084#ifdef __cplusplus
1085}
1086#endif
1087
1088#include <syscalls/device.h>
1089
1090#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:67
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:523
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:603
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition: device.h:442
#define DEVICE_HANDLE_NULL
Flag value used to identify an unknown device.
Definition: device.h:70
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:466
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:501
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:559
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:2674
#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:370
bool initialized
Indicates the device initialization function has been invoked.
Definition: device.h:383
uint8_t init_res
Device initialization return code (positive errno value).
Definition: device.h:378
Runtime device structure (in ROM) per driver instance.
Definition: device.h:399
struct pm_device_base * pm_base
Definition: device.h:427
const device_handle_t * deps
Optional pointer to dependencies associated with the device.
Definition: device.h:419
struct pm_device_isr * pm_isr
Definition: device.h:429
const char * name
Name of the device instance.
Definition: device.h:401
struct pm_device * pm
Definition: device.h:428
void * data
Address of the device instance private data.
Definition: device.h:409
const void * api
Address of the API structure exposed by the device instance.
Definition: device.h:405
struct device_state * state
Address of the common device state.
Definition: device.h:407
const void * config
Address of device instance config information.
Definition: device.h:403
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
Macros to abstract toolchain specific capabilities.
Misc utilities.