Skip to content

[RFC]: moving to eliminate dts_fixup files #11737

@pabigot

Description

@pabigot

DTS fixup files exist, as far as I can reconstruct, to bridge between names formerly used to specify device hardware resource assignments in Kconfig with names that are generated when the resource relationships are defined in device tree source files. They are ugly, verbose, and fragile; in short, a source of errors and maintenance pain.

Work like #11707 gives a hint for how we can get rid of fixup files, but there are impacts in naming that propagate to platform-independent driver code and to application code.

The purpose of this issue is to test the Zephyr community's tolerance for the consequences of this proposal.

As an example let's use samples/sensor/ccs811. The sensor exists on the nrf52_pca20020, and driver code was converted to using DT_ prefix instead of CONFIG_ prefix in #11180. As a result, the existing driver requires the following fixups:

  • DT_CCS811_NAME used in DEVICE_AND_API_INIT (and preferably instead of "CCS811" in the application call to device_get_binding());
  • DT_CCS811_I2C_MASTER_DEV_NAME used in the driver
  • DT_CCS811_I2C_ADDR used in the driver

The board DTS file contains this:

&i2c0 {
        ccs811: ccs811@5a {
                compatible = "ams,ccs811";
                reg = <0x5a>;
                label = "CCS811";
        };
};

In the absence of any dts_fixup.h entries we end up with the following in generated_dts_board.h:

// block 1
#define DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BASE_ADDRESS 0x5a
#define DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BUS_NAME     "I2C_0"
#define DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_LABEL        "CCS811"
// block 2
#define DT_AMS_CCS811_I2C_0_AMS_CCS811_5A_BASE_ADDRESS DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BASE_ADDRESS
#define DT_AMS_CCS811_I2C_0_AMS_CCS811_5A_BUS_NAME     DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BUS_NAME
#define DT_AMS_CCS811_I2C_0_AMS_CCS811_5A_LABEL        DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_LABEL
#define DT_AMS_CCS811_I2C_0_AMS_CCS811_5A_SIZE         DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_SIZE
// block 3
#define I2C_0_AMS_CCS811_5A_BASE_ADDRESS               DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BASE_ADDRESS
#define I2C_0_AMS_CCS811_5A_BUS_NAME                   DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BUS_NAME
#define I2C_0_AMS_CCS811_5A_LABEL                      DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_LABEL
#define I2C_0_AMS_CCS811_5A_SIZE                       DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_SIZE

Block 1 comes from the device tree directly, block 2 is synthesized by extract_dts_includes using a new
alias name incorporating the compatible property, and block 3 comes from the defaulted --old-alias-names. (I think the _SIZE generations are a bug in the extractor as there is no such symbol.)

None of these can be used directly in the sensor driver because the board-specific I2C bus and address are part of the identifier.

We can add the following alias to the DTS file:

/ {
        aliases {
                ccs811 = &ccs811;
        };
};

As a result we automatically get these added to generated_dts_board.h (excluding the _SIZE aliases):

// block 1
#define DT_AMS_CCS811_CCS811_BASE_ADDRESS DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BASE_ADDRESS
#define DT_AMS_CCS811_CCS811_BUS_NAME     DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BUS_NAME
#define DT_AMS_CCS811_CCS811_LABEL        DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_LABEL
// block 2
#define CCS811_BASE_ADDRESS               DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BASE_ADDRESS
#define CCS811_BUS_NAME                   DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BUS_NAME
#define CCS811_LABEL                      DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_LABEL

where extract_dts_includes has produced both old-style and new-style names.

IMO --old-alias-names should be deprecated because the symbols aren't prefixed with DT_, but the new aliases are decoupled from any board-specific wiring and are suitable for use in cross-platform drivers.

So if we're willing to make global name changes like the following:

  • Replace DT_CCS811_NAME with DT_AMS_CCS811_CCS811_LABEL
  • Replace DT_CCS811_I2C_MASTER_DEV_NAME with DT_AMS_CCS811_CCS811_BUS_NAME
  • Replace DT_CCS811_I2C_ADDR with DT_AMS_CCS811_CCS811_BASE_ADDRESS

and more generally accept the names synthesized from the device tree as canonical instead of whatever was used in the past, I think we can entirely get rid of dts_fixup.h files. But take into account what is visible in application code: e.g. the parameter to device_get_binding will change for samples that didn't hard-code the label. Within this development cycle it's already changed (CONFIG_FXOS8700_NAME to DT_FXOS8700_NAME) so a second permanent change (... to DT_NXP_FXOS8700_FXOS8700_LABEL) doesn't seem too harsh.

We could also consider this comment which would change the generated symbols for aliases to:

#define DT_CCS811_BASE_ADDRESS DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BASE_ADDRESS
#define DT_CCS811_BUS_NAME     DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_BUS_NAME
#define DT_CCS811_LABEL        DT_NORDIC_NRF_I2C_40003000_AMS_CCS811_5A_LABEL

This is closer to the pre-device-tree CONFIG_foo naming scheme, and is probably safe as it'd be the responsibility of the device tree overlay that defines the alias to make sure that it identifies a node with the expected compatibility. It would eliminate the oddity of names like DT_AMS_CCS811_CCS811_LABEL with its duplicated CCS811 component.

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions