1 /* 2 * Copyright (c) 2020 Nordic Semiconductor ASA 3 * Copyright 2020 Google LLC 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #ifndef ZEPHYR_INCLUDE_DRIVERS_EMUL_H_ 9 #define ZEPHYR_INCLUDE_DRIVERS_EMUL_H_ 10 11 /** 12 * @brief Emulators used to test drivers and higher-level code that uses them 13 * @defgroup io_emulators Emulator interface 14 * @{ 15 */ 16 17 #ifdef __cplusplus 18 extern "C" { 19 #endif /* __cplusplus */ 20 21 struct device; 22 struct emul; 23 24 /** 25 * Structure uniquely identifying a device to be emulated 26 * 27 * Currently this uses the device node label, but that will go away by 2.5. 28 */ 29 struct emul_link_for_bus { 30 const char *label; 31 }; 32 33 /** List of emulators attached to a bus */ 34 struct emul_list_for_bus { 35 /** Identifiers for children of the node */ 36 const struct emul_link_for_bus *children; 37 /** Number of children of the node */ 38 unsigned int num_children; 39 }; 40 41 /** 42 * Standard callback for emulator initialisation providing the initialiser 43 * record and the device that calls the emulator functions. 44 * 45 * @param emul Emulator to init 46 * @param parent Parent device that is using the emulator 47 */ 48 typedef int (*emul_init_t)(const struct emul *emul, 49 const struct device *parent); 50 51 /** An emulator instance */ 52 struct emul { 53 /** function used to initialise the emulator state */ 54 emul_init_t init; 55 /** handle to the device for which this provides low-level emulation */ 56 const char *dev_label; 57 /** Emulator-specific configuration data */ 58 const void *cfg; 59 }; 60 61 /** 62 * Emulators are aggregated into an array at link time, from which emulating 63 * devices can find the emulators that they are to use. 64 */ 65 extern const struct emul __emul_list_start[]; 66 extern const struct emul __emul_list_end[]; 67 68 /* Use the devicetree node identifier as a unique name. */ 69 #define EMUL_REG_NAME(node_id) (_CONCAT(__emulreg_, node_id)) 70 71 /** 72 * Define a new emulator 73 * 74 * This adds a new struct emul to the linker list of emulations. This is 75 * typically used in your emulator's DT_INST_FOREACH_STATUS_OKAY() clause. 76 * 77 * @param init_ptr function to call to initialise the emulator (see emul_init 78 * typedef) 79 * @param node_id Node ID of the driver to emulate (e.g. DT_DRV_INST(n)) 80 * @param cfg_ptr emulator-specific configuration data 81 */ 82 #define EMUL_DEFINE(init_ptr, node_id, cfg_ptr) \ 83 static struct emul EMUL_REG_NAME(node_id) \ 84 __attribute__((__section__(".emulators"))) __used = { \ 85 .init = (init_ptr), \ 86 .dev_label = DT_LABEL(node_id), \ 87 .cfg = (cfg_ptr), \ 88 }; 89 90 /** 91 * Set up a list of emulators 92 * 93 * @param dev Device the emulators are attached to (e.g. an I2C controller) 94 * @param list List of devices to set up 95 * @return 0 if OK 96 * @return negative value on error 97 */ 98 int emul_init_for_bus_from_list(const struct device *dev, 99 const struct emul_list_for_bus *list); 100 101 #ifdef __cplusplus 102 } 103 #endif /* __cplusplus */ 104 105 /** 106 * @} 107 */ 108 109 #endif /* ZEPHYR_INCLUDE_DRIVERS_EMUL_H_ */ 110