Zephyr Project API  3.3.0
A Scalable Open Source RTOS
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>
16#include <zephyr/sys/util.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
44
51#define DEVICE_HANDLE_SEP INT16_MIN
52
59#define DEVICE_HANDLE_ENDS INT16_MAX
60
62#define DEVICE_HANDLE_NULL 0
63
83#define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
84
85/* Node paths can exceed the maximum size supported by
86 * device_get_binding() in user mode; this macro synthesizes a unique
87 * dev_id from a devicetree node while staying within this maximum
88 * size.
89 *
90 * The ordinal used in this name can be mapped to the path by
91 * examining zephyr/include/generated/devicetree_generated.h.
92 */
93#define Z_DEVICE_DT_DEV_ID(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
94
125#define DEVICE_DEFINE(dev_id, name, init_fn, pm, data, config, level, prio, \
126 api) \
127 Z_DEVICE_STATE_DEFINE(dev_id); \
128 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_id, name, init_fn, pm, data, \
129 config, level, prio, api, \
130 &Z_DEVICE_STATE_NAME(dev_id))
131
143#define DEVICE_DT_NAME(node_id) \
144 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
145
175#define DEVICE_DT_DEFINE(node_id, init_fn, pm, data, config, level, prio, api, \
176 ...) \
177 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
178 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
179 DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
180 level, prio, api, \
181 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
182 __VA_ARGS__)
183
192#define DEVICE_DT_INST_DEFINE(inst, ...) \
193 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
194
209#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_ID(node_id))
210
226#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
227
237#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
238
255#define DEVICE_DT_GET_ANY(compat) \
256 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
257 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
258 (NULL))
259
276#define DEVICE_DT_GET_ONE(compat) \
277 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
278 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
279 (ZERO_OR_COMPILE_ERROR(0)))
280
291#define DEVICE_DT_GET_OR_NULL(node_id) \
292 COND_CODE_1(DT_NODE_HAS_STATUS(node_id, okay), \
293 (DEVICE_DT_GET(node_id)), (NULL))
294
305#define DEVICE_GET(dev_id) (&DEVICE_NAME_GET(dev_id))
306
321#define DEVICE_DECLARE(dev_id) \
322 static const struct device DEVICE_NAME_GET(dev_id)
323
331#define DEVICE_INIT_DT_GET(node_id) \
332 (&Z_INIT_ENTRY_NAME(DEVICE_DT_NAME_GET(node_id)))
333
341#define DEVICE_INIT_GET(dev_id) (&Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)))
342
360
364 bool initialized : 1;
365};
366
367struct pm_device;
368
369#ifdef CONFIG_HAS_DYNAMIC_DEVICE_HANDLES
370#define Z_DEVICE_HANDLES_CONST
371#else
372#define Z_DEVICE_HANDLES_CONST const
373#endif
374
378struct device {
380 const char *name;
382 const void *config;
384 const void *api;
388 void *data;
396 Z_DEVICE_HANDLES_CONST device_handle_t *handles;
397
398#if defined(CONFIG_PM_DEVICE) || defined(__DOXYGEN__)
403 struct pm_device *pm;
404#endif
405};
406
415static inline device_handle_t device_handle_get(const struct device *dev)
416{
418 extern const struct device __device_start[];
419
420 /* TODO: If/when devices can be constructed that are not part of the
421 * fixed sequence we'll need another solution.
422 */
423 if (dev != NULL) {
424 ret = 1 + (device_handle_t)(dev - __device_start);
425 }
426
427 return ret;
428}
429
438static inline const struct device *
440{
441 extern const struct device __device_start[];
442 extern const struct device __device_end[];
443 const struct device *dev = NULL;
444 size_t numdev = __device_end - __device_start;
445
446 if ((dev_handle > 0) && ((size_t)dev_handle <= numdev)) {
447 dev = &__device_start[dev_handle - 1];
448 }
449
450 return dev;
451}
452
471typedef int (*device_visitor_callback_t)(const struct device *dev,
472 void *context);
473
492static inline const device_handle_t *
493device_required_handles_get(const struct device *dev, size_t *count)
494{
495 const device_handle_t *rv = dev->handles;
496
497 if (rv != NULL) {
498 size_t i = 0;
499
500 while ((rv[i] != DEVICE_HANDLE_ENDS) &&
501 (rv[i] != DEVICE_HANDLE_SEP)) {
502 ++i;
503 }
504 *count = i;
505 }
506
507 return rv;
508}
509
528static inline const device_handle_t *
529device_injected_handles_get(const struct device *dev, size_t *count)
530{
531 const device_handle_t *rv = dev->handles;
532 size_t region = 0;
533 size_t i = 0;
534
535 if (rv != NULL) {
536 /* Fast forward to injected devices */
537 while (region != 1) {
538 if (*rv == DEVICE_HANDLE_SEP) {
539 region++;
540 }
541 rv++;
542 }
543 while ((rv[i] != DEVICE_HANDLE_ENDS) &&
544 (rv[i] != DEVICE_HANDLE_SEP)) {
545 ++i;
546 }
547 *count = i;
548 }
549
550 return rv;
551}
552
572static inline const device_handle_t *
573device_supported_handles_get(const struct device *dev, size_t *count)
574{
575 const device_handle_t *rv = dev->handles;
576 size_t region = 0;
577 size_t i = 0;
578
579 if (rv != NULL) {
580 /* Fast forward to supporting devices */
581 while (region != 2) {
582 if (*rv == DEVICE_HANDLE_SEP) {
583 region++;
584 }
585 rv++;
586 }
587 /* Count supporting devices */
588 while (rv[i] != DEVICE_HANDLE_ENDS) {
589 ++i;
590 }
591 *count = i;
592 }
593
594 return rv;
595}
596
627int device_required_foreach(const struct device *dev,
628 device_visitor_callback_t visitor_cb,
629 void *context);
630
660int device_supported_foreach(const struct device *dev,
661 device_visitor_callback_t visitor_cb,
662 void *context);
663
684__syscall const struct device *device_get_binding(const char *name);
685
694size_t z_device_get_all_static(const struct device **devices);
695
710bool z_device_is_ready(const struct device *dev);
711
728__syscall bool device_is_ready(const struct device *dev);
729
730static inline bool z_impl_device_is_ready(const struct device *dev)
731{
732 return z_device_is_ready(dev);
733}
734
745#define Z_DEVICE_STATE_NAME(dev_id) _CONCAT(__devstate_, dev_id)
746
752#define Z_DEVICE_STATE_DEFINE(dev_id) \
753 static Z_DECL_ALIGN(struct device_state) Z_DEVICE_STATE_NAME(dev_id) \
754 __attribute__((__section__(".z_devstate")))
755
762#define Z_DEVICE_HANDLES_NAME(dev_id) _CONCAT(__devicehdl_, dev_id)
763
769#define Z_DEVICE_EXTRA_HANDLES(...) \
770 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
771
773#define Z_DEVICE_HANDLES_SECTION \
774 __attribute__((__section__(".__device_handles_pass1")))
775
811#define Z_DEVICE_HANDLES_DEFINE(node_id, dev_id, ...) \
812 extern Z_DEVICE_HANDLES_CONST device_handle_t Z_DEVICE_HANDLES_NAME( \
813 dev_id)[]; \
814 Z_DEVICE_HANDLES_CONST Z_DECL_ALIGN(device_handle_t) \
815 Z_DEVICE_HANDLES_SECTION __weak Z_DEVICE_HANDLES_NAME(dev_id)[] = { \
816 COND_CODE_1( \
817 DT_NODE_EXISTS(node_id), \
818 (DT_DEP_ORD(node_id), DT_REQUIRES_DEP_ORDS(node_id)), \
819 (DEVICE_HANDLE_NULL,)) \
820 DEVICE_HANDLE_SEP, \
821 Z_DEVICE_EXTRA_HANDLES(__VA_ARGS__) \
822 DEVICE_HANDLE_SEP, \
823 COND_CODE_1(DT_NODE_EXISTS(node_id), \
824 (DT_SUPPORTS_DEP_ORDS(node_id)), ()) \
825 }
826
833#define Z_DEVICE_MAX_NAME_LEN 48
834
840#define Z_DEVICE_NAME_CHECK(name) \
841 BUILD_ASSERT(sizeof(Z_STRINGIFY(name)) <= Z_DEVICE_MAX_NAME_LEN, \
842 Z_STRINGIFY(DEVICE_NAME_GET(name)) " too long")
843
855#define Z_DEVICE_INIT(name_, pm_, data_, config_, api_, state_, handles_) \
856 { \
857 .name = name_, \
858 .data = (data_), \
859 .config = (config_), \
860 .api = (api_), \
861 .state = (state_), \
862 .handles = (handles_), \
863 IF_ENABLED(CONFIG_PM_DEVICE, (.pm = (pm_),)) \
864 }
865
875#define Z_DEVICE_SECTION(level, prio) \
876 __attribute__((__section__(".z_device_" #level STRINGIFY(prio) "_")))
877
894#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
895 prio, api, state, handles) \
896 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
897 const Z_DECL_ALIGN(struct device) DEVICE_NAME_GET( \
898 dev_id) Z_DEVICE_SECTION(level, prio) __used = \
899 Z_DEVICE_INIT(name, pm, data, config, api, state, handles)
900
909#define Z_DEVICE_INIT_ENTRY_DEFINE(dev_id, init_fn, level, prio) \
910 Z_INIT_ENTRY_DEFINE(DEVICE_NAME_GET(dev_id), init_fn, \
911 (&DEVICE_NAME_GET(dev_id)), level, prio)
912
934#define Z_DEVICE_DEFINE(node_id, dev_id, name, init_fn, pm, data, config, \
935 level, prio, api, state, ...) \
936 Z_DEVICE_NAME_CHECK(name); \
937 \
938 Z_DEVICE_HANDLES_DEFINE(node_id, dev_id, __VA_ARGS__); \
939 \
940 Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \
941 prio, api, state, Z_DEVICE_HANDLES_NAME(dev_id)); \
942 \
943 Z_DEVICE_INIT_ENTRY_DEFINE(dev_id, init_fn, level, prio)
944
945#if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__)
956#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \
957 extern const struct device DEVICE_DT_NAME_GET(node_id);
958
959DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL)
960#endif /* CONFIG_HAS_DTS */
961
964#ifdef __cplusplus
965}
966#endif
967
968#include <syscalls/device.h>
969
970#endif /* ZEPHYR_INCLUDE_DEVICE_H_ */
ZTEST_BMEM int count
Definition: main.c:33
Devicetree main header.
DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_EMUL_DECLARE_INTERNAL)
volatile int rv
Definition: main.c:45
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:43
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:493
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:573
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition: device.h:415
#define DEVICE_HANDLE_NULL
Flag value used to identify an unknown device.
Definition: device.h:62
#define DEVICE_HANDLE_SEP
Flag value used in lists of device handles to separate distinct groups.
Definition: device.h:51
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:439
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:471
bool device_is_ready(const struct device *dev)
Verify that a device is ready for use.
#define DEVICE_HANDLE_ENDS
Flag value used in lists of device handles to indicate the end of the list.
Definition: device.h:59
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:529
int device_supported_foreach(const struct device *dev, device_visitor_callback_t visitor_cb, void *context)
Visit every device that dev directly supports.
static ZTEST_BMEM volatile int ret
Definition: k_float_disable.c:28
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:351
bool initialized
Definition: device.h:364
uint8_t init_res
Definition: device.h:359
Runtime device structure (in ROM) per driver instance.
Definition: device.h:378
const char * name
Definition: device.h:380
struct pm_device * pm
Definition: device.h:403
void * data
Definition: device.h:388
const device_handle_t * handles
Definition: device.h:396
const void * api
Definition: device.h:384
struct device_state * state
Definition: device.h:386
const void * config
Definition: device.h:382
Device PM info.
Definition: device.h:121
const struct device * dev
Definition: device.h:124
Misc utilities.