WSL2でESP-IDFの環境構築

## 〇はじめに
当初MicropythonによるESP32を扱っていたいましたが, やや機能不足であるため, ESP-IDFに乗り換えようとしました。
しかし, **WindowsのESP-IDFのビルドがやたらと遅い**(最低限のプログラムをコンパイルするにも5分以上はかかる)。MacやLinuxだとこんなことにはならないみたいですが...
したがって今回は, WSL2のUbuntu環境でESP-IDFの環境構築を行っていきます。

ちなみに, 今回はWSL2での環境構築を行いましたが, ビルド時にコア数を多く振り分け素早くビルドするやり方もあるみたいです。参考までに

https://www.reddit.com/r/esp32/comments/8fvy99/advice_boost_espidf_compile_time_on_windows_10/

## 〇環境
・Windows
・WSL2
・Ubuntu20.04 LTS
・ESP32

## 〇手順
まず, ESP-IDFを実行するためだけの新しいディストリビューションを作成した方が良いかと思います。10GB程度の容量を持ってかれると思います。

1. 新しいディストリビューションの作成
1. ESP-IDF on WSL2 の実行環境の構築
1. USBIPによるWSLへのポートの対応づけ
1. udevの適用による一般ユーザでのデバイスの使用

### 1. 新しいディストリビューションの作成
・ディストリビューションの作成
``` コマンドプロンプト.
wsl --install -d <Distribution Name>
```
https://learn.microsoft.com/ja-jp/windows/wsl/install

・一般ユーザの作成
ユーザを作成し, パスワードを設定し, sudoグループに追加してください

https://www-creators.com/archives/241

・既定ディストリビューションを指定&起動時のログインユーザを設定
```コマンドプロンプト.
wsl -s <作成したディストリビューション名> -u <作成したユーザ名>
```
### 2. ESP-IDF on WSL2 の実行環境の構築
ここを参照してください

https://gist.github.com/abobija/2f11d1b2c7cb079bec4df6e2348d969f

>ページ内のここまでは実行できると思います。
>・Build
>idf.py build

その後, flashで接続先の機器にファームウェアを書き込むときに, エラーが出ます
```
Could not open COM ~
```
PCに接続されている機器が**WSL2では認識されていない**のが原因です。
したがって続く作業を行ってください

:::note warn
idf.pyコマンドを実行するためには, ~/.profileが実行されている必要があります
```Ubuntu.
. ~/.profile || true
```
いちいち実行するのは面倒なため, ~/.bash_profileに以下の処理を書き込む必要があります
```~/.bash_profile
# wsl起動時に実行される処理を記述
if [ -f ~/.profile  ]; then
    . ~/.profile || true
fi
```
:::

### 3. USBIPによるWSLへのポートの対応づけ

:::note warn
USBIPDをダウンロードする前にESP-IDFを実行するディストリビューションを既定ディストリビューションに設定しておいてください。
```コマンドプロンプト.
wsl -s <ディストリビューション名>
```
:::

以下のサイトの
"**USBIPD-WIN プロジェクトをインストールする**"に従ってダウンロードしてください

https://learn.microsoft.com/ja-jp/windows/wsl/connect-usb

続いて, "**Linux に USBIP ツールとハードウェア データベースをインストールする**"に従ってください。
実行できない場合は, sudo apt update & apt upgradeやresolv.confでの設定でインターネットに接続されているかを確認してください。

以上が, 完了したらコマンドで, Windows に接続されたすべての USB デバイスの一覧を表示します。
```コマンドプロンプト.
usbipd wsl list
```
今回はBUSID 2-4のCOM6が接続されています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728179/5210b506-161f-c850-b757-b1afa434853e.png)


次に, WSL2に認識させたいデバイスをアタッチします
アタッチするにはWSLが起動している必要があるので一旦起動させてください
```コマンドプロンプト.
usbipd wsl attach --busid <busid>
```
BUSID 2-4がアタッチされてるのが分かります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728179/a7264a81-6f04-5efd-0b61-7c694540780f.png)


ちなみに, デタッチしたい場合は
```
usbipd wsl detach --busid <busid>
```
WSL2にアタッチするとWindowsの方では認識されなくなりますが, wslがシャットダウンすると自動的にデタッチされます

### 4. udevの適用による一般ユーザでのデバイスの使用
一般ユーザが, デバイスを使用するために権限の設定が行われている必要があります。したがってudevを有効化する必要があります

WSLではsystemdが動いていないので
→ udevだけ動かす

・udevのインストール
```Ubuntu.
sudo apt-get install udev
```

・udevの起動
```Ubuntu.
sudo service udev start
```

udevの起動には意図的に1分のスリープが設けられています。その間に実行をキャンセルできる猶予を与えてくれていますが, 待ちたくない人は/etc/init.d/udevを編集してください

以下の"sleep"部分をいじってください。**自己責任でお願いします**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728179/44d61325-35ff-e59c-d1f3-bc54762ec228.png)

・/etc/wsl.confに以下を書き込み, 起動時に実行されるようにする
```/etc/wsl.conf
[boot]
command = "service udev start"
```

次にデバイスが接続されているかを確認
```Ubuntu.
dmesg | grep tty
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728179/d5af0d3f-5d11-5f11-ac71-99a895c9546c.png)

・該当するデバイスを探す(ここではttyUSB0)
```Ubuntu.
ls -l /dev
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728179/87eaba22-b819-2c61-e344-df3285ea3986.png)

・権限と所有グループが表示されていれば大丈夫です

・一般ユーザを該当するグループに追加(ここではdialout)
```Ubuntu.
gpasswd -a <USER名> <GROUP名>
```

これで整いました！

## ESPに書き込む
先ほど作ったhello-worldのディレクトリに移動し, 以下のコマンドを実行

https://gist.github.com/abobija/2f11d1b2c7cb079bec4df6e2348d969f

```/hello-world.
idf.py flash -p /dev/ttyUSB0
```

次に, 実行します
```/hello-world.
idf.py monitor -p /dev/ttyUSB0
```

実行されたら完了です!お疲れ様でした。

## 参考にさせていただいた記事

https://scratchpad.jp/fix-usb-camera-permission-issue-on-wsl2/

https://nikarana03.blogspot.com/2021/04/wsl2gpio_4.html