1.. _board_porting_guide: 2 3Board Porting Guide 4################### 5 6To add Zephyr support for a new :term:`board`, you at least need a *board 7directory* with various files in it. Files in the board directory inherit 8support for at least one SoC and all of its features. Therefore, Zephyr must 9support your :term:`SoC` as well. 10 11.. _hw_model_v2: 12 13Transition to the current hardware model 14**************************************** 15 16Shortly after Zephyr 3.6.0 was released, a new hardware model was introduced to 17Zephyr. This new model overhauls the way both SoCs and boards are named and 18defined, and adds support for features that had been identified as important 19over the years. Among them: 20 21- Support for multi-core, multi-arch AMP (Asymmetrical Multi Processing) SoCs 22- Support for multi-SoC boards 23- Support for reusing the SoC and board Kconfig trees outside of the Zephyr 24 build system 25- Support for advanced use cases with :ref:`sysbuild` 26- Removal of all existing arbitrary and inconsistent uses of Kconfig and folder 27 names 28 29All the documentation in this page refers to the current hardware model. Please 30refer to the documentation in Zephyr v3.6.0 (or earlier) for information on the 31previous, now obsolete, hardware model. 32 33More information about the rationale, development and concepts behind the new 34model can be found in the :github:`original issue <51831>`, the 35:github:`original Pull Request <50305>` and, for a complete set of changes 36introduced, the `hardware model v2 commit`_. 37 38Some non-critical features, enhancements and improvements of the new hardware 39model are still in development. Check the 40:github:`hardware model v2 enhancements issue <69546>` for a complete list. 41 42The transition from the previous hardware model to the current one (commonly 43referred to as "hardware model v2") requires modifications to all existing board 44and SoC definitions. A decision was made not to provide direct backwards 45compatibility for the previous model, which leaves users transitioning from a 46previous version of Zephyr to one including the new model (v3.7.0 and onwards) 47with two options if they have an out-of-tree board (or SoC): 48 49#. Convert the out-of-tree board to the current hardware model (recommended) 50#. Take the SoC definition from Zephyr v3.6.0 and copy it to your downstream 51 repository (ensuring that the build system can find it via a 52 :ref:`zephyr module <modules>` or ``SOC_ROOT``). This will allow your board, 53 defined in the previous hardware model, to continue to work 54 55When converting your board from the previous to the current hardware model, we 56recommend first reading through this page to understand the model in detail. You 57can then use the `example-application conversion Pull Request`_ as an example on 58how to port a simple board. Additionally, a `conversion script`_ is available 59and works reliably in many cases (though multi-core SoCs may not be handled 60entirely). Finally, the `hardware model v2 commit`_ contains the full conversion 61of all existing boards from the old to the current model, so you can use it as a 62complete conversion reference. 63 64.. _hardware model v2 commit: https://github.com/zephyrproject-rtos/zephyr/commit/8dc3f856229ce083c956aa301c31a23e65bd8cd8 65.. _example-application conversion Pull Request: https://github.com/zephyrproject-rtos/example-application/pull/58 66.. _conversion script: https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/utils/board_v1_to_v2.py 67 68.. _hw_support_hierarchy: 69 70Hardware support hierarchy 71************************** 72 73Zephyr's hardware support is based on a series of hierarchical abstractions. 74Primarily, each :term:`board` has one or more :term:`SoC`. 75Each SoC can be optionally classed into an :term:`SoC series`, which in turn may optionally belong to an :term:`SoC family`. 76Each SoC has one or more :term:`CPU cluster`, each containing one or more :term:`CPU core` of a particular :term:`architecture`. 77 78You can visualize the hierarchy in the diagram below: 79 80.. figure:: board/hierarchy.png 81 :width: 500px 82 :align: center 83 :alt: Hardware support Hierarchy 84 85 Hardware support Hierarchy 86 87Below are some examples of the hierarchy described in this section, in the form 88of a :term:`board` per row with its corresponding hierarchy entries. Notice how 89the :term:`SoC series` and :term:`SoC family` levels are not always used. 90 91.. table:: 92 93 +--------------------------------------------+--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 94 | :term:`board name` | :term:`board qualifiers` | :term:`SoC` | :term:`SoC Series` | :term:`SoC family` | CPU core | :term:`architecture` | 95 +============================================+==========================+=============+====================+====================+================+======================+ 96 | :ref:`nrf52dk <nrf52dk_nrf52832>` | nrf52832 | nRF52832 | nRF52 | Nordic nRF | Arm Cortex-M4 | ARMv7-M | 97 +--------------------------------------------+--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 98 | :zephyr:board:`frdm_k64f <frdm_k64f>` | mk64f12 | MK64F12 | Kinetis K6x | NXP Kinetis | Arm Cortex-M4 | ARMv7-M | 99 +--------------------------------------------+--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 100 | :zephyr:board:`rv32m1_vega <rv32m1_vega>` | openisa_rv32m1/ri5cy | RV32M1 | (Not used) | (Not used) | RI5CY | RISC-V RV32 | 101 +--------------------------------------------+--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 102 | :ref:`nrf5340dk <nrf5340dk_nrf5340>` | nrf5340/cpuapp | nRF5340 | nRF53 | Nordic nRF | Arm Cortex-M33 | ARMv8-M | 103 | +--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 104 | | nrf5340/cpunet | nRF5340 | nRF53 | Nordic nRF | Arm Cortex-M33 | ARMv8-M | 105 +--------------------------------------------+--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 106 | :zephyr:board:`mimx8mp_evk <imx8mp_evk>` | mimx8ml8/a53 | i.MX8M Plus | i.MX8M | NXP i.MX | Arm Cortex-A53 | ARMv8-A | 107 | +--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 108 | | mimx8ml8/m7 | i.MX8M Plus | i.MX8M | NXP i.MX | Arm Cortex-M7 | ARMv7-M | 109 | +--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 110 | | mimx8ml8/adsp | i.MX8M Plus | i.MX8M | NXP i.MX | Cadence HIFI4 | Xtensa LX6 | 111 +--------------------------------------------+--------------------------+-------------+--------------------+--------------------+----------------+----------------------+ 112 113Additional details about terminology can be found in the next section. 114 115.. _board_terminology: 116 117Board terminology 118***************** 119 120The previous section introduced the hierarchical manner in which Zephyr 121classifies and implements hardware support. 122This section focuses on the terminology used around hardware support, and in 123particular when defining and working with boards and SoCs. 124 125The overall set of terms used around the concept of board in Zephyr is depicted 126in the image below, which uses the :zephyr:board:`bl5340_dvk` board as reference. 127 128.. figure:: board/board-terminology.svg 129 :width: 500px 130 :align: center 131 :alt: Board terminology diagram 132 133 Board terminology diagram 134 135The diagram shows the different terms that are used to describe boards: 136 137- The :term:`board name`: ``bl5340_dvk`` 138- The optional :term:`board revision`: ``1.2.0`` 139- The :term:`board qualifiers`, that optionally describe the :term:`SoC`, 140 :term:`CPU cluster` and :term:`variant`: ``nrf5340/cpuapp/ns`` 141- The :term:`board target`, which uniquely identifies a combination of the above 142 and can be used to specify the hardware to build for when using the tooling 143 provided by Zephyr: ``bl5340_dvk@1.2.0/nrf5340/cpuapp/ns`` 144 145Formally this can also be seen as 146:samp:`{board name}[@{revision}][/{board qualifiers}]`, which can be extended to 147:samp:`{board name}[@{revision}][/{SoC}[/{CPU cluster}][/{variant}]]`. 148 149If a board contains only one single-core SoC, then the SoC can be omitted from 150the board target. This implies that if the board does not define any board 151qualifiers, the board name can be used as a board target. Conversely, if 152board qualifiers are part of the board definition, then the SoC can be omitted 153by leaving it out but including the corresponding forward-slashes: ``//``. 154 155Continuing with the example above, The board :zephyr:board:`bl5340_dvk` is a single SoC 156board where the SoC defines two CPU clusters: ``cpuapp`` and ``cpunet``. One of 157the CPU clusters, ``cpuapp``, additionally defines a non-secure board variant, 158``ns``. 159 160The board qualifiers ``nrf5340/cpuapp/ns`` can be read as: 161 162 163- ``nrf5340``: The SoC, which is a Nordic nRF5340 dual-core SoC 164- ``cpuapp``: The CPU cluster ``cpuapp``, which consists of a single Cortex-M33 165 CPU core. The number of cores in a CPU cluster cannot be determined from the 166 board qualifiers. 167- ``ns``: a variant, in this case ``ns`` is a common variant name is 168 Zephyr denoting a non-secure build for boards supporting :ref:`tfm`. 169 170Not all SoCs define CPU clusters or variants. For example a simple board 171like the :ref:`thingy52_nrf52832` contains a single SoC with no CPU clusters and 172no variants. 173For ``thingy52`` the board target ``thingy52/nrf52832`` can be read as: 174 175- ``thingy52``: board name. 176- ``nrf52832``: The board qualifiers, in this case identical to the SoC, which 177 is a Nordic nRF52832. 178 179 180Make sure your SoC is supported 181******************************* 182 183Start by making sure your SoC is supported by Zephyr. If it is, it's time to 184:ref:`create-your-board-directory`. If you don't know, try: 185 186- checking :ref:`boards` for names that look relevant, and reading individual 187 board documentation to find out for sure. 188- asking your SoC vendor 189 190If you need to add a SoC, CPU cluster, or even architecture support, this is the 191wrong page, but here is some general advice. 192 193Architecture 194============ 195 196See :ref:`architecture_porting_guide`. 197 198CPU Core 199======== 200 201CPU core support files go in ``core`` subdirectories under :zephyr_file:`arch`, 202e.g. :zephyr_file:`arch/x86/core`. 203 204See :ref:`gs_toolchain` for information about toolchains (compiler, linker, 205etc.) supported by Zephyr. If you need to support a new toolchain, 206:ref:`build_overview` is a good place to start learning about the build system. 207Please reach out to the community if you are looking for advice or want to 208collaborate on toolchain support. 209 210SoC 211=== 212 213Zephyr SoC support files are in architecture-specific subdirectories of 214:zephyr_file:`soc`. They are generally grouped by SoC family. 215 216When adding a new SoC family or series for a vendor that already has SoC 217support within Zephyr, please try to extract common functionality into shared 218files to avoid duplication. If there is no support for your vendor yet, you can 219add it in a new directory ``zephyr/soc/<VENDOR>/<YOUR-SOC>``; please use 220self-explanatory directory names. 221 222.. _create-your-board-directory: 223 224Create your board directory 225*************************** 226 227Once you've found an existing board that uses your SoC, you can usually start 228by copy/pasting its board directory and changing its contents for your 229hardware. 230 231You need to give your board a unique name. Run ``west boards`` for a list of 232names that are already taken, and pick something new. Let's say your board is 233called ``plank`` (please don't actually use that name). 234 235Start by creating the board directory ``zephyr/boards/<VENDOR>/plank``, where 236``<VENDOR>`` is your vendor subdirectory. (You don't have to put your 237board directory in the zephyr repository, but it's the easiest way to get 238started. See :ref:`custom_board_definition` for documentation on moving your 239board directory to a separate repository once it's working.) 240 241.. note:: 242 A ``<VENDOR>`` subdirectory is mandatory if contributing your board 243 to Zephyr, but if your board is placed in a local repo, then any folder 244 structure under ``<your-repo>/boards`` is permitted. 245 If the vendor is defined in the list in 246 :zephyr_file:`dts/bindings/vendor-prefixes.txt` then you must use 247 that vendor prefix as ``<VENDOR>``. ``others`` may be used as vendor prefix if 248 the vendor is not defined. 249 250.. note:: 251 252 The board directory name does not need to match the name of the board. 253 Multiple boards can even defined be in one directory. 254 255Your board directory should look like this: 256 257.. code-block:: none 258 259 boards/<VENDOR>/plank 260 ├── board.yml 261 ├── board.cmake 262 ├── CMakeLists.txt 263 ├── doc 264 │ ├── plank.webp 265 │ └── index.rst 266 ├── Kconfig.plank 267 ├── Kconfig.defconfig 268 ├── plank_<qualifiers>_defconfig 269 ├── plank_<qualifiers>.dts 270 └── plank_<qualifiers>.yaml 271 272Replace ``plank`` with your board's name, of course. 273 274The mandatory files are: 275 276#. :file:`board.yml`: a YAML file describing the high-level meta data of the 277 boards such as the boards names, their SoCs, and variants. 278 CPU clusters for multi-core SoCs are not described in this file as they are 279 inherited from the SoC's YAML description. 280 281#. :file:`plank_<qualifiers>.dts`: a hardware description 282 in :ref:`devicetree <dt-guide>` format. This declares your SoC, connectors, 283 and any other hardware components such as LEDs, buttons, sensors, or 284 communication peripherals (USB, BLE controller, etc). 285 286#. :file:`Kconfig.plank`: the base software configuration for selecting SoC and 287 other board and SoC related settings. Kconfig settings outside of the board 288 and SoC tree must not be selected. To select general Zephyr Kconfig settings 289 the :file:`Kconfig` file must be used. 290 291 292The optional files are: 293 294- :file:`Kconfig`, :file:`Kconfig.defconfig` software configuration in 295 :ref:`kconfig` formats. This provides default settings for software features 296 and peripheral drivers. 297- :file:`plank_defconfig` and :file:`plank_<qualifiers>_defconfig`: software 298 configuration in Kconfig ``.conf`` format. 299- :file:`board.cmake`: used for :ref:`flash-and-debug-support` 300- :file:`CMakeLists.txt`: if you need to add additional source files to 301 your build. 302- :file:`doc/index.rst`, :file:`doc/plank.webp`: documentation for and a picture 303 of your board. You only need this if you're :ref:`contributing-your-board` to 304 Zephyr. 305- :file:`plank_<qualifiers>.yaml`: a YAML file with miscellaneous metadata used 306 by the :ref:`twister_script`. 307 308Board qualifiers of the form ``<soc>/<cpucluster>/<variant>`` are normalized so 309that ``/`` is replaced with ``_`` when used for filenames, for example: 310``soc1/foo`` becomes ``soc1_foo`` when used in filenames. 311 312.. _board_description: 313 314Write your board YAML 315********************* 316 317The board YAML file describes the board at a high level. 318This includes the SoC, board variants, and board revisions. 319 320Detailed configurations, such as hardware description and configuration are done 321in devicetree and Kconfig. 322 323The skeleton of the board YAML file is: 324 325.. code-block:: yaml 326 327 board: 328 name: <board-name> 329 vendor: <board-vendor> 330 revision: 331 format: <major.minor.patch|letter|number|custom> 332 default: <default-revision-value> 333 exact: <true|false> 334 revisions: 335 - name: <revA> 336 - name: <revB> 337 ... 338 socs: 339 - name: <soc-1> 340 variants: 341 - name: <variant-1> 342 - name: <variant-2> 343 variants: 344 - name: <sub-variant-2-1> 345 ... 346 - name: <soc-2> 347 ... 348 349It is possible to have multiple boards located in the board folder. 350If multiple boards are placed in the same board folder, then the file 351:file:`board.yml` must describe those in a list as: 352 353.. code-block:: yaml 354 355 boards: 356 - name: <board-name-1> 357 vendor: <board-vendor> 358 ... 359 - name: <board-name-2> 360 vendor: <board-vendor> 361 ... 362 ... 363 364 365.. _default_board_configuration: 366 367Write your devicetree 368********************* 369 370The devicetree file :file:`boards/<vendor>/plank/plank.dts` or 371:file:`boards/<vendor>/plank/plank_<qualifiers>.dts` describes your board 372hardware in the Devicetree Source (DTS) format (as usual, change ``plank`` to 373your board's name). If you're new to devicetree, see :ref:`devicetree-intro`. 374 375In general, :file:`plank.dts` should look like this: 376 377.. code-block:: devicetree 378 379 /dts-v1/; 380 #include <your_soc_vendor/your_soc.dtsi> 381 382 / { 383 model = "A human readable name"; 384 compatible = "yourcompany,plank"; 385 386 chosen { 387 zephyr,console = &your_uart_console; 388 zephyr,sram = &your_memory_node; 389 /* other chosen settings for your hardware */ 390 }; 391 392 /* 393 * Your board-specific hardware: buttons, LEDs, sensors, etc. 394 */ 395 396 leds { 397 compatible = "gpio-leds"; 398 led0: led_0 { 399 gpios = < /* GPIO your LED is hooked up to */ >; 400 label = "LED 0"; 401 }; 402 /* ... other LEDs ... */ 403 }; 404 405 buttons { 406 compatible = "gpio-keys"; 407 /* ... your button definitions ... */ 408 }; 409 410 /* These aliases are provided for compatibility with samples */ 411 aliases { 412 led0 = &led0; /* now you support the blinky sample! */ 413 /* other aliases go here */ 414 }; 415 }; 416 417 &some_peripheral_you_want_to_enable { /* like a GPIO or SPI controller */ 418 status = "okay"; 419 }; 420 421 &another_peripheral_you_want { 422 status = "okay"; 423 }; 424 425Only one ``.dts`` file will be used, and the most specific file which exists 426will be used. 427 428This means that if both :file:`plank.dts` and :file:`plank_soc1_foo.dts` exist, 429then when building for ``plank`` / ``plank/soc1``, then :file:`plank.dts` is 430used. When building for ``plank//foo`` / ``plank/soc1/foo`` the 431:file:`plank_soc1_foo.dts` is used. 432 433This allows board maintainers to write a base devicetree file for the board 434or write specific devicetree files for a given board's SoC or variant. 435 436If you're in a hurry, simple hardware can usually be supported by copy/paste 437followed by trial and error. If you want to understand details, you will need 438to read the rest of the devicetree documentation and the devicetree 439specification. 440 441.. _dt_k6x_example: 442 443Example: FRDM-K64F and Hexiwear K64 444=================================== 445 446.. Give the filenames instead of the full paths below, as it's easier to read. 447 The cramped 'foo.dts<path>' style avoids extra spaces before commas. 448 449This section contains concrete examples related to writing your board's 450devicetree. 451 452The FRDM-K64F and Hexiwear K64 board devicetrees are defined in 453:zephyr_file:`frdm_k64fs.dts <boards/nxp/frdm_k64f/frdm_k64f.dts>` and 454:zephyr_file:`hexiwear_k64.dts <boards/nxp/hexiwear/hexiwear_mk64f12.dts>` 455respectively. Both boards have NXP SoCs from the same Kinetis SoC family, the 456K6X. 457 458Common devicetree definitions for K6X are stored in :zephyr_file:`nxp_k6x.dtsi 459<dts/arm/nxp/nxp_k6x.dtsi>`, which is included by both board :file:`.dts` 460files. :zephyr_file:`nxp_k6x.dtsi<dts/arm/nxp/nxp_k6x.dtsi>` in turn includes 461:zephyr_file:`armv7-m.dtsi<dts/arm/armv7-m.dtsi>`, which has common definitions 462for Arm v7-M cores. 463 464Since :zephyr_file:`nxp_k6x.dtsi<dts/arm/nxp/nxp_k6x.dtsi>` is meant to be 465generic across K6X-based boards, it leaves many devices disabled by default 466using ``status`` properties. For example, there is a CAN controller defined as 467follows (with unimportant parts skipped): 468 469.. code-block:: devicetree 470 471 can0: can@40024000 { 472 ... 473 status = "disabled"; 474 ... 475 }; 476 477It is up to the board :file:`.dts` or application overlay files to enable these 478devices as desired, by setting ``status = "okay"``. The board :file:`.dts` 479files are also responsible for any board-specific configuration of the device, 480such as adding nodes for on-board sensors, LEDs, buttons, etc. 481 482For example, FRDM-K64 (but not Hexiwear K64) :file:`.dts` enables the CAN 483controller and sets the bus speed: 484 485.. code-block:: devicetree 486 487 &can0 { 488 status = "okay"; 489 }; 490 491The ``&can0 { ... };`` syntax adds/overrides properties on the node with label 492``can0``, i.e. the ``can@4002400`` node defined in the :file:`.dtsi` file. 493 494Other examples of board-specific customization is pointing properties in 495``aliases`` and ``chosen`` to the right nodes (see :ref:`dt-alias-chosen`), and 496making GPIO/pinmux assignments. 497 498.. _board_kconfig_files: 499 500Write Kconfig files 501******************* 502 503Zephyr uses the Kconfig language to configure software features. Your board 504needs to provide some Kconfig settings before you can compile a Zephyr 505application for it. 506 507Setting Kconfig configuration values is documented in detail in 508:ref:`setting_configuration_values`. 509 510There is one mandatory Kconfig file in the board directory, and several optional 511files for a board named ``plank``: 512 513.. code-block:: none 514 515 boards/<vendor>/plank 516 ├── Kconfig 517 ├── Kconfig.plank 518 ├── Kconfig.defconfig 519 ├── plank_defconfig 520 └── plank_<qualifiers>_defconfig 521 522:file:`Kconfig.plank` 523 A shared Kconfig file which can be sourced both in Zephyr Kconfig and sysbuild 524 Kconfig trees. 525 526 This file selects the SoC in the Kconfig tree and potential other SoC related 527 Kconfig settings. This file must not select anything outside the re-usable 528 Kconfig board and SoC trees. 529 530 A :file:`Kconfig.plank` may look like this: 531 532 .. code-block:: kconfig 533 534 config BOARD_PLANK 535 select SOC_SOC1 536 537 The Kconfig symbols :samp:`BOARD_{board}` and 538 :samp:`BOARD_{normalized_board_target}` are constructed by the build 539 system, therefore no type shall be defined in above code snippet. 540 541:file:`Kconfig` 542 Included by :zephyr_file:`boards/Kconfig`. 543 544 This file can add Kconfig settings which are specific to the current board. 545 546 Not all boards have a :file:`Kconfig` file. 547 548 A board specific setting should be defining a custom setting and usually with 549 a prompt, like this: 550 551 .. code-block:: kconfig 552 553 config BOARD_FEATURE 554 bool "Board specific feature" 555 556 If the setting name is identical to an existing Kconfig setting in Zephyr and 557 only modifies the default value of said setting, then 558 :file:`Kconfig.defconfig` should be used instead. 559 560:file:`Kconfig.defconfig` 561 Board-specific default values for Kconfig options. 562 563 Not all boards have a :file:`Kconfig.defconfig` file. 564 565 The entire file should be inside an ``if BOARD_PLANK`` / ``endif`` pair of 566 lines, like this: 567 568 .. code-block:: kconfig 569 570 if BOARD_PLANK 571 572 config FOO 573 default y 574 575 if NETWORKING 576 config SOC_ETHERNET_DRIVER 577 default y 578 endif # NETWORKING 579 580 endif # BOARD_PLANK 581 582:file:`plank_defconfig` / :file:`plank_<qualifiers>_defconfig` 583 A Kconfig fragment that is merged as-is into the final build directory 584 :file:`.config` whenever an application is compiled for your board. 585 586 If both the common :file:`plank_defconfig` file and one or more board 587 qualifiers specific :file:`plank_<qualifiers>_defconfig` files exist, then 588 all matching files will be used. 589 This allows you to place configuration which is common for all board SoCs, 590 CPU clusters, and board variants in the base :file:`plank_defconfig` and only 591 place the adjustments specific for a given SoC or board variant in the 592 :file:`plank_<qualifiers>_defconfig`. 593 594 The ``_defconfig`` should contain mandatory settings for your system clock, 595 console, etc. The results are architecture-specific, but typically look 596 something like this: 597 598 .. code-block:: cfg 599 600 CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=120000000 # set up your clock, etc 601 CONFIG_SERIAL=y 602 603:file:`plank_x_y_z_defconfig` / :file:`plank_<qualifiers>_x_y_z_defconfig` 604 A Kconfig fragment that is merged as-is into the final build directory 605 :file:`.config` whenever an application is compiled for your board revision 606 ``x.y.z``. 607 608Build, test, and fix 609******************** 610 611Now it's time to build and test the application(s) you want to run on your 612board until you're satisfied. 613 614For example: 615 616.. code-block:: console 617 618 west build -b plank samples/hello_world 619 west flash 620 621For ``west flash`` to work, see :ref:`flash-and-debug-support` below. You can 622also just flash :file:`build/zephyr/zephyr.elf`, :file:`zephyr.hex`, or 623:file:`zephyr.bin` with any other tools you prefer. 624 625.. _porting-general-recommendations: 626 627General recommendations 628*********************** 629 630For consistency and to make it easier for users to build generic applications 631that are not board specific for your board, please follow these guidelines 632while porting. 633 634- Unless explicitly recommended otherwise by this section, leave peripherals 635 and their drivers disabled by default. 636 637- Configure and enable a system clock, along with a tick source. 638 639- Provide pin and driver configuration that matches the board's valuable 640 components such as sensors, buttons or LEDs, and communication interfaces 641 such as USB, Ethernet connector, or Bluetooth/Wi-Fi chip. 642 643- If your board uses a well-known connector standard (like Arduino, Mikrobus, 644 Grove, or 96Boards connectors), add connector nodes to your DTS and configure 645 pin muxes accordingly. 646 647- Configure components that enable the use of these pins, such as 648 configuring an SPI instance to use the usual Arduino SPI pins. 649 650- If available, configure and enable a serial output for the console 651 using the ``zephyr,console`` chosen node in the devicetree. 652 Development boards with a built-in debug adapter or USB-to-UART adapter should 653 by default configure and use the UART controller connected to that adapter. 654 For boards like :ref:`nRF52840 Dongle <nrf52840dongle_nrf52840>`, that do not 655 have a debug adapter, but a USB device controller, there is a common 656 :zephyr_file:`Kconfig file <boards/common/usb/Kconfig.cdc_acm_serial.defconfig>` 657 that must be included in the board's Kconfig.defconfig file and 658 :zephyr_file:`devicetree file <boards/common/usb/cdc_acm_serial.dtsi>` 659 that must be included if the board's devicetree, if the board want to use the 660 CDC ACM UART as the default backend for logging and shell. 661 662- If your board supports networking, configure a default interface. 663 664- Enable all GPIO ports connected to peripherals or expansion connectors. 665 666- If available, enable pinmux and interrupt controller drivers. 667 668- It is recommended to enable the MPU by default, if there is support for it 669 in hardware. For boards with limited memory resources it is acceptable to 670 disable it. When the MPU is enabled, it is recommended to also enable 671 hardware stack protection (CONFIG_HW_STACK_PROTECTION=y) and, thus, allow the 672 kernel to detect stack overflows when the system is running in privileged 673 mode. 674 675.. _flash-and-debug-support: 676 677Flash and debug support 678*********************** 679 680Zephyr supports :ref:`west-build-flash-debug` via west extension commands. 681 682To add ``west flash`` and ``west debug`` support for your board, you need to 683create a :file:`board.cmake` file in your board directory. This file's job is 684to configure a "runner" for your board. (There's nothing special you need to 685do to get ``west build`` support for your board.) 686 687"Runners" are Zephyr-specific Python classes that wrap :ref:`flash and debug 688host tools <flash-debug-host-tools>` and integrate with west and the zephyr build 689system to support ``west flash`` and related commands. Each runner supports 690flashing, debugging, or both. You need to configure the arguments to these 691Python scripts in your :file:`board.cmake` to support those commands like this 692example :file:`board.cmake`: 693 694.. code-block:: cmake 695 696 board_runner_args(jlink "--device=nrf52" "--speed=4000") 697 board_runner_args(pyocd "--target=nrf52" "--frequency=4000000") 698 699 include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 700 include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 701 include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 702 703This example configures the ``nrfjprog``, ``jlink``, and ``pyocd`` runners. 704 705.. warning:: 706 707 Runners usually have names which match the tools they wrap, so the ``jlink`` 708 runner wraps Segger's J-Link tools, and so on. But the runner command line 709 options like ``--speed`` etc. are specific to the Python scripts. 710 711.. note:: 712 713 Runners and board configuration should be created without being targeted to 714 a single operating system if the tool supports multiple operating systems, 715 nor should it rely upon special system setup/configuration. For example; do 716 not assume that a user will have prior knowledge/configuration or (if using 717 Linux) special udev rules installed, do not assume one specific ``/dev/X`` 718 device for all platforms as this will not be compatible with Windows or 719 macOS, and allow for overriding of the selected device so that multiple 720 boards can be connected to a single system and flashed/debugged at the 721 choice of the user. 722 723For more details: 724 725- Run ``west flash --context`` to see a list of available runners which support 726 flashing, and ``west flash --context -r <RUNNER>`` to view the specific options 727 available for an individual runner. 728- Run ``west debug --context`` and ``west debug --context <RUNNER>`` to get 729 the same output for runners which support debugging. 730- Run ``west flash --help`` and ``west debug --help`` for top-level options 731 for flashing and debugging. 732- See :ref:`west-runner` for Python APIs. 733- Look for :file:`board.cmake` files for other boards similar to your own for 734 more examples. 735 736To see what a ``west flash`` or ``west debug`` command is doing exactly, run it 737in verbose mode: 738 739.. code-block:: sh 740 741 west --verbose flash 742 west --verbose debug 743 744Verbose mode prints any host tool commands the runner uses. 745 746The order of the ``include()`` calls in your :file:`board.cmake` matters. The 747first ``include`` sets the default runner if it's not already set. For example, 748including ``nrfjprog.board.cmake`` first means that ``nrfjprog`` is the default 749flash runner for this board. Since ``nrfjprog`` does not support debugging, 750``jlink`` is the default debug runner. 751 752.. _porting_board_revisions: 753 754Multiple board revisions 755************************ 756 757See :ref:`application_board_version` for basics on this feature from the user 758perspective. 759 760Board revisions are described in the ``revision`` entry of the 761:file:`board.yml`. 762 763.. code-block:: yaml 764 765 board: 766 revision: 767 format: <major.minor.patch|letter|number|custom> 768 default: <default-revision-value> 769 exact: <true|false> 770 revisions: 771 - name: <revA> 772 - name: <revB> 773 774Zephyr natively supports the following revision formats: 775 776- ``major.minor.patch``: match a three digit revision, such as ``1.2.3``. 777- ``number``: matches integer revisions 778- ``letter``: matches single letter revisions from ``A`` to ``Z`` only 779 780.. _board_fuzzy_revision_matching: 781 782Fuzzy revision matching 783======================= 784 785Fuzzy revision matching is enabled per default. 786 787If the user selects a revision between those available, the closest revision 788number that is not larger than the user's choice is used. For example, if the 789board ``plank`` defines revisions ``0.5.0``, and ``1.5.0`` and the user builds 790for ``plank@0.7.0``, the build system will target revision ``0.5.0``. 791 792The build system will print this at CMake configuration time: 793 794.. code-block:: console 795 796 -- Board: plank, Revision: 0.7.0 (Active: 0.5.0) 797 798This allows you to only create revision configuration files for board revision 799numbers that introduce incompatible changes. 800 801Similar for ``letter`` where revision ``A``, ``D``, and ``F`` could be defined 802and the user builds for ``plank@E``, the build system will target revision ``D`` 803. 804 805Exact revision matching 806======================= 807 808Exact revision matching is enabled when ``exact: true`` is specified in the 809revision section in :file:`board.yml`. 810 811When exact is defined then building for ``plank@0.7.0`` in the above example 812will result in the following error message: 813 814.. code-block:: console 815 816 Board revision `0.7.0` not found. Please specify a valid board revision. 817 818Board revision configuration adjustment 819======================================= 820 821When the user builds for board ``plank@<revision>`` it is possible to make 822adjustments to the board's normal configuration. 823 824As described in the :ref:`default_board_configuration` and 825:ref:`board_kconfig_files` sections the board default configuration is created 826from the files :file:`<board>.dts` / :file:`<board>_<qualifiers>.dts` and 827:file:`<board>_defconfig` / :file:`<board>_<qualifiers>_defconfig`. 828When building for a specific board revision, the above files are used as a 829starting point and the following board files will be used in addition: 830 831- :file:`<board>_<qualifiers>_<revision>_defconfig`: a specific revision 832 defconfig which is only used for the board and SOC / variants identified by 833 ``<board>_<qualifiers>``. 834 835- :file:`<board>_<revision>_defconfig`: a specific revision defconfig which is 836 used for the board regardless of the SOC / variants. 837 838- :file:`<board>_<qualifiers>_<revision>.overlay`: a specific revision dts 839 overlay which is only used for the board and SOC / variants identified by 840 ``<board>_<qualifiers>``. 841 842- :file:`<board>_<revision>.overlay`: a specific revision dts overlay which is 843 used for the board regardless of the SOC / variants. 844 845This split allows boards with multiple SoCs, multi-core SoCs, or variants to 846place common revision adjustments which apply to all SoCs and variants in a 847single file, while still providing the ability to place SoC or variant specific 848adjustments in a dedicated revision file. 849 850Using the ``plank`` board from previous sections, then we could have the following 851revision adjustments: 852 853.. code-block:: none 854 855 boards/zephyr/plank 856 ├── plank_0_5_0_defconfig # Kconfig adjustment for all plank board qualifiers on revision 0.5.0 857 ├── plank_0_5_0.overlay # DTS overlay for all plank board qualifiers on revision 0.5.0 858 └── plank_soc1_foo_1_5_0_defconfig # Kconfig adjustment for plank board when building for soc1 variant foo on revision 1.5.0 859 860Custom revision.cmake files 861*************************** 862 863Some boards may not use board revisions supported natively by Zephyr. 864For example string revisions. 865 866One reason why Zephyr doesn't support string revisions is that strings can take 867many forms and it's not always clear if the given strings are just strings, such 868as ``blue``, ``green``, ``red``, etc. or if they provide an order which can be 869matched against higher or lower revisions, such as ``alpha``, ``beta```, 870``gamma``. 871 872Due to the sheer number of possibilities with strings, including the possibility 873of doing regex matches internally, then string revisions must be done using 874``custom`` revision type. 875 876To indicate to the build system that ``custom`` revisions are used, the format 877field in the ``revision`` section of the :file:`board.yml` must be written as: 878 879.. code-block:: yaml 880 881 board: 882 revision: 883 format: custom 884 885When using custom revisions then a :file:`revision.cmake` must be created in the 886board directory. 887 888The :file:`revision.cmake` will be included by the build system when building 889for the board and it is the responsibility of the file to validate the revision 890specified by the user. 891 892The :makevar:`BOARD_REVISION` variable holds the revision value specified by the 893user. 894 895To signal to the build system that it should use a different revision than the 896one specified by the user, :file:`revision.cmake` can set the variable 897``ACTIVE_BOARD_REVISION`` to the revision to use instead. The corresponding 898Kconfig files and devicetree overlays must be named 899:file:`<board>_<ACTIVE_BOARD_REVISION>_defconfig` and 900:file:`<board>_<ACTIVE_BOARD_REVISION>.overlay`. 901 902.. _contributing-your-board: 903 904Contributing your board 905*********************** 906 907If you want to contribute your board to Zephyr, first -- thanks! 908 909There are some extra things you'll need to do: 910 911#. Make sure you've followed all the :ref:`porting-general-recommendations`. 912 They are requirements for boards included with Zephyr. 913 914#. Add documentation for your board using the template file 915 :zephyr_file:`doc/templates/board.tmpl`. See :ref:`zephyr_doc` for 916 information on how to build your documentation before submitting 917 your pull request. 918 919#. Prepare a pull request adding your board which follows the 920 :ref:`contribute_guidelines`. 921 922.. _extend-board: 923 924Board extensions 925**************** 926 927The board hardware model in Zephyr allows you to extend an existing board with 928new board variants. Such board extensions can be done in your custom repository 929and thus outside of the Zephyr repository. 930 931Extending an existing board with an extra variant allows you to adjust an 932existing board and thereby during build to select building for the existing, 933unmodified board, or the new variant. 934 935To extend an existing board, first create a :file:`board.yml` in your extended 936board. Make sure to use the directory structure described in 937:ref:`create-your-board-directory`. 938 939The skeleton of the board YAML file for extending a board is: 940 941.. code-block:: yaml 942 943 board: 944 extend: <existing-board-name> 945 variants: 946 - name: <new-variant> 947 qualifier: <existing-qualifier> 948 949When extending a board, your board directory should look like: 950 951.. code-block:: none 952 953 boards/<VENDOR>/plank 954 ├── board.yml 955 ├── plank_<new-qualifiers>_defconfig 956 └── plank_<new-qualifiers>.dts 957 958Replace ``plank`` with the real name of the board you extend. 959 960In some cases you might want to also adjust additional settings, like the 961:file:`Kconfig.defconfig` or :file:`Kconfig.{board}`. 962Therefore it is also possible to provide the following in addition when 963extending a board. 964 965.. code-block:: none 966 967 boards/<VENDOR>/plank 968 ├── board.cmake 969 ├── Kconfig 970 ├── Kconfig.plank 971 ├── Kconfig.defconfig 972 └── plank_<new-qualifiers>.yaml 973 974Board extensions (Old hardware model) 975************************************* 976 977.. note:: 978 979 This extension mechanism is intended for boards in old hardware description 980 format. For boards described in new hardware model format, use the extension 981 feature described in :ref:`extend-board`. 982 983Boards already supported by Zephyr can be extended by downstream users, such as 984``example-application`` or vendor SDKs. In some situations, certain hardware 985description or :ref:`choices <devicetree-chosen-nodes>` can not be added in the 986upstream Zephyr repository, but they can be in a downstream project, where 987custom bindings or driver classes can also be created. This feature may also be 988useful in development phases, when the board skeleton lives upstream, but other 989features are developed in a downstream module. 990 991Board extensions are board fragments that can be present in an out-of-tree board 992root folder, under ``${BOARD_ROOT}/boards/extensions``. Here is an example 993structure of an extension for the ``plank`` board and its revisions: 994 995.. code-block:: none 996 997 boards/extensions/plank 998 ├── plank.conf # optional 999 ├── plank_<revision>.conf # optional 1000 ├── plank.overlay # optional 1001 └── plank_<revision>.overlay # optional 1002 1003A board extension directory must follow the naming structure of the original 1004board it extends. It may contain Kconfig fragments and/or devicetree overlays. 1005Extensions are, by default, automatically loaded and applied on top of board 1006files, before anything else. There is no guarantee on which order extensions are 1007applied, in case multiple exist. This feature can be disabled by passing 1008``-DBOARD_EXTENSIONS=OFF`` when building. 1009 1010Note that board extensions need to follow the 1011:ref:`same guidelines <porting-general-recommendations>` as regular boards. For 1012example, it is wrong to enable extra peripherals or subsystems in a board 1013extension. 1014 1015.. warning:: 1016 1017 Board extensions are not allowed in any module referenced in Zephyr's 1018 ``west.yml`` manifest file. Any board changes are required to be submitted to 1019 the main Zephyr repository. 1020