ESP-IDFを使ってみる

IDE Component Manager


esp-idf v5.0から、今まで標準でバンドルされていたComponentの幾つかが、component registryに移りました。
これにより、ESP-IDFのバージョンアップとは非同期に、コンポーネントだけを単独でアップデートできるようになります。

component registryを使うためには、IDF Component Manager Manifest File(idf_component.yml)を作る必要が有ります。
IDF Component Managerの公式ドキュメントがこ ちらに有りますが、一番最初に

The IDF Component manager is a tool that downloads dependencies for any ESP-IDF CMake project.
The download happens automatically during a run of CMake.
It can source components either from the component registry or from a Git repository.

と書かれています。
重要なのは3行目でcomponent registryだけでなく、git repositoryからもソースを持ってこれるというところです。

git repositoryには、かなりの数のESP-IDF用のcomponentsが公開されています。
今まで、git repositoryに公開されているcomponentsを使う場合は、以下の様にcomponentsディレクトリの下に手動でクローンする必要が ありました。
$ idf.py set-target esp32
$ git clone https://github.com/Molorius/esp32-websocket components
$ idf.py menuconfig
$ idf.py flash

idf_component.ymlを定義することで、プロジェクトのビルド時に自動的にgit repositoryに公開されているcomponentsをダウンロードしてくれます。
$ cat main/idf_component.yml
dependencies:
  Molorius/esp32-websocket:
    git: https://github.com/Molorius/esp32-websocket

idf_component.ymlに定義されているcomponentは、managed_componentsに格納されます。
$ ls managed_components/
Molorius__esp32-websocket

$ ls managed_components/Molorius__esp32-websocket
CMakeLists.txt  LICENSE    component.mk  websocket.c
Kconfig         README.md  include       websocket_server.c

これは最近他の方から教えて頂いたのですが、リポジトリの一部にcomponentsが含まれている場合、componentsだけを抜き出して 取り出すことができます。
例えば、私のこちらの リポジトリは、以下の様になっています。
esp-idf-ssd1306 --+-- AnimationDemo
                  +-- BalloonDemo
                  +-- BdfFontDemo

                  (中略)

                  +-- components/ssd1306

以下の様に定義すると、このリポジトリから、components/ssd1306だけを抜き出して、 managed_componentsに格納します。
$ cat idf_component.yml
dependencies:
  ssd1306:
    path: components/ssd1306/
    git: https://github.com/nopnop2002/esp-idf-ssd1306.git

見事にcomponents/ssd1306だけがクローンされます。
gitコマンドでもなかなか難しい特定ディレクトリだけのクローンが、簡単にできてしまいます。
$ ls managed_components/ssd1306/
CMakeLists.txt     font8x8_basic.h  ssd1306.h             ssd1306_i2c_new.c
Kconfig.projbuild  ssd1306.c        ssd1306_i2c_legacy.c  ssd1306_spi.c

リモート側が更新されたときは、ビルド時に以下の様に更新が有ったことが表示されます。
idf.py update-dependenciesを実行すると、最新版をフェッチします。
NOTICE:
Following dependencies have new versions available:
Dependency "nopnop2002/RCSwitch": "6f9fe7f068239f02b0a0de2c4e4d693f9612949d" -> "fd6d8d02ccb6597dd8d82449accd1327c0eccc4a"
Consider running "idf.py update-dependencies" to update your lock file.
NOTICE: Processing 2 dependencies:
NOTICE: [1/2] nopnop2002/RCSwitch (6f9fe7f068239f02b0a0de2c4e4d693f9612949d)
NOTICE: [2/2] idf (5.3.2)



複数のcomponentを利用する場合は、idf_component.yml に複数のcomponentを定義ます。
以下の例ではcomponent registry の mdns と、git repository の websocket を定義しています。
mdnsのコンポーネントは、ESP-IDF V4では標準のコンポーネントでしたが、ESP-IDF V5になって上旬から外れました。
そこで、mdnsのコンポーネントはESP-IDF V5の時だけ有効となるような条件を付けています。
$ cat main/idf_component.yml
## IDF Component Manager Manifest File
dependencies:
  espressif/mdns:
    version: "^1.0.3"
    rules:
      - if: "idf_version >=5.0"
  Molorius/esp32-websocket:
    git: https://github.com/Molorius/esp32-websocket



Manifest File(idf_component.yml)には、ダウンロードするコンポーネントのバージョンを指定することができます。
以下の様にすると、必ず1.0.3をダウンロードします。
$ cat main/idf_component.yml
## IDF Component Manager Manifest File
dependencies:
  espressif/mdns:
    version: "1.0.3"
    rules:
      - if: "idf_version >=5.0"

以下の様にすると、その時点の最新の1.x.xをダウンロードします。
仮に2.0.0が有っても、メジャーバージョンが異なるバージョンはダウンロードしません。
$ cat main/idf_component.yml
## IDF Component Manager Manifest File
dependencies:
  espressif/mdns:
    version: "^1.0.3"
    rules:
      - if: "idf_version >=5.0"

バージョン指定が無いときは、その時点の最新版をダウンロードします。
$ cat main/idf_component.yml
## IDF Component Manager Manifest File
dependencies:
  espressif/mdns:
    rules:
      - if: "idf_version >=5.0"

ダウンロードしたコンポーネントのバージョンは、以下のコマンドで確認することができます。
$ cat managed_components/espressif__mdns/idf_component.yml
dependencies:
  idf:
    version: '>=5.0'
description: Multicast UDP service used to provide local network service and host
  discovery.
documentation: https://docs.espressif.com/projects/esp-protocols/mdns/docs/latest/en/index.html
issues: https://github.com/espressif/esp-protocols/issues
repository: git://github.com/espressif/esp-protocols.git
repository_info:
  commit_sha: 4394f845fccf93bc49111808c24bbd25fbbb20f4
  path: components/mdns
url: https://github.com/espressif/esp-protocols/tree/master/components/mdns
version: 1.4.3

コンポーネントが更新されたときは、ビルド時に以下の様に表示されます。
これは、mdnsのコンポーネントとして1.4.2がローカルにインストールされていて、リモートリポジトリには1.5.2が有ることを示してい ます。
Following dependencies have new versions available:
Dependency "espressif/mdns": "1.4.2" -> "1.5.2"
Consider running "idf.py update-dependencies" to update your lock file.
NOTICE: Processing 2 dependencies:
NOTICE: [1/2] espressif/mdns (1.4.2)
NOTICE: [2/2] idf (5.3.2)

リモートリポジトリに更新版が有るときは、以下の手順でコンポーネントを更新することができます。
これで、mdnsのコンポーネントが最新版になります。
$ rm -r managed_components
$ rm dependencies.lock
$ idf.py build

NOTICE: Dependencies lock doesn't exist, solving dependencies.
..NOTICE: Updating lock file at /home/nop/rtos/esp-idf-mirf/mqtt/dependencies.lock
NOTICE: Processing 2 dependencies:
NOTICE: [1/2] espressif/mdns (1.5.2)
NOTICE: [2/2] idf (5.3.2)



Manifest File(idf_component.yml)には以下のようなルールを適用することができます。
rules:
  - if: "idf_version >=3.3,<5.0" # supports all SimpleSpec grammars (https://python-semanticversion.readthedocs.io/en/latest/reference.html#semantic_version.SimpleSpec)
  - if: "target in [esp32, esp32c3]" # supports boolean operator ==, !=, in, not in.

複数のルールを適用する場合、このようになります。
## IDF Component Manager Manifest File
dependencies:
  espressif/esp_tinyusb:
    version: "^1.0.0"
    rules:
      - if: "idf_version >=5.0"
      - if: "target in [esp32s2, esp32s3]"

続く....