Zephyr RTOS の開発環境を VSCode Dev Container で構築

Zephyr RTOS の開発環境を整えた。手元の環境とは切り離したかったが書き込み先のターゲット(基板)とUSBで接続して flash する必要があるため物理的にパソコンは必要となる。

そのため手元のパソコンに Linuxデュアルブートでインストールして環境を構築したのでメモ。ただし Linuxデュアルブート環境を可能な限り既存の Windows とは分離したかったのでその点についてもメモしておく。

つまり本記事は下記の内容を含む。必要な個所のみ参照してOK。

  • Ubuntu インストール、Windowsとの共存
  • Docker、Docker Compose で Zephyr RTOS の開発環境を構築
  • VSCode Dev Container 化

前提

環境は下記を対象

  • Zephyr RTOS の開発環境を既存の環境とは切り離して構築したい
  • 基板への書き込みを伴うのでUSB接続可能なパソコンが物理的に必要(VPSなどではビルドはできても書き込めない、あるいは別に書き込む手段が必要)
  • Linux で構築。ここは今回特に必須ではないが今回は Linux を採用。

最終構成

  • Linux PC
  • Zephyr RTOS の開発環境を Docker で構築
  • VSCode Dev Container 導入

手順

Linux PC の用意(方針)

  • Linux 環境の準備の仕方は特に問わないが、今回は物理的に Linux PC がある状態にしたかったのと、かつ環境を可能な限り既存の Windows とは分離したかったので下記の構成とした
  • ツール RufusUbuntu の ISO ファイルを使ってブータブルUSB(インストーラのUSB)を作成し、次にそのUSBをPCに挿して別のUSBにUbuntuをインストール(インストール先のUSB)
  • ブートローダのインストール先をインストール先のUSBにすることで、Linux USB を挿している場合は Linux が起動、挿していないときは Windows が起動するようにした

Linux PC の用意(手順)

  1. 必要なものの準備

    • Linux PC: Ubuntu をインストールする先のPC(既存の Windows PC)
    • インストール用 USB: Rufus で作成する Ubuntu インストーラ用の USBメモリ(インストールのみ使用するので容量さえ十分であればOK)
    • インストール先 USB: Ubuntu を実際にインストールし、起動ディスクとして使用する USB ドライブ(十分な容量と高速な転送速度を持つUSBメモリを推奨)
    • Ubuntu ISO ファイル: インストールに使用する Ubuntu のディスクイメージファイル。任意のバージョンを公式からダウンロードして準備。
  2. インストールの実施

    • インストール元 USB の作成
      • Windows PC 上で、ダウンロードした Ubuntu ISO ファイルを使ってブータブル USB を作成する
    • Ubuntu のインストール
      • 作成したインストール元 USB を使用して PC を起動し、Ubuntu をインストールする
      • インストール元 USB とインストール先 USB の両方をターゲット PC に挿入し、BIOS/UEFI の設定またはブートメニューからインストール元 USB ドライブから起動するように選択
      • Ubuntuインストーラーを起動してインストールを進める
      • インストール先をインストール先 USB ドライブに指定する
      • 重要:「ブートローダをインストールするデバイス」の選択項目で、必ずインストール先 USB ドライブ自体(例: /dev/sdb など)を選択すること。これにより、Windowsブートローダーに影響を与えない。
  3. 運用の仕方

    • Linux を起動したい場合: インストール先 USB を挿した状態で PC を起動する。PC のブート順設定によっては、USB ドライブからの起動を優先するように設定するか、起動時にBIOSでブートメニューを表示させて USB ドライブを選択する必要がある。
    • Windows を起動したい場合: インストール先 USB を抜いた状態で PC を起動します。通常通り Windows が起動する。

Docker のインストールと設定(方針)

  • Docker および Docker Compose をインストールする
  • この後 Docker 上に Zephyr RTOS の開発環境を構築する
  • ただし LinuxUSBメモリにインストールした場合、USBメモリへの書き込みは比較的遅いことが予想されるので、Disk I/O のパフォーマンス低下を最小限に抑えるために、Windows がインストールされているパソコンのディスク(SSD)を下記の通り活用する

Docker のインストールと設定(手順)

  1. Windows 側で SSD の空き領域を作る(縮小)

    • Windows の「ディスクの管理」で C: ドライブを縮小して「未割り当て領域」を作成
    • BitLocker が有効でも問題なし
    • 未割り当て領域は暗号化されていない
    • この後 Ubuntuext4 にする
  2. Ubuntu に RDP(xrdp)と SSH サーバを導入(必要に応じて)

    • 手順省略
  3. Docker CE をインストール

  4. Docker Compose(v2)の確認

     docker compose version
    
  5. SSD の空き領域に ext4 パーティションを作成

    • GParted を使う(手順省略)
  6. ext4 パーティションUbuntu にマウント

    • マウントポイント作成

        sudo mkdir -p /mnt/ssd-ext4
      
    • マウント

        sudo mount /dev/nvme0n1p5 /mnt/ssd-ext4
      
    • 自動マウント設定(推奨)

        sudo blkid /dev/nvme0n1p5
      
      • 例:

          UUID="abcd-1234-ef56-7890"
        
      • /etc/fstab に追加

          UUID=abcd-1234-ef56-7890  /mnt/ssd-ext4  ext4  defaults  0  2
        
  7. Docker のデータディレクトリを ext4 に移動

    • Docker を停止

        sudo systemctl stop docker.socket
        sudo systemctl stop docker
      
    • データ移動

        sudo mv /var/lib/docker /mnt/ssd-ext4/docker
      
    • シンボリックリンク

        sudo ln -s /mnt/ssd-ext4/docker /var/lib/docker
      
    • Docker 再起動

        sudo systemctl start docker.socket
        sudo systemctl start docker
      

Zephyr RTOS の開発環境を Docker で構築

  1. Zephyr 用 Docker Compose プロジェクトを ext4 上に作成。ここでは例として zephyr-docker というフォルダ名とする。

     cd /mnt/ssd-ext4
     mkdir -p zephyr-docker/workspace
     cd zephyr-docker
    
    • 補足:
      • もし /mnt/ssd-ext4 に書き込み権限がない場合には下記を実施。

          sudo chown -R $USER:$USER /mnt/ssd-ext4
        
  2. docker-compose.yml を作成(常駐型コンテナ)

  3. /mnt/ssd-ext4/zephyr-docker/Dockerfile ファイルを新設

      FROM zephyrprojectrtos/ci
    
      RUN apt update && \
          apt install -y usbutils minicom && \
          apt clean
    
  4. /mnt/ssd-ext4/zephyr-docker/docker-compose.yml ファイルを新設

      version: "3.9"
    
      services:
        zephyr:
          build:
            context: .
            dockerfile: Dockerfile
          container_name: zephyr-dev
          working_dir: /work
          volumes:
            - ./workspace:/work
          tty: true
          stdin_open: true
          command: sleep infinity
          privileged: true
          devices:
            - "/dev/ttyACM0:/dev/ttyACM0"
            - "/dev/bus/usb:/dev/bus/usb"
    
  5. コンテナをバックグラウンドで起動

     docker compose up -d
    

Zephyr RTOS を使用して build と flash を実施(VSCode Dev Containerではない手順)

このあと VSCode + Dev Container での手順を実施するがこの時点で Linux で Docker コンテナ内で Zephyr RTOS を使用したビルドと書き込みが可能になるので手順をメモ、

  1. コンテナをバックグラウンドで起動

    • コンテナ起動

        docker compose up -d
      
    • ホスト側で Zephyr を clone

        cd /mnt/ssd-ext4/zephyr-docker/workspace
        git clone https://github.com/zephyrproject-rtos/zephyr.git
      
  2. コンテナに入って Zephyr プロジェクトを初期化

    • コンテナに入る

        docker exec -it zephyr-dev bash
      
    • コンテナ内で

        west init -l zephyr
        west update
      
  3. west のビルド(コンテナ内)

     west build -b qemu_x86 zephyr/samples/hello_world
     west build -t run
    
  4. 実機書き込み(必要な場合)

     west flash
    

VS Code + Dev Containers で Zephyr 開発環境を構築する手順

  1. 前提:環境
  2. Docker CE / Docker Compose 導入済み
  3. Dockerfile 及び docker-compose.yml で zephyr-dev コンテナを作成(設定)済
    • /mnt/ssd-ext4/zephyr-docker/ にあるとする
  4. zephyr-dev コンテナは docker compose up -d で常駐可能な状態

上記の状態から VS CodeIDE として使えるようにする手順を下記で示す。

  1. 前提:プロジェクトの場所

    • Dockerfile 及び docker-compose.yml を導入した Ubuntu 上の下記が VS Code で開くべきフォルダとなる。例えば下記。

        /mnt/ssd-ext4/zephyr-docker
      
  2. VS Code をインストール(Ubuntu に)

    • VS Code 本体をUbuntu にインストールして使用する場合には実施する
      • 具体的なインストール方法は省略
    • さらに別のパソコンの VS Code から Remote SSH と Dev Containers を組み合わせて接続する場合には Ubuntu 側に VS Code のインストールは不要
  3. VS Code 拡張機能をインストール

    • VS Code を開き、以下をインストールする
      • Dev Containers
  4. Dev Containers 用の設定ファイルを作成

    • プロジェクトディレクトリは下記とする(例)

        /mnt/ssd-ext4/zephyr-docker/
      
    • ここに .devcontainer/ を作成する

        mkdir /mnt/ssd-ext4/zephyr-docker/.devcontainer
      
  5. devcontainer.json を作成する

    • /mnt/ssd-ext4/zephyr-docker/.devcontainer/devcontainer.json ファイルを下記の内容で新設

        {
          "name": "Zephyr Dev",
          "dockerComposeFile": "../docker-compose.yml",
          "service": "zephyr",
          "workspaceFolder": "/work",
          "remoteUser": "root",
      
          "customizations": {
            "vscode": {
              "extensions": [
                "ms-vscode.cpptools",
                "ms-vscode.cmake-tools",
                "ms-vscode.remote-containers"
              ]
            }
          },
      
          "postCreateCommand": "west update"
        }
      
    • メモ
      • workspaceFolder /work は Docker コンテナ内のパス
      • 実体は Ubuntu 上の workspace/
  6. VS Code で Dev Container を開く

    • VS CodeUbuntu 上のプロジェクトを開く

        /mnt/ssd-ext4/zephyr-docker
      
    • 左下の緑のアイコン → 「Reopen in Container」

    • VS Code が自動で下記を実施する

      • docker compose を読み込み
      • zephyr-dev コンテナに接続
      • /work をワークスペースとして開く
      • west update を実行
  7. west build を VS Code から実行する

    • VS Code のターミナルで下記を実施。これは実際にはコンテナ内で実行されることになる。

        west build -b qemu_x86 zephyr/samples/hello_world
      
    • 例:

        west build -b nucleo_l476rg --shield x_nucleo_idb05a1 zephyr/samples/hello_world
        west build -b nucleo_l476rg --shield x_nucleo_idb05a1 zephyr/samples/basic/blinky
        west build -b nucleo_l476rg --shield x_nucleo_idb05a1 ./zephyr/samples/bluetooth/direct_adv
      
        west build -b esp32_devkitc_wroom/esp32/procpu zephyr/samples/hello_world
      
  8. 実機書き込み(USB デバイスがコンテナ内で認識されている状態)

    • VS Code のターミナルで下記を実施

        west flash
      
    • openOCD 経由で書き込みの場合は下記

        west flash --runner openocd
      
    • USB デバイスの認識方法の確認の仕方

      • USB デバイスがホスト側で認識しているかの確認

          lsusb
          ls -l /dev/ttyACM*
        
      • docker-compose.yml に設定されている USB デバイスが合致しているかを確認すること

          services:
            zephyr:
              privileged: true
              devices:
                - "/dev/ttyACM0:/dev/ttyACM0"
                - "/dev/bus/usb:/dev/bus/usb"
        
  9. 実機の Zephyr Console ログの確認方法

     minicom -D /dev/ttyACM0 -b 115200
    
  10. コンテナを停止したいとき

   docker compose down