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, Bluetooth 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/nrfutil.board.cmake) 700 include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) 701 include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 702 include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) 703 704This example configures the ``nrfutil``, ``nrfjprog``, ``jlink``, and ``pyocd`` 705runners. 706 707.. warning:: 708 709 Runners usually have names which match the tools they wrap, so the ``jlink`` 710 runner wraps Segger's J-Link tools, and so on. But the runner command line 711 options like ``--speed`` etc. are specific to the Python scripts. 712 713.. note:: 714 715 Runners and board configuration should be created without being targeted to 716 a single operating system if the tool supports multiple operating systems, 717 nor should it rely upon special system setup/configuration. For example; do 718 not assume that a user will have prior knowledge/configuration or (if using 719 Linux) special udev rules installed, do not assume one specific ``/dev/X`` 720 device for all platforms as this will not be compatible with Windows or 721 macOS, and allow for overriding of the selected device so that multiple 722 boards can be connected to a single system and flashed/debugged at the 723 choice of the user. 724 725For more details: 726 727- Run ``west flash --context`` to see a list of available runners which support 728 flashing, and ``west flash --context -r <RUNNER>`` to view the specific options 729 available for an individual runner. 730- Run ``west debug --context`` and ``west debug --context <RUNNER>`` to get 731 the same output for runners which support debugging. 732- Run ``west flash --help`` and ``west debug --help`` for top-level options 733 for flashing and debugging. 734- See :ref:`west-runner` for Python APIs. 735- Look for :file:`board.cmake` files for other boards similar to your own for 736 more examples. 737 738To see what a ``west flash`` or ``west debug`` command is doing exactly, run it 739in verbose mode: 740 741.. code-block:: sh 742 743 west --verbose flash 744 west --verbose debug 745 746Verbose mode prints any host tool commands the runner uses. 747 748The order of the ``include()`` calls in your :file:`board.cmake` matters. The 749first ``include`` sets the default runner if it's not already set. For example, 750including ``nrfjprog.board.cmake`` first means that ``nrfjprog`` is the default 751flash runner for this board. Since ``nrfjprog`` does not support debugging, 752``jlink`` is the default debug runner. 753 754.. _porting_board_revisions: 755 756Multiple board revisions 757************************ 758 759See :ref:`application_board_version` for basics on this feature from the user 760perspective. 761 762Board revisions are described in the ``revision`` entry of the 763:file:`board.yml`. 764 765.. code-block:: yaml 766 767 board: 768 revision: 769 format: <major.minor.patch|letter|number|custom> 770 default: <default-revision-value> 771 exact: <true|false> 772 revisions: 773 - name: <revA> 774 - name: <revB> 775 776Zephyr natively supports the following revision formats: 777 778- ``major.minor.patch``: match a three digit revision, such as ``1.2.3``. 779- ``number``: matches integer revisions 780- ``letter``: matches single letter revisions from ``A`` to ``Z`` only 781 782.. _board_fuzzy_revision_matching: 783 784Fuzzy revision matching 785======================= 786 787Fuzzy revision matching is enabled per default. 788 789If the user selects a revision between those available, the closest revision 790number that is not larger than the user's choice is used. For example, if the 791board ``plank`` defines revisions ``0.5.0``, and ``1.5.0`` and the user builds 792for ``plank@0.7.0``, the build system will target revision ``0.5.0``. 793 794The build system will print this at CMake configuration time: 795 796.. code-block:: console 797 798 -- Board: plank, Revision: 0.7.0 (Active: 0.5.0) 799 800This allows you to only create revision configuration files for board revision 801numbers that introduce incompatible changes. 802 803Similar for ``letter`` where revision ``A``, ``D``, and ``F`` could be defined 804and the user builds for ``plank@E``, the build system will target revision ``D`` 805. 806 807Exact revision matching 808======================= 809 810Exact revision matching is enabled when ``exact: true`` is specified in the 811revision section in :file:`board.yml`. 812 813When exact is defined then building for ``plank@0.7.0`` in the above example 814will result in the following error message: 815 816.. code-block:: console 817 818 Board revision `0.7.0` not found. Please specify a valid board revision. 819 820Board revision configuration adjustment 821======================================= 822 823When the user builds for board ``plank@<revision>`` it is possible to make 824adjustments to the board's normal configuration. 825 826As described in the :ref:`default_board_configuration` and 827:ref:`board_kconfig_files` sections the board default configuration is created 828from the files :file:`<board>.dts` / :file:`<board>_<qualifiers>.dts` and 829:file:`<board>_defconfig` / :file:`<board>_<qualifiers>_defconfig`. 830When building for a specific board revision, the above files are used as a 831starting point and the following board files will be used in addition: 832 833- :file:`<board>_<qualifiers>_<revision>_defconfig`: a specific revision 834 defconfig which is only used for the board and SOC / variants identified by 835 ``<board>_<qualifiers>``. 836 837- :file:`<board>_<revision>_defconfig`: a specific revision defconfig which is 838 used for the board regardless of the SOC / variants. 839 840- :file:`<board>_<qualifiers>_<revision>.overlay`: a specific revision dts 841 overlay which is only used for the board and SOC / variants identified by 842 ``<board>_<qualifiers>``. 843 844- :file:`<board>_<revision>.overlay`: a specific revision dts overlay which is 845 used for the board regardless of the SOC / variants. 846 847This split allows boards with multiple SoCs, multi-core SoCs, or variants to 848place common revision adjustments which apply to all SoCs and variants in a 849single file, while still providing the ability to place SoC or variant specific 850adjustments in a dedicated revision file. 851 852Using the ``plank`` board from previous sections, then we could have the following 853revision adjustments: 854 855.. code-block:: none 856 857 boards/zephyr/plank 858 ├── plank_0_5_0_defconfig # Kconfig adjustment for all plank board qualifiers on revision 0.5.0 859 ├── plank_0_5_0.overlay # DTS overlay for all plank board qualifiers on revision 0.5.0 860 └── plank_soc1_foo_1_5_0_defconfig # Kconfig adjustment for plank board when building for soc1 variant foo on revision 1.5.0 861 862Custom revision.cmake files 863*************************** 864 865Some boards may not use board revisions supported natively by Zephyr. 866For example string revisions. 867 868One reason why Zephyr doesn't support string revisions is that strings can take 869many forms and it's not always clear if the given strings are just strings, such 870as ``blue``, ``green``, ``red``, etc. or if they provide an order which can be 871matched against higher or lower revisions, such as ``alpha``, ``beta```, 872``gamma``. 873 874Due to the sheer number of possibilities with strings, including the possibility 875of doing regex matches internally, then string revisions must be done using 876``custom`` revision type. 877 878To indicate to the build system that ``custom`` revisions are used, the format 879field in the ``revision`` section of the :file:`board.yml` must be written as: 880 881.. code-block:: yaml 882 883 board: 884 revision: 885 format: custom 886 887When using custom revisions then a :file:`revision.cmake` must be created in the 888board directory. 889 890The :file:`revision.cmake` will be included by the build system when building 891for the board and it is the responsibility of the file to validate the revision 892specified by the user. 893 894The :makevar:`BOARD_REVISION` variable holds the revision value specified by the 895user. 896 897To signal to the build system that it should use a different revision than the 898one specified by the user, :file:`revision.cmake` can set the variable 899``ACTIVE_BOARD_REVISION`` to the revision to use instead. The corresponding 900Kconfig files and devicetree overlays must be named 901:file:`<board>_<ACTIVE_BOARD_REVISION>_defconfig` and 902:file:`<board>_<ACTIVE_BOARD_REVISION>.overlay`. 903 904.. _contributing-your-board: 905 906Contributing your board 907*********************** 908 909If you want to contribute your board to Zephyr, first -- thanks! 910 911There are some extra things you'll need to do: 912 913#. Make sure you've followed all the :ref:`porting-general-recommendations`. 914 They are requirements for boards included with Zephyr. 915 916#. Add documentation for your board using the template file 917 :zephyr_file:`doc/templates/board.tmpl`. See :ref:`zephyr_doc` for 918 information on how to build your documentation before submitting 919 your pull request. 920 921#. Prepare a pull request adding your board which follows the 922 :ref:`contribute_guidelines`. 923 924.. _extend-board: 925 926Board extensions 927**************** 928 929The board hardware model in Zephyr allows you to extend an existing board with 930new board variants. Such board extensions can be done in your custom repository 931and thus outside of the Zephyr repository. 932 933Extending an existing board with an extra variant allows you to adjust an 934existing board and thereby during build to select building for the existing, 935unmodified board, or the new variant. 936 937To extend an existing board, first create a :file:`board.yml` in your extended 938board. Make sure to use the directory structure described in 939:ref:`create-your-board-directory`. 940 941The skeleton of the board YAML file for extending a board is: 942 943.. code-block:: yaml 944 945 board: 946 extend: <existing-board-name> 947 variants: 948 - name: <new-variant> 949 qualifier: <existing-qualifier> 950 951When extending a board, your board directory should look like: 952 953.. code-block:: none 954 955 boards/<VENDOR>/plank 956 ├── board.yml 957 ├── plank_<new-qualifiers>_defconfig 958 └── plank_<new-qualifiers>.dts 959 960Replace ``plank`` with the real name of the board you extend. 961 962In some cases you might want to also adjust additional settings, like the 963:file:`Kconfig.defconfig` or :file:`Kconfig.{board}`. 964Therefore it is also possible to provide the following in addition when 965extending a board. 966 967.. code-block:: none 968 969 boards/<VENDOR>/plank 970 ├── board.cmake 971 ├── Kconfig 972 ├── Kconfig.plank 973 ├── Kconfig.defconfig 974 └── plank_<new-qualifiers>.yaml 975 976Board extensions (Old hardware model) 977************************************* 978 979.. note:: 980 981 This extension mechanism is intended for boards in old hardware description 982 format. For boards described in new hardware model format, use the extension 983 feature described in :ref:`extend-board`. 984 985Boards already supported by Zephyr can be extended by downstream users, such as 986``example-application`` or vendor SDKs. In some situations, certain hardware 987description or :ref:`choices <devicetree-chosen-nodes>` can not be added in the 988upstream Zephyr repository, but they can be in a downstream project, where 989custom bindings or driver classes can also be created. This feature may also be 990useful in development phases, when the board skeleton lives upstream, but other 991features are developed in a downstream module. 992 993Board extensions are board fragments that can be present in an out-of-tree board 994root folder, under ``${BOARD_ROOT}/boards/extensions``. Here is an example 995structure of an extension for the ``plank`` board and its revisions: 996 997.. code-block:: none 998 999 boards/extensions/plank 1000 ├── plank.conf # optional 1001 ├── plank_<revision>.conf # optional 1002 ├── plank.overlay # optional 1003 └── plank_<revision>.overlay # optional 1004 1005A board extension directory must follow the naming structure of the original 1006board it extends. It may contain Kconfig fragments and/or devicetree overlays. 1007Extensions are, by default, automatically loaded and applied on top of board 1008files, before anything else. There is no guarantee on which order extensions are 1009applied, in case multiple exist. This feature can be disabled by passing 1010``-DBOARD_EXTENSIONS=OFF`` when building. 1011 1012Note that board extensions need to follow the 1013:ref:`same guidelines <porting-general-recommendations>` as regular boards. For 1014example, it is wrong to enable extra peripherals or subsystems in a board 1015extension. 1016 1017.. warning:: 1018 1019 Board extensions are not allowed in any module referenced in Zephyr's 1020 ``west.yml`` manifest file. Any board changes are required to be submitted to 1021 the main Zephyr repository. 1022