2026 年 09 月 04 日 ソリューション統括部
Zephyr OS とは ? について解説するブログの第五回目です。
Zephyr アプリに挑戦(中編)では、前編で構築した見本アプリ app を Zephyr 上で使えるようにしていきます。
「Zephyr アプリに挑戦」は全三回を予定しています。前編はこちら。後編は 10 月中旬頃の公開予定です。
これまでの Zephyr ブログを読んでいない方は 「Zephyrブログ 第一回 はじめての Zephyr(前編)」から読んでいただけると、より理解が深まります。
applications/CMakeLists.txt ファイルには次のような行があるので、これらのファイルを cmake が読み込んでくれれば良さそうです。
そのためには applications ディレクトリがモジュールとして登録できれば良さそうと考えました。
モジュールとは、「はじめての Zephyr」の回で簡単に述べましたが、Zephyr とは無関係にメンテされているソースコードで Zephyr の構築システムに組み込まれたもののことです。
では、モジュール として登録するにはどうすればよいのでしょうか?そもそも example-application リポジトリはモジュールとして使用することができるのでしょうか?
まず、モジュールとして使用できるのかどうかですが、
https://docs.zephyrproject.org/latest/develop/modules.html#module-yaml-file-description
によると、モジュールは zephyr/module.yml ファイルによってその内容を記述できると書かれています。
example-application リポジトリにはファイル zephyr/module.yml があります。モジュールとして使用されることが想定されているようです。
次に、モジュールとして登録するにはどうすればよいかですが、
https://docs.zephyrproject.org/latest/develop/modules.html#integrate-modules-in-zephyr-build-system によれば、EXTRA_ZEPHYR_MODULES という CMake 変数ないし環境変数があって、これを使ってモジュールを追加できるようです。
環境変数でもよいということで、次のようにしてみました。
$ export EXTRA_ZEPHYR_MODULES=$PWD $ west build -b mimxrt1170_evk/mimxrt1176/cm7 app
the undefined symbol BLINK エラーは出ませんでした。うまくいったようです。
構築するためには applications ディレクトリをモジュールとして登録する必要があります。
そのためには環境変数 EXTRA_ZEPHYR_MODULES に applications ディレクトリの絶対パスを次のように設定した上で west build コマンドを実行すればよいです。
$ cd ~/zephyrproject/applications $ export EXTRA_ZEPHYR_MODULES=$PWD
applications ディレクトリをモジュールとして登録することによって the undefined symbol BLINK エラーは出なくなったのですが、別のエラーが出てしまいました。 そのエラーメッセージだけ抜粋します。
..(snip)..
/home/hoge/zephyrproject/applications/app/src/main.c: In function 'main':
/home/hoge/zephyrproject/zephyr/include/zephyr/device.h:96:41: error: '__device_dts_ord_DT_N_NODELABEL_example_sensor_ORD' undeclared (first use in this function)
96 | #define DEVICE_NAME_GET(dev_id) _CONCAT(__device_, dev_id)
| ^~~~~~~~~
..(snip)..
/home/hoge/zephyrproject/applications/app/src/main.c:28:18: note: in expansion of macro 'DEVICE_DT_GET'
28 | sensor = DEVICE_DT_GET(DT_NODELABEL(example_sensor));
| ^~~~~~~~~~~~~
app/src/main.c の 28 行目の DT_NODELABEL(example_sensor) マクロの展開で
'__device_dts_ord_DT_N_NODELABEL_example_sensor_ORD' undeclared エラーになっているようです。
このエラーは、調べてみますと、デバイスツリーのノードラベル example_sensor を参照したもので、そのノードラベルの定義が存在しないために発生しているようです。
「はじめての Zephyr」の回でと述べましたが、Zephyr はデバイスツリーでソースコードの構成ができます。
それは上記のように C マクロを使ってデバイスツリーのノードやプロパティを参照できるようにしていることに依るのです。
example_sensor はアプリディレクトリ配下の boards/nucleo_f302r8.overlay で定義されていました。当該箇所を引用します。
/ {
example_sensor: example-sensor {
compatible = "zephyr,example-sensor";
input-gpios = <&gpioc 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
};
blink_led: blink-led {
compatible = "blink-gpio-led";
led-gpios = <&gpiob 13 GPIO_ACTIVE_HIGH>;
blink-period-ms = <1000>;
};
};
&gpioc {
status = "okay";
};
したがって、MIMXRT1170-EVKB ボード用の example_sensor (と blink_led) ノードを定義すればよさそうです。
その定義をどこに書けばよいのでしょうか ?
デバイスツリーノードの追加定義の仕方を知るためには、Zephyr ではデバイスツリーがどのように構成されているのかを知る必要がありました。
Zephyr では最終的なデバイスツリーソースは 4 種類ある DTS ファイルをマージして作成されます。
DTSファイルはファイル名のサフィックスを使って分類されています。
次のとおりです
(https://docs.zephyrproject.org/latest/build/dts/intro-input-output.html#input-files より)。
さて、そうすると、最終的な DTS ファイルの生成に向かって、残る問題は次の二つです。
前者の .dts ファイルはボードディレクトリ配下の .dts ファイルから選ばれます。
ボードディレクトリとその .dts ファイル名は west build コマンドの -b BOARD オプションを使って指定します。
BOARD について、このあたりで少し精密に議論してみましょう。
これまで -b オプションには引数 mimxrt1170_evk/mimxrt1176/cm7 を与えてきました。
これをボードターゲット といいます
(https://docs.zephyrproject.org/latest/glossary.html#term-board-target 参照)。
この / で区切られた最初の要素がボード名であり、それがボードディレクトリ名となります。
それ以降は ボード修飾子 (qualifiers) といいます。
ボード修飾子は最大で次の三つの要素からなり、各々を / で区切ってボードターゲットを構成します。
なお、ボード修飾子は右から順に無くてもかまいません。全部無くてもかまいません。
ボードターゲットの構成要素にはこのほかに ボードリビジョン があります。
ボードリビジョンはボード修飾子の一部ではありません。
ボード名の後ろに @ を添えて追加できます。
たとえば mimxrt1170_evk@B/mimxrt1176/cm7 というようになります。
ボードターゲットからリビジョンがあれば取り除き、 / を _ に置き変えてできる文字列を
すると
mimxrt1170_evk/mimxrt1176/cm7 の場合はファイル名は mimxrt1170_evk_mimxrt1176_cm7.dts となります。
次に、後者の .overlay ファイルですが、これはアプリディレクトリ配下の .overlay ファイルから選ばれます(シールドやリビジョン用の .overlay は除く)。
そのファイル名がボードターゲットから作られる点は .dts ファイルの場合と同様ですが、選び方がちょっと複雑です。
その選択規則は次のとおりです
(https://docs.zephyrproject.org/latest/build/dts/howtos.html#set-devicetree-overlays より)。
CMake 変数 DTC_OVERLAY_FILE には、空白かセミコロンで区切って複数の .overlay ファイルを並べることができます。
相対パスで指定した場合はアプリコンフィグディレクトリ配下を意味します。
1 の
ただし SoC 部はすでに示されているので、CPU cluster 部以下となります。例によって省略可能なようです。
<以上の結果選ばれた DTS ファイルがすべてマージされて、最終的な DTS ファイルが作成されます。
それは構築ディレクトリ配下の zephyr/zephyr.dts に出力されます。
また、C マクロ定義が同配下の
zephyr/include/generated/zephyr/devicetree_generated.hに出力されます。
その内容は
以上から、アプリディレクトリ配下にboards/mimxrt1170_evk_mimxrt1176_cm7.overlay という名のファイルを作成すればよさそうです。
または、リビジョン B がデフォルトなので、boards/mimxrt1170_evk_mimxrt1176_cm7_B.overlay としてもよいです。
ソースコードの構成がデバイスツリーでもできることは、Zephyr の特徴のひとつといえるでしょう。
ここではもう一つのソースコードの構成方法、Kconfig コンフィグについて簡単に説明します。
本項は https://docs.zephyrproject.org/latest/build/kconfig/setting.html#the-initial-configuration をベースにしています。
デバイスツリーと Kconfig コンフィグの使い分け方はhttps://docs.zephyrproject.org/latest/build/dts/dt-vs-kconfig.html#devicetree-versus-kconfig に詳細があります。
簡単にいえば、
ということになります。
ソースコードの構成という目的からは、どちらかがあればよいわけですが、このように分けておくことは意義があり、Linux kernel と同じ使い分けをするものと推測します。 ただし、例外事項があります。
Kconfig はデバイスツリーに比べて記述力が弱いので、それを補うためなら、ソフトウェアのことであってもデバイスツリー側で設定してもよいことになっています。
たとえば、ドライバが内部で使用するバッファのサイズなどです。
そのような目的のプロパティ名には zephyr, を接頭することになっています。
Kconfig コンフィグ設定も、デバイスツリー同様、複数のソースから作成されます。
それは次の 3 種類です(この並び順で優先順位が高くなります)。
同じ CONFIG シンボルが複数回設定されているときはより優先順位の高いほうが採用されます。
この構成の仕方はデバイスツリーの場合と同じです。ボードディレクトリが基礎を提供し(1. の
アプリコンフィグディレクトリ配下には .conf をサフィックスとするファイルがいくつか存在します。
これを Kconfig フラグメント (fragment) といいます。
アプリコンフィグ とは、Kconfig フラグメントファイルの中から次に述べる規則に従って選択されてマージされたものをいいます。
該当する項目があった時点で、ビルドシステムは検索を停止します。
要約すれば、CONF_FILE 変数が設定されていればCONF_FILE 変数がが、設定されていなければアプリに固有のprj.conf にボードに固有の Kconfig フラグメントファイルをマージしたものが、アプリコンフィグとなります。
なお CONF_FILE 変数は CMake 変数のほかに環境変数としても設定することができます
(https://docs.zephyrproject.org/latest/develop/application/index.html#important-build-system-variables 参照)。
空白かセミコロンで区切って複数の Kconfig フラグメントファイルを並べることができます。
相対パスの場合はアプリコンフィグディレクトリ配下を意味します。
以上の結果が構築ディレクトリ配下の zephyr/.config に出力されます。
これを初期コンフィグ (initial configuration) といいます。
初期コンフィグは menuconfig や guiconfig を使って編集することができます。
2025 年 05 月 14 日 Vigiles サポート
2024 年 09 月 02 日 Vigiles サポート
2024 年 03 月 01 日 Vigiles サポート
2026 年 02 月 09 日 Yocto Project よもやま話
2026 年 02 月 09 日 Yocto Project よもやま話
2026 年 02 月 09 日 Yocto Project よもやま話
2024 年 01 月 10 日 Linux 技術ネタ
2023 年 12 月 12 日 Linux 技術ネタ
2023 年 03 月 31 日 Linux 技術ネタ
2026 年 08 月 05 日 イベントレポート
2025 年 12 月 01 日 イベントレポート
2025 年 08 月 08 日 イベントレポート
2025 年 04 月 01 日 リクルート
2023 年 05 月 30 日 リクルート
2022 年 12 月 27 日 リクルート
2026 年 08 月 19 日 信州リネオ便り
2026 年 07 月 01 日 信州リネオ便り
2026 年 05 月 25 日 信州リネオ便り
2026 年 09 月 04 日 ソリューション統括部
2026 年 08 月 07 日 ソリューション統括部
2026 年 05 月 26 日 ソリューション統括部
2019 年 12 月 13 日 マーケティング統括部
2019 年 04 月 25 日 マーケティング統括部
2018 年 12 月 18 日 マーケティング統括部