1 /* 2 * Copyright (c) 2015 Intel Corporation. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_INIT_H_ 8 #define ZEPHYR_INCLUDE_INIT_H_ 9 10 #include <toolchain.h> 11 #include <kernel.h> 12 #include <zephyr/types.h> 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /* 19 * System initialization levels. The PRE_KERNEL_1 and PRE_KERNEL_2 levels are 20 * executed in the kernel's initialization context, which uses the interrupt 21 * stack. The remaining levels are executed in the kernel's main task. 22 */ 23 24 #define _SYS_INIT_LEVEL_PRE_KERNEL_1 0 25 #define _SYS_INIT_LEVEL_PRE_KERNEL_2 1 26 #define _SYS_INIT_LEVEL_POST_KERNEL 2 27 #define _SYS_INIT_LEVEL_APPLICATION 3 28 29 #ifdef CONFIG_SMP 30 #define _SYS_INIT_LEVEL_SMP 4 31 #endif 32 33 struct device; 34 35 /** 36 * @brief Static init entry structure for each device driver or services 37 * 38 * @param init init function for the init entry which will take the dev 39 * attribute as parameter. See below. 40 * @param dev pointer to a device driver instance structure. Can be NULL 41 * if the init entry is not used for a device driver but a service. 42 */ 43 struct init_entry { 44 /** Initialization function for the init entry which will take 45 * the dev attribute as parameter. See below. 46 */ 47 int (*init)(const struct device *dev); 48 /** Pointer to a device driver instance structure. Can be NULL 49 * if the init entry is not used for a device driver but a services. 50 */ 51 const struct device *dev; 52 }; 53 54 void z_sys_init_run_level(int32_t level); 55 56 /* A counter is used to avoid issues when two or more system devices 57 * are declared in the same C file with the same init function. 58 */ 59 #define Z_SYS_NAME(_init_fn) _CONCAT(_CONCAT(sys_init_, _init_fn), __COUNTER__) 60 61 /** 62 * @def Z_INIT_ENTRY_DEFINE 63 * 64 * @brief Create an init entry object and set it up for boot time initialization 65 * 66 * @details This macro defines an init entry object that will be automatically 67 * configured by the kernel during system initialization. Note that 68 * init entries will not be accessible from user mode. Also this macro should 69 * not be used directly, use relevant macro such as SYS_INIT() or 70 * DEVICE_DEFINE() instead. 71 * 72 * @param _entry_name Init entry name. It is the name this instance exposes to 73 * the system. 74 * 75 * @param _init_fn Address to the init function of the entry. 76 * 77 * @param _device A device driver instance pointer or NULL 78 * 79 * @param _level The initialization level at which configuration 80 * occurs. See SYS_INIT(). 81 * 82 * @param prio The initialization priority of the object, relative to 83 * other objects of the same initialization level. See SYS_INIT(). 84 */ 85 #define Z_INIT_ENTRY_DEFINE(_entry_name, _init_fn, _device, _level, _prio) \ 86 static const Z_DECL_ALIGN(struct init_entry) \ 87 _CONCAT(__init_, _entry_name) __used \ 88 __attribute__((__section__(".z_init_" #_level STRINGIFY(_prio)"_"))) = { \ 89 .init = (_init_fn), \ 90 .dev = (_device), \ 91 } 92 93 /** 94 * @def SYS_INIT 95 * 96 * @ingroup device_model 97 * 98 * @brief Run an initialization function at boot at specified priority 99 * 100 * @details This macro lets you run a function at system boot. 101 * 102 * @param _init_fn Pointer to the boot function to run 103 * 104 * @param _level The initialization level at which configuration occurs. 105 * Must be one of the following symbols, which are listed in the order 106 * they are performed by the kernel: 107 * \n 108 * \li PRE_KERNEL_1: Used for initialization objects that have no dependencies, 109 * such as those that rely solely on hardware present in the processor/SOC. 110 * These objects cannot use any kernel services during configuration, since 111 * they are not yet available. 112 * \n 113 * \li PRE_KERNEL_2: Used for initialization objects that rely on objects 114 * initialized as part of the PRE_KERNEL_1 level. These objects cannot use any 115 * kernel services during configuration, since they are not yet available. 116 * \n 117 * \li POST_KERNEL: Used for initialization objects that require kernel services 118 * during configuration. 119 * \n 120 * \li POST_KERNEL_SMP: Used for initialization objects that require kernel 121 * services during configuration after SMP initialization. 122 * \n 123 * \li APPLICATION: Used for application components (i.e. non-kernel components) 124 * that need automatic configuration. These objects can use all services 125 * provided by the kernel during configuration. 126 * 127 * @param _prio The initialization priority of the object, relative to 128 * other objects of the same initialization level. Specified as an integer 129 * value in the range 0 to 99; lower values indicate earlier initialization. 130 * Must be a decimal integer literal without leading zeroes or sign (e.g. 32), 131 * or an equivalent symbolic name (e.g. \#define MY_INIT_PRIO 32); symbolic 132 * expressions are *not* permitted 133 * (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5). 134 */ 135 #define SYS_INIT(_init_fn, _level, _prio) \ 136 Z_INIT_ENTRY_DEFINE(Z_SYS_NAME(_init_fn), _init_fn, NULL, _level, _prio) 137 138 #ifdef __cplusplus 139 } 140 #endif 141 142 #endif /* ZEPHYR_INCLUDE_INIT_H_ */ 143