Spresense 開発環境構築 WSL Ver

# Spresense開発環境について
まずSpresenseには2通りの開発方法があります。
1. Arduino IDEでArduino互換として開発する
1. Spresense SDKとIDEを用いて開発する

今回はSpresense SDK+IDEで開発する環境を整えてみたいと思います。
ただし、[スタートガイド](https://developer.sony.com/ja/spresense/development-guides/sdk_set_up_ide_ja.html)を見ればわかるのですが、せっかくWSLでUSBのサポートが始まったのにわざわざ専用ドライバをインストールしているのがもったいないのでそのドライバ無しでやってみたいと思います。


# WSL側の準備
Spresense SDKはwslの場合Ubuntuを想定しているらしいので、まずUbuntu環境から準備します。
次にドライバを使わなくて済むように、WSLとUSB通信ができるようにします。

## WSLとUbuntuのインストール
まず初めにUbuntuをインストールしますが、これは世の中にたくさん記事があるので簡単に済ませます。
ちなみに、WSLをインストールするとデフォルトでUbuntuが入るので以下のコマンドを実行するだけで終了です。
```posh
wsl --install
```
また、usb接続にはWSL 2でありかつ最新でないといけないので注意しましょう。
```posh
# 更新
wsl --update
# wsl 1からwsl 2に変更
wsl --set-version Ubuntu 2
```

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

## USBを使えるようにする
WSLはデフォルトの状態だとUSB通信ができません。そこでms公式のいうとおりにUSBが使えるようにセットアップしていきます。
以下公式ページです。

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

### USBIPD-WIN プロジェクトをインストールする
まずusbを使えるようにすることができるアプリをインストールします。
今回はwingetで入れてみたいとおもいます。公式にはインストーラ(msi)のリンクもあるのでそちらでも構いません。
```posh
winget install --interactive --exact dorssel.usbipd-win
```

### WSLにUSBをアタッチする
上記のアプリを入れただけでは使えず、使用するUSBポートをWSLにアタッチする必要があります。

#### 1. SpresenseがつながっているUSBのBUSIDを調べる
Spresenseをパソコンにつないだうえで、PowerShellを**管理者**モードで開き、以下のコマンドを実行します。
```posh
usbipd list
```
するとこんな感じの結果が出力されるので、「CP2102N USB to UART Bridge Controller」とあるもののBUSIDを控えておきましょう。（ここでは`6-1`）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476116/969708bf-7c79-512d-f7eb-33012c2ce510.png)

#### 2. SpresenseがつながっているUSBの利用をWSLに許可する
今の状態だとWindowsのみにusb接続が固定されているので、WSlでも利用できるようにセットアップします。
上に引き続き管理者モードの状態で以下のコマンドを実行します。
```posh
usbipd bind --busid "先ほど控えたBUSID"
```
このあとで`usbipd list`を実行すると実際に共有可能になっていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476116/2533cb63-f563-5610-a2d9-ada0ce7686d8.png)

#### 3. SpresenseがつながっているUSBをWSLにアタッチする
最後に、USBをWSLにアタッチします。ここからは管理者権限は必要ありません。
Ubuntuを起動して、PowerShellで以下のコマンドを実行するだけです。
```posh
usbipd attach --wsl --busid "1で控えたBUSID"
```
ちなみに、今回は関係ありませんがUSBをアタッチしている間はアタッチされたUSBにWindows側からアクセスできなくなるので、今後USBメモリなどをWSLに接続する際は頭に入れておきましょう。

### Ubuntuでユーザがシリアル通信を読み取れるようにする
WSLで入れたUbuntuのデフォルト設定ではユーザにシリアル通信を読み取る権限がありません。
そこで、以下のコマンドを実行して自分の使うユーザをシリアル通信可能にします。
```bash
sudo usermod -a -G dialout <user-name>
```

# Spresense SDKの準備
ここからはSpresense SDKの準備を行っていきます。
基本は[スタートガイド](https://developer.sony.com/ja/spresense/development-guides/sdk_set_up_ide_ja.html#_linux%E5%90%91%E3%81%91%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97)通りですが、そこそこ手を加えるので注意してください。
## spresenseenvのインストール
ここではLinux向けセットアップ手順2.を行いますが、`install-tools.sh`はWSLかどうかの判定をしてインストールするライブラリ等を変更しているのでこのシェルファイルを変更する必要があります。
### 1. シェルスクリプトをダウンロード
以下のコマンドをたたいて`install-tools.sh`をダウンロードしてください。
```bash
wget https://raw.githubusercontent.com/sonydevworld/spresense/master/install-tools.sh
```

### 2. `install-tools.sh`を編集
次にインストールしたシェルファイルから以下の関数を削除します。
- win_install_tools()
- mac_install_tools()
- wsl_install_tools()
- win_install_toolchain()
- mac_install_toolchain()
- wsl_install_toolchain()
- win_install_openocd()
- mac_install_openocd()
- wsl_install_openocd()

さらに以下のコードを削除してください。
```diff_shell:install-tools.sh(358～361行目)
- if [ "$(grep enabled /proc/sys/fs/binfmt_misc/WSLInterop 2>/dev/null)" = "enabled" ]; then
-    OS="wsl"
- fi
```

```diff_shell:install-tools.sh(397～407行目)
- # On WSL, we need to symbolic links to .exe files and add x permission
- 
- if [ "$OS" = "wsl" ]; then
-     cd ${SPRROOT}/windows/bin
-     for f in *
-     do
-         chmod +x $f 2>/dev/null
-         ln -sf $f $(basename $f .exe) 2>/dev/null
-     done
-     cd - >/dev/null 2>&1
- fi
```

### 3. `install-tools.sh`を実行
ここまでで編集した`install-tools.sh`を実行します。
また、ホームディレクトリで実行するのがよいかと思います。
```bash
bash install-tools.sh
```
最後に、`.bashrc`に以下のコマンドを書き込んだらspresenseenvのインストールは終了です。
```bash
source ~/spresenseenv/setup
```


## Spresense SDKのインストールと改変
ここからはSDKのインストールし、書き換えていきます。

### Spresense SDKのインストール
早速SDKをインストールしていきますが、ただ単にクローンするだけです。
以下のコマンドを実行すればインストールは終了です。
```bash
git clone --recursive https://github.com/sonydevworld/spresense.git
```

### Spresense SDKの改造
インストールツールとフラッシュツールにwsl固有の処理が入っているので変更していきます
#### 1. インストールツール(`install-tools.sh`)の変更
これは名前から察した方がほとんどかと思いますが、先ほどダウンロードしたものになります。
インストールしたSDKのディレクトリ直下（`./spresense/`)にあるので先ほどダウンロードしたもので置換しましょう。

#### 2. フラッシュツール(`flash.sh`)の変更
spresenseにビルドしたデータを書き込むために使われます。必ず修正しましょう。
以下のコードを`flash.sh`から削除してください。
```diff_shell:flash.sh(113～123行目）
- # WSL/WSL2 detection
- if [ "${PLATFORM}" == "linux" ]; then
-	if [ "$(uname -r | grep -i microsoft)" != "" ]; then
-		if [[ "$UART_PORT" == COM* ]]; then
-			# WSL/WSL2 is a linux but USB related SDK tools
-			# should use windows binary.
-			PLATFORM=windows
-			EXEEXT=".exe"
-		fi
-	fi
- fi
```

### ブートローダのインストール
Spresenseのブートローダをインストールします。これがないとSpresenseが動きません。
これに関しては変更することなく動作しているので下記公式サイトの手順通りにやれば問題ないでしょう。

https://developer.sony.com/ja/spresense/development-guides/sdk_set_up_ja.html#_%E3%83%96%E3%83%BC%E3%83%88%E3%83%AD%E3%83%BC%E3%83%80%E3%83%BC%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB


## Spresense IDEのインストールと変更
ここではIDEのインストールと変更を行っていきます。

### Spresense IDEのインストール
Spresense IDEはArduino IDEとは異なり単なるVS Code拡張機能でしかないので拡張機能をインストールします。
インストールについては例によって公式が図付きで解説しているのでそちらを参照ください。以下のリンクから見ることができます。

https://developer.sony.com/ja/spresense/development-guides/sdk_set_up_ide_ja.html#_spresense_%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

### Spresense IDEの変更
ここからが本題です。当然拡張機能にもWSL固有の処理が埋め込まれているので書き換えていきます。
Spresense拡張機能を指示通りWSLにもインストールすると`~/.vscode-server/extensions/sony-spresense.spresense-vscode-ide-1.5.100`に拡張機能がインストールされます。
ここからは編集するファイルの位置を**このフォルダからの相対パスでファイル位置を表す**のでご注意ください。
あと、このフォルダをVS Codeで開いておくと編集しやすいです。

#### ./out/helper.jsの編集
シリアルポート選択やシリアルコンソール起動に必要なバンドルアプリをlinuxに切り替えないといけないので、以下のようにコードを編集しましょう。
```diff_javascript:helper.js(12～14行目）
if (p === 'wsl') {
-    p = 'win32';
+    p = 'linux';
}
```

#### ./out/setting.jsの編集
SDKの設定をWSL固有のものからlinux用に変更すしないといけないので、以下のようにコードを2か所削除またはコメントアウトしましょう。
```diff_javascript:setting.js(206～214行目)
switch (platform) {
    case 'win32':
-   case 'wsl':
        platform = 'windows';
        break;
    case 'darwin':
        platform = 'macos';
        break;
}
```

```diff_javascript:setting.js(206～214行目)
- else if (platform === 'wsl') {
-     // Set windows binary path for Cortex-Debug extension can find the cross gdb and openocd.
-     const p = path.resolve(toolchainPath, '..', '..', 'windows', 'bin');
-     sprEnvConf.update('toolchain.path', toolchainPath, vscode.ConfigurationTarget.Workspace);
-     debugConf.update('armToolchainPath', toolchainPath, vscode.ConfigurationTarget.Workspace);
-     debugConf.update('openocdPath', path.resolve(p, 'openocd'), vscode.ConfigurationTarget.Workspace);
-     sprEnvConf.update('extension.path', path.resolve(context.extensionPath), vscode.ConfigurationTarget.Workspace);
- }
```

# 最後に
以上で環境構築が終わったはずです。お疲れさまでした。
実際に[チュートリアル](https://developer.sony.com/ja/spresense/development-guides/sdk_set_up_ide_ja.html#_%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3_myapps_%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E5%AE%9F%E8%A1%8C)をこなしてみて実際に動作することを確認しましょう！

感想としては、今回の記事が好評でしたらSDKとかIDEにコントリビュートしてみたいですね。
それではありがとうございました。

# 環境
- Windows 11 23H2 (ビルド番号22631.3447)
- WSL バージョン: 2.1.5.0
- linux カーネル バージョン: 5.15.146.1-2
- Ubuntu 22.04.4 LTS