Zephyr Project API  3.1.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
29#include <zephyr/init.h>
32#include <zephyr/sys/util.h>
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
54
60#define DEVICE_HANDLE_SEP INT16_MIN
61
67#define DEVICE_HANDLE_ENDS INT16_MAX
68
70#define DEVICE_HANDLE_NULL 0
71
72#define Z_DEVICE_MAX_NAME_LEN 48
73
96#define DEVICE_NAME_GET(name) _CONCAT(__device_, name)
97
110#define SYS_DEVICE_DEFINE(drv_name, init_fn, level, prio) \
111 __DEPRECATED_MACRO SYS_INIT(init_fn, level, prio)
112
113/* Node paths can exceed the maximum size supported by device_get_binding() in user mode,
114 * so synthesize a unique dev_name from the devicetree node.
115 *
116 * The ordinal used in this name can be mapped to the path by
117 * examining zephyr/include/generated/device_extern.h header. If the
118 * format of this conversion changes, gen_defines should be updated to
119 * match it.
120 */
121#define Z_DEVICE_DT_DEV_NAME(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
122
123/* Synthesize a unique name for the device state associated with
124 * dev_name.
125 */
126#define Z_DEVICE_STATE_NAME(dev_name) _CONCAT(__devstate_, dev_name)
127
134#define Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
135 static struct device_state Z_DEVICE_STATE_NAME(dev_name) \
136 __attribute__((__section__(".z_devstate")));
137
181#define DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_device, \
182 data_ptr, cfg_ptr, level, prio, api_ptr) \
183 Z_DEVICE_STATE_DEFINE(DT_INVALID_NODE, dev_name) \
184 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_name, drv_name, init_fn, \
185 pm_device, \
186 data_ptr, cfg_ptr, level, prio, api_ptr, \
187 &Z_DEVICE_STATE_NAME(dev_name))
188
202#define DEVICE_DT_NAME(node_id) \
203 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
204
248#define DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
249 data_ptr, cfg_ptr, level, prio, \
250 api_ptr, ...) \
251 Z_DEVICE_STATE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id)) \
252 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
253 DEVICE_DT_NAME(node_id), init_fn, \
254 pm_device, \
255 data_ptr, cfg_ptr, level, prio, \
256 api_ptr, \
257 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_NAME(node_id)), \
258 __VA_ARGS__)
259
271#define DEVICE_DT_INST_DEFINE(inst, ...) \
272 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
273
291#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_NAME(node_id))
292
311#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
312
323#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
324
343#define DEVICE_DT_GET_ANY(compat) \
344 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
345 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
346 (NULL))
347
367#define DEVICE_DT_GET_ONE(compat) \
368 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
369 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
370 (ZERO_OR_COMPILE_ERROR(0)))
371
386#define DEVICE_DT_GET_OR_NULL(node_id) \
387 COND_CODE_1(DT_NODE_HAS_STATUS(node_id, okay), \
388 (DEVICE_DT_GET(node_id)), (NULL))
389
402#define DEVICE_GET(name) (&DEVICE_NAME_GET(name))
403
419#define DEVICE_DECLARE(name) static const struct device DEVICE_NAME_GET(name)
420
437 unsigned int init_res : 8;
438
442 bool initialized : 1;
443};
444
445struct pm_device;
446
447#ifdef CONFIG_HAS_DYNAMIC_DEVICE_HANDLES
448#define Z_DEVICE_HANDLES_CONST
449#else
450#define Z_DEVICE_HANDLES_CONST const
451#endif
452
456struct device {
458 const char *name;
460 const void *config;
462 const void *api;
464 struct device_state * const state;
466 void * const data;
474 Z_DEVICE_HANDLES_CONST device_handle_t * const handles;
475
476#ifdef CONFIG_PM_DEVICE
478 struct pm_device * const pm;
479#endif
480};
481
490static inline device_handle_t
491device_handle_get(const struct device *dev)
492{
494 extern const struct device __device_start[];
495
496 /* TODO: If/when devices can be constructed that are not part of the
497 * fixed sequence we'll need another solution.
498 */
499 if (dev != NULL) {
500 ret = 1 + (device_handle_t)(dev - __device_start);
501 }
502
503 return ret;
504}
505
514static inline const struct device *
516{
517 extern const struct device __device_start[];
518 extern const struct device __device_end[];
519 const struct device *dev = NULL;
520 size_t numdev = __device_end - __device_start;
521
522 if ((dev_handle > 0) && ((size_t)dev_handle <= numdev)) {
523 dev = &__device_start[dev_handle - 1];
524 }
525
526 return dev;
527}
528
548typedef int (*device_visitor_callback_t)(const struct device *dev, void *context);
549
570static inline const device_handle_t *
572 size_t *count)
573{
574 const device_handle_t *rv = dev->handles;
575
576 if (rv != NULL) {
577 size_t i = 0;
578
579 while ((rv[i] != DEVICE_HANDLE_ENDS)
580 && (rv[i] != DEVICE_HANDLE_SEP)) {
581 ++i;
582 }
583 *count = i;
584 }
585
586 return rv;
587}
588
610static inline const device_handle_t *
612 size_t *count)
613{
614 const device_handle_t *rv = dev->handles;
615 size_t region = 0;
616 size_t i = 0;
617
618 if (rv != NULL) {
619 /* Fast forward to supporting devices */
620 while (region != 2) {
621 if (*rv == DEVICE_HANDLE_SEP) {
622 region++;
623 }
624 rv++;
625 }
626 /* Count supporting devices */
627 while (rv[i] != DEVICE_HANDLE_ENDS) {
628 ++i;
629 }
630 *count = i;
631 }
632
633 return rv;
634}
635
669int device_required_foreach(const struct device *dev,
670 device_visitor_callback_t visitor_cb,
671 void *context);
672
705int device_supported_foreach(const struct device *dev,
706 device_visitor_callback_t visitor_cb,
707 void *context);
708
731__syscall const struct device *device_get_binding(const char *name);
732
741size_t z_device_get_all_static(const struct device * *devices);
742
757bool z_device_is_ready(const struct device *dev);
758
774__syscall bool device_is_ready(const struct device *dev);
775
776static inline bool z_impl_device_is_ready(const struct device *dev)
777{
778 return z_device_is_ready(dev);
779}
780
794__deprecated static inline int z_device_usable_check(const struct device *dev)
795{
796 return z_device_is_ready(dev) ? 0 : -ENODEV;
797}
798
809__deprecated static inline int device_usable_check(const struct device *dev)
810{
811 return device_is_ready(dev) ? 0 : -ENODEV;
812}
813
818/* Synthesize the name of the object that holds device ordinal and
819 * dependency data. If the object doesn't come from a devicetree
820 * node, use dev_name.
821 */
822#define Z_DEVICE_HANDLE_NAME(node_id, dev_name) \
823 _CONCAT(__devicehdl_, \
824 COND_CODE_1(DT_NODE_EXISTS(node_id), \
825 (node_id), \
826 (dev_name)))
827
828#define Z_DEVICE_EXTRA_HANDLES(...) \
829 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
830
831/*
832 * Utility macro to define and initialize the device state.
833 *
834 * @param node_id Devicetree node id of the device.
835 * @param dev_name Device name.
836 */
837#define Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
838 static struct device_state Z_DEVICE_STATE_NAME(dev_name) \
839 __attribute__((__section__(".z_devstate")));
840
841/* Construct objects that are referenced from struct device. These
842 * include power management and dependency handles.
843 */
844#define Z_DEVICE_DEFINE_PRE(node_id, dev_name, ...) \
845 Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, __VA_ARGS__)
846
847/* Initial build provides a record that associates the device object
848 * with its devicetree ordinal, and provides the dependency ordinals.
849 * These are provided as weak definitions (to prevent the reference
850 * from being captured when the original object file is compiled), and
851 * in a distinct pass1 section (which will be replaced by
852 * postprocessing).
853 *
854 * Before processing in gen_handles.py, the array format is:
855 * {
856 * DEVICE_ORDINAL (or DEVICE_HANDLE_NULL if not a devicetree node),
857 * List of devicetree dependency ordinals (if any),
858 * DEVICE_HANDLE_SEP,
859 * List of injected dependency ordinals (if any),
860 * DEVICE_HANDLE_SEP,
861 * List of devicetree supporting ordinals (if any),
862 * }
863 *
864 * After processing in gen_handles.py, the format is updated to:
865 * {
866 * List of existing devicetree dependency handles (if any),
867 * DEVICE_HANDLE_SEP,
868 * List of injected dependency ordinals (if any),
869 * DEVICE_HANDLE_SEP,
870 * List of existing devicetree support handles (if any),
871 * DEVICE_HANDLE_NULL
872 * }
873 *
874 * It is also (experimentally) necessary to provide explicit alignment
875 * on each object. Otherwise x86-64 builds will introduce padding
876 * between objects in the same input section in individual object
877 * files, which will be retained in subsequent links both wasting
878 * space and resulting in aggregate size changes relative to pass2
879 * when all objects will be in the same input section.
880 *
881 * The build assert will fail if device_handle_t changes size, which
882 * means the alignment directives in the linker scripts and in
883 * `gen_handles.py` must be updated.
884 */
885BUILD_ASSERT(sizeof(device_handle_t) == 2, "fix the linker scripts");
886#define Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, ...) \
887 extern Z_DEVICE_HANDLES_CONST device_handle_t \
888 Z_DEVICE_HANDLE_NAME(node_id, dev_name)[]; \
889 Z_DEVICE_HANDLES_CONST device_handle_t \
890 __aligned(sizeof(device_handle_t)) \
891 __attribute__((__weak__, \
892 __section__(".__device_handles_pass1"))) \
893 Z_DEVICE_HANDLE_NAME(node_id, dev_name)[] = { \
894 COND_CODE_1(DT_NODE_EXISTS(node_id), ( \
895 DT_DEP_ORD(node_id), \
896 DT_REQUIRES_DEP_ORDS(node_id) \
897 ), ( \
898 DEVICE_HANDLE_NULL, \
899 )) \
900 DEVICE_HANDLE_SEP, \
901 Z_DEVICE_EXTRA_HANDLES(__VA_ARGS__) \
902 DEVICE_HANDLE_SEP, \
903 COND_CODE_1(DT_NODE_EXISTS(node_id), \
904 (DT_SUPPORTS_DEP_ORDS(node_id)), ()) \
905 };
906
907#define Z_DEVICE_DEFINE_INIT(node_id, dev_name) \
908 .handles = Z_DEVICE_HANDLE_NAME(node_id, dev_name),
909
910/* Like DEVICE_DEFINE but takes a node_id AND a dev_name, and trailing
911 * dependency handles that come from outside devicetree.
912 */
913#define Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, pm_device,\
914 data_ptr, cfg_ptr, level, prio, api_ptr, state_ptr, ...) \
915 Z_DEVICE_DEFINE_PRE(node_id, dev_name, __VA_ARGS__) \
916 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
917 const Z_DECL_ALIGN(struct device) \
918 DEVICE_NAME_GET(dev_name) __used \
919 __attribute__((__section__(".z_device_" #level STRINGIFY(prio)"_"))) = { \
920 .name = drv_name, \
921 .config = (cfg_ptr), \
922 .api = (api_ptr), \
923 .state = (state_ptr), \
924 .data = (data_ptr), \
925 COND_CODE_1(CONFIG_PM_DEVICE, (.pm = pm_device,), ()) \
926 Z_DEVICE_DEFINE_INIT(node_id, dev_name) \
927 }; \
928 BUILD_ASSERT(sizeof(Z_STRINGIFY(drv_name)) <= Z_DEVICE_MAX_NAME_LEN, \
929 Z_STRINGIFY(DEVICE_NAME_GET(drv_name)) " too long"); \
930 Z_INIT_ENTRY_DEFINE(DEVICE_NAME_GET(dev_name), init_fn, \
931 (&DEVICE_NAME_GET(dev_name)), level, prio)
932
933#ifdef __cplusplus
934}
935#endif
936
937/* device_extern is generated based on devicetree nodes */
938#include <device_extern.h>
939
940#include <syscalls/device.h>
941
942#endif /* ZEPHYR_INCLUDE_DEVICE_H_ */
ZTEST_BMEM int count
Definition: main.c:33
volatile int rv
Definition: main.c:45
const struct device * device_get_binding(const char *name)
Get a const struct device* from its name field.
int16_t device_handle_t
Type used to represent a "handle" for a device.
Definition: device.h:53
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:571
static int device_usable_check(const struct device *dev)
Determine whether a device is ready for use.
Definition: device.h:809
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:611
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition: device.h:491
#define DEVICE_HANDLE_NULL
Flag value used to identify an unknown device.
Definition: device.h:70
#define DEVICE_HANDLE_SEP
Flag value used in lists of device handles to separate distinct groups.
Definition: device.h:60
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:515
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:548
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:67
int device_supported_foreach(const struct device *dev, device_visitor_callback_t visitor_cb, void *context)
Visit every device that dev directly supports.
#define ENODEV
Definition: errno.h:58
static ZTEST_BMEM volatile int ret
Definition: k_float_disable.c:28
Definitions of various linker Sections.
__INT16_TYPE__ int16_t
Definition: stdint.h:73
Runtime device dynamic structure (in RAM) per driver instance.
Definition: device.h:429
bool initialized
Definition: device.h:442
unsigned int init_res
Definition: device.h:437
Runtime device structure (in ROM) per driver instance.
Definition: device.h:456
const char * name
Definition: device.h:458
const void * api
Definition: device.h:462
struct device_state *const state
Definition: device.h:464
const device_handle_t *const handles
Definition: device.h:474
void *const data
Definition: device.h:466
const void * config
Definition: device.h:460
Misc utilities.