Zephyr API Documentation  3.5.0
A Scalable Open Source RTOS
3.5.0
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
62
64#define DEVICE_HANDLE_NULL 0
65
85#define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
86
87/* Node paths can exceed the maximum size supported by
88 * device_get_binding() in user mode; this macro synthesizes a unique
89 * dev_id from a devicetree node while staying within this maximum
90 * size.
91 *
92 * The ordinal used in this name can be mapped to the path by
93 * examining zephyr/include/generated/devicetree_generated.h.
94 */
95#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
96
127#define DEVICE_DEFINE(dev_id, name, init_fn, pm, data, config, level, prio, \
128 api) \
129 Z_DEVICE_STATE_DEFINE(dev_id); \
130 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, pm, data, \
131 config, level, prio, api, \
132 &Z_DEVICE_STATE_NAME(dev_id))
133
145#define DEVICE_DT_NAME(node_id) \
146 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
147
178#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \
179 ...) \
180 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
181 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
182 DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
183 level, prio, api, \
184 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
185 __VA_ARGS__)
186
195#define DEVICE_DT_INST_DEFINE(inst, ...) \
196 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
197
212#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
213
229#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
230
240#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
241
258#define DEVICE_DT_GET_ANY(compat) \
259 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
260 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
261 (NULL))
262
279#define DEVICE_DT_GET_ONE(compat) \
280 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
281 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
282 (ZERO_OR_COMPILE_ERROR(0)))
283
294#define DEVICE_DT_GET_OR_NULL(node_id) \
295 COND_CODE_1(DT_NODE_HAS_STATUS(node_id, okay), \
296 (DEVICE_DT_GET(node_id)), (NULL))
297
308#define DEVICE_GET(dev_id) (&DEVICE_NAME_GET(dev_id))
309
324#define DEVICE_DECLARE(dev_id) \
325 static const struct device DEVICE_NAME_GET(dev_id)
326
334#define DEVICE_INIT_DT_GET(node_id) \
335 (&Z_INIT_ENTRY_NAME(DEVICE_DT_NAME_GET(node_id)))
336
344#define DEVICE_INIT_GET(dev_id) (&Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)))
345
363
367 bool initialized : 1;
368};
369
370struct pm_device;
371
372#ifdef CONFIG_DEVICE_DEPS_DYNAMIC
373#define Z_DEVICE_DEPS_CONST
374#else
375#define Z_DEVICE_DEPS_CONST const
376#endif
377
381struct device {
383 const char *name;
385 const void *config;
387 const void *api;
391 void *data;
392#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
401 Z_DEVICE_DEPS_CONST device_handle_t *deps;
402#endif /* CONFIG_DEVICE_DEPS */
403#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
408 struct pm_device *pm;
409#endif
410};
411
420static inline device_handle_t device_handle_get(const struct device *dev)
421{
424
425 /* TODO: If/when devices can be constructed that are not part of the
426 * fixed sequence we'll need another solution.
427 */
428 if (dev != NULL) {
430 }
431
432 return ret;
433}
434
443static inline const struct device *
445{
447 const struct device *dev = NULL;
448 size_t numdev;
449
451
452 if ((dev_handle > 0) && ((size_t)dev_handle <= numdev)) {
453 dev = &STRUCT_SECTION_START(device)[dev_handle - 1];
454 }
455
456 return dev;
457}
458
459#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
460
479typedef int (*device_visitor_callback_t)(const struct device *dev,
480 void *context);
481
500static inline const device_handle_t *
501device_required_handles_get(const struct device *dev, size_t *count)
502{
503 const device_handle_t *rv = dev->deps;
504
505 if (rv != NULL) {
506 size_t i = 0;
507
508 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
509 (rv[i] != Z_DEVICE_DEPS_SEP)) {
510 ++i;
511 }
512 *count = i;
513 }
514
515 return rv;
516}
517
536static inline const device_handle_t *
537device_injected_handles_get(const struct device *dev, size_t *count)
538{
539 const device_handle_t *rv = dev->deps;
540 size_t region = 0;
541 size_t i = 0;
542
543 if (rv != NULL) {
544 /* Fast forward to injected devices */
545 while (region != 1) {
546 if (*rv == Z_DEVICE_DEPS_SEP) {
547 region++;
548 }
549 rv++;
550 }
551 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
552 (rv[i] != Z_DEVICE_DEPS_SEP)) {
553 ++i;
554 }
555 *count = i;
556 }
557
558 return rv;
559}
560
580static inline const device_handle_t *
581device_supported_handles_get(const struct device *dev, size_t *count)
582{
583 const device_handle_t *rv = dev->deps;
584 size_t region = 0;
585 size_t i = 0;
586
587 if (rv != NULL) {
588 /* Fast forward to supporting devices */
589 while (region != 2) {
590 if (*rv == Z_DEVICE_DEPS_SEP) {
591 region++;
592 }
593 rv++;
594 }
595 /* Count supporting devices.
596 * Trailing NULL's can be injected by gen_device_deps.py due to
597 * CONFIG_PM_DEVICE_POWER_DOMAIN_DYNAMIC_NUM
598 */
599 while ((rv[i] != Z_DEVICE_DEPS_ENDS) &&
600 (rv[i] != DEVICE_HANDLE_NULL)) {
601 ++i;
602 }
603 *count = i;
604 }
605
606 return rv;
607}
608
639int device_required_foreach(const struct device *dev,
640 device_visitor_callback_t visitor_cb,
641 void *context);
642
672int device_supported_foreach(const struct device *dev,
673 device_visitor_callback_t visitor_cb,
674 void *context);
675
676#endif /* CONFIG_DEVICE_DEPS */
677
698__syscall const struct device *device_get_binding(const char *name);
699
708size_t z_device_get_all_static(const struct device **devices);
709
724bool z_device_is_ready(const struct device *dev);
725
742__syscall bool device_is_ready(const struct device *dev);
743
744static inline bool z_impl_device_is_ready(const struct device *dev)
745{
746 return z_device_is_ready(dev);
747}
748
759#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
760
766#define Z_DEVICE_STATE_DEFINE(dev_id) \
767 static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
768 __attribute__((__section__(".z_devstate")))
769
770#if defined(CONFIG_DEVICE_DEPS) || defined(__DOXYGEN__)
771
778#define Z_DEVICE_DEPS_NAME(dev_id) _CONCAT(__devicedeps_, dev_id)
779
785#define Z_DEVICE_EXTRA_DEPS(...) \
786 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
787
789#define Z_DEVICE_DEPS_SECTION \
790 __attribute__((__section__(".__device_deps_pass1")))
791
792#ifdef __cplusplus
793#define Z_DEVICE_DEPS_EXTERN extern
794#else
795#define Z_DEVICE_DEPS_EXTERN
796#endif
797
833#define Z_DEVICE_DEPS_DEFINE(node_id, dev_id, ...) \
834 extern Z_DEVICE_DEPS_CONST device_handle_t Z_DEVICE_DEPS_NAME( \
835 dev_id)[]; \
836 Z_DEVICE_DEPS_CONST Z_DECL_ALIGN(device_handle_t) \
837 Z_DEVICE_DEPS_SECTION Z_DEVICE_DEPS_EXTERN __weak \
838 Z_DEVICE_DEPS_NAME(dev_id)[] = { \
839 COND_CODE_1( \
840 DT_NODE_EXISTS(node_id), \
841 (DT_DEP_ORD(node_id), DT_REQUIRES_DEP_ORDS(node_id)), \
842 (DEVICE_HANDLE_NULL,)) \
843 Z_DEVICE_DEPS_SEP, \
844 Z_DEVICE_EXTRA_DEPS(__VA_ARGS__) \
845 Z_DEVICE_DEPS_SEP, \
846 COND_CODE_1(DT_NODE_EXISTS(node_id), \
847 (DT_SUPPORTS_DEP_ORDS(node_id)), ()) \
848 }
849
850#endif /* CONFIG_DEVICE_DEPS */
851
859#define Z_DEVICE_INIT_SUB_PRIO(node_id) \
860 COND_CODE_1(DT_NODE_EXISTS(node_id), \
861 (DT_DEP_ORD_STR_SORTABLE(node_id)), (0))
862
869#define Z_DEVICE_MAX_NAME_LEN 48U
870
876#define Z_DEVICE_NAME_CHECK(name) \
877 BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN, \
878 Z_STRINGIFY(DEVICE_NAME_GET(name)) " too long")
879
891#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, deps_) \
892 { \
893 .name = name_, \
894 .config = (config_), \
895 .api = (api_), \
896 .state = (state_), \
897 .data = (data_), \
898 IF_ENABLED(CONFIG_DEVICE_DEPS, (.deps = (deps_),)) \
899 IF_ENABLED(CONFIG_PM_DEVICE, (.pm = (pm_),)) \
900 }
901
908#define Z_DEVICE_SECTION_NAME(level, prio) \
909 _CONCAT(INIT_LEVEL_ORD(level), _##prio)
910
927#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
928 prio, api, state, deps) \
929 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
930 const STRUCT_SECTION_ITERABLE_NAMED(device, \
931 Z_DEVICE_SECTION_NAME(level, prio), \
932 DEVICE_NAME_GET(dev_id)) = \
933 Z_DEVICE_INIT(name, pm, data, config, api, state, deps)
934
935/* deprecated device initialization levels */
936#define Z_DEVICE_LEVEL_DEPRECATED_EARLY \
937 __WARN("EARLY device driver level is deprecated")
938#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_1
939#define Z_DEVICE_LEVEL_DEPRECATED_PRE_KERNEL_2
940#define Z_DEVICE_LEVEL_DEPRECATED_POST_KERNEL
941#define Z_DEVICE_LEVEL_DEPRECATED_APPLICATION \
942 __WARN("APPLICATION device driver level is deprecated")
943#define Z_DEVICE_LEVEL_DEPRECATED_SMP \
944 __WARN("SMP device driver level is deprecated")
945
951#define Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \
952 Z_DEVICE_LEVEL_DEPRECATED_##level
953
964#define Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn_, level, prio) \
965 Z_DEVICE_LEVEL_CHECK_DEPRECATED_LEVEL(level) \
966 \
967 static const Z_DECL_ALIGN(struct init_entry) __used __noasan \
968 Z_INIT_ENTRY_SECTION(level, prio, \
969 Z_DEVICE_INIT_SUB_PRIO(node_id)) \
970 Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \
971 .init_fn = {.dev = (init_fn_)}, \
972 .dev = &DEVICE_NAME_GET(dev_id), \
973 }
974
996#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
997 level, prio, api, state, ...) \
998 Z_DEVICE_NAME_CHECK(name); \
999 \
1000 IF_ENABLED(CONFIG_DEVICE_DEPS, \
1001 (Z_DEVICE_DEPS_DEFINE(node_id, dev_id, __VA_ARGS__);)) \
1002 \
1003 Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
1004 prio, api, state, Z_DEVICE_DEPS_NAME(dev_id)); \
1005 \
1006 Z_DEVICE_INIT_ENTRY_DEFINE(node_id, dev_id, init_fn, level, prio)
1007
1008#if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__)
1019#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \
1020 extern const struct device DEVICE_DT_NAME_GET(node_id);
1021
1022DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL)
1023#endif /* CONFIG_HAS_DTS */
1024
1027#ifdef __cplusplus
1028}
1029#endif
1030
1031#include <syscalls/device.h>
1032
1033#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:61
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:501
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:581
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition: device.h:420
#define DEVICE_HANDLE_NULL
Flag value used to identify an unknown device.
Definition: device.h:64
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:444
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:479
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:537
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:2498
#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:281
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:354
bool initialized
Indicates the device initialization function has been invoked.
Definition: device.h:367
uint8_t init_res
Device initialization return code (positive errno value).
Definition: device.h:362
Runtime device structure (in ROM) per driver instance.
Definition: device.h:381
const device_handle_t * deps
Optional pointer to dependencies associated with the device.
Definition: device.h:401
const char * name
Name of the device instance.
Definition: device.h:383
struct pm_device * pm
Reference to the device PM resources (only available if <code>CONFIG_PM_DEVICE</code> <verbatim>em...
Definition: device.h:408
void * data
Address of the device instance private data.
Definition: device.h:391
const void * api
Address of the API structure exposed by the device instance.
Definition: device.h:387
struct device_state * state
Address of the common device state.
Definition: device.h:389
const void * config
Address of device instance config information.
Definition: device.h:385
Device PM info.
Definition: device.h:126
const struct device * dev
Pointer to the device.
Definition: device.h:129
Macros to abstract toolchain specific capabilities.
Misc utilities.