NanoPi Neo3 とは
NanoPi Neo3 は、ミニサイズの CPU ボードです。
以前紹介した
FreeBSD で NanoPi Neo2
NanoPi Neo でFreeBSD (動作編)
といったCPUボードの後継になります。
これらのボードの共通の特徴は
- サイズは極小
- 無線 LAN/Bluetooth 無し
- HDMIのような画面出力も無し
- 有線 LAN 1 Port
- USB 1 Port
宅内の極小サーバの構築などの用途が考えられます。
画面出力がないのでキーボードとディスプレイを繋いで、といったPCやRaspberryPi のような使い方はできません。シリアルコンソールかネットワークからの ssh 接続で操作します。
NEO3の詳細や以前紹介した NEO2との違いは公式サイトを参照してください。
SoCが変わってますが、CPUは同じARM Architecture で、クロック数やコア数も同じです。オンボードのUSB端子がUSB3になっているのが大きな違いでしょうか。またボードのサイズは一回り大きくなっています。給電は micro USB から USB TypeC になっています。
FreeBSD の公式最新配布イメージで動かすには
FreeBSD での動作自体は去年 @mina_im さんが
で確認しています。しかし、動作確認したイメージはかつて作られた拾い物ということでアップデートされていません。できれば download.FreeBSD.org で公開している最新イメージを動かす方法があるといいですね。
で、検索すると The FreeBSD forums(forums.freebsd.org) にやり方が書いてありましたので試してみます。
説明は Linux 環境での説明になってるので FreeBSD 環境用に合わせています。
aarch64 公式最新イメージをダウンロード
上記ページにおいてある ROCK64 のイメージをダウンロードします。
wget https://download.freebsd.org/ftp/snapshots/arm64/aarch64/ISO-IMAGES/14.0/FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20211209-b7c55487ff2-251490.img.xz
これを展開しておきます。
xz -d FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20211209-b7c55487ff2-251490.img.xz
これで FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20211209-b7c55487ff2-251490.imgが展開されます。
ブート用のファイルをダウンロード
ブート用のファイルの入ったDebianパッケージをダウンロードして展開
wget https://mirrors.dotsrc.org/armbian-apt/pool/main/l/linux-u-boot-nanopineo3-current/linux-u-boot-current-nanopineo3_21.02.1_arm64.deb
ar x linux-u-boot-current-nanopineo3_21.02.1_arm64.deb
tar xzvf data.tar.gz
欲しいファイルはこの三つです。
./usr/lib/linux-u-boot-current-nanopineo3_21.02.1_arm64/idbloader.bin
./usr/lib/linux-u-boot-current-nanopineo3_21.02.1_arm64/trust.bin
./usr/lib/linux-u-boot-current-nanopineo3_21.02.1_arm64/uboot.img
dd でブート用ファイルを公式イメージの特定アドレスに書き込む
Forum の書き込みではこんなコマンドを実行しろとなっています(linux 用なので of= の外部ストレージのデバイスノード指定が/dev/sdbになっています)
dd if=idbloader.bin of=/dev/sdb seek=64 conv=notrunc
dd if=uboot.img of=/dev/sdb seek=16384 conv=notrunc
dd if=trust.bin of=/dev/sdb seek=24576 conv=notrunc
このseekで指定されている64 や16384 というアドレスはなんじゃらほい?と思ったら RockChip の都合のようです。
下記の RockChipの wiki に詳細が書かれていました。
こちらの表によると、
- pre-loader の idbloader.bin が 0x40(64)
- その後に実行されるuboot.img が 0x4000(16384)
- idbloader.bin から使われる trust.bin が 0x6000(24576)
にそれぞれ配置しなくてはいけないようです。
Linux環境ではROCK64のイメージをSDに書き込んだ後に書き込んでますが、FreeBSD の私の環境では書き込みエラーとなりました。デバイスに書き込んでからだと制限でうまくいかないようなので、イメージファイルに先に書き込んでからそのイメージを SD に書き込みます。/dev/da0 が SDだとすると(うっかり他の外部ストレージに出力しないように確認してから)。
(イメージファイルにブート用ファイルを位置指定で書き込み)
# dd if=./usr/lib/linux-u-boot-current-nanopineo3_21.02.1_arm64/idbloader.bin of=FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20211209-b7c55487ff2-251490.img seek=0x40 conv=notrunc
# dd if=./usr/lib/linux-u-boot-current-nanopineo3_21.02.1_arm64/uboot.img of=FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20211209-b7c55487ff2-251490.img seek=0x4000 conv=notrunc
# dd if=./usr/lib/linux-u-boot-current-nanopineo3_21.02.1_arm64/trust.bin of=FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20211209-b7c55487ff2-251490.img seek=0x6000 conv=notrunc
(SDに書き込み)
# dd if=FreeBSD-14.0-CURRENT-arm64-aarch64-ROCK64-20211209-b7c55487ff2-251490.img of=/dev/da0 bs=2m
これで NanoPi NEO3 で起動する SD が出来ました。確認しましょう。
給電前にシリアルコンソール確認用 USB-シリアル変換ケーブルを挿して、PCと接続しておきます。
PC側でシリアルのbpsを150000に設定したターミナルソフトを起動しておきます。FreeBSD ならば以下のコマンドです。
# cu -l /dev/cuaU0 -s 150000
そして SD を NanoPi NEO3に挿入してUSB TypeCの給電ケーブルを挿します。
FreeBSD の起動ログがでて、ログインプロンプトが出れば成功です。
loader.conf で dtb を読み込ませる
起動までは出来ましたが、このままだと USB が動きません。
そこで USB ポートを使えるようにしましょう、と言いたいところですが、以下の手順でも USB オンボードの USB3 ポートは結局使えないのです……。
ですがヘッダーピンに接続して使う USB2 外付け端子が使えるようになります。全く使えないよりはマシです。
/boot/loader.conf に以下の記述を追記して、nanopi-r2s の dtb ファイルを起動時に読み込ませるようにします。
rk3328_nanopi_r2s_load="YES"
rk3328_nanopi_r2s_type="dtb"
rk3328_nanopi_r2s_name="rk3328-nanopi-r2s.dtb"
動くデバイス
有線ネットワークは動く
問題なく動きます(dwc0)。DHCP環境ならばLANケーブルに繋いで起動すればすぐにネットワーク接続できます。
USB はオンボードのポート(USB3)は動かない
すでに述べた通りオンボードのUSB3のポートが動きません。
外付けのポート(USB2)は動く
USBポート(USB2)に繋ぐためのヘッダーピンが2ポート分あるので、現状USBを使いたい場合はヘッダーピンから線を伸ばして、外付けのポートを使うしかないです。無線LANドングル(ロジテック LAN-W300N/U25)などの動作を確認しました。
ヘッダーピンから線を伸ばしてUSBポートに接続し、WiFiドングルを挿した状態。
GPIOは動く
ヘッダーピンの GPIO ポートは、コントローラー/dev/gpioc0 〜 /dev/gpioc3 のどれか(ポートによって違うっぽい)で制御し、入力や出力ができました。全部のポートの対応はまだ取れていません。
オンボード LED は /dev/gpioc0 の PA2への出力で点灯制御
オンボードのLEDのうち、緑色のLEDはGPIOで制御出来ます。/dev/gpioc0 の PA2 を0 にすると消灯、1 にすると点灯します。
# gpioctl -f /dev/gpioc0 PA2 1 (点灯)
# gpioctl -f /dev/gpioc0 PA2 0 (消灯)
オンボードスイッチは /dev/gpioc0 の PA0 の入力
NanoPi NEO3 にはユーザーが自由に使えるスイッチがオンボードのヘリについています。
押されているかどうかは /dev/gpioc0 の PA0 の入力値を監視し、0 ならば押されています(論理が反転してます)。
# gpioctl -f /dev/gpioc0 PA0
1 (押されてない)
# gpioctl -f /dev/gpioc0 PA0
0 (押されている)
I2C はまだ未確認
まだ試していません。RaspberryPiとかで確認したコードが動くか確認してみるつもりです。
実演
起動まで
USB 接続の WiFi ドングルでネットワークも設定されています(鼻息が…)。
センサーチェック
障害物センサーの値を GPI で監視し、検知したら GPO でのLED点灯/消灯のトグルと、PCにネットワークで文字列「障害」を nc で投げます(PC 側は nc で待ち受け)。
オンボードスイッチチェック
オンボードのスイッチONで、 オンボードのLEDの点灯/消灯トグルと、PCにネットワークで文字列「switch on」を nc で投げます(PC 側は nc で待ち受け)。
監視用スクリプトはこんな感じ
#!/bin/sh
while true; do
if [ `gpioctl -f /dev/gpioc0 PA0` -eq 0 ] ; then
echo switch on | nc -N 192.168.11.12 9029;
gpioctl -f /dev/gpioc0 -t PA2
fi
if [ `gpioctl -f /dev/gpioc2 PA2` -eq 0 ] ; then
echo 障害 | nc -N 192.168.11.12 9029;
gpioctl -f /dev/gpioc2 -t PB7
fi
sleep 1
done
動かしてはみましたが
USB3 ポートが使えないとちょっとまだ厳しいですなぁ。