From 8165008f44beb68f686ac37b6db99f94a6ced71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 5 Oct 2020 20:02:13 -0700 Subject: [PATCH] dts: remove legacy macro support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The legacy macros were first deprecated in Zephyr v2.3. Now that Zephyr v2.4 has been released, that makes two releases where these macros have been deprecated, so it's OK to remove them. This leaves support for legacy binding syntax in place. Removing that is left to future work. We need to update various pieces of documentation related to flash partitions that never got updated when the new API was introduced. Consolidate this information in the flash_map.h API reference page, since that's really where users will run into it. This also gives us the opportunity to improve this documentation. Adjust a couple of kconfigfunctions.py and sanitycheck bits to use non-legacy edtlib APIs. Signed-off-by: Martí Bolívar --- Kconfig.zephyr | 7 - boards/arm/nucleo_f429zi/doc/index.rst | 2 +- cmake/dts.cmake | 33 +- doc/guides/device_mgmt/dfu.rst | 4 +- doc/guides/dts/howtos.rst | 212 --- doc/guides/dts/index.rst | 1 - doc/guides/dts/intro.rst | 6 +- doc/guides/dts/legacy-macros.bnf | 106 -- doc/guides/dts/legacy-macros.rst | 1154 ----------------- doc/reference/devicetree/index.rst | 3 +- .../storage/flash_map/example_fragment.dts | 42 + doc/reference/storage/flash_map/flash_map.rst | 104 +- doc/releases/release-notes-2.3.rst | 17 +- doc/releases/release-notes-2.5.rst | 5 + include/devicetree.h | 13 - include/storage/flash_map.h | 59 +- samples/subsys/fs/littlefs/README.rst | 2 +- samples/subsys/mgmt/mcumgr/smp_svr/README.rst | 3 +- samples/subsys/mgmt/updatehub/README.rst | 4 +- samples/subsys/usb/dfu/README.rst | 2 +- scripts/dts/edtlib.py | 42 +- scripts/dts/gen_legacy_defines.py | 827 ------------ scripts/dts/test.dts | 25 - scripts/dts/testedtlib.py | 9 - scripts/kconfig/kconfigfunctions.py | 14 +- scripts/sanity_chk/expr_parser.py | 6 +- tests/deprecated/dts/CMakeLists.txt | 8 - tests/deprecated/dts/boards/frdm_k64f.overlay | 9 - tests/deprecated/dts/prj.conf | 1 - tests/deprecated/dts/src/main.c | 25 - tests/deprecated/dts/testcase.yaml | 4 - .../lib/devicetree/legacy_api/CMakeLists.txt | 9 - tests/lib/devicetree/legacy_api/README | 5 - tests/lib/devicetree/legacy_api/app.overlay | 95 -- tests/lib/devicetree/legacy_api/prj.conf | 2 - tests/lib/devicetree/legacy_api/src/main.c | 207 --- tests/lib/devicetree/legacy_api/testcase.yaml | 8 - 37 files changed, 202 insertions(+), 2873 deletions(-) delete mode 100644 doc/guides/dts/legacy-macros.bnf delete mode 100644 doc/guides/dts/legacy-macros.rst create mode 100644 doc/reference/storage/flash_map/example_fragment.dts delete mode 100755 scripts/dts/gen_legacy_defines.py delete mode 100644 tests/deprecated/dts/CMakeLists.txt delete mode 100644 tests/deprecated/dts/boards/frdm_k64f.overlay delete mode 100644 tests/deprecated/dts/prj.conf delete mode 100644 tests/deprecated/dts/src/main.c delete mode 100644 tests/deprecated/dts/testcase.yaml delete mode 100644 tests/lib/devicetree/legacy_api/CMakeLists.txt delete mode 100644 tests/lib/devicetree/legacy_api/README delete mode 100644 tests/lib/devicetree/legacy_api/app.overlay delete mode 100644 tests/lib/devicetree/legacy_api/prj.conf delete mode 100644 tests/lib/devicetree/legacy_api/src/main.c delete mode 100644 tests/lib/devicetree/legacy_api/testcase.yaml diff --git a/Kconfig.zephyr b/Kconfig.zephyr index e17956cc4ce..7b94a03bedc 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -342,13 +342,6 @@ config MAKEFILE_EXPORTS Generates a file with build information that can be read by third party Makefile-based build systems. -config LEGACY_DEVICETREE_MACROS - bool "Allow use of legacy devicetree macros" - help - Allows use of legacy devicetree macros which were used in - Zephyr 2.2 and previous versions, rather than the devicetree.h - API introduced during the Zephyr 2.3 development cycle. - config DEPRECATED_ZEPHYR_INT_TYPES bool "Allow the use of the deprecated zephyr integer types" help diff --git a/boards/arm/nucleo_f429zi/doc/index.rst b/boards/arm/nucleo_f429zi/doc/index.rst index f877613260f..55ec85f301d 100644 --- a/boards/arm/nucleo_f429zi/doc/index.rst +++ b/boards/arm/nucleo_f429zi/doc/index.rst @@ -189,7 +189,7 @@ Flash partitions for MCUBoot bootloader *************************************** The on-board STM32F429ZI MCU has 2MBs of internal flash memory. To use `MCUboot`_, -define a :ref:`Zephyr partition table ` for the flash memory in +define a :ref:`Zephyr partition table ` for the flash memory in its devicetree file ``nucleo_f429zi.dts``. As a reference, a partition table for MCUBoot is already defined in the devicetree file, with these settings: diff --git a/cmake/dts.cmake b/cmake/dts.cmake index 69cdb986bd1..69a96095281 100644 --- a/cmake/dts.cmake +++ b/cmake/dts.cmake @@ -4,15 +4,11 @@ file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/include/generated) # Zephyr code can configure itself based on a KConfig'uration with the # header file autoconf.h. There exists an analogous file devicetree_unfixed.h -# that allows configuration based on information encoded in DTS, and a similar -# file with legacy contents called devicetree_unfixed_legacy.h. +# that allows configuration based on information encoded in DTS. # -# Here we call on dtc, the gcc preprocessor, -# scripts/dts/gen_defines.py, and scripts/dts/gen_legacy_defines.py to -# generate various DT-related files at CMake configure-time. -# -# The devicetree.conf file is still needed by some deprecated -# functions in kconfigfunctions.py. +# Here we call on dtc, the gcc preprocessor and +# scripts/dts/gen_defines.py to generate various DT-related files at +# CMake configure-time. # # See the Devicetree user guide in the Zephyr documentation for details. set(GEN_DEFINES_SCRIPT ${ZEPHYR_BASE}/scripts/dts/gen_defines.py) @@ -25,7 +21,6 @@ set(ZEPHYR_DTS ${PROJECT_BINARY_DIR}/zephyr.dts) # and should not be made part of the documentation. set(EDT_PICKLE ${PROJECT_BINARY_DIR}/edt.pickle) set(DEVICETREE_UNFIXED_H ${PROJECT_BINARY_DIR}/include/generated/devicetree_unfixed.h) -set(DEVICETREE_UNFIXED_LEGACY_H ${PROJECT_BINARY_DIR}/include/generated/devicetree_legacy_unfixed.h) set(DTS_POST_CPP ${PROJECT_BINARY_DIR}/${BOARD}.dts.pre.tmp) set_ifndef(DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts) @@ -225,16 +220,6 @@ if(SUPPORTS_DTS) --edt-pickle-out ${EDT_PICKLE} ) - # - # Run gen_legacy_defines.py to create a header file with legacy contents - # and a .conf file. - # - - set(CMD_LEGACY_EXTRACT ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/dts/gen_legacy_defines.py - --edt-pickle ${EDT_PICKLE} - --header-out ${DEVICETREE_UNFIXED_LEGACY_H} - ) - execute_process( COMMAND ${CMD_EXTRACT} WORKING_DIRECTORY ${PROJECT_BINARY_DIR} @@ -247,15 +232,6 @@ if(SUPPORTS_DTS) message(STATUS "Generated devicetree_unfixed.h: ${DEVICETREE_UNFIXED_H}") endif() - execute_process( - COMMAND ${CMD_LEGACY_EXTRACT} - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - RESULT_VARIABLE ret - ) - if(NOT "${ret}" STREQUAL "0") - message(FATAL_ERROR "gen_legacy_defines.py failed with return code: ${ret}") - endif() - # A file that used to be generated by 'dtc'. zephyr.dts is the new # equivalent. Will be removed in Zephyr 2.3. file(WRITE ${PROJECT_BINARY_DIR}/${BOARD}.dts_compiled @@ -263,5 +239,4 @@ if(SUPPORTS_DTS) else() file(WRITE ${DEVICETREE_UNFIXED_H} "/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */") - file(WRITE ${DEVICETREE_UNFIXED_LEGACY_H} "/* WARNING. THIS FILE IS AUTO-GENERATED. DO NOT MODIFY! */") endif(SUPPORTS_DTS) diff --git a/doc/guides/device_mgmt/dfu.rst b/doc/guides/device_mgmt/dfu.rst index 015b26f508e..732c187520e 100644 --- a/doc/guides/device_mgmt/dfu.rst +++ b/doc/guides/device_mgmt/dfu.rst @@ -34,8 +34,8 @@ is the boot loader used with Zephyr. The source code itself is hosted in the In order to use MCUboot with Zephyr you need to take the following into account: -1. You will need to define the :ref:`mcuboot_partitions` required by MCUboot in - the :ref:`legacy_flash_partitions`. +1. You will need to define the flash partitions required by MCUboot; see + :ref:`flash_map_api` for details. 2. Your application's :file:`.conf` file needs to enable the :option:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option in order for Zephyr to be built in an MCUboot-compatible manner diff --git a/doc/guides/dts/howtos.rst b/doc/guides/dts/howtos.rst index 9fb357af061..b2ca1e8d17b 100644 --- a/doc/guides/dts/howtos.rst +++ b/doc/guides/dts/howtos.rst @@ -566,218 +566,6 @@ done in the :ref:`blinky-sample`. The application can then be configured in :ref:`BOARD.dts ` files or via :ref:`devicetree overlays `. -.. _dt-migrate-legacy: - -Migrate from the legacy macros -****************************** - -This section shows how to migrate from the :ref:`dt-legacy-macros` to the -:ref:`devicetree.h API `. (Please feel free to :ref:`ask for help -` if a use case you need is missing here and existing documentation is -not enough to figure out what to do.) - -This DTS is used for examples: - -.. literalinclude:: ../../../tests/lib/devicetree/legacy_api/app.overlay - :language: DTS - :start-after: start-after-here - :end-before: end-before-here - -The following shows equivalent ways to access this devicetree, using legacy -macros and the new devicetree.h API. - -.. warning:: - - The INST numbers below were carefully chosen to work. Instance numbering - properties have changed in the devicetree.h API compared to the legacy - macros, and are not guaranteed to be the same in all cases. See - :c:func:`DT_INST` for details. - -.. code-block:: c - - /* - * label - * - * These use the label property in /migration/gpio@1000. - * They all expand to "MGR_GPIO". - */ - - /* Legacy: */ - DT_VND_GPIO_1000_LABEL - DT_INST_0_VND_GPIO_LABEL - DT_ALIAS_MGR_GPIO_LABEL - - /* Use these instead: */ - DT_LABEL(DT_PATH(migration, gpio_1000)) - DT_LABEL(DT_INST(0, vnd_gpio)) - DT_LABEL(DT_ALIAS(mgr_gpio)) - DT_LABEL(DT_NODELABEL(migration_gpio)) - - /* - * reg base addresses and sizes - * - * These use the reg property in /migration/gpio@1000. - * The base addresses all expand to 0x1000, and sizes to 0x2000. - */ - - /* Legacy addresses: */ - DT_VND_GPIO_1000_BASE_ADDRESS - DT_INST_0_VND_GPIO_BASE_ADDRESS - DT_ALIAS_MGR_GPIO_BASE_ADDRESS - - /* Use these instead: */ - DT_REG_ADDR(DT_PATH(migration, gpio_1000)) - DT_REG_ADDR(DT_INST(0, vnd_gpio)) - DT_REG_ADDR(DT_ALIAS(mgr_gpio)) - DT_REG_ADDR(DT_NODELABEL(migration_gpio)) - - /* Legacy sizes: */ - DT_VND_GPIO_1000_SIZE - DT_INST_0_VND_GPIO_SIZE - DT_ALIAS_MGR_GPIO_SIZE - - /* Use these instead: */ - DT_REG_SIZE(DT_PATH(migration, gpio_1000)) - DT_REG_SIZE(DT_INST(0, vnd_gpio)) - DT_REG_SIZE(DT_ALIAS(mgr_gpio)) - DT_REG_SIZE(DT_NODELABEL(migration_gpio)) - - /* - * interrupts IRQ numbers and priorities - * - * These use the interrupts property in /migration/gpio@1000. - * The interrupt number is 0, and the priority is 1. - */ - - /* Legacy interrupt numbers: */ - DT_VND_GPIO_1000_IRQ_0 - DT_INST_0_VND_GPIO_IRQ_0 - DT_ALIAS_MGR_GPIO_IRQ_0 - - /* Use these instead: */ - DT_IRQN(DT_PATH(migration, gpio_1000)) - DT_IRQN(DT_INST(0, vnd_gpio)) - DT_IRQN(DT_ALIAS(mgr_gpio)) - DT_IRQN(DT_NODELABEL(migration_gpio)) - - /* Legacy priorities: */ - DT_VND_GPIO_1000_IRQ_0_PRIORITY, - DT_INST_0_VND_GPIO_IRQ_0_PRIORITY, - DT_ALIAS_MGR_GPIO_IRQ_0_PRIORITY, - - /* Use these instead: */ - DT_IRQ(DT_PATH(migration, gpio_1000), priority) - DT_IRQ(DT_INST(0, vnd_gpio), priority) - DT_IRQ(DT_ALIAS(mgr_gpio), priority) - DT_IRQ(DT_NODELABEL(migration_gpio), priority) - - /* - * Other property access - * - * These use the baud-rate property in /migration/serial@3000. - * They all expand to 115200. - */ - - /* Legacy: */ - DT_VND_SERIAL_3000_BAUD_RATE - DT_ALIAS_MGR_SERIAL_BAUD_RATE - DT_INST_0_VND_SERIAL_BAUD_RATE - - /* Use these instead: */ - DT_PROP(DT_PATH(migration, serial_3000), baud_rate) - DT_PROP(DT_ALIAS(mgr_serial), baud_rate) - DT_PROP(DT_NODELABEL(migration_serial), baud_rate) - DT_PROP(DT_INST(0, vnd_serial), baud_rate) - - /* - * I2C bus controller label access for an I2C peripheral device. - * - * These are different ways to get the bus controller label property - * from the peripheral device /migration/i2c@1000/i2c-dev-10. - * - * They all expand to "MGR_I2C". - */ - - /* Legacy: */ - DT_VND_I2C_10000_VND_I2C_DEVICE_10_BUS_NAME - DT_ALIAS_MGR_I2C_DEV_BUS_NAME - DT_INST_0_VND_I2C_DEVICE_BUS_NAME - - /* Use these instead (the extra #defines are just for readability): */ - #define I2C_DEV_PATH DT_PATH(migration, i2c_10000, i2c_dev_10) - #define I2C_DEV_ALIAS DT_ALIAS(mgr_i2c_dev) - #define I2C_DEV_NODELABEL DT_NODELABEL(mgr_i2c_device) - #define I2C_DEV_INST DT_INST(0, vnd_i2c_device) - - DT_LABEL(DT_BUS(I2C_DEV_PATH)) - DT_LABEL(DT_BUS(I2C_DEV_ALIAS))) - DT_LABEL(DT_BUS(I2C_DEV_NODELABEL))) - DT_LABEL(DT_BUS(I2C_DEV_INST))) - - /* - * SPI device chip-select controller. - * - * These use /migration/spi@2000/spi-dev@0. They all expand to - * "MGR_GPIO", which is the label property of /migration/gpio@1000, - * which is the SPI device's chip select pin GPIO controller. This is - * taken from the parent node's cs-gpios property. - */ - - /* Legacy */ - DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_CONTROLLER - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_CONTROLLER - DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_CONTROLLER - - /* Use these instead (extra #defines just for readability): */ - #define SPI_DEV_PATH DT_PATH(migration, spi_20000, migration_spi_dev_0) - #define SPI_DEV_ALIAS DT_ALIAS(mgr_spi_dev) - #define SPI_DEV_NODELABEL DT_NODELABEL(mgr_spi_device) - #define SPI_DEV_INST DT_INST(0, vnd_spi_device) - - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_PATH) - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_ALIAS) - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_NODELABEL) - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_INST) - - /* - * SPI device chip-select pin. - * - * These use /migration/spi@2000/spi-dev@0. - * They all expand to 17, which is also from cs-gpios. - */ - - /* Legacy: */ - DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_PIN - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_PIN - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_PIN - DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_PIN - - /* Use these instead (extra #defines from above): */ - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_PATH) - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_ALIAS) - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_NODEPIN) - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_INST) - - /* - * SPI device chip-select pin's flags for the gpio.h API. - * - * These use /migration/spi@2000/spi-dev@0. They all expand to - * GPIO_ACTIVE_LOW (technically, its numeric value after - * preprocessing), which is also from cs-gpios. - */ - - /* Legacy: */ - DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_FLAGS - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_FLAGS - DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_FLAGS - DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_FLAGS - - /* Use these instead (extra #defines from above): */ - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_PATH) - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_ALIAS) - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_NODEFLAGS) - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_INST) - .. _dt-trouble: Troubleshoot devicetree issues diff --git a/doc/guides/dts/index.rst b/doc/guides/dts/index.rst index 80070a4d161..8e1b7e7ff42 100644 --- a/doc/guides/dts/index.rst +++ b/doc/guides/dts/index.rst @@ -15,6 +15,5 @@ development. See :ref:`devicetree_api` for an API reference. design.rst bindings.rst api-usage.rst - legacy-macros.rst howtos.rst dt-vs-kconfig.rst diff --git a/doc/guides/dts/intro.rst b/doc/guides/dts/intro.rst index 9a408588bc6..6ec0794aca8 100644 --- a/doc/guides/dts/intro.rst +++ b/doc/guides/dts/intro.rst @@ -336,6 +336,8 @@ interrupts .. _Devicetree Specification release v0.3: https://www.devicetree.org/specifications/ +.. _dt-alias-chosen: + Aliases and chosen nodes ************************ @@ -514,10 +516,6 @@ These are created in your application's build directory. The generated macros and additional comments describing the devicetree. Included by ``devicetree.h``. -:file:`/zephyr/include/generated/devicetree_legacy_unfixed.h` - The generated :ref:`dt-legacy-macros`. - Included by ``devicetree.h``. - :file:`/zephyr/include/generated/devicetree_fixups.h` The concatenated contents of any :file:`dts_fixup.h` files. Included by ``devicetree.h``. diff --git a/doc/guides/dts/legacy-macros.bnf b/doc/guides/dts/legacy-macros.bnf deleted file mode 100644 index 05501d2b4bb..00000000000 --- a/doc/guides/dts/legacy-macros.bnf +++ /dev/null @@ -1,106 +0,0 @@ -; dt-macro is the top level nonterminal. It defines the possible -; macros generated by gen_defines.py. -; -; A dt-macro starts with uppercase "DT_" followed by either: -; -; - a property-macro, generated for a particular node -; property -; - some other-macro, a catch-all for other types of macros, -; which contain either global information about the tree or -; are special cases -; -; This does *not* cover macros pulled out of DT via Kconfig, -; like CONFIG_SRAM_BASE_ADDRESS, etc. -dt-macro = %s"DT_" ( property-macro / other-macro ) - -; -------------------------------------------------------------------- -; A property-macro is a sequence of: -; -; - node-id: a way to identify a node -; - property-id: a way to identify one of the node's properties -; - property-suf: an optional property-specific suffix -property-macro = node-id "_" property-id ["_" property-suf] - -; A node-id is a way to refer to a node within the devicetree. -; There are a few different flavors. - -node-id = compat-unit-id / inst-id / alias-id - -compat-unit-id = [bus-id-part "_"] compat-id-part "_" unit-addr-id-part -inst-id = %s"INST_" 1*DIGIT "_" compat-id-part -alias-id = %s"ALIAS_" alias-id-part - -; Various components of a property-macro are just c-idents, -; which are made of uppercase letters, numbers, and underscores. -; -; This is a problem, because it makes it possible for different nodes -; or properties in a devicetree to generate the same macro twice -; with different values. - -bus-id-part = c-ident ; ID for information about a node's bus -compat-id-part = c-ident ; ID for a node's compatible -unit-addr-id-part = c-ident ; ID for a node's unit-address -alias-id-part = c-ident ; ID for an /aliases node property -property-id = c-ident ; ID for a node property -- this also - ; covers special cases like "reg", - ; "interrupts", and "cs-gpios" for now, - ; as they all collide with non-special - ; cases. -property-suf = c-ident ; a suffix for part of a property value, - ; like an array index or a phandle - ; specifier name converted to a c-ident - -; -------------------------------------------------------------------- -; An other-macro is a grab bag for everything that isn't a -; property-macro. It reuses some of the nonterminals (namely node-id -; and compat-id-part) defined above. -other-macro = existence-flag / bus-macro / flash-macro / chosen-macro - -existence-flag = compat-existence-flag / inst-existence-flag -compat-flag = %s"COMPAT_" c-ident -inst-flag = %s"INST_" 1*DIGIT "_" c-ident - -bus-macro = bus-name-macro / on-bus-macro -bus-name-macro = node-id %s"_BUS_NAME" -on-bus-macro = compat-id-part %s"_BUS_" bus-name -bus-name = c-ident ; a bus name ("i2c") to a DT C - ; identifier ("I2C") - -flash-macro = %s"FLASH_AREA_" node-label-ident "_" flash-suf -flash-suf = %s"ID" / %s"READ_ONLY" / (%s"OFFSET" ["_" 1*DIGIT]) / - (%s"SIZE" ["_" 1*DIGIT]) / %s"DEV" - -; Macros generated from /chosen node properties. -chosen-macro = chosen-flash / - %s"CODE_PARTITION_OFFSET" / %s"CODE_PARTITION_SIZE" / - %s"CCM_BASE_ADDRESS" / %s"CCM_SIZE" / - %s"DTCM_BASE_ADDRESS" / %s"DTCM_SIZE" / - %s"IPC_SHM_BASE_ADDRESS" / %s"IPC_SHM_SIZE" -; These come from the /chosen/zephyr,flash property. -chosen-flash = %s"FLASH_BASE_ADDRESS" / - %s"FLASH_SIZE" / - %s"FLASH_ERASE_BLOCK_SIZE" / - %s"FLASH_WRITE_BLOCK_SIZE" - -; -------------------------------------------------------------------- -; Helper definitions. - -; A c-ident is one or more: -; - uppercase letters (A-Z) -; - numbers (0-9) -; - underscores ("_") -; -; They are the result of converting names or combinations of names -; from devicetree to a valid component of a C identifier by -; uppercasing letters and converting non-alphanumeric characters to -; underscores. -c-ident = 1*( UPPER / DIGIT / "_" ) - -; a node's "label" property value, as an identifier -node-label-ident = c-ident - -; "uppercase ASCII letter" turns out to be pretty annoying to specify -; in RFC-7405 syntax. -; -; This is just ASCII letters A (0x41) through Z (0x5A). -UPPER = %x41-5A diff --git a/doc/guides/dts/legacy-macros.rst b/doc/guides/dts/legacy-macros.rst deleted file mode 100644 index 6cd17018b27..00000000000 --- a/doc/guides/dts/legacy-macros.rst +++ /dev/null @@ -1,1154 +0,0 @@ -.. _dt-legacy-macros: - -Legacy devicetree macros -######################## - -.. warning:: - - As of Zephyr v2.3, you can still use these macros if you set - ``CONFIG_LEGACY_DEVICETREE_MACROS=y`` in your application's :ref:`kconfig`. - Legacy macro support will be maintained for at least two releases, including - v2.3 itself. - - See :ref:`dt-from-c` for a usage guide for the new API, and - :ref:`dt-migrate-legacy` for a migration guide for existing code. - -This page describes legacy C preprocessor macros which Zephyr's :ref:`build -system ` generates from a devicetree. It assumes you're -familiar with the concepts in :ref:`devicetree-intro` and :ref:`dt-bindings`. - -These macros have somewhat inconsistent names, and their use in new code is -discouraged. See :ref:`dt-from-c` for the recommended API. - -These macros are generated by the :ref:`devicetree scripts `, -start with ``DT_``, and use all-uppercase. - -.. _dt-legacy-node-identifiers: - -Legacy node identifiers -*********************** - -Macros generated from individual devicetree nodes or their properties start -with ``DT_``, where ```` is a C identifier for the devicetree node. -This section describes the different ```` values in the legacy macros. - -.. _dt-legacy-node-main-ex: - -We'll use the following DTS fragment from the :ref:`FRDM-K64F ` -board's devicetree as the main example throughout this section. - -.. code-block:: DTS - - / { - - aliases { - i2c-0 = &i2c0; - }; - - soc { - i2c0: i2c@40066000 { - compatible = "nxp,kinetis-i2c"; - reg = <0x40066000 0x1000>; - status = "okay"; - /* ... */ - - fxos8700@1d { - compatible = "nxp,fxos8700"; - status = "okay"; - /* ... */ - }; - }; - }; - }; - -The binding for the "nxp,fxos8700" :ref:`compatible property -` contains this line: - -.. code-block:: yaml - - on-bus: i2c - -The generated macros for this example can be found in a build directory for the -:ref:`FXOS8700 sample application ` built for the ``frdm_k64f`` -board, in the file -:file:`build/zephyr/include/generated/devicetree_legacy_unfixed.h`. - -Here is part of :file:`devicetree_legacy_unfixed.h` showing some of the macros -for the node labeled ``i2c0``. Notice the comment with the node's path in the -devicetree and its dependency relationships with other nodes. - -.. code-block:: c - - /* - * Devicetree node: - * /soc/i2c@40066000 - * - * Binding (compatible = nxp,kinetis-i2c): - * $ZEPHYR_BASE/dts/bindings/i2c/nxp,kinetis-i2c.yaml - * - * Dependency Ordinal: 66 - * - * Requires: - * 6 /soc - * ... - * - * Supports: - * 67 /soc/i2c@40066000/fxos8700@1d - * - * Description: - * Kinetis I2C node - */ - #define DT_NXP_KINETIS_I2C_40066000_BASE_ADDRESS 0x40066000 - #define DT_NXP_KINETIS_I2C_40066000_SIZE 4096 - #define DT_ALIAS_I2C_0_BASE_ADDRESS DT_NXP_KINETIS_I2C_40066000_BASE_ADDRESS - #define DT_ALIAS_I2C_0_SIZE DT_NXP_KINETIS_I2C_40066000_SIZE - #define DT_INST_0_NXP_KINETIS_I2C_BASE_ADDRESS DT_NXP_KINETIS_I2C_40066000_BASE_ADDRESS - #define DT_INST_0_NXP_KINETIS_I2C_SIZE DT_NXP_KINETIS_I2C_40066000_SIZE - -Most macros are generated for individual nodes or their properties. Some macros -are generated for "global" information about the entire devicetree. - -In this example, the node identifiers for ``i2c@40066000`` are: - -- ``NXP_KINETIS_I2C_40066000`` -- ``ALIAS_I2C_0`` -- ``INST_0_NXP_KINETIS_I2C`` - -In general, the following ``DT_`` macro prefixes are created for each -node. - -``DT_(_)_`` - The node's compatible property converted to a C identifier, followed by its - :ref:`unit address `. If the node has multiple compatible - strings, the one for its :ref:`matching binding ` is - used. - - If the node appears on a bus (and therefore has ``on-bus:`` in its binding, - like ``fxos8700@1d`` does), then the compatible string and unit address of - the bus node is put before the compatible string for the node itself. If - the node does not appear on a bus (no ``on-bus:`` in the binding, like - ``i2c@40066000``) then there will be no ``_`` portion in the node - identifier. - - The ``i2c@40066000`` node identifier is ``NXP_KINETIS_I2C_40066000``: - - - there is no ``_`` portion - - ```` is ``NXP_KINETIS_I2C``, which is its - compatible ``"nxp,kinetis-i2c"`` converted to a C identifier - by uppercasing and replacing non-alphanumeric characters with underscores - - ```` is ``40066000`` - - The ``fxos8700@1d`` node identifier is - ``NXP_KINETIS_I2C_40066000_NXP_FXOS8700_1D``: - - - ```` is ``NXP_KINETIS_I2C_40066000`` - - ```` is ``NXP_FXOS8700`` - - ```` is ``1D`` - - If the node has no unit address, the unit address of the parent node plus - the node's name converted to a C identifier is used for ```` - instead. If the parent node has no unit address either, the name of the - node is used as a fallback. - - For example, take this DTS fragment: - - .. code-block:: DTS - - ethernet@400c0004 { - compatible = "nxp,kinetis-ethernet"; - reg = <0x400c0004 0x620>; - status = "okay"; - ptp { - compatible = "nxp,kinetis-ptp"; - status = "okay"; - interrupts = <0x52 0x0>; - }; - }; - - The ``ptp`` node identifier is ``NXP_KINETIS_PTP_400C0004_PTP``: - - - there is no ``_`` portion - - ```` is ``NXP_KINETIS_PTP`` - - ```` is ``400C0004_PTP``, which combines its parent's unit - address and the node's name converted to a C identifier - - Here is another example DTS fragment. - - .. code-block:: DTS - - soc { - temp1 { - compatible = "nxp,kinetis-temperature"; - status = "okay"; - }; - }; - - The ``temp1`` node identifier is ``NXP_KINETIS_TEMPERATURE_TEMP1``: - - - there is no ``_`` portion - - ```` is ``NXP_KINETIS_TEMPERATURE`` - - ```` is the fallback value ``TEMP1``, because neither - the node nor its parent have a unit address - -``DT_INST__`` - An instance number for the node, combined with its compatible - converted to a C identifier. - - The instance number is a unique index among all enabled - (``status = "okay"``) nodes that have a particular compatible string, - starting from zero. - - The ``i2c@40066000`` node identifier in the :ref:`main example - ` is ``INST_0_NXP_KINETIS_I2C``: - - - ```` is 0 because it was the first node with compatible - "nxp,kinetis-i2c" that the devicetree scripts happened to discover as they - walked the tree - - ```` is ``NXP_KINETIS_I2C`` - - As another example, if there are two enabled nodes that have ``compatible = - "foo,uart"``, then these node identifiers get generated: - - .. code-block:: none - - INST_0_FOO_UART - INST_1_FOO_UART - - .. warning:: - - Instance numbers are simple indexes among enabled nodes with the same - compatible. They **in no way reflect** any numbering scheme that might - exist in SoC documentation, node labels or unit addresses, or properties - of the /aliases node. - - There is no guarantee that the same node will have the same instance - number between application builds. The only guarantee is that instance - numbers will start at 0, be contiguous, and be assigned for each enabled - node with a matching compatible. - -``DT_ALIAS_`` - Generated from the names of any properties in the ``/aliases`` node. - See :ref:`dt-alias-chosen` for an overview. - - Here is a simple example. - - .. code-block:: DTS - - / { - aliases { - uart-1 = &my_uart; - }; - - my_uart: uart@12345 { /* ... */ }; - }; - - The ``uart@12345`` node identifier is ``ALIAS_UART_1``: ```` is - ``UART_1`` by uppercasing ``uart-1`` and replacing non-alphanumeric - characters with underscores. The alias refers to ``uart@12345`` using its - :ref:`label ` ``my_uart``. - - For such a simple concept, dealing with aliases can be surprisingly tricky - due to multiple names which have only minor differences. - - For a real-world example, the ``i2c@40066000`` node's alias identifier in - the :ref:`main example ` is ``ALIAS_I2C_0``: - ```` is ``I2C_0`` because the property ``i2c-0 = &i2c0;`` in the - ``/aliases`` node "points at" ``i2c@40066000`` using its label ``i2c0``. - The alias name ``i2c-0`` is converted to C identifier ``I2C_0``. - - The differences between ``i2c-0``, ``&i2c0``, ``i2c0``, and - ``i2c@40006000`` in this example are very subtle and can be quite confusing - at first. Here is some more clarification: - - - ``i2c-0`` is the *name* of a property in the ``/aliases`` node; this is - the alias name - - ``&i2c0`` is that property's *value*, which is the *phandle* of the - the node with label ``i2c0`` - - ``i2c@40006000`` is the name of the node which happens to have label - ``i2c0`` in this example - - See the devicetree specification for full details. - - .. note:: - - Another ``DT__`` form is also - generated for aliases. For the example above, assuming the compatible - string for the ``&uart1`` node is ``"foo,uart"``, this gives - ``DT_FOO_UART_UART_1``. - -.. _legacy-property-macros: - -Macros generated for properties -******************************* - -Macros for node property values have the form ``DT__``, where -```` is a :ref:`node identifier ` and ```` -identifies the property. The macros generated for a property usually depend on -its ``type:`` key in the matching devicetree binding. - -The following general purpose rules apply in most cases: - -- :ref:`generic-legacy-macros` -- :ref:`phandle-array-legacy-macros` -- :ref:`enum-legacy-macros` - -However, some "special" properties get individual treatment: - -- :ref:`reg_legacy_macros` -- :ref:`irq_legacy_macros` -- :ref:`clk_legacy_macros` -- :ref:`spi_cs_legacy_macros` - -No macros are currently generated for properties with type ``phandle``, -``phandles``, ``path``, or ``compound``. - -.. _generic-legacy-macros: - -Generic property macros -======================= - -This section documents the macros generated for non-"special" properties by -example. These properties are handled based on their devicetree binding -``type:`` keys. - -In the generic case, the ```` portion of a ``DT__`` -macro begins with the property's name converted to a C identifier by -uppercasing it and replacing non-alphanumeric characters with underscores. For -example, a ``baud-rate`` property has a ```` portion that starts with -``BAUD_RATE``. - -The table below gives the values generated for simple types. Note that an index -is added at the end of identifiers generated from properties with ``array`` or -``string-array`` type, and that ``array`` properties generate an additional -compound initializer (``{ ... }``). - - - -+------------------+------------------------+----------------------------------------+ -| Type | Property and value | Generated macros | -+==================+========================+========================================+ -| ``int`` | ``foo = <1>`` | ``#define DT__FOO 1`` | -+------------------+------------------------+----------------------------------------+ -| ``array`` | ``foo = <1 2>`` | | ``#define DT__FOO_0 1`` | -| | | | ``#define DT__FOO_1 2`` | -| | | | ``#define DT__FOO {1, 2}`` | -+------------------+------------------------+----------------------------------------+ -| ``string`` | ``foo = "bar"`` | ``#define DT__FOO "bar"`` | -+------------------+------------------------+----------------------------------------+ -| ``string-array`` | ``foo = "bar", "baz"`` | | ``#define DT__FOO_0 "bar"`` | -| | | | ``#define DT__FOO_1 "baz"`` | -+------------------+------------------------+----------------------------------------+ -| ``uint8-array`` | ``foo = [01 02]`` | ``#define DT__FOO {0x01, 0x02}`` | -+------------------+------------------------+----------------------------------------+ - -For ``type: boolean``, the generated macro is set to 1 if the property exists -on the node, and to 0 otherwise: - -.. code-block:: none - - #define DT__FOO 0/1 - -For non-boolean types the property macros are not generated if the binding's -``category`` is ``optional`` and the property is not present in the devicetree -source. - -.. _phandle-array-legacy-macros: - -Properties with type ``phandle-array`` -====================================== - -The generation for properties with type ``phandle-array`` is the most complex. -To understand it, it is a good idea to first go through the documentation for -``phandle-array`` in :ref:`dt-bindings`. - -Take the following devicetree nodes and binding contents as an example: - -.. code-block:: DTS - :caption: Devicetree nodes for PWM controllers - - pwm_ctrl_0: pwm-controller-0 { - label = "pwm-0"; - #pwm-cells = <2>; - /* ... */ - }; - - pwm_ctrl_1: pwm-controller-1 { - label = "pwm-1"; - #pwm-cells = <2>; - /* ... */ - }; - -.. code-block:: yaml - :caption: ``pwm-cells`` declaration in binding for ``vendor,pwm-controller`` - - pwm-cells: - - channel - - period - -Assume the property assignment looks like this: - -.. code-block:: DTS - - pwm-user@0 { - status = "okay"; - pwms = <&pwm_ctrl_0 1 10>, <&pwm_ctrl_1 2 20>; - pwm-names = "first", "second"; - /* ... */ - }; - -These macros then get generated. - -.. code-block:: none - - #define DT__PWMS_CONTROLLER_0 "pwm-0" - #define DT__PWMS_CHANNEL_0 1 - #define DT__PWMS_PERIOD_0 10 - - #define DT__PWMS_CONTROLLER_1 "pwm-1" - #define DT__PWMS_CHANNEL_1 2 - #define DT__PWMS_PERIOD_1 20 - - #define DT__PWMS_NAMES_0 "first" - #define DT__PWMS_NAMES_1 "second" - - #define DT__FIRST_PWMS_CONTROLLER DT__PWMS_CONTROLLER_0 - #define DT__FIRST_PWMS_CHANNEL DT__PWMS_CHANNEL_0 - #define DT__FIRST_PWMS_PERIOD DT__PWMS_PERIOD_0 - - #define DT__SECOND_PWMS_CONTROLLER DT__PWMS_CONTROLLER_1 - #define DT__SECOND_PWMS_CHANNEL DT__PWMS_CHANNEL_1 - #define DT__SECOND_PWMS_PERIOD DT__PWMS_PERIOD_1 - - /* Initializers */ - - #define DT__PWMS_0 {"pwm-0", 1, 10} - #define DT__PWMS_1 {"pwm-1", 2, 20} - #define DT__PWMS {DT__PWMS_0, DT__PWMS_1} - #define DT__PWMS_COUNT 2 - -Macros with a ``*_0`` suffix deal with the first entry in ``pwms`` -(``<&pwm_ctrl_0 1 10>``). Macros with a ``*_1`` suffix deal with the second -entry (``<&pwm_ctrl_1 2 20>``). The index suffix is only added if there's more -than one entry in the property. - -The ``DT__PWMS_CONTROLLER(_)`` macros are set to the string from -the ``label`` property of the referenced controller. The -``DT__PWMS_CHANNEL(_)`` and ``DT__PWMS_PERIOD(_)`` -macros are set to the values of the corresponding cells in the ``pwms`` -property, with macro names generated from the strings in ``pwm-cells:`` in -the binding for the controller. - -The macros in the ``/* Initializers */`` section provide the same information -as ``DT__PWMS_{CONTROLLER,CHANNEL,PERIOD}(_)``, except as compound -initializers that can be used to initialize C ``struct`` variables. - -If a ``pwm-names`` property exists on the same node as ``pwms`` (more -generally, if a ``foo-names`` property is defined next to a ``foo`` property -with type ``phandle-array``), it gives a list of strings that name each entry -in ``pwms``. The names are used to generate extra macro names with the name -instead of an index, like ``DT__FIRST_PWMS_CONTROLLER`` above. - -.. _enum-legacy-macros: - -Properties with ``enum:`` in the binding -======================================== - -Properties declared with an ``enum:`` key in their binding generate a macro -that gives the the zero-based index of the property's value in the ``enum:`` -list. - -Take this binding declaration as an example: - -.. code-block:: yaml - - properties: - foo: - type: string - enum: - - one - - two - - three - -The property ``foo = "three"`` then generates this macro: - -.. code-block:: none - - #define DT__FOO_ENUM 2 - -.. _reg_legacy_macros: - -``reg`` property macros -======================= - -``reg`` properties generate the macros ``DT__BASE_ADDRESS(_)`` and -``DT__SIZE(_)``. ```` is a numeric index starting from 0, -which is only added if there's more than one register defined in ``reg``. - -For example, the ``reg = <0x4004700 0x1060>`` assignment in the example -devicetree above gives these macros: - -.. code-block:: none - - #define DT__BASE_ADDRESS 0x40047000 - #define DT__SIZE 4192 - -.. note:: - - The length of the address and size portions of ``reg`` is determined from - the ``#address-cells`` and ``#size-cells`` properties. See the devicetree - specification for more information. - - In this case, both ``#address-cells`` and ``#size-cells`` are 1, and there's - just a single register in ``reg``. Four numbers would give two registers. - -If a ``reg-names`` property exists on the same node as ``reg``, it gives a list -of strings that names each register in ``reg``. The names are used to generate -extra macros. For example, ``reg-names = "foo"`` together with the example node -generates these macros: - -.. code-block:: c - - #define DT__FOO_BASE_ADDRESS 0x40047000 - #define DT__FOO_SIZE 4192 - -.. _irq_legacy_macros: - -``interrupts`` property macros -============================== - -Take these devicetree nodes as an example: - -.. code-block:: DTS - - timer@123 { - interrupts = <1 5 2 6>; - interrupt-parent = <&intc>; - /* ... */ - }; - - intc: interrupt-controller { /* ... */ }; - -Assume that the binding for ``interrupt-controller`` has these lines: - -.. code-block:: yaml - - interrupt-cells: - - irq - - priority - -Then these macros get generated for ``timer@123``: - -.. code-block:: c - - #define DT__IRQ_0 1 - #define DT__IRQ_0_PRIORITY 5 - #define DT__IRQ_1 2 - #define DT__IRQ_1_PRIORITY 6 - -These macros have the the format ``DT__IRQ_(_)``, where -```` is the node identifier for ``timer@123``, ```` is an index -that identifies the particular interrupt, and ```` is the identifier for -the cell value (a number within ``interrupts = <...>``), taken from the -binding. - -Bindings for interrupt controllers are expected to declare a cell named ``irq`` -in ``interrupt-cells``, giving the interrupt number. The ``_`` suffix is -skipped for macros generated from ``irq`` cells, which is why there's e.g. a -``DT__IRQ_0`` macro and no ``DT__IRQ_0_IRQ`` macro. - -If the interrupt controller in turn generates other interrupts, Zephyr uses a -multi-level interrupt encoding for the interrupt numbers at each level. See -:ref:`multi_level_interrupts` for more information. - -There is also hard-coded logic for mapping Arm GIC interrupts to linear IRQ -numbers. See the source code for details. - -Additional macros that use names instead of indices for interrupts can be -generated by including an ``interrupt-names`` property on the -interrupt-generating node. For example, this node: - -.. code-block:: DTS - - timer@456 { - interrupts = <10 50 20 60>; - interrupt-parent = <&intc>; - interrupt-names = "timer-a", "timer-b"; - /* ... */ - }; - -generates these macros: - -.. code-block:: c - - #define DT__IRQ_TIMER_A 1 - #define DT__IRQ_TIMER_A_PRIORITY 5 - #define DT__IRQ_TIMER_B 2 - #define DT__IRQ_TIMER_B_PRIORITY 6 - -.. _clk_legacy_macros: - -``clocks`` property macros -========================== - -``clocks`` work the same as other :ref:`phandle-array-legacy-macros`, except the -generated macros have ``CLOCK`` in them instead of ``CLOCKS``, giving for -example ``DT__CLOCK_CONTROLLER_0`` instead of -``DT__CLOCKS_CONTROLLER_0``. - -If a ``clocks`` controller node has a ``"fixed-clock"`` compatible, it -must also have a ``clock-frequency`` property giving its frequency in Hertz. -In this case, an additional macro is generated: - -.. code-block:: none - - #define DT__CLOCKS_CLOCK_FREQUENCY - -.. _spi_cs_legacy_macros: - -``cs-gpios`` property macros -============================ - -.. boards/arm/sensortile_box/sensortile_box.dts has a real-world example - -Take these devicetree nodes as an example. where the binding for -``vendor,spi-controller`` is assumed to have ``bus: spi``, and the bindings for -the SPI slaves are assumed to have ``on-bus: spi``: - -.. code-block:: DTS - - gpioa: gpio@400ff000 { - compatible = "vendor,gpio-ctlr"; - reg = <0x400ff000 0x40>; - label = "GPIOA"; - gpio-controller; - #gpio-cells = <0x1>; - }; - - spi { - compatible = "vendor,spi-controller"; - cs-gpios = <&gpioa 1>, <&gpioa 2>; - spi-slave@0 { - compatible = "vendor,foo-spi-device"; - reg = <0>; - }; - spi-slave@1 { - compatible = "vendor,bar-spi-device"; - reg = <1>; - }; - }; - -Here, the unit address of the SPI slaves (0 and 1) is taken as a chip select -number, which is used as an index into ``cs-gpios`` (a ``phandle-array``). -``spi-slave@0`` is matched to ``<&gpioa 1>``, and ``spi-slave@1`` to -``<&gpiob 2>``. - -The output for ``spi-slave@0`` and ``spi-slave@1`` is the same as if the -devicetree had looked like this: - -.. code-block:: DTS - - gpioa: gpio@400ff000 { - compatible = "vendor,gpio-ctlr"; - reg = <0x400ff000 0x40>; - label = "GPIOA"; - gpio-controller; - #gpio-cells = <1>; - }; - - spi { - compatible = "vendor,spi-controller"; - spi-slave@0 { - compatible = "vendor,foo-spi-device"; - reg = <0>; - cs-gpios = <&gpioa 1>; - }; - spi-slave@1 { - compatible = "vendor,bar-spi-device"; - reg = <1>; - cs-gpios = <&gpioa 2>; - }; - }; - -See the ``phandle-array`` section in :ref:`generic-legacy-macros` for more -information. - -For example, since the node labeled ``gpioa`` has property -``label = "GPIOA"`` and 1 and 2 are pin numbers, macros like the following -will be generated for ``spi-slave@0``: - -.. code-block:: none - - #define DT__CS_GPIOS_CONTROLLER "GPIOA" - #define DT__CS_GPIOS_PIN 1 - -.. _other-macros: - -Other macros -************ - -These are generated in addition to macros generated for :ref:`properties -`. - -- :ref:`dt-existence-legacy-macros` -- :ref:`bus-legacy-macros` -- :ref:`flash-legacy-macros` - -.. _dt-existence-legacy-macros: - -Node existence flags -==================== - -An "existence flag" is a macro which is defined when the devicetree contains -nodes matching some criterion. - -Existence flags are generated for each compatible property that appears on an -enabled node: - -.. code-block:: none - - #define DT_COMPAT_ 1 - -An existence flag is also written for all enabled nodes with a matching -compatible: - -.. code-block:: none - - #define DT_INST__ 1 - -For the ``i2c@40066000`` node in the :ref:`example ` above, -assuming the node is the first node with ``compatible = "nxp,kinetis-i2c"``, -the following existence flags would be generated: - -.. code-block:: c - - /* At least one node had compatible nxp,kinetis-i2c: */ - #define DT_COMPAT_NXP_KINETIS_I2C 1 - - /* Instance 0 of compatible nxp,kinetis-i2c exists: */ - #define DT_INST_0_NXP_KINETIS_I2C 1 - -If additional nodes had compatible ``nxp,kinetis-i2c``, additional existence -flags would be generated: - -.. code-block:: c - - #define DT_INST_1_NXP_KINETIS_I2C 1 - #define DT_INST_2_NXP_KINETIS_I2C 1 - /* ... and so on, one for each node with this compatible. */ - -.. _bus-legacy-macros: - -Bus-related macros -================== - -These macros get generated for nodes that appear on buses (have ``on-bus:`` in -their binding): - -.. code-block:: none - - #define DT__BUS_NAME "" - #define DT__BUS_ 1 - -```` is taken from the ``label`` property on the bus node, which -must exist. ```` is the identifier for the bus as given in -``on-bus:`` in the binding. - -.. _flash-legacy-macros: - -Macros generated from flash partitions -====================================== - -.. note:: - - This section only covers flash partitions. See :ref:`dt-alias-chosen` for - some other flash-related macros that get generated from devicetree, via - ``/chosen``. - -If a node has a name that looks like ``partition@``, it is -assumed to represent a flash partition. - -Assume the devicetree has this: - -.. code-block:: DTS - - flash@0 { - /* ... */ - label = "foo-flash"; - - partitions { - /* ... */ - #address-cells = <1>; - #size-cells = <1>; - - boot_partition: partition@0 { - label = "mcuboot"; - reg = <0x00000000 0x00010000>; - read-only; - }; - slot0_partition: partition@10000 { - label = "image-0"; - reg = <0x00010000 0x00020000 - 0x00040000 0x00010000>; - }; - /* ... */ - }; - -These macros then get generated: - -.. code-block:: c - - #define DT_FLASH_AREA_MCUBOOT_ID 0 - #define DT_FLASH_AREA_MCUBOOT_READ_ONLY 1 - #define DT_FLASH_AREA_MCUBOOT_OFFSET_0 0x0 - #define DT_FLASH_AREA_MCUBOOT_SIZE_0 0x10000 - #define DT_FLASH_AREA_MCUBOOT_OFFSET DT_FLASH_AREA_MCUBOOT_OFFSET_0 - #define DT_FLASH_AREA_MCUBOOT_SIZE DT_FLASH_AREA_MCUBOOT_SIZE_0 - #define DT_FLASH_AREA_MCUBOOT_DEV "foo-flash" - - #define DT_FLASH_AREA_IMAGE_0_ID 0 - #define DT_FLASH_AREA_IMAGE_0_READ_ONLY 1 - #define DT_FLASH_AREA_IMAGE_0_OFFSET_0 0x10000 - #define DT_FLASH_AREA_IMAGE_0_SIZE_0 0x20000 - #define DT_FLASH_AREA_IMAGE_0_OFFSET_1 0x40000 - #define DT_FLASH_AREA_IMAGE_0_SIZE_1 0x10000 - #define DT_FLASH_AREA_IMAGE_0_OFFSET DT_FLASH_AREA_IMAGE_0_OFFSET_0 - #define DT_FLASH_AREA_IMAGE_0_SIZE DT_FLASH_AREA_IMAGE_0_SIZE_0 - #define DT_FLASH_AREA_IMAGE_0_DEV "foo-flash" - - /* Same macros, just with index instead of label */ - #define DT_FLASH_AREA_0_ID 0 - #define DT_FLASH_AREA_0_READ_ONLY 1 - ... - -The ``*_ID`` macro gives the zero-based index for the partition. - -The ``*_OFFSET_`` and ``*_SIZE_`` macros give the offset and size -for each partition, derived from ``reg``. The ``*_OFFSET`` and ``*_SIZE`` -macros, with no index, are aliases that point to the first sector (with index -0). - -.. _dt-alias-chosen: - -``aliases`` and ``chosen`` nodes -================================ - -Using an alias with a common name for a particular node makes it easier for you -to write board-independent source code. Devicetree ``aliases`` nodes are used -for this purpose, by mapping certain generic, commonly used names to specific -hardware resources: - -.. code-block:: yaml - - aliases { - led0 = &led0; - sw0 = &button0; - sw1 = &button1; - uart-0 = &uart0; - uart-1 = &uart1; - }; - -Certain software subsystems require a specific hardware resource to bind to in -order to function properly. Some of those subsystems are used with many -different boards, which makes using the devicetree ``chosen`` nodes very -convenient. By doing so, the software subsystem can rely on having the specific -hardware peripheral assigned to it. In the following example we bind the shell -to ``uart1`` in this board: - -.. code-block:: yaml - - chosen { - zephyr,shell-uart = &uart1; - }; - -The table below lists Zephyr-specific ``chosen`` properties. The macro -identifiers that start with ``CONFIG_*`` are generated from Kconfig symbols -that reference devicetree data via the :ref:`Kconfig preprocessor -`. - -.. note:: - - Since the particular devicetree isn't known while generating Kconfig - documentation, the Kconfig symbol reference pages linked below do not - include information derived from devicetree. Instead, you might see e.g. an - empty default: - - .. code-block:: none - - default "" if HAS_DTS - - To see how the preprocessor is used for a symbol, look it up directly in the - :file:`Kconfig` file where it is defined instead. The reference page for the - symbol gives the definition location. - -.. list-table:: - :header-rows: 1 - - * - ``chosen`` node name - - Generated macros - - * - ``zephyr,flash`` - - ``DT_FLASH_BASE_ADDRESS``/``DT_FLASH_SIZE``/``DT_FLASH_ERASE_BLOCK_SIZE``/``DT_FLASH_WRITE_BLOCK_SIZE`` - * - ``zephyr,code-partition`` - - ``DT_CODE_PARTITION_OFFSET``/``DT_CODE_PARTITION_SIZE`` - * - ``zephyr,sram`` - - :option:`CONFIG_SRAM_BASE_ADDRESS`/:option:`CONFIG_SRAM_SIZE` - * - ``zephyr,ccm`` - - ``DT_CCM_BASE_ADDRESS``/``DT_CCM_SIZE`` - * - ``zephyr,dtcm`` - - ``DT_DTCM_BASE_ADDRESS``/``DT_DTCM_SIZE`` - * - ``zephyr,ipc_shm`` - - ``DT_IPC_SHM_BASE_ADDRESS``/``DT_IPC_SHM_SIZE`` - * - ``zephyr,console`` - - :option:`CONFIG_UART_CONSOLE_ON_DEV_NAME` - * - ``zephyr,shell-uart`` - - :option:`CONFIG_UART_SHELL_ON_DEV_NAME` - * - ``zephyr,bt-uart`` - - :option:`CONFIG_BT_UART_ON_DEV_NAME` - * - ``zephyr,uart-pipe`` - - :option:`CONFIG_UART_PIPE_ON_DEV_NAME` - * - ``zephyr,bt-mon-uart`` - - :option:`CONFIG_BT_MONITOR_ON_DEV_NAME` - * - ``zephyr,bt-c2h-uart`` - - :option:`CONFIG_BT_CTLR_TO_HOST_UART_DEV_NAME` - * - ``zephyr,uart-mcumgr`` - - :option:`CONFIG_UART_MCUMGR_ON_DEV_NAME` - -.. _legacy_flash_partitions: - -Legacy flash partitions -*********************** - -Devicetree can be used to describe a partition layout for any flash -device in the system. - -Two important uses for this mechanism are: - -#. To force the Zephyr image to be linked into a specific area on - Flash. - - This is useful, for example, if the Zephyr image must be linked at - some offset from the flash device's start, to be loaded by a - bootloader at runtime. - -#. To generate compile-time definitions for the partition layout, - which can be shared by Zephyr subsystems and applications to - operate on specific areas in flash. - - This is useful, for example, to create areas for storing file - systems or other persistent state. These defines only describe the - boundaries of each partition. They don't, for example, initialize a - partition's flash contents with a file system. - -Partitions are generally managed using device tree overlays. See -:ref:`set-devicetree-overlays` for examples. - -Defining Partitions -=================== - -The partition layout for a flash device is described inside the -``partitions`` child node of the flash device's node in the device -tree. - -You can define partitions for any flash device on the system. - -Most Zephyr-supported SoCs with flash support in device tree -will define a label ``flash0``. This label refers to the primary -on-die flash programmed to run Zephyr. To generate partitions -for this device, add the following snippet to a device tree overlay -file: - -.. code-block:: DTS - - &flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* Define your partitions here; see below */ - }; - }; - -To define partitions for another flash device, modify the above to -either use its label or provide a complete path to the flash device -node in the device tree. - -The content of the ``partitions`` node looks like this: - -.. code-block:: DTS - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition1_label: partition@START_OFFSET_1 { - label = "partition1_name"; - reg = <0xSTART_OFFSET_1 0xSIZE_1>; - }; - - /* ... */ - - partitionN_label: partition@START_OFFSET_N { - label = "partitionN_name"; - reg = <0xSTART_OFFSET_N 0xSIZE_N>; - }; - }; - -Where: - -- ``partitionX_label`` are device tree labels that can be used - elsewhere in the device tree to refer to the partition - -- ``partitionX_name`` controls how defines generated by the Zephyr - build system for this partition will be named - -- ``START_OFFSET_x`` is the start offset in hexadecimal notation of - the partition from the beginning of the flash device - -- ``SIZE_x`` is the hexadecimal size, in bytes, of the flash partition - -The partitions do not have to cover the entire flash device. The -device tree compiler currently does not check if partitions overlap; -you must ensure they do not when defining them. - -Example Primary Flash Partition Layout -====================================== - -Here is a complete (but hypothetical) example device tree overlay -snippet illustrating these ideas. Notice how the partitions do not -overlap, but also do not cover the entire device. - -.. code-block:: DTS - - &flash0 { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - code_dts_label: partition@8000 { - label = "zephyr-code"; - reg = <0x00008000 0x34000>; - }; - - data_dts_label: partition@70000 { - label = "application-data"; - reg = <0x00070000 0xD000>; - }; - }; - }; - -Linking Zephyr Within a Partition -================================= - -To force the linker to output a Zephyr image within a given flash -partition, add this to a device tree overlay: - -.. code-block:: DTS - - / { - chosen { - zephyr,code-partition = &slot0_partition; - }; - }; - -Then, enable the :option:`CONFIG_USE_DT_CODE_PARTITION` Kconfig option. - -Flash Partition Macros -====================== - -The Zephyr build system generates definitions for each flash device -partition. These definitions are available to any files which -include ````. - -Consider this flash partition: - -.. code-block:: DTS - - dts_label: partition@START_OFFSET { - label = "def-name"; - reg = <0xSTART_OFFSET 0xSIZE>; - }; - -The build system will generate the following corresponding defines: - -.. code-block:: c - - #define DT_FLASH_AREA_DEF_NAME_DEV "def-name" - #define DT_FLASH_AREA_DEF_NAME_OFFSET_0 0xSTART_OFFSET - #define DT_FLASH_AREA_DEF_NAME_SIZE_0 0xSIZE - #define DT_FLASH_AREA_DEF_NAME_OFFSET DT_FLASH_AREA_DEF_NAME_OFFSET_0 - #define DT_FLASH_AREA_DEF_NAME_SIZE DT_FLASH_AREA_DEF_NAME_SIZE_0 - -As you can see, the ``label`` property is capitalized when forming the -macro names. Other simple conversions to ensure it is a valid C -identifier, such as converting "-" to "_", are also performed. The -offsets and sizes are available as well. - -.. _mcuboot_partitions: - -MCUboot Partitions -================== - -`MCUboot`_ is a secure bootloader for 32-bit microcontrollers. - -Some Zephyr boards provide definitions for the flash partitions which -are required to build MCUboot itself, as well as any applications -which must be chain-loaded by MCUboot. - -The device tree labels for these partitions are: - -**boot_partition** - This is the partition where the bootloader is expected to be - placed. MCUboot's build system will attempt to link the MCUboot - image into this partition. - -**slot0_partition** - MCUboot loads the executable application image from this - partition. Any application bootable by MCUboot must be linked to run - from this partition. - -**slot1_partition** - This is the partition which stores firmware upgrade images. Zephyr - applications which receive firmware updates must ensure the upgrade - images are placed in this partition (the Zephyr DFU subsystem can be - used for this purpose). MCUboot checks for upgrade images in this - partition, and can move them to ``slot0_partition`` for execution. - The ``slot0_partition`` and ``slot1_partition`` must be the same - size. - -**scratch_partition** - This partition is used as temporary storage while swapping the - contents of ``slot0_partition`` and ``slot1_partition``. - -.. important:: - - Upgrade images are only temporarily stored in ``slot1_partition``. - They must be linked to execute of out of ``slot0_partition``. - -See the `MCUboot documentation`_ for more details on these partitions. - -.. _MCUboot: https://mcuboot.com/ - -.. _MCUboot documentation: - https://github.com/runtimeco/mcuboot/blob/master/docs/design.md#image-slots - -File System Partitions -====================== - -**storage_partition** - This is the area where e.g. LittleFS or NVS or FCB expects its partition. - -ABNF grammar -************ - -This section contains an Augmented Backus-Naur Form grammar for the macros -generated from a devicetree. See `RFC 7405`_ (which extends `RFC 5234`_) for a -syntax specification. - -.. literalinclude:: legacy-macros.bnf - :language: abnf - -.. _RFC 7405: https://tools.ietf.org/html/rfc7405 -.. _RFC 5234: https://tools.ietf.org/html/rfc5234 diff --git a/doc/reference/devicetree/index.rst b/doc/reference/devicetree/index.rst index 1b43ae48c87..cea67c9366b 100644 --- a/doc/reference/devicetree/index.rst +++ b/doc/reference/devicetree/index.rst @@ -211,7 +211,8 @@ Fixed flash partitions These conveniences may be used for the special-purpose ``fixed-partitions`` compatible used to encode information about flash memory partitions in the -device tree. +device tree. See :zephyr_file:`dts/bindings/mtd/partition.yaml` for this +compatible's binding. .. doxygengroup:: devicetree-fixed-partition :project: Zephyr diff --git a/doc/reference/storage/flash_map/example_fragment.dts b/doc/reference/storage/flash_map/example_fragment.dts new file mode 100644 index 00000000000..cdcef3eacbe --- /dev/null +++ b/doc/reference/storage/flash_map/example_fragment.dts @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + */ +/* start-after-here */ +/ { + soc { + flashctrl: flash-controller@deadbeef { + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 0x100000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <0x1>; + #size-cells = <0x1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 0x10000>; + read-only; + }; + storage_partition: partition@1e000 { + label = "storage"; + reg = <0x1e000 0x2000>; + }; + slot0_partition: partition@20000 { + label = "image-0"; + reg = <0x20000 0x60000>; + }; + slot1_partition: partition@80000 { + label = "image-1"; + reg = <0x80000 0x60000>; + }; + scratch_partition: partition@e0000 { + label = "image-scratch"; + reg = <0xe0000 0x20000>; + }; + }; + }; + }; + }; +}; diff --git a/doc/reference/storage/flash_map/flash_map.rst b/doc/reference/storage/flash_map/flash_map.rst index eaf6e810a45..788451dfb88 100644 --- a/doc/reference/storage/flash_map/flash_map.rst +++ b/doc/reference/storage/flash_map/flash_map.rst @@ -1,36 +1,96 @@ .. _flash_map_api: -Flash map (flash_map) -########################## +Flash map +######### -Flash map is a way for storing flash partitioning information in one central -location in flash_area structures array form. +The ```` API allows accessing information about device +flash partitions via :c:struct:`flash_area` structures. -Flash map is generated from DTS based on content of :ref:`legacy_flash_partitions` -nodes. -The flash_area API provides a way to access data in the flash map. -The flash_area_open() API is the interface for obtaining the flash partitions -flash_area from the flash map. +Each ``struct flash_area`` describes a flash partition. The API provides access +to a "flash map", which contains predefined flash areas accessible via globally +unique ID numbers. You can also create ``flash_area`` structures at runtime for +application-specific purposes. +The ``flash_area`` structure contains the name of the flash device the +partition is part of; this name can be passed to :c:func:`device_get_binding` +to get the corresponding :c:struct:`device` structure which can be read and +written to using the :ref:`flash API `. The ``flash_area`` also +contains the start offset and size of the partition within the flash memory the +device represents. -Flash Area API (flash_area) -########################### +The flash_map.h API provides functions for operating on a ``flash_area``. The +main examples are :c:func:`flash_area_read` and :c:func:`flash_area_write`. +These functions are basically wrappers around the flash API with input +parameter range checks. Not all flash APIs have flash_map.h wrappers, but +:c:func:`flash_area_get_device` allows easily retrieving the ``struct device`` +from a ``struct flash_area``. -The flash_area concept combines methods for operating on a flash chunk -together with a description of this chunk. Its methods are basically wrappers -around the flash API, with input parameter range checks. Not all flash -operation are wrapped so an API call to retrieve the flash area driver is -included as well. The flash area methods are designed to be used along with -the flash_area structures of flash_map and user-specific flash_areas, with -the exception of the area_open API used to fetch a flash_area from -the flash_map. +Use :c:func:`flash_area_open()` to access a ``struct flash_area``. This +function takes a flash area ID number and returns a pointer to the flash area +structure. The ID number for a flash area can be obtained from a human-readable +"label" using :c:macro:`FLASH_AREA_ID`; these labels are obtained from the +devicetree as described below. +Relationship with Devicetree +**************************** + +The flash_map.h API uses data generated from the :ref:`devicetree_api`, in +particular its :ref:`devicetree-flash-api`. Zephyr additionally has some +partitioning conventions used for :ref:`dfu` via the MCUboot bootloader, as +well as defining partitions usable by :ref:`file systems ` or +other nonvolatile :ref:`storage `. + +Here is an example devicetree fragment which uses fixed flash partitions for +both MCUboot and a storage partition. Some details were left out for clarity. + +.. literalinclude:: example_fragment.dts + :language: DTS + :start-after: start-after-here + +The ``boot_partition``, ``slot0_partition``, ``slot1_partition``, and +``scratch_partition`` nodes are defined for MCUboot, though not all MCUboot +configurations require all of them to be defined. See the `MCUboot +documentation`_ for more details. + +The ``storage_partition`` node is defined for use by a file system or other +nonvolatile storage API. + +.. _MCUboot documentation: https://mcuboot.com/ + +To get a numeric flash area ID from one of the child nodes of the +``partitions`` node: + +#. take the node's ``label`` property value +#. lowercase it +#. convert all special characters to underscores (``_``) +#. pass the result **without quotes** to ``FLASH_AREA_ID()`` + +For example, the ``flash_area`` ID number for ``slot0_partition`` is +``FLASH_AREA_ID(image_0)``. + +The same rules apply for other macros which take a "label", such as +:c:macro:`FLASH_AREA_OFFSET` and :c:macro:`FLASH_AREA_SIZE`. For example, +``FLASH_AREA_OFFSET(image_0)`` would return the start offset for +``slot0_partition`` within its flash device. This is determined by the node's +:ref:`devicetree-reg-property`, and in this case is 0x20000. + +To get a pointer to the flash area structure and do something with it starting +with a devicetree label like ``"image-0"``, use something like this: + +.. code-block:: c + + struct flash_area *my_area; + int err = flash_area_open(FLASH_AREA_ID(image_0), &my_area); + + if (err != 0) { + handle_the_error(err); + } else { + flash_area_read(my_area, ...); + } API Reference ************* -flash_area API -============== - .. doxygengroup:: flash_area_api :project: Zephyr + :members: diff --git a/doc/releases/release-notes-2.3.rst b/doc/releases/release-notes-2.3.rst index 5d6d03104a3..b280d1b484c 100644 --- a/doc/releases/release-notes-2.3.rst +++ b/doc/releases/release-notes-2.3.rst @@ -133,8 +133,12 @@ Deprecated in this release * See :ref:`dt-from-c` for a high-level guide to the new API, and :ref:`devicetree_api` for an API reference. * Use of the legacy macros now requires explicitly enabling - :option:`CONFIG_LEGACY_DEVICETREE_MACROS`. See :ref:`dt-legacy-macros` for - more information, including a link to a migration guide to the new API. + ``CONFIG_LEGACY_DEVICETREE_MACROS``. See `the Zephyr v2.3 legacy devicetree + macro page`_ for more information, including a link to a migration guide to + the new API. + +.. _the Zephyr v2.3 legacy devicetree macro page: + https://docs.zephyrproject.org/2.3.0/guides/dts/legacy-macros.html#dt-legacy-macros * Other @@ -666,9 +670,12 @@ Build and Infrastructure * Devicetree * A new :ref:`devicetree_api` was added. This API is not generated, but is - still included via ````. The :ref:`dt-legacy-macros` are now - deprecated; users should replace the generated macros with new API. The - :ref:`dt-howtos` page has been extended for the new API, and a new + still included via ````. + + See `the Zephyr v2.3 legacy devicetree macro page`_ for more information, + including a link to a migration guide to the new API. + + The :ref:`dt-howtos` page has been extended for the new API, and a new :ref:`dt-from-c` API usage guide was also added. Libraries / Subsystems diff --git a/doc/releases/release-notes-2.5.rst b/doc/releases/release-notes-2.5.rst index 33739dc706d..fb618e95f2d 100644 --- a/doc/releases/release-notes-2.5.rst +++ b/doc/releases/release-notes-2.5.rst @@ -190,6 +190,11 @@ Build and Infrastructure * Devicetree * :c:macro:`DT_ENUM_IDX_OR`: new macro + * Support for legacy devicetree macros via + ``CONFIG_LEGACY_DEVICETREE_MACROS`` was removed. All devicetree-based code + should be using the new devicetree API introduced in Zephyr 2.3 and + documented in :ref:`dt-from-c`. Information on flash partitions has moved + to :ref:`flash_map_api`. Libraries / Subsystems ********************** diff --git a/include/devicetree.h b/include/devicetree.h index 49f2574264a..9f67b0aed15 100644 --- a/include/devicetree.h +++ b/include/devicetree.h @@ -16,20 +16,7 @@ #ifndef DEVICETREE_H #define DEVICETREE_H -#ifdef _LINKER -/* - * Linker scripts include this file too, and autoconf.h isn't - * automatically included for those files the way it is for C source - * files. Make sure we pull it in before using - * CONFIG_LEGACY_DEVICETREE_MACROS in that case. - */ -#include -#endif - #include -#ifdef CONFIG_LEGACY_DEVICETREE_MACROS -#include -#endif #include #include diff --git a/include/storage/flash_map.h b/include/storage/flash_map.h index dcfaa2edfd0..0f209036294 100644 --- a/include/storage/flash_map.h +++ b/include/storage/flash_map.h @@ -14,29 +14,22 @@ #define ZEPHYR_INCLUDE_STORAGE_FLASH_MAP_H_ /** - * @brief Abstraction over flash area and its driver which helps to operate on - * flash regions easily and effectively. + * @brief Abstraction over flash partitions/areas and their drivers * * @defgroup flash_area_api flash area Interface * @{ */ +/* + * This API makes it possible to operate on flash areas easily and + * effectively. + * + * The system contains global data about flash areas. Every area + * contains an ID number, offset, and length. + */ + /** * - * Provides abstraction of flash regions for type of use, - * for example, where's my image? - * - * System will contain a map which contains flash areas. Every - * region will contain flash identifier, offset within flash, and length. - * - * 1. This system map could be in a file within filesystem (Initializer - * must know/figure out where the filesystem is at). - * 2. Map could be at fixed location for project (compiled to code) - * 3. Map could be at specific place in flash (put in place at mfg time). - * - * Note that the map you use must be valid for BSP it's for, - * match the linker scripts when platform executes from flash, - * and match the target offset specified in download script. */ #include #include @@ -46,22 +39,32 @@ extern "C" { #endif -#define SOC_FLASH_0_ID 0 /** device_id for SoC flash memory driver */ -#define SPI_FLASH_0_ID 1 /** device_id for external SPI flash driver */ +/** Provided for compatibility with MCUboot */ +#define SOC_FLASH_0_ID 0 +/** Provided for compatibility with MCUboot */ +#define SPI_FLASH_0_ID 1 /** - * @brief Structure for store flash partition data + * @brief Flash partition * - * It is used as the flash_map array entry or stand-alone user data. Structure - * contains all data needed to operate on the flash partitions. + * This structure represents a fixed-size partition on a flash device. + * Each partition contains one or more flash sectors. */ struct flash_area { - uint8_t fa_id; /** ID of flash area */ + /** ID number */ + uint8_t fa_id; + /** Provided for compatibility with MCUboot */ uint8_t fa_device_id; uint16_t pad16; - off_t fa_off; /** flash partition offset */ - size_t fa_size; /** flash partition size */ - const char *fa_dev_name; /** flash device name */ + /** Start offset from the beginning of the flash device */ + off_t fa_off; + /** Total size */ + size_t fa_size; + /** + * Name of the flash device, suitable for passing to + * device_get_binding(). + */ + const char *fa_dev_name; }; /** @@ -71,8 +74,10 @@ struct flash_area { * consumes much less RAM than @ref flash_area */ struct flash_sector { - off_t fs_off; /** flash sector offset */ - size_t fs_size; /** flash sector size */ + /** Sector offset from the beginning of the flash device */ + off_t fs_off; + /** Sector size in bytes */ + size_t fs_size; }; #if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY) diff --git a/samples/subsys/fs/littlefs/README.rst b/samples/subsys/fs/littlefs/README.rst index ff5c098c91c..b032f8a43bf 100644 --- a/samples/subsys/fs/littlefs/README.rst +++ b/samples/subsys/fs/littlefs/README.rst @@ -18,7 +18,7 @@ Requirements ************ The partition labeled "storage" will be used for the file system; see -:ref:`legacy_flash_partitions`. If that area does not already have a +:ref:`flash_map_api`. If that area does not already have a compatible littlefs file system its contents will be replaced by an empty file system. You will see diagnostics like this:: diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst index d07774f708f..b24aa911730 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst +++ b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst @@ -183,8 +183,7 @@ Flashing the sample image ************************* Upload the :file:`zephyr.signed.bin` file from the previous to image slot-0 of your -board. The location of image slot-0 varies by board, as described in -:ref:`mcuboot_partitions`. +board. See :ref:`flash_map_api` for details on flash partitioning. To upload the initial image file to an empty slot-0, we simply use ``west flash`` like normal. ``west flash`` will automatically detect slot-0 address and confirm diff --git a/samples/subsys/mgmt/updatehub/README.rst b/samples/subsys/mgmt/updatehub/README.rst index 8e0b633dda4..333b1fca714 100644 --- a/samples/subsys/mgmt/updatehub/README.rst +++ b/samples/subsys/mgmt/updatehub/README.rst @@ -150,8 +150,8 @@ Step 6: Flash the first image ============================= Upload the :file:`signed.bin` file from Step 4 to image slot-0 of your -board. The location of image slot-0 varies by board, as described in -:ref:`mcuboot_partitions`. For the frdm_k64f, slot-0 is located at address +board. The location of the slot 0 image varies by board; see +:ref:`flash_map_api` for details. For the frdm_k64f, slot-0 is located at address ``0xc000``. Using :file:`pyocd` you don't need to specify the slot-0 starting address. diff --git a/samples/subsys/usb/dfu/README.rst b/samples/subsys/usb/dfu/README.rst index ba44ca6d5cb..f18e22ee985 100644 --- a/samples/subsys/usb/dfu/README.rst +++ b/samples/subsys/usb/dfu/README.rst @@ -14,7 +14,7 @@ Requirements This project requires an USB device driver. Currently, the USB DFU class provided by the Zephyr project depends on DFU image manager and -partition layout. Refer to :ref:`legacy_flash_partitions` for details about +partition layout. Refer to :ref:`flash_map_api` for details about partition layout. You SoC must run MCUboot as the stage 1 bootloader. This sample is built as an application for the MCUboot bootloader. diff --git a/scripts/dts/edtlib.py b/scripts/dts/edtlib.py index 1b63b96e678..fa37228ee38 100644 --- a/scripts/dts/edtlib.py +++ b/scripts/dts/edtlib.py @@ -100,27 +100,6 @@ class EDT: nodes: A list of Node objects for the nodes that appear in the devicetree - compat2enabled: - A collections.defaultdict that maps each 'compatible' string that appears - on some enabled Node to a list of enabled Nodes. - - For example, edt.compat2enabled["bar"] would include the 'foo' and 'bar' - nodes below. - - foo { - compatible = "bar"; - status = "okay"; - ... - }; - bar { - compatible = "foo", "bar", "baz"; - status = "okay"; - ... - }; - - This exists only for the sake of gen_legacy_defines.py. It will probably - be removed following the Zephyr 2.3 release. - compat2nodes: A collections.defaultdict that maps each 'compatible' string that appears on some Node to a list of Nodes with that compatible. @@ -524,7 +503,6 @@ class EDT: self.label2node = OrderedDict() self.dep_ord2node = OrderedDict() - self.compat2enabled = defaultdict(list) self.compat2nodes = defaultdict(list) self.compat2okay = defaultdict(list) @@ -535,9 +513,6 @@ class EDT: for compat in node.compats: self.compat2nodes[compat].append(node) - if node.enabled: - self.compat2enabled[compat].append(node) - if node.status == "okay": self.compat2okay[compat].append(node) @@ -703,8 +678,8 @@ class Node: A non-negative integer value such that the value for a Node is less than the value for all Nodes that depend on it. - The ordinal is defined for all Nodes including those that are not - 'enabled', and is unique among nodes in its EDT 'nodes' list. + The ordinal is defined for all Nodes, and is unique among nodes in its + EDT 'nodes' list. required_by: A list with the nodes that directly depend on the node @@ -717,12 +692,6 @@ class Node: has no status property set. If the node's status property is "ok", it is converted to "okay" for consistency. - enabled: - True unless the node has 'status = "disabled"' - - This exists only for the sake of gen_legacy_defines.py. It will probably - be removed following the Zephyr 2.3 release. - read_only: True if the node has a 'read-only' property, and False otherwise @@ -866,11 +835,6 @@ class Node: return as_string - @property - def enabled(self): - "See the class docstring" - return "status" not in self._node.props or self.status != "disabled" - @property def read_only(self): "See the class docstring" @@ -1182,7 +1146,7 @@ class Node: prop = node.props.get(name) if not prop: - if required and self.enabled: + if required and self.status == "okay": _err("'{}' is marked as required in 'properties:' in {}, but " "does not appear in {!r}".format( name, self.binding_path, node)) diff --git a/scripts/dts/gen_legacy_defines.py b/scripts/dts/gen_legacy_defines.py deleted file mode 100755 index 0baa8d31655..00000000000 --- a/scripts/dts/gen_legacy_defines.py +++ /dev/null @@ -1,827 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2019 Nordic Semiconductor ASA -# Copyright (c) 2019 Linaro Limited -# SPDX-License-Identifier: BSD-3-Clause - -# This script is similar to gen_defines.py, but is for the legacy -# macro syntax used in e.g. Zephyr 2.2. -# -# It should be considered frozen code. New macro-related functionality -# should be done by modifying the macro namespaces managed by -# gen_defines.py. - -import argparse -import os -import pathlib -import pickle - -# Set this to True to generated deprecated macro warnings. Since this -# entire file is deprecated and must be explicitly enabled with -# CONFIG_LEGACY_DEVICETREE_MACROS, this was turned off by default -# shortly before the v2.3 release (this was the least impactful way to -# do it, which resulted in the smallest and least-risky patch). -DEPRECATION_MESSAGES = False - -def main(): - global header_file - global flash_area_num - - args = parse_args() - - with open(args.edt_pickle, 'rb') as f: - edt = pickle.load(f) - - header_file = open(args.header_out, "w", encoding="utf-8") - flash_area_num = 0 - - write_top_comment(edt) - - for node in sorted(edt.nodes, key=lambda node: node.dep_ordinal): - write_node_comment(node) - - # Flash partition nodes are handled as a special case. It - # would be nicer if we had bindings that would let us - # avoid that, but this will do for now. - if node.name.startswith("partition@"): - write_flash_partition(node, flash_area_num) - flash_area_num += 1 - - if node.enabled and node.matching_compat: - write_regs(node) - write_irqs(node) - write_props(node) - write_clocks(node) - write_spi_dev(node) - write_bus(node) - write_existence_flags(node) - - out_comment("Compatibles appearing on enabled nodes") - for compat in sorted(edt.compat2enabled): - #define DT_COMPAT_ 1 - out(f"COMPAT_{str2ident(compat)}", 1) - - # Definitions derived from /chosen nodes - write_addr_size(edt, "zephyr,ccm", "CCM") - write_addr_size(edt, "zephyr,dtcm", "DTCM") - write_addr_size(edt, "zephyr,ipc_shm", "IPC_SHM") - write_flash(edt) - - header_file.close() - - -def parse_args(): - # Returns parsed command-line arguments - - parser = argparse.ArgumentParser() - parser.add_argument("--edt-pickle", required=True, - help="pickle file containing EDT object") - parser.add_argument("--header-out", required=True, - help="path to write header to") - - return parser.parse_args() - - -def write_top_comment(edt): - # Writes an overview comment with misc. info at the top of the header and - # configuration file - - s = f"""\ -Generated by gen_legacy_defines.py - -DTS input file: - {edt.dts_path} - -Directories with bindings: - {", ".join(map(relativize, edt.bindings_dirs))} - -Nodes in dependency order (ordinal and path): -""" - - for scc in edt.scc_order: - if len(scc) > 1: - err("cycle in devicetree involving " - + ", ".join(node.path for node in scc)) - s += f" {scc[0].dep_ordinal:<3} {scc[0].path}\n" - - s += """ -Definitions derived from these nodes in dependency order are next, -followed by tree-wide information (active compatibles, chosen nodes, -etc.). -""" - - out_comment(s, blank_before=False) - - -def write_node_comment(node): - # Writes a comment describing 'node' to the header and configuration file - - s = f"""\ -Devicetree node: - {node.path} -""" - if node.matching_compat: - if node.binding_path: - s += f""" -Binding (compatible = {node.matching_compat}): - {relativize(node.binding_path)} -""" - else: - s += f""" -Binding (compatible = {node.matching_compat}): - No yaml (bindings inferred from properties) -""" - else: - s += "\nNo matching binding.\n" - - s += f"\nDependency Ordinal: {node.dep_ordinal}\n" - - if node.depends_on: - s += "\nRequires:\n" - for dep in node.depends_on: - s += f" {dep.dep_ordinal:<3} {dep.path}\n" - - if node.required_by: - s += "\nSupports:\n" - for req in node.required_by: - s += f" {req.dep_ordinal:<3} {req.path}\n" - - if node.description: - # Indent description by two spaces - s += "\nDescription:\n" + \ - "\n".join(" " + line for line in - node.description.splitlines()) + \ - "\n" - - if not node.enabled: - s += "\nNode is disabled.\n" - - out_comment(s) - - -def relativize(path): - # If 'path' is within $ZEPHYR_BASE, returns it relative to $ZEPHYR_BASE, - # with a "$ZEPHYR_BASE/..." hint at the start of the string. Otherwise, - # returns 'path' unchanged. - - zbase = os.getenv("ZEPHYR_BASE") - if zbase is None: - return path - - try: - return str("$ZEPHYR_BASE" / pathlib.Path(path).relative_to(zbase)) - except ValueError: - # Not within ZEPHYR_BASE - return path - - -def write_regs(node): - # Writes address/size output for the registers in the node's 'reg' property - - def write_reg(reg, base_ident, val): - # Drop '_0' from the identifier if there's a single register, for - # backwards compatibility - if len(reg.node.regs) > 1: - ident = f"{base_ident}_{reg.node.regs.index(reg)}" - else: - ident = base_ident - - out_node(node, ident, val, - # Name alias from 'reg-names = ...' - f"{str2ident(reg.name)}_{base_ident}" if reg.name else None) - - for reg in node.regs: - write_reg(reg, "BASE_ADDRESS", hex(reg.addr)) - if reg.size: - write_reg(reg, "SIZE", reg.size) - - -def write_props(node): - # Writes any properties defined in the "properties" section of the binding - # for the node - - for prop in node.props.values(): - if not should_write(prop): - continue - - if prop.description is not None: - out_comment(prop.description, blank_before=False) - - ident = str2ident(prop.name) - - if prop.type == "boolean": - out_node(node, ident, 1 if prop.val else 0) - elif prop.type == "string": - out_node_s(node, ident, prop.val) - elif prop.type == "int": - out_node(node, ident, prop.val) - elif prop.type == "array": - for i, val in enumerate(prop.val): - out_node(node, f"{ident}_{i}", val) - out_node_init(node, ident, prop.val) - elif prop.type == "string-array": - for i, val in enumerate(prop.val): - out_node_s(node, f"{ident}_{i}", val) - elif prop.type == "uint8-array": - out_node_init(node, ident, - [f"0x{b:02x}" for b in prop.val]) - else: # prop.type == "phandle-array" - write_phandle_val_list(prop) - - # Generate DT_..._ENUM if there's an 'enum:' key in the binding - if prop.enum_index is not None: - out_node(node, ident + "_ENUM", prop.enum_index) - - -def should_write(prop): - # write_props() helper. Returns True if output should be generated for - # 'prop'. - - # Skip #size-cell and other property starting with #. Also skip mapping - # properties like 'gpio-map'. - if prop.name[0] == "#" or prop.name.endswith("-map"): - return False - - # See write_clocks() - if prop.name == "clocks": - return False - - # For these, Property.val becomes an edtlib.Node, a list of edtlib.Nodes, - # or None. Nothing is generated for them at the moment. - if prop.type in {"phandle", "phandles", "path", "compound"}: - return False - - # Skip properties that we handle elsewhere - if prop.name in { - "reg", "compatible", "status", "interrupts", - "interrupt-controller", "gpio-controller" - }: - return False - - return True - - -def write_bus(node): - # Generate bus-related #defines - - if not node.bus_node: - return - - if node.bus_node.label is None: - err(f"missing 'label' property on bus node {node.bus_node!r}") - - # #define DT__BUS_NAME - out_node_s(node, "BUS_NAME", str2ident(node.bus_node.label), "Macro is deprecated") - - for compat in node.compats: - # #define DT__BUS_ 1 - out(f"{str2ident(compat)}_BUS_{str2ident(node.on_bus)}", 1) - - -def write_existence_flags(node): - # Generate #defines of the form - # - # #define DT_INST__ 1 - # - # for enabled nodes. These are flags for which devices exist. - - for compat in node.compats: - instance_no = node.edt.compat2enabled[compat].index(node) - out(f"INST_{instance_no}_{str2ident(compat)}", 1) - - -def node_ident(node): - # Returns an identifier for 'node'. Used e.g. when building macro names. - - # TODO: Handle PWM on STM - # TODO: Better document the rules of how we generate things - - ident = "" - - if node.bus_node: - if node.bus_node.unit_addr is not None: - ident += "{}_{:X}_".format( - str2ident(node.bus_node.matching_compat), node.bus_node.unit_addr) - else: - ident += str2ident(node.bus_node.matching_compat) - - ident += f"{str2ident(node.matching_compat)}_" - - if node.unit_addr is not None: - ident += f"{node.unit_addr:X}" - elif node.parent.unit_addr is not None: - ident += f"{node.parent.unit_addr:X}_{str2ident(node.name)}" - else: - # This is a bit of a hack - ident += str2ident(node.name) - - return ident - - -def node_aliases(node): - # Returns a list of aliases for 'node', used e.g. when building macro names - - return node_path_aliases(node) + node_instance_aliases(node) - - -def node_path_aliases(node): - # Returns a list of aliases for 'node', based on the aliases registered for - # it in the /aliases node. Used e.g. when building macro names. - - if node.matching_compat is None: - return [] - - compat_s = str2ident(node.matching_compat) - - aliases = [] - for alias in node.aliases: - aliases.append(f"ALIAS_{str2ident(alias)}") - # TODO: See if we can remove or deprecate this form - aliases.append(f"{compat_s}_{str2ident(alias)}") - - return aliases - - -def node_instance_aliases(node): - # Returns a list of aliases for 'node', based on the compatible string and - # the instance number (each node with a particular compatible gets its own - # instance number, starting from zero). - # - # This is a list since a node can have multiple 'compatible' strings, each - # with their own instance number. - - res = [] - for compat in node.compats: - instance_no = node.edt.compat2enabled[compat].index(node) - res.append(f"INST_{instance_no}_{str2ident(compat)}") - return res - - -def write_addr_size(edt, prop_name, prefix): - # Writes _BASE_ADDRESS and _SIZE for the node pointed at by - # the /chosen property named 'prop_name', if it exists - - node = edt.chosen_node(prop_name) - if not node: - return - - if not node.regs: - err("missing 'reg' property in node pointed at by " - f"/chosen/{prop_name} ({node!r})") - - out_comment(f"/chosen/{prop_name} ({node.path})") - out(f"{prefix}_BASE_ADDRESS", hex(node.regs[0].addr)) - out(f"{prefix}_SIZE", node.regs[0].size//1024) - - -def write_flash(edt): - # Writes chosen and tree-wide flash-related output - - write_flash_node(edt) - write_code_partition(edt) - - if flash_area_num != 0: - out_comment("Number of flash partitions") - out("FLASH_AREA_NUM", flash_area_num) - - -def write_flash_node(edt): - # Writes output for the top-level flash node pointed at by - # zephyr,flash in /chosen - - node = edt.chosen_node("zephyr,flash") - - out_comment(f"/chosen/zephyr,flash ({node.path if node else 'missing'})") - - if not node: - # No flash node. Write dummy values. - out("FLASH_BASE_ADDRESS", 0) - out("FLASH_SIZE", 0) - return - - if len(node.regs) != 1: - err("expected zephyr,flash to have a single register, has " - f"{len(node.regs)}") - - if node.on_bus == "spi" and len(node.bus_node.regs) == 2: - reg = node.bus_node.regs[1] # QSPI flash - else: - reg = node.regs[0] - - out("FLASH_BASE_ADDRESS", hex(reg.addr)) - if reg.size: - out("FLASH_SIZE", reg.size//1024) - - if "erase-block-size" in node.props: - out("FLASH_ERASE_BLOCK_SIZE", node.props["erase-block-size"].val) - - if "write-block-size" in node.props: - out("FLASH_WRITE_BLOCK_SIZE", node.props["write-block-size"].val) - - -def write_code_partition(edt): - # Writes output for the node pointed at by zephyr,code-partition in /chosen - - node = edt.chosen_node("zephyr,code-partition") - - out_comment("/chosen/zephyr,code-partition " - f"({node.path if node else 'missing'})") - - if not node: - # No code partition. Write dummy values. - out("CODE_PARTITION_OFFSET", 0) - out("CODE_PARTITION_SIZE", 0) - return - - if not node.regs: - err(f"missing 'regs' property on {node!r}") - - out("CODE_PARTITION_OFFSET", node.regs[0].addr) - out("CODE_PARTITION_SIZE", node.regs[0].size) - - -def write_flash_partition(partition_node, index): - if partition_node.label is None: - err(f"missing 'label' property on {partition_node!r}") - - # Generate label-based identifiers - write_flash_partition_prefix( - "FLASH_AREA_" + str2ident(partition_node.label), partition_node, index) - - # Generate index-based identifiers - write_flash_partition_prefix(f"FLASH_AREA_{index}", partition_node, index) - - -def write_flash_partition_prefix(prefix, partition_node, index): - # write_flash_partition() helper. Generates identifiers starting with - # 'prefix'. - - out(f"{prefix}_ID", index) - - out(f"{prefix}_READ_ONLY", 1 if partition_node.read_only else 0) - - for i, reg in enumerate(partition_node.regs): - # Also add aliases that point to the first sector (TODO: get rid of the - # aliases?) - out(f"{prefix}_OFFSET_{i}", reg.addr, - aliases=[f"{prefix}_OFFSET"] if i == 0 else []) - out(f"{prefix}_SIZE_{i}", reg.size, - aliases=[f"{prefix}_SIZE"] if i == 0 else []) - - controller = partition_node.flash_controller - if controller.label is not None: - out_s(f"{prefix}_DEV", controller.label) - - -def write_irqs(node): - # Writes IRQ num and data for the interrupts in the node's 'interrupt' - # property - - def irq_name_alias(irq, cell_name): - if not irq.name: - return None - - alias = f"IRQ_{str2ident(irq.name)}" - if cell_name != "irq": - alias += f"_{str2ident(cell_name)}" - return alias - - def map_arm_gic_irq_type(irq, irq_num): - # Maps ARM GIC IRQ (type)+(index) combo to linear IRQ number - if "type" not in irq.data: - err(f"Expected binding for {irq.controller!r} to have 'type' in " - "interrupt-cells") - irq_type = irq.data["type"] - - if irq_type == 0: # GIC_SPI - return irq_num + 32 - if irq_type == 1: # GIC_PPI - return irq_num + 16 - err(f"Invalid interrupt type specified for {irq!r}") - - def encode_zephyr_multi_level_irq(irq, irq_num): - # See doc/reference/kernel/other/interrupts.rst for details - # on how this encoding works - - irq_ctrl = irq.controller - # Look for interrupt controller parent until we have none - while irq_ctrl.interrupts: - irq_num = (irq_num + 1) << 8 - if "irq" not in irq_ctrl.interrupts[0].data: - err(f"Expected binding for {irq_ctrl!r} to have 'irq' in " - "interrupt-cells") - irq_num |= irq_ctrl.interrupts[0].data["irq"] - irq_ctrl = irq_ctrl.interrupts[0].controller - return irq_num - - for irq_i, irq in enumerate(node.interrupts): - for cell_name, cell_value in irq.data.items(): - ident = f"IRQ_{irq_i}" - if cell_name == "irq": - if "arm,gic" in irq.controller.compats: - cell_value = map_arm_gic_irq_type(irq, cell_value) - cell_value = encode_zephyr_multi_level_irq(irq, cell_value) - else: - ident += f"_{str2ident(cell_name)}" - - out_node(node, ident, cell_value, - name_alias=irq_name_alias(irq, cell_name)) - - -def write_spi_dev(node): - # Writes SPI device GPIO chip select data if there is any - - cs_gpio = node.spi_cs_gpio - if cs_gpio is not None: - write_phandle_val_list_entry(node, cs_gpio, None, "CS_GPIOS") - - -def write_phandle_val_list(prop): - # Writes output for a phandle/value list, e.g. - # - # pwms = <&pwm-ctrl-1 10 20 - # &pwm-ctrl-2 30 40>; - # - # prop: - # phandle/value Property instance. - # - # If only one entry appears in 'prop' (the example above has two), the - # generated identifier won't get a '_0' suffix, and the '_COUNT' and - # group initializer are skipped too. - # - # The base identifier is derived from the property name. For example, 'pwms = ...' - # generates output like this: - # - # #define _PWMS_CONTROLLER_0 "PWM_0" (name taken from 'label = ...') - # #define _PWMS_CHANNEL_0 123 (name taken from *-cells in binding) - # #define _PWMS_0 {"PWM_0", 123} - # #define _PWMS_CONTROLLER_1 "PWM_1" - # #define _PWMS_CHANNEL_1 456 - # #define _PWMS_1 {"PWM_1", 456} - # #define _PWMS_COUNT 2 - # #define _PWMS {_PWMS_0, _PWMS_1} - # ... - - # pwms -> PWMS - # foo-gpios -> FOO_GPIOS - ident = str2ident(prop.name) - - initializer_vals = [] - for i, entry in enumerate(prop.val): - initializer_vals.append(write_phandle_val_list_entry( - prop.node, entry, i if len(prop.val) > 1 else None, ident)) - - if len(prop.val) > 1: - out_node(prop.node, ident + "_COUNT", len(initializer_vals)) - out_node_init(prop.node, ident, initializer_vals) - - -def write_phandle_val_list_entry(node, entry, i, ident): - # write_phandle_val_list() helper. We could get rid of it if it wasn't for - # write_spi_dev(). Adds 'i' as an index to identifiers unless it's None. - # - # 'entry' is an edtlib.ControllerAndData instance. - # - # Returns the identifier for the macro that provides the - # initializer for the entire entry. - - initializer_vals = [] - if entry.controller.label is not None: - ctrl_ident = ident + "_CONTROLLER" # e.g. PWMS_CONTROLLER - if entry.name: - name_alias = f"{str2ident(entry.name)}_{ctrl_ident}" - else: - name_alias = None - # Ugly backwards compatibility hack. Only add the index if there's - # more than one entry. - if i is not None: - ctrl_ident += f"_{i}" - initializer_vals.append(quote_str(entry.controller.label)) - out_node_s(node, ctrl_ident, entry.controller.label, name_alias) - - for cell, val in entry.data.items(): - cell_ident = f"{ident}_{str2ident(cell)}" # e.g. PWMS_CHANNEL - if entry.name: - # From e.g. 'pwm-names = ...' - name_alias = f"{str2ident(entry.name)}_{cell_ident}" - else: - name_alias = None - # Backwards compatibility (see above) - if i is not None: - cell_ident += f"_{i}" - out_node(node, cell_ident, val, name_alias) - - initializer_vals += entry.data.values() - - initializer_ident = ident - if entry.name: - name_alias = f"{initializer_ident}_{str2ident(entry.name)}" - else: - name_alias = None - if i is not None: - initializer_ident += f"_{i}" - return out_node_init(node, initializer_ident, initializer_vals, name_alias) - - -def write_clocks(node): - # Writes clock information. - # - # Most of this ought to be handled in write_props(), but the identifiers - # that get generated for 'clocks' are inconsistent with the with other - # 'phandle-array' properties. - # - # See https://github.com/zephyrproject-rtos/zephyr/pull/19327#issuecomment-534081845. - - if "clocks" not in node.props: - return - - for clock_i, clock in enumerate(node.props["clocks"].val): - controller = clock.controller - - if controller.label is not None: - out_node_s(node, "CLOCK_CONTROLLER", controller.label) - - for name, val in clock.data.items(): - if clock_i == 0: - clk_name_alias = "CLOCK_" + str2ident(name) - else: - clk_name_alias = None - - out_node(node, f"CLOCK_{str2ident(name)}_{clock_i}", val, - name_alias=clk_name_alias) - - if "fixed-clock" not in controller.compats: - continue - - if "clock-frequency" not in controller.props: - err(f"{controller!r} is a 'fixed-clock' but lacks a " - "'clock-frequency' property") - - out_node(node, "CLOCKS_CLOCK_FREQUENCY", - controller.props["clock-frequency"].val) - - -def str2ident(s): - # Converts 's' to a form suitable for (part of) an identifier - - return s.replace("-", "_") \ - .replace(",", "_") \ - .replace("@", "_") \ - .replace("/", "_") \ - .replace(".", "_") \ - .replace("+", "PLUS") \ - .upper() - - -def out_node(node, ident, val, name_alias=None, deprecation_msg=None): - # Writes a - # - # _ = - # - # assignment, along with a set of - # - # _ - # - # aliases, for each path/instance alias for the node. If 'name_alias' (a - # string) is passed, then these additional aliases are generated: - # - # _ - # _ (for each node alias) - # - # 'name_alias' is used for reg-names and the like. - # - # If a 'deprecation_msg' string is passed, the generated identifiers will - # generate a warning if used, via __WARN()). - # - # Returns the identifier used for the macro that provides the value - # for 'ident' within 'node', e.g. DT_MFG_MODEL_CTL_GPIOS_PIN. - - node_prefix = node_ident(node) - - aliases = [f"{alias}_{ident}" for alias in node_aliases(node)] - if name_alias is not None: - aliases.append(f"{node_prefix}_{name_alias}") - aliases += [f"{alias}_{name_alias}" for alias in node_aliases(node)] - - return out(f"{node_prefix}_{ident}", val, aliases, deprecation_msg) - - -def out_node_s(node, ident, s, name_alias=None, deprecation_msg=None): - # Like out_node(), but emits 's' as a string literal - # - # Returns the generated macro name for 'ident'. - - return out_node(node, ident, quote_str(s), name_alias, deprecation_msg) - - -def out_node_init(node, ident, elms, name_alias=None, deprecation_msg=None): - # Like out_node(), but generates an {e1, e2, ...} initializer with the - # elements in the iterable 'elms'. - # - # Returns the generated macro name for 'ident'. - - return out_node(node, ident, "{" + ", ".join(map(str, elms)) + "}", - name_alias, deprecation_msg) - - -def out_s(ident, val): - # Like out(), but puts quotes around 'val' and escapes any double - # quotes and backslashes within it - # - # Returns the generated macro name for 'ident'. - - return out(ident, quote_str(val)) - - -def out(ident, val, aliases=(), deprecation_msg=None): - # Writes '#define ' to the header and '=' to the - # the configuration file. - # - # Also writes any aliases listed in 'aliases' (an iterable). For the - # header, these look like '#define '. For the configuration - # file, the value is just repeated as '=' for each alias. - # - # See out_node() for the meaning of 'deprecation_msg'. - # - # Returns the generated macro name for 'ident'. - - out_define(ident, val, deprecation_msg, header_file) - primary_ident = f"DT_{ident}" - - d_msg = deprecation_msg - - for alias in aliases: - if alias != ident: - if alias.startswith("INST_"): - deprecation_msg = "Macro is deprecated" - - out_define(alias, "DT_" + ident, deprecation_msg, header_file) - - deprecation_msg = d_msg - - return primary_ident - - -def out_define(ident, val, deprecation_msg, out_file): - # out() helper for writing a #define. See out_node() for the meaning of - # 'deprecation_msg'. - - s = f"#define DT_{ident:40}" - - if DEPRECATION_MESSAGES and deprecation_msg: - s += fr' __WARN("{deprecation_msg}")' - s += f" {val}" - print(s, file=out_file) - - -def out_comment(s, blank_before=True): - # Writes 's' as a comment to the header and configuration file. 's' is - # allowed to have multiple lines. blank_before=True adds a blank line - # before the comment. - - if blank_before: - print(file=header_file) - - if "\n" in s: - # Format multi-line comments like - # - # /* - # * first line - # * second line - # * - # * empty line before this line - # */ - res = ["/*"] - for line in s.splitlines(): - # Avoid an extra space after '*' for empty lines. They turn red in - # Vim if space error checking is on, which is annoying. - res.append(" *" if not line.strip() else " * " + line) - res.append(" */") - print("\n".join(res), file=header_file) - else: - # Format single-line comments like - # - # /* foo bar */ - print("/* " + s + " */", file=header_file) - - -def escape(s): - # Backslash-escapes any double quotes and backslashes in 's' - - # \ must be escaped before " to avoid double escaping - return s.replace("\\", "\\\\").replace('"', '\\"') - - -def quote_str(s): - # Puts quotes around 's' and escapes any double quotes and - # backslashes within it - - return f'"{escape(s)}"' - - -def err(s): - raise Exception(s) - - -if __name__ == "__main__": - main() diff --git a/scripts/dts/test.dts b/scripts/dts/test.dts index 8bc4d43d708..e1d2865d9c2 100644 --- a/scripts/dts/test.dts +++ b/scripts/dts/test.dts @@ -311,31 +311,6 @@ default-not-used = <234>; }; - // - // For testing EDT.compat2enabled - // - - compat2enabled { - foo-1 { - status = "okay"; - compatible = "compat2enabled"; - }; - foo-disabled { - status = "disabled"; - compatible = "compat2enabled"; - }; - foo-2 { - // No 'status', which is also treated as enabled - compatible = "compat2enabled"; - }; - // Should not create an entry in compat2enabled, since all nodes - // with the compatible are disabled - bar { - status = "disabled"; - compatible = "compat2enabled-disabled"; - }; - }; - // // For testing 'bus:' and 'on-bus:' // diff --git a/scripts/dts/testedtlib.py b/scripts/dts/testedtlib.py index a2b02475be3..48ec03a8590 100644 --- a/scripts/dts/testedtlib.py +++ b/scripts/dts/testedtlib.py @@ -155,15 +155,6 @@ def test_child_binding(): assert str(grandchild.description) == "grandchild node" assert str(grandchild.props) == "OrderedDict([('grandchild-prop', )])" -def test_compat2enabled(): - '''Test EDT.compat2enabled''' - edt = edtlib.EDT("test.dts", ["test-bindings"]) - - assert str(edt.compat2enabled["compat2enabled"]) == \ - "[, ]" - - assert "compat2enabled-disabled" not in edt.compat2enabled - def test_props(): '''Test Node.props (derived from DT and 'properties:' in the binding)''' edt = edtlib.EDT("test.dts", ["test-bindings"]) diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py index 957676ae9d7..17ba32dc5e7 100644 --- a/scripts/kconfig/kconfigfunctions.py +++ b/scripts/kconfig/kconfigfunctions.py @@ -72,7 +72,7 @@ def dt_chosen_enabled(kconf, _, chosen): return "n" node = edt.chosen_node(chosen) - return "y" if node and node.enabled else "n" + return "y" if node and node.status == "okay" else "n" def dt_chosen_path(kconf, _, chosen): @@ -117,7 +117,7 @@ def dt_node_enabled(kconf, name, node): except edtlib.EDTError: return "n" - return "y" if node and node.enabled else "n" + return "y" if node and node.status == "okay" else "n" def dt_nodelabel_enabled(kconf, _, label): @@ -132,7 +132,7 @@ def dt_nodelabel_enabled(kconf, _, label): node = edt.label2node.get(label) - return "y" if node and node.enabled else "n" + return "y" if node and node.status == "okay" else "n" def _node_reg_addr(node, index, unit): @@ -350,13 +350,13 @@ def dt_node_int_prop(kconf, name, path, prop): def dt_compat_enabled(kconf, _, compat): """ - This function takes a 'compat' and returns "y" if we find an "enabled" + This function takes a 'compat' and returns "y" if we find a status "okay" compatible node in the EDT otherwise we return "n" """ if doc_mode or edt is None: return "n" - return "y" if compat in edt.compat2enabled else "n" + return "y" if compat in edt.compat2okay else "n" def dt_compat_on_bus(kconf, _, compat, bus): @@ -367,7 +367,7 @@ def dt_compat_on_bus(kconf, _, compat, bus): if doc_mode or edt is None: return "n" - for node in edt.compat2enabled[compat]: + for node in edt.compat2okay[compat]: if node.on_bus is not None and node.on_bus == bus: return "y" @@ -383,7 +383,7 @@ def dt_nodelabel_has_compat(kconf, _, label, compat): if doc_mode or edt is None: return "n" - for node in edt.compat2enabled[compat]: + for node in edt.compat2okay[compat]: if label in node.labels: return "y" diff --git a/scripts/sanity_chk/expr_parser.py b/scripts/sanity_chk/expr_parser.py index b0c87208fdd..4fc324adeb6 100644 --- a/scripts/sanity_chk/expr_parser.py +++ b/scripts/sanity_chk/expr_parser.py @@ -224,20 +224,20 @@ def ast_expr(ast, env, edt): elif ast[0] == "dt_compat_enabled": compat = ast[1][0] for node in edt.nodes: - if compat in node.compats and node.enabled: + if compat in node.compats and node.status == "okay": return True return False elif ast[0] == "dt_alias_exists": alias = ast[1][0] for node in edt.nodes: - if alias in node.aliases and node.enabled: + if alias in node.aliases and node.status == "okay": return True return False elif ast[0] == "dt_compat_enabled_with_alias": compat = ast[1][0] alias = ast[1][1] for node in edt.nodes: - if node.enabled and alias in node.aliases and node.matching_compat == compat: + if node.status == "okay" and alias in node.aliases and node.matching_compat == compat: return True return False diff --git a/tests/deprecated/dts/CMakeLists.txt b/tests/deprecated/dts/CMakeLists.txt deleted file mode 100644 index 5333a6ad575..00000000000 --- a/tests/deprecated/dts/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.13.1) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(test_dts) - -target_sources(app PRIVATE src/main.c) diff --git a/tests/deprecated/dts/boards/frdm_k64f.overlay b/tests/deprecated/dts/boards/frdm_k64f.overlay deleted file mode 100644 index f036a555b48..00000000000 --- a/tests/deprecated/dts/boards/frdm_k64f.overlay +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2020, Linaro Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -&storage_partition { - status = "disabled"; -}; diff --git a/tests/deprecated/dts/prj.conf b/tests/deprecated/dts/prj.conf deleted file mode 100644 index 10e909f1dde..00000000000 --- a/tests/deprecated/dts/prj.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_LEGACY_DEVICETREE_MACROS=y diff --git a/tests/deprecated/dts/src/main.c b/tests/deprecated/dts/src/main.c deleted file mode 100644 index d4b647e118e..00000000000 --- a/tests/deprecated/dts/src/main.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2020 Linaro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -void main(void) -{ - BUILD_ASSERT(DT_FLASH_AREA_MCUBOOT_ID == FLASH_AREA_ID(mcuboot), - "FLASH AREA ID mismatch for MCUBOOT partition"); - /* disabled status is ignored for partitions */ - BUILD_ASSERT(DT_FLASH_AREA_STORAGE_ID == FLASH_AREA_ID(storage), - "FLASH AREA ID mismatch for STORAGE partition"); - BUILD_ASSERT(DT_FLASH_AREA_IMAGE_0_ID == FLASH_AREA_ID(image_0), - "FLASH AREA ID mismatch for IMAGE_0 partition"); - BUILD_ASSERT(DT_FLASH_AREA_IMAGE_1_ID == FLASH_AREA_ID(image_1), - "FLASH AREA ID mismatch for IMAGE_1 partition"); - BUILD_ASSERT(DT_FLASH_AREA_IMAGE_SCRATCH_ID == - FLASH_AREA_ID(image_scratch), - "FLASH AREA ID mismatch for IMAGE_SCRATCH partition"); -} diff --git a/tests/deprecated/dts/testcase.yaml b/tests/deprecated/dts/testcase.yaml deleted file mode 100644 index cae0776426e..00000000000 --- a/tests/deprecated/dts/testcase.yaml +++ /dev/null @@ -1,4 +0,0 @@ -tests: - dts.build.build: - build_only: true - platform_allow: frdm_k64f diff --git a/tests/lib/devicetree/legacy_api/CMakeLists.txt b/tests/lib/devicetree/legacy_api/CMakeLists.txt deleted file mode 100644 index 60a04403df7..00000000000 --- a/tests/lib/devicetree/legacy_api/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.13.1) - -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(devicetree) - -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) diff --git a/tests/lib/devicetree/legacy_api/README b/tests/lib/devicetree/legacy_api/README deleted file mode 100644 index 5ecfd2cc5b4..00000000000 --- a/tests/lib/devicetree/legacy_api/README +++ /dev/null @@ -1,5 +0,0 @@ -Test cases that ensure the legacy macros match the results for the -devicetree.h API. This directory is safe to remove once the legacy -devicetree macros documented here are no longer supported: - -https://docs.zephyrproject.org/latest/guides/dts/legacy-macros.html diff --git a/tests/lib/devicetree/legacy_api/app.overlay b/tests/lib/devicetree/legacy_api/app.overlay deleted file mode 100644 index 3ff374d5eeb..00000000000 --- a/tests/lib/devicetree/legacy_api/app.overlay +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - * - * Application overlay for testing the legacy devicetree macros can - * be migrated to the devicetree.h API. - * - * Names in this file should be chosen in a way that won't conflict - * with real-world devicetree nodes, to allow these tests to run on - * (and be extended to test) real hardware. - */ -#include - -/* - * The "start-after..." and "end-before..." comments are because - * this file is included in the migration HOWTO. - */ - -/* start-after-here */ -/ { - aliases { - mgr-gpio = &migration_gpio; - mgr-serial = &migration_serial; - mgr-i2c-dev = &mgr_i2c_device; - mgr-spi-dev = &mgr_spi_device; - }; - - migration { - #address-cells = <0x1>; - #size-cells = <0x1>; - interrupt-parent = <&migration_intc>; - - migration_gpio: gpio@1000 { - compatible = "vnd,gpio"; - gpio-controller; - reg = <0x1000 0x2000>; - interrupts = <0 1>; - #gpio-cells = <0x2>; - label = "MGR_GPIO"; - }; - - migration_serial: serial@3000 { - compatible = "vnd,serial"; - reg = <0x3000 0x1000>; - interrupts = <2 1>; - label = "MGR_SERIAL"; - baud-rate = <115200>; - }; - - i2c@10000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "vnd,i2c"; - reg = < 0x10000 0x1000 >; - label = "MGR_I2C"; - clock-frequency = <100000>; - interrupts = <10 1>; - - mgr_i2c_device: i2c-dev@10 { - compatible = "vnd,i2c-device"; - label = "MGR_I2C_DEV"; - reg = <0x10>; - }; - }; - - spi@20000 { - #address-cells = < 1 >; - #size-cells = < 0 >; - compatible = "vnd,spi"; - reg = <0x20000 0x1000>; - interrupts = <20 1>; - label = "MGR_SPI"; - clock-frequency = <2000000>; - - cs-gpios = <&migration_gpio 17 GPIO_ACTIVE_LOW>; - - mgr_spi_device: spi-dev@0 { - compatible = "vnd,spi-device"; - label = "MGR_SPI_DEV"; - reg = <0>; - spi-max-frequency = <2000000>; - }; - }; - - migration_intc: interrupt-controller@30000 { - compatible = "vnd,intc"; - reg = <0x30000 0x1000>; - label = "MGR_INTC"; - interrupt-controller; - #interrupt-cells = <2>; - }; - }; -}; -/* end-before-here */ diff --git a/tests/lib/devicetree/legacy_api/prj.conf b/tests/lib/devicetree/legacy_api/prj.conf deleted file mode 100644 index a4cb36f7751..00000000000 --- a/tests/lib/devicetree/legacy_api/prj.conf +++ /dev/null @@ -1,2 +0,0 @@ -CONFIG_ZTEST=y -CONFIG_LEGACY_DEVICETREE_MACROS=y diff --git a/tests/lib/devicetree/legacy_api/src/main.c b/tests/lib/devicetree/legacy_api/src/main.c deleted file mode 100644 index 6c012539e24..00000000000 --- a/tests/lib/devicetree/legacy_api/src/main.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -/* - * We test most common properties (label, reg, interrupts) on just the - * GPIO node, since they work the same way on all nodes. - */ - -static void test_gpio(void) -{ - /* label */ - zassert_equal(DT_VND_GPIO_1000_LABEL, - DT_LABEL(DT_PATH(migration, gpio_1000)), - ""); - - zassert_equal(DT_INST_0_VND_GPIO_LABEL, - DT_LABEL(DT_INST(0, vnd_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_LABEL, - DT_LABEL(DT_ALIAS(mgr_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_LABEL, - DT_LABEL(DT_NODELABEL(migration_gpio)), - ""); - - /* reg base address */ - zassert_equal(DT_VND_GPIO_1000_BASE_ADDRESS, - DT_REG_ADDR(DT_PATH(migration, gpio_1000)), - ""); - - zassert_equal(DT_INST_0_VND_GPIO_BASE_ADDRESS, - DT_REG_ADDR(DT_INST(0, vnd_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_BASE_ADDRESS, - DT_REG_ADDR(DT_ALIAS(mgr_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_BASE_ADDRESS, - DT_REG_ADDR(DT_NODELABEL(migration_gpio)), - ""); - - /* reg size */ - zassert_equal(DT_VND_GPIO_1000_SIZE, - DT_REG_SIZE(DT_PATH(migration, gpio_1000)), - ""); - - zassert_equal(DT_INST_0_VND_GPIO_SIZE, - DT_REG_SIZE(DT_INST(0, vnd_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_SIZE, - DT_REG_SIZE(DT_ALIAS(mgr_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_SIZE, - DT_REG_SIZE(DT_NODELABEL(migration_gpio)), - ""); - - /* irq number */ - zassert_equal(DT_VND_GPIO_1000_IRQ_0, - DT_IRQN(DT_PATH(migration, gpio_1000)), - ""); - - zassert_equal(DT_INST_0_VND_GPIO_IRQ_0, - DT_IRQN(DT_INST(0, vnd_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_IRQ_0, - DT_IRQN(DT_ALIAS(mgr_gpio)), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_IRQ_0, - DT_IRQN(DT_NODELABEL(migration_gpio)), - ""); - - /* irq priority */ - zassert_equal(DT_VND_GPIO_1000_IRQ_0_PRIORITY, - DT_IRQ(DT_PATH(migration, gpio_1000), priority), - ""); - - zassert_equal(DT_INST_0_VND_GPIO_IRQ_0_PRIORITY, - DT_IRQ(DT_INST(0, vnd_gpio), priority), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_IRQ_0_PRIORITY, - DT_IRQ(DT_ALIAS(mgr_gpio), priority), - ""); - - zassert_equal(DT_ALIAS_MGR_GPIO_IRQ_0_PRIORITY, - DT_IRQ(DT_NODELABEL(migration_gpio), priority), - ""); -} - -/* - * The serial device is how we test specific properties. - */ - -static void test_serial(void) -{ - zassert_equal(DT_VND_SERIAL_3000_BAUD_RATE, - DT_PROP(DT_PATH(migration, serial_3000), baud_rate), - ""); - zassert_equal(DT_ALIAS_MGR_SERIAL_BAUD_RATE, - DT_PROP(DT_ALIAS(mgr_serial), baud_rate), - ""); - zassert_equal(DT_ALIAS_MGR_SERIAL_BAUD_RATE, - DT_PROP(DT_NODELABEL(migration_serial), baud_rate), - ""); - zassert_equal(DT_INST_0_VND_SERIAL_BAUD_RATE, - DT_PROP(DT_INST(0, vnd_serial), baud_rate), - ""); -} - -/* - * The I2C and SPI devices are used to test inter-device relationships. - */ - -#define I2C_DEV_PATH DT_PATH(migration, i2c_10000, i2c_dev_10) -#define I2C_DEV_ALIAS DT_ALIAS(mgr_i2c_dev) -#define I2C_DEV_NODELABEL DT_NODELABEL(mgr_i2c_device) -#define I2C_DEV_INST DT_INST(0, vnd_i2c_device) -static void test_i2c_device(void) -{ - /* Bus controller name */ - zassert_true(!strcmp(DT_VND_I2C_10000_VND_I2C_DEVICE_10_BUS_NAME, - DT_LABEL(DT_BUS(I2C_DEV_PATH))), - ""); - zassert_true(!strcmp(DT_ALIAS_MGR_I2C_DEV_BUS_NAME, - DT_LABEL(DT_BUS(I2C_DEV_ALIAS))), - ""); - zassert_true(!strcmp(DT_ALIAS_MGR_I2C_DEV_BUS_NAME, - DT_LABEL(DT_BUS(I2C_DEV_NODELABEL))), - ""); - zassert_true(!strcmp(DT_INST_0_VND_I2C_DEVICE_BUS_NAME, - DT_LABEL(DT_BUS(I2C_DEV_INST))), - ""); -} - -#define SPI_DEV_PATH DT_PATH(migration, spi_20000, spi_dev_0) -#define SPI_DEV_ALIAS DT_ALIAS(mgr_spi_dev) -#define SPI_DEV_NODELABEL DT_NODELABEL(mgr_spi_device) -#define SPI_DEV_INST DT_INST(0, vnd_spi_device) -static void test_spi_device(void) -{ - /* cs-gpios controller label */ - zassert_true( - !strcmp(DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_CONTROLLER, - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_PATH)), - ""); - zassert_true(!strcmp(DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_CONTROLLER, - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_ALIAS)), - ""); - zassert_true(!strcmp(DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_CONTROLLER, - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_NODELABEL)), - ""); - zassert_true(!strcmp(DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_CONTROLLER, - DT_SPI_DEV_CS_GPIOS_LABEL(SPI_DEV_INST)), - ""); - - /* cs-gpios pin number */ - zassert_equal(DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_PIN, - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_PATH), - ""); - zassert_equal(DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_PIN, - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_ALIAS), - ""); - zassert_equal(DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_PIN, - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_NODELABEL), - ""); - zassert_equal(DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_PIN, - DT_SPI_DEV_CS_GPIOS_PIN(SPI_DEV_INST), - ""); - - /* cs-gpios GPIO flags */ - zassert_equal(DT_VND_SPI_20000_VND_SPI_DEVICE_0_CS_GPIOS_FLAGS, - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_PATH), - ""); - zassert_equal(DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_FLAGS, - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_ALIAS), - ""); - zassert_equal(DT_ALIAS_MGR_SPI_DEV_CS_GPIOS_FLAGS, - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_NODELABEL), - ""); - zassert_equal(DT_INST_0_VND_SPI_DEVICE_CS_GPIOS_FLAGS, - DT_SPI_DEV_CS_GPIOS_FLAGS(SPI_DEV_INST), - ""); -} - -void test_main(void) -{ - ztest_test_suite(devicetree_legacy_api, - ztest_unit_test(test_gpio), - ztest_unit_test(test_serial), - ztest_unit_test(test_i2c_device), - ztest_unit_test(test_spi_device) - ); - ztest_run_test_suite(devicetree_legacy_api); -} diff --git a/tests/lib/devicetree/legacy_api/testcase.yaml b/tests/lib/devicetree/legacy_api/testcase.yaml deleted file mode 100644 index 628acd56b6c..00000000000 --- a/tests/lib/devicetree/legacy_api/testcase.yaml +++ /dev/null @@ -1,8 +0,0 @@ -tests: - libraries.devicetree.legacy: - tags: devicetree - # We only need this to run on one platform so use native_posix as it - # will mostly likely be the fastest. - integration_platforms: - - native_posix - platform_exclude: pinnacle_100_dvk