Zephyr API Documentation  2.7.0-rc2
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 <init.h>
30#include <linker/sections.h>
31#include <pm/device.h>
32#include <sys/device_mmio.h>
33#include <sys/util.h>
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
46
52#define DEVICE_HANDLE_SEP INT16_MIN
53
59#define DEVICE_HANDLE_ENDS INT16_MAX
60
62#define DEVICE_HANDLE_NULL 0
63
64#define Z_DEVICE_MAX_NAME_LEN 48
65
81#define DEVICE_NAME_GET(name) _CONCAT(__device_, name)
82
93#define SYS_DEVICE_DEFINE(drv_name, init_fn, pm_control_fn, level, prio) \
94 DEVICE_DEFINE(Z_SYS_NAME(init_fn), drv_name, init_fn, \
95 pm_control_fn, \
96 NULL, NULL, level, prio, NULL)
97
137#define DEVICE_DEFINE(dev_name, drv_name, init_fn, pm_control_fn, \
138 data_ptr, cfg_ptr, level, prio, api_ptr) \
139 Z_DEVICE_DEFINE(DT_INVALID_NODE, dev_name, drv_name, init_fn, \
140 pm_control_fn, \
141 data_ptr, cfg_ptr, level, prio, api_ptr)
142
155#define DEVICE_DT_NAME(node_id) \
156 DT_PROP_OR(node_id, label, DT_NODE_FULL_NAME(node_id))
157
195#define DEVICE_DT_DEFINE(node_id, init_fn, pm_control_fn, \
196 data_ptr, cfg_ptr, level, prio, \
197 api_ptr, ...) \
198 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_NAME(node_id), \
199 DEVICE_DT_NAME(node_id), init_fn, \
200 pm_control_fn, \
201 data_ptr, cfg_ptr, level, prio, \
202 api_ptr, __VA_ARGS__)
203
214#define DEVICE_DT_INST_DEFINE(inst, ...) \
215 DEVICE_DT_DEFINE(DT_DRV_INST(inst), __VA_ARGS__)
216
233#define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_NAME(node_id))
234
247#define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
248
256#define DEVICE_DT_INST_GET(inst) DEVICE_DT_GET(DT_DRV_INST(inst))
257
276#define DEVICE_DT_GET_ANY(compat) \
277 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
278 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
279 (NULL))
280
299#define DEVICE_DT_GET_ONE(compat) \
300 COND_CODE_1(DT_HAS_COMPAT_STATUS_OKAY(compat), \
301 (DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(compat))), \
302 (ZERO_OR_COMPILE_ERROR(0)))
303
316#define DEVICE_GET(name) (&DEVICE_NAME_GET(name))
317
333#define DEVICE_DECLARE(name) static const struct device DEVICE_NAME_GET(name)
334
351 unsigned int init_res : 8;
352
356 bool initialized : 1;
357
358#ifdef CONFIG_PM_DEVICE
359 /* Power management data */
360 struct pm_device pm;
361#endif /* CONFIG_PM_DEVICE */
362};
363
367struct device {
369 const char *name;
371 const void *config;
373 const void *api;
375 struct device_state * const state;
377 void * const data;
386#ifdef CONFIG_PM_DEVICE
390 struct pm_device * const pm;
391#endif
392};
393
402static inline device_handle_t
404{
406 extern const struct device __device_start[];
407
408 /* TODO: If/when devices can be constructed that are not part of the
409 * fixed sequence we'll need another solution.
410 */
411 if (dev != NULL) {
412 ret = 1 + (device_handle_t)(dev - __device_start);
413 }
414
415 return ret;
416}
417
426static inline const struct device *
428{
429 extern const struct device __device_start[];
430 extern const struct device __device_end[];
431 const struct device *dev = NULL;
432 size_t numdev = __device_end - __device_start;
433
434 if ((dev_handle > 0) && ((size_t)dev_handle <= numdev)) {
435 dev = &__device_start[dev_handle - 1];
436 }
437
438 return dev;
439}
440
457typedef int (*device_visitor_callback_t)(const struct device *dev, void *context);
458
473static inline const device_handle_t *
475 size_t *count)
476{
477 const device_handle_t *rv = dev->handles;
478
479 if (rv != NULL) {
480 size_t i = 0;
481
482 while (rv[i] != DEVICE_HANDLE_SEP) {
483 ++i;
484 }
485 *count = i;
486 }
487
488 return rv;
489}
490
506static inline const device_handle_t *
508 size_t *count)
509{
510 const device_handle_t *rv = dev->handles;
511 size_t region = 0;
512 size_t i = 0;
513
514 if (rv != NULL) {
515 /* Fast forward to supporting devices */
516 while (region != 2) {
517 if (*rv == DEVICE_HANDLE_SEP) {
518 region++;
519 }
520 rv++;
521 }
522 /* Count supporting devices */
523 while (rv[i] != DEVICE_HANDLE_ENDS) {
524 ++i;
525 }
526 *count = i;
527 }
528
529 return rv;
530}
531
565int device_required_foreach(const struct device *dev,
566 device_visitor_callback_t visitor_cb,
567 void *context);
568
601int device_supported_foreach(const struct device *dev,
602 device_visitor_callback_t visitor_cb,
603 void *context);
604
618__syscall const struct device *device_get_binding(const char *name);
619
628size_t z_device_get_all_static(const struct device * *devices);
629
636bool z_device_ready(const struct device *dev);
637
647static inline int z_device_usable_check(const struct device *dev)
648{
649 return z_device_ready(dev) ? 0 : -ENODEV;
650}
651
663__syscall int device_usable_check(const struct device *dev);
664
665static inline int z_impl_device_usable_check(const struct device *dev)
666{
667 return z_device_usable_check(dev);
668}
669
686static inline bool device_is_ready(const struct device *dev)
687{
688 return device_usable_check(dev) == 0;
689}
690
695/* Node paths can exceed the maximum size supported by device_get_binding() in user mode,
696 * so synthesize a unique dev_name from the devicetree node.
697 *
698 * The ordinal used in this name can be mapped to the path by
699 * examining zephyr/include/generated/device_extern.h header. If the
700 * format of this conversion changes, gen_defines should be updated to
701 * match it.
702 */
703#define Z_DEVICE_DT_DEV_NAME(node_id) _CONCAT(dts_ord_, DT_DEP_ORD(node_id))
704
705/* Synthesize a unique name for the device state associated with
706 * dev_name.
707 */
708#define Z_DEVICE_STATE_NAME(dev_name) _CONCAT(__devstate_, dev_name)
709
714#define Z_DEVICE_HANDLE_NAME(node_id, dev_name) \
715 _CONCAT(__devicehdl_, \
716 COND_CODE_1(DT_NODE_EXISTS(node_id), \
717 (node_id), \
718 (dev_name)))
719
720#define Z_DEVICE_EXTRA_HANDLES(...) \
721 FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__)
722
723#ifdef CONFIG_PM_DEVICE
724#define Z_DEVICE_STATE_PM_INIT(node_id, dev_name) \
725 .pm = Z_PM_DEVICE_INIT(Z_DEVICE_STATE_NAME(dev_name).pm, node_id),
726#else
727#define Z_DEVICE_STATE_PM_INIT(node_id, dev_name)
728#endif
729
736#define Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
737 static struct device_state Z_DEVICE_STATE_NAME(dev_name) \
738 __attribute__((__section__(".z_devstate"))) = { \
739 Z_DEVICE_STATE_PM_INIT(node_id, dev_name) \
740 };
741
742/* If device power management is enabled, this macro defines a pointer to a
743 * device in the z_pm_device_slots region. When invoked for each device, this
744 * will effectively result in a device pointer array with the same size of the
745 * actual devices list. This is used internally by the device PM subsystem to
746 * keep track of suspended devices during system power transitions.
747 */
748#if CONFIG_PM_DEVICE
749#define Z_DEVICE_DEFINE_PM_SLOT(dev_name) \
750 static const Z_DECL_ALIGN(struct device *) \
751 _CONCAT(__pm_device_slot_, DEVICE_NAME_GET(dev_name)) __used \
752 __attribute__((__section__(".z_pm_device_slots")));
753#else
754#define Z_DEVICE_DEFINE_PM_SLOT(dev_name)
755#endif
756
757/* Construct objects that are referenced from struct device. These
758 * include power management and dependency handles.
759 */
760#define Z_DEVICE_DEFINE_PRE(node_id, dev_name, ...) \
761 Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, __VA_ARGS__) \
762 Z_DEVICE_STATE_DEFINE(node_id, dev_name) \
763 Z_DEVICE_DEFINE_PM_SLOT(dev_name)
764
765
766/* Initial build provides a record that associates the device object
767 * with its devicetree ordinal, and provides the dependency ordinals.
768 * These are provided as weak definitions (to prevent the reference
769 * from being captured when the original object file is compiled), and
770 * in a distinct pass1 section (which will be replaced by
771 * postprocessing).
772 *
773 * Before processing in gen_handles.py, the array format is:
774 * {
775 * DEVICE_ORDINAL (or DEVICE_HANDLE_NULL if not a devicetree node),
776 * List of devicetree dependency ordinals (if any),
777 * DEVICE_HANDLE_SEP,
778 * List of injected dependency ordinals (if any),
779 * DEVICE_HANDLE_SEP,
780 * List of devicetree supporting ordinals (if any),
781 * }
782 *
783 * After processing in gen_handles.py, the format is updated to:
784 * {
785 * List of existing devicetree dependency handles (if any),
786 * DEVICE_HANDLE_SEP,
787 * List of injected dependency ordinals (if any),
788 * DEVICE_HANDLE_SEP,
789 * List of existing devicetree support handles (if any),
790 * DEVICE_HANDLE_NULL padding to original length (at least one)
791 * }
792 *
793 * It is also (experimentally) necessary to provide explicit alignment
794 * on each object. Otherwise x86-64 builds will introduce padding
795 * between objects in the same input section in individual object
796 * files, which will be retained in subsequent links both wasting
797 * space and resulting in aggregate size changes relative to pass2
798 * when all objects will be in the same input section.
799 *
800 * The build assert will fail if device_handle_t changes size, which
801 * means the alignment directives in the linker scripts and in
802 * `gen_handles.py` must be updated.
803 */
804BUILD_ASSERT(sizeof(device_handle_t) == 2, "fix the linker scripts");
805#define Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, ...) \
806 extern const device_handle_t \
807 Z_DEVICE_HANDLE_NAME(node_id, dev_name)[]; \
808 const device_handle_t \
809 __aligned(sizeof(device_handle_t)) \
810 __attribute__((__weak__, \
811 __section__(".__device_handles_pass1"))) \
812 Z_DEVICE_HANDLE_NAME(node_id, dev_name)[] = { \
813 COND_CODE_1(DT_NODE_EXISTS(node_id), ( \
814 DT_DEP_ORD(node_id), \
815 DT_REQUIRES_DEP_ORDS(node_id) \
816 ), ( \
817 DEVICE_HANDLE_NULL, \
818 )) \
819 DEVICE_HANDLE_SEP, \
820 Z_DEVICE_EXTRA_HANDLES(__VA_ARGS__) \
821 DEVICE_HANDLE_SEP, \
822 COND_CODE_1(DT_NODE_EXISTS(node_id), \
823 (DT_SUPPORTS_DEP_ORDS(node_id)), ()) \
824 };
825
826#ifdef CONFIG_PM_DEVICE
827#define Z_DEVICE_DEFINE_PM_INIT(dev_name, pm_control_fn) \
828 .pm_control = (pm_control_fn), \
829 .pm = &Z_DEVICE_STATE_NAME(dev_name).pm,
830#else
831#define Z_DEVICE_DEFINE_PM_INIT(dev_name, pm_control_fn)
832#endif
833
834#define Z_DEVICE_DEFINE_INIT(node_id, dev_name, pm_control_fn) \
835 .handles = Z_DEVICE_HANDLE_NAME(node_id, dev_name), \
836 Z_DEVICE_DEFINE_PM_INIT(dev_name, pm_control_fn)
837
838/* Like DEVICE_DEFINE but takes a node_id AND a dev_name, and trailing
839 * dependency handles that come from outside devicetree.
840 */
841#define Z_DEVICE_DEFINE(node_id, dev_name, drv_name, init_fn, pm_control_fn, \
842 data_ptr, cfg_ptr, level, prio, api_ptr, ...) \
843 Z_DEVICE_DEFINE_PRE(node_id, dev_name, __VA_ARGS__) \
844 COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \
845 const Z_DECL_ALIGN(struct device) \
846 DEVICE_NAME_GET(dev_name) __used \
847 __attribute__((__section__(".z_device_" #level STRINGIFY(prio)"_"))) = { \
848 .name = drv_name, \
849 .config = (cfg_ptr), \
850 .api = (api_ptr), \
851 .state = &Z_DEVICE_STATE_NAME(dev_name), \
852 .data = (data_ptr), \
853 Z_DEVICE_DEFINE_INIT(node_id, dev_name, pm_control_fn) \
854 }; \
855 BUILD_ASSERT(sizeof(Z_STRINGIFY(drv_name)) <= Z_DEVICE_MAX_NAME_LEN, \
856 Z_STRINGIFY(DEVICE_NAME_GET(drv_name)) " too long"); \
857 Z_INIT_ENTRY_DEFINE(DEVICE_NAME_GET(dev_name), init_fn, \
858 (&DEVICE_NAME_GET(dev_name)), level, prio)
859
860#ifdef __cplusplus
861}
862#endif
863
864/* device_extern is generated based on devicetree nodes */
865#include <device_extern.h>
866
867#include <syscalls/device.h>
868
869#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)
Retrieve the device structure for a driver by name.
int16_t device_handle_t
Type used to represent devices and functions.
Definition: device.h:45
static const device_handle_t * device_required_handles_get(const struct device *dev, size_t *count)
Get the set of handles for devicetree dependencies of this device.
Definition: device.h:474
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:507
static device_handle_t device_handle_get(const struct device *dev)
Get the handle for a given device.
Definition: device.h:403
#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:52
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:427
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:457
#define DEVICE_HANDLE_ENDS
Flag value used in lists of device handles to indicate the end of the list.
Definition: device.h:59
int device_usable_check(const struct device *dev)
Determine whether a device is ready for use.
static bool device_is_ready(const struct device *dev)
Verify that a device is ready for use.
Definition: device.h:686
int device_supported_foreach(const struct device *dev, device_visitor_callback_t visitor_cb, void *context)
Visit every device that dev directly supports.
int(* pm_device_control_callback_t)(const struct device *dev, enum pm_device_action action)
Device power management control function callback.
Definition: device.h:139
#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:43
Runtime device dynamic structure (in RAM) per driver instance.
Definition: device.h:343
bool initialized
Definition: device.h:356
unsigned int init_res
Definition: device.h:351
Runtime device structure (in ROM) per driver instance.
Definition: device.h:367
const char * name
Definition: device.h:369
const void * api
Definition: device.h:373
struct device_state *const state
Definition: device.h:375
const device_handle_t *const handles
Definition: device.h:385
void *const data
Definition: device.h:377
const void * config
Definition: device.h:371
Device PM info.
Definition: device.h:88
const struct device * dev
Definition: device.h:90
Misc utilities.