hardware/porting/shields.html · hardware/porting/shields.rst 공식 원문 ↗

Zephyr 3.7.0 · Hardware · Porting

실드 이식과 구성

Add-on board를 재사용 가능한 shield로 정의하고 connector pin과 SoC GPIO를 안전하게 연결합니다.

Official pathhardware/porting/shields.html
Source filehardware/porting/shields.rst
Source versionZephyr 3.7.0
TranslationFull · reviewed

본문 기준: Zephyr 3.7.0 LTS3 · 이후 유지보수 패치는 별도입니다.

Part 1

요약·해설

Shield file 구조, board·revision override, west 활성화, variant와 GPIO nexus flag 전달을 설명합니다.

Files

overlay · Kconfig

Selection

--shield · variants

GPIO

nexus · mask · pass-thru

Part 2

접을 수 있는 영어 원문 전체

영어 원문 전체 펼치기
원문 SHA-256 55BEE55CD6860B2F50E9063E968CC2B257187CA82075F53AE7103CEAD09C89D6
.. _shields:

Shields
#######

Shields, also known as "add-on" or "daughter boards", attach to a board
to extend its features and services for easier and modularized prototyping.
In Zephyr, the shield feature provides Zephyr-formatted shield
descriptions for easier compatibility with applications.

Shield porting and configuration
********************************

Shield configuration files are available in the board directory
under :zephyr_file:`/boards/shields`:

.. code-block:: none

   boards/shields/<shield>
   ├── <shield>.overlay
   ├── Kconfig.shield
   └── Kconfig.defconfig

These files provides shield configuration as follows:

* **<shield>.overlay**: This file provides a shield description in devicetree
  format that is merged with the board's :ref:`devicetree <dt-guide>`
  before compilation.

* **Kconfig.shield**: This file defines shield Kconfig symbols that will be
  used for default shield configuration. To ease use with applications,
  the default shield configuration here should be consistent with those in
  the :ref:`default_board_configuration`.

* **Kconfig.defconfig**: This file defines the default shield configuration. It
  is made to be consistent with the :ref:`default_board_configuration`. Hence,
  shield configuration should be done by keeping in mind that features
  activation is application responsibility.

Besides, in order to avoid name conflicts with devices that may be defined at
board level, it is advised, specifically for shields devicetree descriptions,
to provide a device nodelabel is the form <device>_<shield>, for instance:

.. code-block:: devicetree

        sdhc_myshield: sdhc@1 {
                reg = <1>;
                ...
        };


Board compatibility
*******************

Hardware shield-to-board compatibility depends on the use of well-known
connectors used on popular boards (such as Arduino and 96boards).  For
software compatibility, boards must also provide a configuration matching
their supported connectors.

This should be done at two different level:

* Pinmux: Connector pins should be correctly configured to match shield pins

* Devicetree: A board :ref:`devicetree <dt-guide>` file,
  :file:`BOARD.dts` should define an alternate nodelabel for each connector interface.
  For example, for Arduino I2C:

.. code-block:: devicetree

        arduino_i2c: &i2c1 {};

Board specific shield configuration
-----------------------------------

If modifications are needed to fit a shield to a particular board or board
revision, you can override a shield description for a specific board by adding
board or board revision overriding files to a shield, as follows:

.. code-block:: none

   boards/shields/<shield>
   └── boards
       ├── <board>_<revision>.overlay
       ├── <board>.overlay
       ├── <board>.defconfig
       ├── <board>_<revision>.conf
       └── <board>.conf


Shield activation
*****************

Activate support for one or more shields by adding the matching ``--shield`` arguments
to the west command:

  .. zephyr-app-commands::
     :zephyr-app: your_app
     :shield: x_nucleo_idb05a1,x_nucleo_iks01a1
     :goals: build


Alternatively, it could be set by default in a project's CMakeLists.txt:

.. code-block:: cmake

	set(SHIELD x_nucleo_iks01a1)

Shield variants
***************

Some shields may support several variants or revisions. In that case, it is
possible to provide multiple version of the shields description:

.. code-block:: none

   boards/shields/<shield>
   ├── <shield_v1>.overlay
   ├── <shield_v1>.defconfig
   ├── <shield_v2>.overlay
   └── <shield_v2>.defconfig

In this case, a shield-particular revision name can be used:

  .. zephyr-app-commands::
     :zephyr-app: your_app
     :shield: shield_v2
     :goals: build

You can also provide a board-specific configuration to a specific shield
revision:

.. code-block:: none

   boards/shields/<shield>
   ├── <shield_v1>.overlay
   ├── <shield_v1>.defconfig
   ├── <shield_v2>.overlay
   ├── <shield_v2>.defconfig
   └── boards
       └── <shield_v2>
           ├── <board>.overlay
           └── <board>.defconfig

GPIO nexus nodes
****************

GPIOs accessed by the shield peripherals must be identified using the
shield GPIO abstraction, for example from the ``arduino-header-r3``
compatible.  Boards that provide the header must map the header pins
to SOC-specific pins.  This is accomplished by including a `nexus
node`_ that looks like the following into the board devicetree file:

.. _nexus node:
    https://github.com/devicetree-org/devicetree-specification/blob/4b1dac80eaca45b4babf5299452a951008a5d864/source/devicetree-basics.rst#nexus-nodes-and-specifier-mapping

.. code-block:: devicetree

    arduino_header: connector {
            compatible = "arduino-header-r3";
            #gpio-cells = <2>;
            gpio-map-mask = <0xffffffff 0xffffffc0>;
            gpio-map-pass-thru = <0 0x3f>;
            gpio-map = <0 0 &gpioa 0 0>,    /* A0 */
                       <1 0 &gpioa 1 0>,    /* A1 */
                       <2 0 &gpioa 4 0>,    /* A2 */
                       <3 0 &gpiob 0 0>,    /* A3 */
                       <4 0 &gpioc 1 0>,    /* A4 */
                       <5 0 &gpioc 0 0>,    /* A5 */
                       <6 0 &gpioa 3 0>,    /* D0 */
                       <7 0 &gpioa 2 0>,    /* D1 */
                       <8 0 &gpioa 10 0>,   /* D2 */
                       <9 0 &gpiob 3 0>,    /* D3 */
                       <10 0 &gpiob 5 0>,   /* D4 */
                       <11 0 &gpiob 4 0>,   /* D5 */
                       <12 0 &gpiob 10 0>,  /* D6 */
                       <13 0 &gpioa 8 0>,   /* D7 */
                       <14 0 &gpioa 9 0>,   /* D8 */
                       <15 0 &gpioc 7 0>,   /* D9 */
                       <16 0 &gpiob 6 0>,   /* D10 */
                       <17 0 &gpioa 7 0>,   /* D11 */
                       <18 0 &gpioa 6 0>,   /* D12 */
                       <19 0 &gpioa 5 0>,   /* D13 */
                       <20 0 &gpiob 9 0>,   /* D14 */
                       <21 0 &gpiob 8 0>;   /* D15 */
    };

This specifies how Arduino pin references like ``<&arduino_header 11
0>`` are converted to SOC gpio pin references like ``<&gpiob 4 0>``.

In Zephyr GPIO specifiers generally have two parameters (indicated by
``#gpio-cells = <2>``): the pin number and a set of flags.  The low 6
bits of the flags correspond to features that can be configured in
devicetree.  In some cases it's necessary to use a non-zero flag value
to tell the driver how a particular pin behaves, as with:

.. code-block:: devicetree

    drdy-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>;

After preprocessing this becomes ``<&arduino_header 11 1>``.  Normally
the presence of such a flag would cause the map lookup to fail,
because there is no map entry with a non-zero flags value.  The
``gpio-map-mask`` property specifies that, for lookup, all bits of the
pin and all but the low 6 bits of the flags are used to identify the
specifier.  Then the ``gpio-map-pass-thru`` specifies that the low 6
bits of the flags are copied over, so the SOC GPIO reference becomes
``<&gpiob 4 1>`` as intended.

See `nexus node`_ for more information about this capability.

Part 3

한국어 전문 번역

Shield는 add-on board 또는 daughter board라고도 하며, base board에 연결해 기능과 service를 확장하고 prototype을 쉽게 modularize합니다. Zephyr shield 기능은 application과 호환하기 쉬운 Zephyr 형식의 shield description을 제공합니다.

Shield porting and configuration

boards/shields 아래 board directory에 shield configuration file을 둡니다.

boards/shields/<shield>
├── <shield>.overlay
├── Kconfig.shield
└── Kconfig.defconfig

각 file의 역할은 다음과 같습니다.

  • <shield>.overlay: Compile 전에 board Devicetree와 merge되는 shield hardware description입니다.
  • Kconfig.shield: Default shield configuration에 사용할 shield Kconfig symbol을 정의합니다. Application에서 쉽게 쓸 수 있도록 board default configuration과 일관되어야 합니다.
  • Kconfig.defconfig: Default shield configuration을 정의합니다. Board default와 일관성을 유지하고 feature activation은 application의 책임이라는 원칙을 지켜야 합니다.

Board level에 정의된 device와 name conflict를 피하려면 shield Devicetree nodelabel을 <device>_<shield> 형식으로 두는 것이 좋습니다.

sdhc_myshield: sdhc@1 {
        reg = <1>;
        ...
};

Board compatibility

Shield와 board의 hardware compatibility는 Arduino·96Boards처럼 널리 쓰이는 connector에 달려 있습니다. Software compatibility를 위해 board도 지원 connector에 맞는 configuration을 제공해야 합니다.

두 level에서 맞춰야 합니다.

  • Pinmux: Connector pin을 shield pin과 일치하도록 구성합니다.
  • Devicetree: Board BOARD.dts가 connector interface마다 alternate nodelabel을 정의합니다. Arduino I2C 예는 다음과 같습니다.
arduino_i2c: &i2c1 {};

Board specific shield configuration

특정 board 또는 revision에 shield를 맞추기 위해 수정해야 한다면 shield directory에 board·revision override file을 추가합니다.

boards/shields/<shield>
└── boards
    ├── <board>_<revision>.overlay
    ├── <board>.overlay
    ├── <board>.defconfig
    ├── <board>_<revision>.conf
    └── <board>.conf

Shield activation

West command에 일치하는 --shield argument를 추가해 shield 하나 이상을 활성화합니다.

# From the root of the zephyr repository
west build -b None --shield x_nucleo_idb05a1 --shield x_nucleo_iks01a1 your_app

Project `CMakeLists.txt`에서 default shield를 지정할 수도 있습니다.

set(SHIELD x_nucleo_iks01a1)

Shield variants

Shield가 variant나 revision을 여러 개 지원한다면 description version도 여러 개 제공할 수 있습니다.

boards/shields/<shield>
├── <shield_v1>.overlay
├── <shield_v1>.defconfig
├── <shield_v2>.overlay
└── <shield_v2>.defconfig

이 경우 shield별 revision name으로 build합니다.

# From the root of the zephyr repository
west build -b None --shield shield_v2 your_app

특정 shield revision에 board별 configuration도 추가할 수 있습니다.

boards/shields/<shield>
├── <shield_v1>.overlay
├── <shield_v1>.defconfig
├── <shield_v2>.overlay
├── <shield_v2>.defconfig
└── boards
    └── <shield_v2>
        ├── <board>.overlay
        └── <board>.defconfig

GPIO nexus nodes

arduino-header-r3 compatible 같은 shield GPIO abstraction으로 shield peripheral의 GPIO를 식별해야 합니다. Header를 제공하는 board는 header pin을 SoC별 pin에 mapping해야 하며 board Devicetree에 nexus node를 넣어 구현합니다.

arduino_header: connector {
        compatible = "arduino-header-r3";
        #gpio-cells = <2>;
        gpio-map-mask = <0xffffffff 0xffffffc0>;
        gpio-map-pass-thru = <0 0x3f>;
        gpio-map = <0 0 &gpioa 0 0>,    /* A0 */
                   <1 0 &gpioa 1 0>,    /* A1 */
                   <2 0 &gpioa 4 0>,    /* A2 */
                   <3 0 &gpiob 0 0>,    /* A3 */
                   <4 0 &gpioc 1 0>,    /* A4 */
                   <5 0 &gpioc 0 0>,    /* A5 */
                   <6 0 &gpioa 3 0>,    /* D0 */
                   <7 0 &gpioa 2 0>,    /* D1 */
                   <8 0 &gpioa 10 0>,   /* D2 */
                   <9 0 &gpiob 3 0>,    /* D3 */
                   <10 0 &gpiob 5 0>,   /* D4 */
                   <11 0 &gpiob 4 0>,   /* D5 */
                   <12 0 &gpiob 10 0>,  /* D6 */
                   <13 0 &gpioa 8 0>,   /* D7 */
                   <14 0 &gpioa 9 0>,   /* D8 */
                   <15 0 &gpioc 7 0>,   /* D9 */
                   <16 0 &gpiob 6 0>,   /* D10 */
                   <17 0 &gpioa 7 0>,   /* D11 */
                   <18 0 &gpioa 6 0>,   /* D12 */
                   <19 0 &gpioa 5 0>,   /* D13 */
                   <20 0 &gpiob 9 0>,   /* D14 */
                   <21 0 &gpiob 8 0>;   /* D15 */
};

<&arduino_header 11 0> 같은 Arduino pin reference는 이 map을 거쳐 <&gpiob 4 0> 같은 SoC GPIO reference로 바뀝니다.

#gpio-cells = <2>인 Zephyr GPIO specifier는 일반적으로 pin number와 flags 두 parameter를 갖습니다. Flags의 하위 6 bit는 Devicetree에서 설정할 수 있는 기능입니다. 특정 pin 동작을 driver에 알리려면 0이 아닌 flag가 필요할 수 있습니다.

drdy-gpios = <&arduino_header 11 GPIO_ACTIVE_LOW>;

Preprocessing 뒤 이 값은 <&arduino_header 11 1>이 됩니다. Map entry에는 non-zero flags가 없어 원래대로라면 lookup이 실패합니다. gpio-map-mask는 lookup 때 pin 전체와 flags의 하위 6 bit를 제외한 부분만 identifier로 쓰게 하고, gpio-map-pass-thru는 하위 6 bit를 결과에 복사합니다. 따라서 원하는 SoC GPIO reference <&gpiob 4 1>이 됩니다.

자세한 mapping semantics는 Devicetree specification의 nexus node 절을 참고합니다.

Source

출처

영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.