zephyr:device_drivers
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| zephyr:device_drivers [2025/07/02 15:21] – utedass | zephyr:device_drivers [2025/07/08 19:08] (current) – utedass | ||
|---|---|---|---|
| Line 3: | Line 3: | ||
| ===== Brief ===== | ===== Brief ===== | ||
| - | A custom driver will probably involve: | + | During the development the structure might differ, as many of the following pieces will be in your project directory. But it is good to know when browsing around the drivers already in upstream Zephyr. |
| + | |||
| + | == A custom driver will probably involve | ||
| | Driver C source code | The structure does not seem to be unified. Most drivers are stored in a flat structure under '' | | Driver C source code | The structure does not seem to be unified. Most drivers are stored in a flat structure under '' | ||
| | KConfig source file | Placed together with the C source, declaring the CONFIG_* that CMakeLists.txt will listen for | | | KConfig source file | Placed together with the C source, declaring the CONFIG_* that CMakeLists.txt will listen for | | ||
| Line 11: | Line 13: | ||
| | Preferrably some sample code | Somehow sorted under '' | | Preferrably some sample code | Somehow sorted under '' | ||
| - | Using it will involve | + | == Using it will involve |
| | Device tree entry | in a device tree overlay file, the line '' | | Device tree entry | in a device tree overlay file, the line '' | ||
| | KConfig config | An entry in you projects settings along the lines '' | | KConfig config | An entry in you projects settings along the lines '' | ||
| + | |||
| + | == The connections between the different files are == | ||
| + | | Device tree | '' | ||
| + | | Device tree binding | '' | ||
| + | | C Source | ''# | ||
| + | | C Source | '' | ||
| + | |||
| + | |||
| + | ===== DT Macros ===== | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | Many macros exist in two versions, '' | ||
| + | |||
| + | <code c> | ||
| + | // Get property from node identifier | ||
| + | #define DT_PROP(node_id, | ||
| + | |||
| + | // Get node identifier from instance number | ||
| + | #define DT_DRV_INST(inst) DT_INST(inst, | ||
| + | |||
| + | // Get property from instance number | ||
| + | #define DT_INST_PROP(inst, | ||
| + | </ | ||
| + | |||
| + | The instance number is, according to comment in '' | ||
| + | |||
| + | <code c> | ||
| + | /* | ||
| + | * All nodes with a particular compatible property value are assigned | ||
| + | * instance numbers, which are zero-based indexes specific to that | ||
| + | * compatible. You can get a node identifier for these nodes by | ||
| + | * passing DT_INST() an instance number, @p inst, along with the | ||
| + | * lowercase-and-underscores version of the compatible, @p compat. | ||
| + | * | ||
| + | * Instance numbers have the following properties: | ||
| + | * | ||
| + | * - for each compatible, instance numbers start at 0 and are contiguous | ||
| + | * - exactly one instance number is assigned for each node with a compatible, | ||
| + | | ||
| + | * - enabled nodes (status property is `okay` or missing) are assigned the | ||
| + | | ||
| + | | ||
| + | * ... | ||
| + | * Nodes whose `compatible` property has multiple values are assigned | ||
| + | * independent instance numbers for each compatible. | ||
| + | */ | ||
| + | </ | ||
| + | |||
| + | So the instance nubmer is an index of all nodes with a particular compatible. Node identifier, I assume, is an index over ALL device tree nodes. So like a local vs global index. | ||
| + | |||
| + | By checking the build folder and the generated include files, one can observe that | ||
| + | |||
| + | <code c> | ||
| + | // An instance number is a number 0 through n | ||
| + | // But the node identifier will be something along the lines of DT_N_S_soc_S_i2c_40005400_S_si5351_60 | ||
| + | // The macro DT_INST(0, skyworks_si5351) would retrieve this define from the generated source | ||
| + | #define DT_N_INST_0_skyworks_si5351 DT_N_S_soc_S_i2c_40005400_S_si5351_60 | ||
| + | |||
| + | // The DT_DRV_COMPAT that you define to something along the lines skyworks_si5351 will be just that, a token. Not anything magical. | ||
| + | // But it will be used by the zephyr provided helper macros to construct the names for the defines generated by the build system to the devicetree_generated.h so that you can retrieve them | ||
| + | |||
| + | // For example, the macro used to retrieve a property | ||
| + | DT_INST_PROP(inst, | ||
| + | // would expand to DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_plla_p1 | ||
| + | |||
| + | // According to the generated header: | ||
| + | /* | ||
| + | * Devicetree node: / | ||
| + | * | ||
| + | * Node identifier: DT_N_S_soc_S_i2c_40005400_S_si5351_60 | ||
| + | * | ||
| + | * Binding (compatible = skyworks, | ||
| + | | ||
| + | * | ||
| + | * (Descriptions have moved to the Devicetree Bindings Index | ||
| + | * in the documentation.) | ||
| + | */ | ||
| + | |||
| + | // Some of the generated properties looks like this | ||
| + | /* Generic property macros: */ | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_clkin_div 1 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_clkin_div_IDX_0_ENUM_IDX 0 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_clkin_div_IDX_0_EXISTS 1 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_clkin_div_IDX_0_ENUM_VAL_1_EXISTS 1 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_clkin_div_EXISTS 1 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_plla_p1 1638 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_plla_p1_EXISTS 1 | ||
| + | |||
| + | // For things like string enum there are a whole bunch of lines generated | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source " | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_STRING_UNQUOTED XTAL | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_STRING_TOKEN XTAL | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_STRING_UPPER_TOKEN XTAL | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_IDX_0 " | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_IDX_0_EXISTS 1 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_IDX_0_ENUM_IDX 0 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_IDX_0_ENUM_VAL_XTAL_EXISTS 1 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_FOREACH_PROP_ELEM(fn) fn(DT_N_S_soc_S_i2c_40005400_S_si5351_60, | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_FOREACH_PROP_ELEM_SEP(fn, | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_FOREACH_PROP_ELEM_VARGS(fn, | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_FOREACH_PROP_ELEM_SEP_VARGS(fn, | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_LEN 1 | ||
| + | #define DT_N_S_soc_S_i2c_40005400_S_si5351_60_P_pllb_clock_source_EXISTS 1 | ||
| + | </ | ||
| + | |||
zephyr/device_drivers.1751469662.txt.gz · Last modified: 2025/07/02 15:21 by utedass
