Spresenseの開発環境をRaspberryPiで作ってみる

# はじめに

ソニーから発売されているSpresenseはGNSSによる位置測位や、ハイレゾオーディオ、
ソニー製イメージセンサを使ったカメラ、そしてLTE接続などに対応した高機能ボードです。

公式から公開されている開発環境はWindows/Linux/macOSですが、Linuxはどうやらx86_64環境だけに対応している模様。
今回はaarch64(ARM 64bit)であるRaspberryPiを使ってSpresenseで遊んでみようと思います。

# 用意するもの

## Spresense
今回はSpresenseメインボードとLTE拡張ボードを使ってみます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/b6e1e86f-c762-0436-2902-bcf686d07799.jpeg" width="50%">
ここで購入しました。
https://www.switch-science.com/catalog/3900/

## RaspberryPi
今回は開発環境をRaspberryPi 4 model Bを使いました。発熱がすごいので金属ケースも追加で買いました。
ここで購入しました。
https://www.switch-science.com/catalog/6370/
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/ac78bb20-6bb5-91cb-d243-a52153091ad5.jpeg" width="50%">

# 接続方法

RaspberryPi 4 model BはほぼほぼPCと同一なので特にこれといった特殊な接続はないです。
RaspberryPi 4 model BのUSBポートにSpresense MainボードのUSBをUSBケーブルで接続するだけです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/43f365ee-dc86-451e-1299-235d3de5424d.jpeg" width="80%">

# RaspberryPiの作業概要

1. RaspberryPiにUbuntuをセットアップ
1. 公式の手順で環境セットアップ
1. SPKツールのビルド
1. 書き込みツールのビルド

# RaspberryPiにUbuntuをセットアップ
@y-tsutsuさんのページを参考にセットアップしました。
[Raspberry Pi 4でUbuntuデスクトップを動かして遊ぶ](https://qiita.com/y-tsutsu/items/b50d44bd70c25279d130)

# 公式の手順で環境セットアップ
まずは公式の手順でセットアップしちゃいます。
公式の手順は[Spresense SDK スタートガイド (CLI 版)](https://developer.sony.com/develop/spresense/docs/sdk_set_up_ja.html)に記載されています。
### ターミナルを開く
すべてはターミナルを開いてから始まります。
`Ctrl` + `Alt` + `t` キーを同時押してサクッと立ち上げます。

![Screenshot.from.2021-12-11.21-18-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/58db85ac-eee5-4d58-ae40-832c781baa9c.png)


### シリアル通信の設定
Spresense MainボードとのUART接続は以下のコマンドを実行すると可能になる。
コマンド実行後RaspberryPiを再起動しないといけないので要注意。
<pre>
$ sudo usermod -a -G dialout $USER
</pre>

### ツールチェーンのインストール
ツールチェーンはスクリプトで一括インストールできる。
スクリプトをダウンロードして、bashで実行するだけのようだ。
内部でsudoを実行しているのでパスワードが1回聞かれます。要注意！
<pre>
$ wget https://raw.githubusercontent.com/sonydevworld/spresense/master/install-tools.sh
$ bash install-tools.sh -r
</pre>

![Screenshot.from.2021-12-11.21-17-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/97cb011b-c3cc-c675-4951-1fdd6aae8bc8.png)

### ツールチェーンの有効化
ツールチェーンの有効化というよりは、ツールチェーンのPATHを設定している模様。

<pre>
$ source ~/spresenseenv/setup
</pre>

#### .bashrc に spresenseenv/setup を追加

毎度このコマンドを実行するのはダルいので以下のコマンドで自動実行されるようにする。
コマンドの中の `>>` は2文字が重要！1文字にしないように要注意！

<pre>
$ echo "source ~/spresenseenv/setup" >> ~/.bashrc
</pre>

### Spresense SDKのダウンロード
Spresense SDKはGithubで公開されているので、`git` コマンドを使ってダウンロードする。

<pre>
$ git clone --recursive https://github.com/sonydevworld/spresense.git
</pre>

![Screenshot.from.2021-12-11.21-29-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/bfe6ee9b-8f35-e2a3-bae3-16c96e410f6c.png)


### ビルドを試してみる

すんなり、ツールチェーンもインストールできてしまった。
もしかしてこのままRaspberryPiでSpresenseをビルドして遊ぶことができちゃう・・？(だとしたらこの記事の意味...)

![Screenshot.from.2021-12-11.21-42-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/60934658-c854-abbd-1d69-62d6e2659070.png)


やはり対応していないようでビルドに失敗する。
ビルドエラーの失敗の要因は以下のメッセージのようだ。どうやらmkspkというツールがx86_64用にコンパイルされている模様。
これをaarch64デコンパイルしてみたらビルド成功するのでは・・？
<pre>
/bin/sh: 1: tools/cxd56/mkspk: Exec format error
</pre>
mkspkを作り直してみよう。

# SPKツールのビルド
ここでは、先ほどビルド失敗した要因のSPKツール(mkspk)をaarch64用にコンパイルして使えるようにしてみる。

mkspkのソースコードは `spresense/nuttx/tools/cxd56` に有ったのでこれをコンパイルしてみる。
<pre>
$ cd spresense/nuttx/tools/cxd56
$ make -f Makefile.host clean
$ make -f Makefile.host
</pre>

試しに実行してみる。

![Screenshot.from.2021-12-11.22-15-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/0c1a14b9-82ec-8698-b730-a6ac6e000afa.png)


おぉ！formatエラーから解放されたようだ！
これを `spresense/sdk/tools/linux/` にコピーすればCleanしても使い続けられるようなので次のコマンドでコピーする。

<pre>
$ cp -a mkspk ../../../sdk/tools/linux/
</pre>

改めてSpresenseをビルドしなおしてみる。

<pre>
$ cd spresense/sdk
$ ./tools/config.py examples/hello
$ make -j
</pre>

![Screenshot.from.2021-12-11.22-18-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/7b779864-c6e9-859b-711d-bdb31d667726.png)


めでたくビルドが通った！
次はビルドした `nuttx.spk` をSpresenseに書き込んでみる。

![Screenshot.from.2021-12-11.22-18-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/e5147265-d706-f5e7-297f-d63ac1385013.png)


おっと、、、書き込みのツールもx86_64用にコンパイルされているようだ。
flash_writerも作り直してみよう。

# 書き込みツールのビルド
ここでは先ほど失敗した `nuttx.spk` の書き込みに使う `flash_writer` をaarch64用にコンパイルしてみる。

`flash_writer` のソースコードは `spresense/sdk/tools/flash_writer` にあるようだ。
この中の　`README.md` によると `pyserial` と `pyinstaller` が必要なので、次のコマンドでサクッとインストール。
<pre>
$ pip install pyserial
$ pip install pyinstaller
</pre>

そして、 `Makefile` も用意されているのでコンパイルも `make` を実行するだけでよいらしい。

<pre>
$ cd spresense/sdk/tools/flash_writer
$ make
</pre>

![Screenshot.from.2021-12-11.22-25-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/ae3a0a12-de60-d230-70f3-5c5580a327e5.png)

無事にコンパイルできたようだ。
試しに、 `nuttx.spk` をSpresenseに書き込んでみる。

<pre>
$ cd spresense/sdk
$ ./tools/flash.sh -c /dev/ttyUSB0 nuttx.spk
</pre>

おぉ！書き込みもできた！

![Screenshot.from.2021-12-11.22-34-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/5055ff8f-aa49-1b49-920b-ba783558a807.png)

続いて試しにSpresenseのターミナルを `minicom` で開いてみる。

<pre>
$ minicom -D /dev/ttyUSB0
</pre>

ビルドしたものでターミナルを開くこともできた！

![Screenshot.from.2021-12-11.22-36-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/1f9c81cb-19e9-7fa3-4ec4-e8be55d97cd7.png)

★minicomで開くときは `Hardware Flow Control` を `No` にしておく必要があるので要注意。

![Screenshot.from.2021-12-11.22-36-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374160/8b0ea8af-18af-c6b3-31d8-f52d2f540802.png)

# 最後に

Spresense SDKの開発環境をWindowsで用意している人は、そのセットアップの複雑さやビルド時間の長さで困っている人も多いと思います。
より安価で準備できるRaspberryPiを使うことでそれが少しでも改善すればうれしいです。

また、今回 `mkspk` や `flash_writer` を再作成する方法を紹介しましたが、これを一発で行えるpatchファイルを作ったので、
是非使ってみてください。

[更新ファイル(spresense-aarch64.tar.bz2)ダウンロード](https://github.com/skz-0614/spresense/releases/download/v2.3.1/spresense-aarch64.tar.bz2)

### 反映方法
<pre>
$ cd spresense/
$ tar xvf spresense-aarch64.tar.bz2
</pre>