Raspberry Pi Pico Version of IchigoJam

Programming Club Networkさまから、IchigoJamのRaspberry Pi Picoバージョンについて、寄稿いただきました。

IchigoJAM P: https://pcn.club/sp/ijp/


軽快な Raspberry Pi Pico 、これで IchigoJam BASIC が動いたら楽しそう!

そこで IchigoJam BASIC を RP2040 に移植!

ブレッドボードで回路を組んで、

Picoにファームウェアを焼いて、

合体!モニタはDVI、キーボードはUSB。

10 LED1:WAIT30:LED0:WAIT30
30 GOTO10

もちろん、Lチカできるし、

かわくだりゲームだって

BASIC で動いちゃう。

ロボットに搭載すれば、

BASICで自在に動かせるよ!

ファームウェアは今夏リリース予定、お楽しみに!

RP1チップをJTAGでデバッグしてみよう

はじめに

こんにちは、tnishinagaです。
今回はRP1のJTAGデバッグ方法を見つけたので、ご紹介します。

注意

本記事ではRP1が想定していない操作を行うため、本内容の実施によりRP1含めRaspberry Pi 5が故障する可能性があります。
十分ご注意の上、実施される際は自己責任のもとでお願いします。

要約

overview in english

RP1とリバースエンジニアリング

RP1はRaspberry Pi 5に搭載されているサウスブリッジ的なチップです。
Pi 5のIOのほぼすべてをこのRP1が担っているため、RP1を自由に制御できればPi5を自由に制御できると言えるのではと勝手に思っています。

このRP1のペリフェラルマニュアルは公開されていますが、中で動いているコードや一部仕様については非公開となっています。
そのため自由に扱うにはリバースエンジニアリングが必要であり、私を含め国内外で数人が取り組んでいるようです。

リバースエンジニアリングでは、人間がコンピューターの状態をなんとかして知る手段の確保が重要です。
その中でもとくにJTAGデバッガーが利用可能になると、プロセッサの制御を自由に行えて大変嬉しいです。
どこかに使えるJTAG端子は生えていないでしょうか?

RP1のJTAGを探す旅

RP1のペリフェラルマニュアルを読んでみると、6ページのFigure2にARM DEBUGと書かれた部分があり、少なくともプロセッサコアからJTAG端子が出ているとわかります。

画像はRP1のペリフェラルマニュアル, pp.6, Figure2より引用

また、特殊電子回路株式会社のなひたふさんの解析結果より、Pi 5のUSB端子の下にあるフレキシブルケーブル用のパターンからRP1のJTAG端子が出ていることが確認されています。

実際に自分も0.5mmピッチのフレキシブルケーブルと端子を購入してJTAGデバッガーとつなげて様子を見てみたところ、Raspberry Pi Trading LtdのTAPが見つかりました。

~/p/t/r/pi5_jtag ❯❯❯ openocd -f interface/ftdi/olimex-arm-usb-tiny-h.cfg -c 'transport select jtag'
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
jtag
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Warn : An adapter speed is not selected in the init scripts. OpenOCD will try to run the adapter at the low speed (100 kHz)
Warn : To remove this warnings and achieve reasonable communication speed with the target, set "adapter speed" or "jtag_rclk" in the init scripts.
Warn : libusb_detach_kernel_driver() failed with LIBUSB_ERROR_ACCESS, trying to continue anyway
Info : clock speed 100 kHz
Warn : There are no enabled taps.  AUTO PROBING MIGHT NOT WORK!!
Info : JTAG tap: auto0.tap tap/device found: 0x20001927 (mfg: 0x493 (Raspberry Pi Trading Ltd), part: 0x0001, ver: 0x2)
Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -irlen 5 -expected-id 0x20001927"
Warn : gdb services need one or more targets defined

これがRP1のCortex-M3コアのTAPと考えてDAPの接続等を試行しましたが、うまくいきませんでした。
Arm Debug Interfaceでは命令ビット長は4または8bitと決められていますが、OpenOCDがAutoProbeで見つけた命令ビット長は5bitなので、合っていません。
よって、Cortex-M3以外の何らかのTAPが見えていると考えられます。

※Arm Debug Interfaceの仕様やデバッグの詳細については手前味噌ですがこちらの資料をご覧ください。

隠しコマンド、発見

TAPID 0x20001927へのDAP接続試行を何度か試していたところ、たまに違うTAPIDが見つかる事がありました。

# 当時のログを再現
Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : JTAG tap: auto1.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -irlen 4 -expected-id 0x4ba00477"
Warn : AUTO auto1.tap - use "jtag newtap auto1 tap -irlen 4 -expected-id 0x4ba00477"

最初はTAPのStateがおかしくなったのかなと思っていたのですが、よく見るとTAP IDのManufacturer ID Code部がArm Ltdとなっています。
もしやと思って出てきたTAPに対しDAPの接続を試したところ、Cortex-M3のDebug Unitが見えました。

そしてさらに調査を行ったところ、以下の操作を行うことでRP1のCortex-M3のTAPが見えるようになることを見つけました。

  • IRに0x1dをセットする
  • DRに0を128bit送る

どうやら隠しコマンドを見つけてしまったようです。
もしかすると他にも似たような隠しコマンドがあるかもしれません。

RP1にJTAG接続する方法

ここでやり方をまとめましょう。

ハードウェアの準備

Raspberry Pi 5のUSB下にあるフレキケーブル端子のパターン、またはテストポイントからJTAGに使う以下の線を引き出してください。
(端子とテストポイントの対応はなひたふさんのブログ記事を参考)

  • TDI : TP53
  • TDO : TP54
  • TCK : TP55
  • TMS : TP56
  • GND : GPIO端子等
  • 3.3V: GPIO端子等

引き出したらJTAGデバッガーと接続します。
私の使用したARM-USB-TINY-Hというデバッガーと接続するための回路図を共有しますので、ARM JTAG 20のピン配置を確認しつつ接続を行ってください。

ARM JTAG 20のピン配置はなひたふさんの解説がわかりやすくてオススメです。

私はつなぎ間違えが怖いので基板を作りました。

隠しコマンドの発行

JTAGデバッガーをつなぎ、OpenOCDを入れたマシンに以下のスクリプトを保存し、実行します。
これで次回のOpenOCD実行時からCortex-M3のTAPが見えるようになります。

# SPDX-License-Identifier: GPL-2.0-or-later
# Toshifumi Nishinaga<tnishinaga.dev@gmail.com>

# rp1_init.cfg
transport select jtag
adapter speed 1

jtag newtap cpu0 cpu -expected-id 0x20001927 -irlen 5

init

pathmove IRSHIFT
irscan cpu0.cpu 0x1d 

pathmove DRSHIFT
drscan cpu0.cpu 8 0
openocd -f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f rp1_init.cfg

Cortex-M3コアへの接続

先ほどと同様に、以下のファイルを作ってからopenocdを実行してください。

# rp1.cfg
# This file is based on target/bcm2711.cfg
# SPDX-License-Identifier: GPL-2.0-or-later
# Toshifumi Nishinaga<tnishinaga.dev@gmail.com>

transport select jtag
adapter speed 100

jtag newtap cpu0 cpu -expected-id 0x4ba00477 -irlen 4
jtag newtap cpu1 cpu -expected-id 0x4ba00477 -irlen 4

dap create cpu0.dap -chain-position cpu0.cpu
dap create cpu1.dap -chain-position cpu1.cpu

# cpu0
target create cpu0.ap mem_ap -dap cpu0.dap -ap-num 0
target create cpu0 cortex_m -dap cpu0.dap -ap-num 0 -dbgbase 0xe000e000
# cpu1
target create cpu1.ap mem_ap -dap cpu1.dap -ap-num 0
target create cpu1 cortex_m -dap cpu1.dap -ap-num 0 -dbgbase 0xe000e000
openocd -f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f rp1.cfg

以下のようなログが出たら成功です。

~/p/t/r/pi5_jtag ❯❯❯ openocd -f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f rp1.cfg
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
3758153728
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Warn : libusb_detach_kernel_driver() failed with LIBUSB_ERROR_ACCESS, trying to continue anyway
Info : clock speed 100 kHz
Info : JTAG tap: cpu0.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : JTAG tap: cpu1.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : [cpu0] Cortex-M3 r2p1 processor detected
Info : [cpu0] target has 6 breakpoints, 4 watchpoints
Info : [cpu1] Cortex-M3 r2p1 processor detected
Info : [cpu1] target has 6 breakpoints, 4 watchpoints
Info : gdb port disabled
Info : starting gdb server for cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Info : gdb port disabled
Info : starting gdb server for cpu1 on 3334
Info : Listening on port 3334 for gdb connections

あとはgdbでTCP 3333や3334番につなぐとRP1を自由に操作できます。

(gdb) tar remote :3334

(gdb) i r
r0             0x676e6f6c          1735290732
r1             0x77207265          1998615141
r2             0x696b726f          1768649327
r3             0x1                 1
r4             0x34                52
r5             0x100029b0          268446128
r6             0x34                52
r7             0x20003990          536885648
r8             0x200057d0          536893392
r9             0x10002010          268443664
r10            0x200057d8          536893400
r11            0x200057d4          536893396
r12            0x0                 0
sp             0x10002980          0x10002980
lr             0x100002dd          268436189
pc             0x100003ae          0x100003ae
xPSR           0x81000000          -2130706432
msp            0x10002980          0x10002980
psp            0x0                 0x0
primask        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0
control        0x0                 0

試しにRP1のcore1に接続してレジスタを眺めたところ、PCがProc Local ISRAMの領域を指している様子が伺えました。

以上です。
Happy Hacking!

Raspberry Pi 5をハードウェアデバッグしてみよう

はじめに

はじめまして。 tnishinagaです。
この度ご縁があって、こちらのブログに寄稿させていただく事になりました。
よろしくお願いいたします。

要約

  • Raspberry Pi 5のハードウェアデバッグはJTAGからSWDを使う方法に変わりました
  • Raspberry Pi Debug ProbeとOpenOCDを使えばハードウェアデバッグできます

BareMetalで遊びたい! Raspberry Pi 5

この度Raspberry Pi 5が日本で発表されました。
ここで私を含めシステムプログラマが気になるのは「Raspberry Pi 5で自作OS開発などのベアメタル開発ができるのか」ではないでしょうか。

早速入手したRaspberry Pi5を用いてハードウェアデバッグ方法について調べてみたので、今回はその方法を共有します。

おことわり

とくに言及がない限り、本内容はすべて「オープンな情報」および「リバースエンジニアリングで得た情報」を用いて調査して書かれています。
Raspberry Pi財団等の公式見解ではないため、誤りがあったり、今後の仕様変更で記載した方法を利用できなくなることがあります。
あらかじめご了承ください。

ハードウェアデバッグの方法

Raspberry Pi 5からのハードウェアデバッグは、Raspberry Pi 4までと比べて以下の点が変わっていました。

  • デバッグインターフェイスがJTAGからSWDに変わった
  • デバッグ用端子が出ている場所が40pin GPIOからUART/デバッグ用コネクタに変わった
    • UARTとハードウェアデバッグ機能は排他
    • Raspberry Pi Debug Probeがあれば簡単に接続可能
  • デバッグ・CTIのアドレスが変わった
    • OpenOCDの設定ファイルに変更が必要

デバッグの仕組みがSWDに変わったので、Raspberry Pi 4まで利用していたJTAGデバッガーは使えなくなりました。
一方、Raspberry Pi Debug Probeは一般的なデバッガーの中では比較的安価ですし、接続もケーブル1本でよくなりました。
そのため、全体的なデバッグの敷居は低くなった印象です。

必要なもの

今回Raspberry Pi 5のデバッグには以下の製品を利用しました。

SWD接続できるデバッガーであれば何でもよいのですが、接続に使うJSTコネクタを用意するのがちょっとだけ大変なので上記Probeの利用をオススメします。

セットアップ

デバッグまでの事前準備として、以下を行います。

  • config.txt の修正
  • Raspberry PiとDebug Probeの接続
  • OpenOCDのインストールと設定ファイルの作成

Raspberry Pi側の準備

Raspberry Pi ImagerなどでRaspberry Pi OS(64bit)をmicroSDカードに書き込んでください。
その後、第1パーティション(Raspberry Pi OS上からは /boot/firmware/ 以下)の config.txt の末尾に以下の行を追記してください。

enable_jtag_gpio=1

この設定を入れることでRaspberry Pi 5のUART端子の機能が起動時にSWDへ変わり、デバッガーをつなげるようになります。

接続

以下の画像を参考に、Raspberry Pi 5のUART端子(HDMI端子の間)とDebug ProbeのSWD端子(右側のDと書かれたほう)をコネクタで繋いでください。

OpenOCDのインストール

Debug Probe制御のためOpenOCDを利用します。
以下を参考にご自身のPCにOpenOCDをインストールしてください。

https://openocd.org/pages/getting-openocd.html

本記事ではOpenOCD 0.12.0を用いて動作を確認しています。
もしうまく動かない場合は、こちらのバージョンを使って動作を確認してください。

設定ファイルの作成

OpenOCDを使ってデバッグを行う際は、デバッグターゲットの設定ファイルが必要です。
ROM infoから得られる情報を用いてRaspberry Pi 5に搭載されているBCM2712用の設定ファイルを作ったので、以下を適当な場所に保存してください。
(OpenOCDに含まれる target/bcm2711.cfg をベースに作成したので、このファイルのライセンスは元ファイルと同じくGPL2.0で提供します)

# bcm2712.cfg
# SPDX-License-Identifier: GPL-2.0-or-later
# OpenOCD target config file
# This file is based on target/bcm2711.cfg
# I have checked that it works with Open On-Chip Debugger 0.12.0 
# using the Raspberry Pi Debug-Probe interface

transport select swd
adapter speed 1000

if { [info exists CHIPNAME] } {
    set  _CHIPNAME $CHIPNAME
} else {
    set  _CHIPNAME bcm2712
}

if { [info exists CHIPCORES] } {
    set _cores $CHIPCORES
} else {
    set _cores 4
}

if { [info exists USE_SMP] } {
    set _USE_SMP $USE_SMP
} else {
    set _USE_SMP 0
}

if { [info exists DAP_TAPID] } {
    set _DAP_TAPID $DAP_TAPID
} else {
    set _DAP_TAPID 0x2ba00477
}

# swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID
swd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

# MEM-AP for direct access
target create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0

# these addresses are obtained from the ROM table via 'dap info 0' command
set _DBGBASE {0x80010000 0x80110000 0x80210000 0x80310000}
set _CTIBASE {0x80020000 0x80120000 0x80220000 0x80320000}

set _smp_command "target smp"

for { set _core 0 } { $_core < $_cores } { incr _core } {
    set _CTINAME $_CHIPNAME.cti$_core
    set _TARGETNAME $_CHIPNAME.cpu$_core

    cti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]
    target create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME

    set _smp_command "$_smp_command $_TARGETNAME"
}

if {$_USE_SMP} {
    eval $_smp_command
}

# default target is cpu0
targets $_CHIPNAME.cpu0

以上で準備は完了です。

ハードウェアデバッグ

ここからは実際にOpenOCDを立ち上げてデバッグを行ってみます。

OpenOCDの起動

さきほど取得したファイル等を用いてOpenOCDを起動し、Raspberry Pi 5に接続します。
Raspberry Pi 5の電源を入れて数秒待った後(※)、以下のコマンドをPC上で実行してください。
(※: 最初しばらくはブートローダーのログ出力のために使われるので、SWD機能に変わるのを待つ必要があります)

openocd -f interface/cmsis-dap.cfg -f bcm2712.cfg

うまく接続ができれば、以下のようなログが出てきます。

~/p/t/r/pi5_jtag ❯❯❯ openocd -f interface/cmsis-dap.cfg -f bcm2712.cfg
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=SERIAL_NUMBER
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: Test domain timer supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : bcm2712.cpu0: hardware has 6 breakpoints, 4 watchpoints
Info : bcm2712.cpu1: hardware has 6 breakpoints, 4 watchpoints
Info : bcm2712.cpu2: hardware has 6 breakpoints, 4 watchpoints
Info : bcm2712.cpu3: hardware has 6 breakpoints, 4 watchpoints
Info : gdb port disabled
Info : starting gdb server for bcm2712.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Info : starting gdb server for bcm2712.cpu1 on 3334
Info : Listening on port 3334 for gdb connections
Info : starting gdb server for bcm2712.cpu2 on 3335
Info : Listening on port 3335 for gdb connections
Info : starting gdb server for bcm2712.cpu3 on 3336
Info : Listening on port 3336 for gdb connections

GDBの接続

OpenOCDが正常に立ち上がった場合、OpenOCDがtelnetとGDBのサーバーを起動します。
このサーバーに各種デバッガーで接続すると、デバッグを行えます。

例としてGDBの接続方法をご紹介します。
aarch64向けのgdb(aarch64-elf-gdbgdb-multiarch)を起動した後、以下のコマンドを実行してOpenOCDのGDBサーバー接続してください。

target remote :3333

あとは自由にデバッグを行えます。
たとえば Ctrl + C を実行してコアをhaltしたあと、i r でレジスタの中身が見られます。

(gdb) i r
x0             0xffffb001f2910000  18446656121143885824
x1             0xffff8001ffac3a70  18446603344805640816
x2             0xffffd0000d4d84c0  18446691297374602432
x3             0xffffd0000d18c008  18446691297371144200
x4             0x1                 1
x5             0xffffd0000d4d1000  18446691297374572544
x6             0x1db3292f5         7972492021
x7             0x0                 0
x8             0xffffd0000d4c3c98  18446691297374518424
x9             0xffffd0000c0df61c  18446691297353659932
x10            0x1a90              6800
x11            0x1ef               495
x12            0x2                 2
x13            0x0                 0
x14            0x1                 1
x15            0x0                 0
x16            0xffffd0000cc076a0  18446691297365358240
x17            0x0                 0
x18            0x0                 0
x19            0x0                 0
x20            0xffffd0000d4d0998  18446691297374570904
x21            0xffffd0000d4d0878  18446691297374570616
x22            0xffffd0000d1b4e38  18446691297371311672
x23            0xffffd0000cf72108  18446691297368940808
x24            0x0                 0
x25            0x0                 0
x26            0xffffd0000d4d84c0  18446691297374602432
x27            0x0                 0
x28            0x12789fc           19368444
x29            0xffffd0000d4c3d40  18446691297374518592
x30            0xffffd0000cc03464  18446691297365341284
sp             0xffffd0000d4c3d40  0xffffd0000d4c3d40
pc             0xffffd0000cc0344c  0xffffd0000cc0344c

おわり

以上でハードウェアデバッグ方法のご紹介を終わります。
この内容がみなさまのお役に立てれば幸いです。

参考資料

Raspberry Pi 5の日本国内販売が開始

Raspberry Pi 5が日本での工事設計認証取得を完了し、本日より日本のRaspberry Pi Approved ResellerであるKSYおよびスイッチサイエンスの2社から販売が開始されました。

https://raspberry-pi.ksyic.com/main/index/pdp.id/1059,1015,1016/

両リセーラーとも、本体以外にもケースやカメラ・ディスプレイケーブルなどのアクセサリーが同時に販売開始されているため、必要に応じて購入すると良いでしょう。

Raspberry Pi 5の各種NVMe SSDボードを試す

あっきぃです。

日本ではRaspberry Pi 5の発売はまだですが、先週末には日本の技適に関する証書PDFがRaspberry Piのポータルにアップロードされ、進捗が見えてきています。残念ながらこのPDFをもって日本で買ったり使ったりして良いことにはなっておらず、製品(またはパッケージ等)にマークと番号が印字されたものが販売開始されて初めて適法に利用できるようになるため、もう少しの辛抱です。

https://pip.raspberrypi.com/categories/894-approvals

さて、今回はRaspberry Pi 5のNVMe SSD用アクセサリーボードの話題。PCI Expressポートを使用したNVMe SSDの接続用アクセサリーボードについて、公式から販売が予告されていますが、まだ発売はされていません。しかし、すでにサードパーティベンダーからはいくつものNVMe SSDの接続用アクセサリーボードが発売されています。何種類か入手して試してみましたので、それぞれの使用感をレポートしていきます。

3種類のボード

今回紹介するのはこちらの3種類です。

各ボードについて、それぞれ詳しく見ていきましょう。

コンパクトながら2280サイズに対応するX1001

GeekwormのX1001は、Pi 5上に搭載するタイプのボードです。GPIO接続は不要かつGPIO部分が空いているため、HATボードの接続等のGPIOポートアクセスが可能です。固定用のネジ穴は3つで、スペーサーをつけると3本足で立つ、少しふしぎな形になります。

NVMe SSDは2230、2242、2260、2280のサイズに対応しますが、SSDの固定のダボは2280で固定になっていて外せないため、写真のように2280サイズ以外のSSDを使う場合には、別のアダプター等に付属している固定ネジが必要になります。また、動作中はACTのLEDランプが点滅します。

HAT形状のHAT Drive! Top

2023年9月末に設立されたばかりという、ポーランドのPineBerry Piが販売するHAT Drive Top!は、HATサイズにまとまったコンパクトなボードです。コンパクトな分、対応するNVMe SSDのサイズは2230、2242のみとなります。通電中の電源ランプとACTランプを搭載しています。

Raspberry Piへの接続は、PCIeケーブルのみでも動作しましたが、GPIOポートに接続するための延長ピンソケットが付属しており、これを使用して他のHATボードなどとセットで搭載することができます。なお、延長ピンソケットの抜き差しは慣れるまでは少し大変な印象でした。

Pi 5の下に配置!NVMe Base

イギリスのPimoroniが販売するNVMe Baseは、先述の2つとは違い、Pi 5の下に搭載するタイプのボードです(ちなみに、Pineberry PiやGeekwormも同様にボトムに配置するタイプのボードがあるようです)。

SSDのサイズはX1001と同じく2230、2242、2260、2280に対応します。SSDの固定は付属のネジとナットを使用して固定します。

ボードの裏面は波紋のような模様が特徴的。また、FPCケーブルのカーブも面白い設計ですね。

組み立てたあとの様子。ボードが下にあるため、Pi 5の全ポートにアクセス可能なのが便利です。一方、SSDの交換については都度ネジを外す必要があるのが、用途によっては面倒に感じるかも知れません。また、公式ケースやPimoroniのPiBowとは組み合わせられないのも惜しいところです。NVMe Baseに対応したPiBowケースの登場に期待したいです。

Raspberry Pi 5でNVMeブートをするための手順

Pi 5でNVMeブートをするには、事前にPi 5のEEPROM上の設定に対してブート順序の変更が必要なため、MicroSDカードでOSを起動して、rpi-eeprom-configコマンドを実行して設定作業を行います。

コマンドを実行するとエディターに設定が表示されるため、以下の2つのパラメータについて設定します。

$ sudo rpi-eeprom-config --edit

[all]
# BOOT_ORDERを変更。fより右に6を含める
BOOT_ORDER=0xf416

# 追記する
PCIE_PROBE=1

BOOT_ORDERパラメータは、6がfよりも右に含まれるように書き換えます。Raspberry Piの起動時には、数字の右側から起動が試行されます。0xf416の場合は、NVMe、MicroSD、USBの順に試して、起動メディアがなければまたNVMeから再試行していきます。各数字の意味の詳細は公式のドキュメントを参照してください。

https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#BOOT_ORDER

PCIE_PROBEパラメータは、次期HAT(おそらくHAT+)の仕様をサポートしないボードのためのパラメーターで、設定するとCM4と同様のPCIe x1検出方法になります。この設定はX1001とNVMe Baseの場合は不要です。HatDrive! Topの場合のみGPIO接続時にパラメータが必要ですが、GPIOに接続しない場合は不要です(今後のHatDrive!の設計変更によってはGPIO接続時でも不要になる可能性があります)。

https://github.com/raspberrypi/rpi-eeprom/releases/tag/v2023.12.06-2712

設定後はファイルを保存して終了し、一度OSを再起動します。再起動後はOSをシャットダウンしておきます。

NVMe SSDへのOSの用意

NVMe SSDにRaspberry Pi OSをインストールするには、作業PCにNVMe SSDを接続するために、USBに変換するためのエククロージャが必要です。Amazon等で販売されているので、1つ用意しておくと良いでしょう。

USB変換を使用してPC等に接続するとUSBストレージとして認識するので、MicroSDカードのときと同様に、Raspberry Pi Imager等を使用してRaspberry Pi OSを書き込みます。

OSを書き込んだ後、再度PCに接続してブートパーティションをマウントし、/boot/config.txtをエディターで開いて、以下の設定をファイルの末尾に追記します。

[all]
dtparam=pciex1
dtparam=pciex1_gen=3

dtparam=pciex1は、PCI Expressの外部コネクターを有効にするためのオプションです(なくても動作しますが一応記述します)。有効化すると、ポートがPCI Express 2.0 x1として利用できるようになります。

しかし、公式にはサポートされていないものの、dtparam=pciex1_gen=3を追加することで、PCI Express 3.0 x1として利用できるように強制できます。ただし、起動できなかったり、不安定になる場合もあるようなので、不具合が生じた場合はこのパラメータと除いてみてください。

起動!

OSが用意できたらボードをPi 5に搭載して起動します。ユーザー会では引き続き電波暗箱を使用しているため、箱にボードを入れての試験となります。基本的にボードに因る性能差異はなかったため、HatDrive! Topで検証した内容を掲載します。PCIe 3.0×1で問題なく利用できたため、SSDの性能をより引き出すことができました。

まずはhdparmを使用したシーケンシャルリードのテスト。800MB/sという、ラズパイらしからぬ性能が出ています。

akkie@nvmepi1:~ $ sudo hdparm -t /dev/nvme0n1

/dev/nvme0n1:
 Timing buffered disk reads: 2454 MB in  3.00 seconds = 817.58 MB/sec

続けてddコマンドでシーケンシャルライトのテスト。こちらも700MB/s弱の性能を叩き出していて、やはりラズパイらしからぬスピードです。

akkie@nvmepi1:~ $ dd if=/dev/zero of=a.zero bs=1M count=10000
10000+0 records in
10000+0 records out
10485760000 bytes (10 GB, 9.8 GiB) copied, 15.0922 s, 695 MB/s

Raspberry Piのストレージをテストしてサイトに掲載するスクリプトを提供しているPi Benchmarksのスクリプトを使用したテスト結果は以下の通り。DDの書き込み方法が異なるためか、あるいは熱による性能低下によるものかは不明ですが、こちらは359MB/sにダウンしてしまいました。ランダムの読み書き性能は150〜200MB/sと、なかなかの数字となりました。

     Category                  Test                      Result     
HDParm                    Disk Read                 798.84 MB/sec            
HDParm                    Cached Disk Read          675.10 MB/sec            
DD                        Disk Write                359 MB/s                 
FIO                       4k random read            126419 IOPS (505679 KB/s)
FIO                       4k random write           59883 IOPS (239532 KB/s) 
IOZone                    4k read                   198011 KB/s              
IOZone                    4k write                  144889 KB/s              
IOZone                    4k random read            57412 KB/s               
IOZone                    4k random write           167898 KB/s              

                          Score: 37236 

まとめ

色々なNVMeボードについて特徴を解説し、実際にボードをRaspberry Pi 5で利用するための手順について解説しました。

公式のNVMe HATボードがまだ登場していませんが、すでにサードパーティベンダーから、今回紹介したような、使い方やNVMe SSDのサイズに応じた様々なボードを選べるようになっているため、お好みで用意してみてはいかがでしょうか。

NVMe SSDを利用することで、MicroSDカードよりも高信頼かつ高速なRaspberry Piの環境が構築できます。サーバー用にRaspberry Pi 5を検討している方は、NVMe SSDの採用も合わせて検討すると良いでしょう。

Raspberry Pi PicoとWIZnetのEthernetモジュールでWebサーバーを立てて謎APIを作って遊ぼう

こんにちは、あっきぃです。この記事はRaspberry Pi Advent Calendar 2023の15日目の記事です。

WIZnetさんからサンプルをいただいたので、今回はそちらを使って少し遊んでみます。レビューのほうは別の方がする予定となっているため、私からはとにかくなんか遊ぶ感じの話題をお届けします。ちなみにいただいたのは以下の3種類(下のHATは2つ)。WIZnetさん、ありがとうございます!

今回遊ぶ内容的にはどれを使用しても同じですが、今回はEthernet HATの方を使用しました。こちらの場合別途Raspberry Pi Picoが必要になりますが、EVB-Picoよりも全長が少し短くなってコンパクトになります。また、EVB-Picoと比べるとボード上の通電LEDがPicoで覆い隠せるため、実運用に投入するとLEDが眩しくて邪魔という問題が緩和できます。まあ、EVB-PicoのEVBはEValuation Boardの略だと思うので、実運用に適しているのかは不明ですが……。

なお、WIZnet製品は、スイッチサイエンスで購入できます。

https://www.switch-science.com/collections/all/cat:%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC%2F%E3%83%96%E3%83%A9%E3%83%B3%E3%83%89_WIZnet

今回はCircuitPythonを使用して、Raspberry Pi Picoが接続されているPCのマウスカーソル操作をWeb API化して、リモート操作できるようにしてみます。

CircuitPythonを使う時、Macユーザーは注意

Macユーザー向けにナウな注意として、現在のmacOS Sonoma(14.2時点で問題は継続中)では、macOSの不具合によって、CircuitPythonを接続してすぐにスクリプトの読み書きをすると、I/Oエラーが発生してデータが破損するなどのおそれがあります。以下のページにあるシェルスクリプトを使用して再マウントすることで問題を回避できます。

https://learn.adafruit.com/welcome-to-circuitpython/troubleshooting#macos-sonoma-14-dot-x-disk-errors-writing-to-circuitpy-3160304

ネットワークに接続する

WIZnetのデバイスを扱うには、adafruit_wiznet5kモジュールを使用します。CircuitPythonのライブラリバンドルに収録されているので、ここからadafruit_winzet5kモジュールをデバイス上のlibディレクトリにコピーして使用します。

WIZnetのデバイスを使ってDHCPでアドレスを取得するまでのコードは、以下のようになります。このコードをデバイス上の/code.pyとして保存します。

import board
import busio
import digitalio
import time
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K

# SPIの初期化
SPI_SCK = board.GP18
SPI_TX = board.GP19
SPI_RX = board.GP16
SPI_CSn = board.GP17
W5500_RSTn = board.GP20
cs = digitalio.DigitalInOut(SPI_CSn)
spi_bus = busio.SPI(SPI_SCK, MOSI=SPI_TX, MISO=SPI_RX)

# デバイスをリセットする
ethernetRst = digitalio.DigitalInOut(W5500_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True

# 接続する
eth = WIZNET5K(spi_bus, cs, is_dhcp=True)
print("MAC Address:", [hex(i) for i in eth.mac_address])
print("My IP address is:", eth.pretty_ip(eth.ip_address))

実行結果は以下の通り。デバイスはMACアドレスは持っていないため、”dead beef feed”になっています。MACアドレスを指定することは可能なため、複数動かすなどの場合には適宜変更すると良さそうです。

code.py output:
MAC Address: ['0xde', '0xad', '0xbe', '0xef', '0xfe', '0xed']
My IP address is: 192.168.29.127

Code done running.

Webサーバーにする

CircuitPythonでWebサーバーを作成するにはadafruit_httpserverモジュールを使うのが簡単です。ただ、WIZnetのボード向けのCircuitPythonにはhashlibモジュールが内蔵されていないため、現在のモジュールのバージョンでは、インポート時にエラーが発生します。そのため、ライブラリバンドルからではなく、Githubリポジトリから最新のコードを取得して、adafruit_httpserver/response.pyにあるimport hashlibの行をコメントアウトする必要があります。この問題は報告をして、現在やり取りをしているところです。 (追記)修正されたようです。リリースもされたため最新のバージョンが使用可能です。

https://github.com/adafruit/Adafruit_CircuitPython_HTTPServer/issues/73

ライブラリの方に一手間が発生してしまいましたが、気を取り直して、上記のIPアドレスを取得するコードに、次のコードを書き加えると、Webサーバーが起動するようになります。

import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket
from adafruit_httpserver import Server, Request, Response

socket.set_interface(eth)
server = Server(socket)

@server.route("/")
def root(request: Request):
    print("GET /")
    return Response(request, "Hello!")

server.serve_forever(str(eth.pretty_ip(eth.ip_address)))

実行時に表示されたIPアドレスにアクセスすると、Hello!の文字が表示されました。

マウスを操作する

個人的にCircuitPythonを気に入っている理由の一つに、USB HIDデバイスとして使えるという点が上げられます。MicroPythonにはないので、私がCircuitPython推しなのはこの一点が大きいです。

USB HIDとして使えるようにするには、adafruit_hidモジュールを使用します。code.pyにコードを書く……前に、以下の内容を記述したboot.pyを用意する必要があります。

import usb_hid

usb_hid.enable((usb_hid.Device.MOUSE,))

Webサーバーが動くようになったcode.pyは一旦リネームして退避しておき、あたらしいcode.pyには以下のコードを用意します。

import time
import usb_hid
from adafruit_hid.mouse import Mouse

mouse = 0
while not mouse:
    try:
        mouse = Mouse(usb_hid.devices)
    except:
        pass
    time.sleep(1)

for i in range(0, 8):
    mouse.move(x=20, y=20)
    time.sleep(0.25)

boot.pyの反映はソフトリセットではできないため、code.pyの保存までできたら、ケーブルを抜き差ししてハードリセットします。(macOS Sonomaユーザーは上に書いた再マウントのWorkaroundを忘れずに!)。

抜き差し直後に、マウスカーソルをよく見ると、右下に少しだけカクカクと移動していきます。hidモジュールはクリックなどの操作ももちろんできるので、マクロ的な操作も作ることができます。

マウス移動をWeb APIにする

WIZnetのデバイス初期化、Webサーバー起動、マウス操作を組み合わせて、マウスカーソル移動をWeb APIにしてみます。

マウス操作のテストコードのうち、import timeとfor文以外をコピーして、退避したWebサーバーのコードをcode.pyにリネームし直し、コピーしたコードをcode.pyの最初の方にでも貼りつけておきます。

/にアクセスしたときは、マウスカーソルを操作するボタンを配置したHTMLを返すように変更します。また、マウスカーソルを上下左右に20px移動するAPIとして、/mouse/up・/mouse/down・/mouse/left・/mouse/rightを作成します。

Hello!を返すためのコードのかたまり(4行)を消して、以下のコードを追加します。

indexhtml = """<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width,initial-scale=1"><meta charset="utf-8"><title>Web mouse cursor API</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script><script>function s(p){fetch(p).then(function(r){return r.text()}).then(function(t){document.getElementById('r').innerText=t;});}</script></head><body><main class="px-3 col-6 mx-auto text-center"><h1 class="mt-2">Web mouse cursor API</h1><div class="container"><div class="row"><button class="btn btn-primary mt-3 mb-3" onclick="s('/mouse/up');">👆</button></div><div class="row d-flex justify-content-between"><button class="btn btn-primary col-5 mt-3 mb-3" onclick="s('/mouse/left');">👈</button><button class="btn btn-primary col-5 mt-3 mb-3" onclick="s('/mouse/right');">👉</button></div><div class="row"><button class="btn btn-primary col-12 mt-3 mb-3" onclick="s('/mouse/down');">👇</button></div></div><div id="r" class="m-3"></div></main></body></html>"""

@server.route("/")
def root(request: Request):
    print("GET /")
    return Response(request, indexhtml, content_type="text/html")

@server.route("/mouse/<direction>")
def move_mouse(request: Request, direction: str):
    print("GET /mouse/%s" % direction)
    if direction == "up":
        mouse.move(x=0, y=-20)
    elif direction == "down":
        mouse.move(x=0, y=20)
    elif direction == "left":
        mouse.move(x=-20, y=0)
    elif direction == "right":
        mouse.move(x=20, y=0)
    else:
        return Response(request, "invalid parameter")
    return Response(request, "moved mouse cursor to %s side" % direction)

マウスの操作APIについては@server.route("/mouse/<direction>")のようにパラメータを変数に取ることができるので、これを活用しました。あとはパラメータに応じてマウスカーソルを移動させて、メッセージを返します。

完成

Web画面を開くと、以下のような画面が表示され、ボタンをクリックするとマウスカーソルが移動します。

スマートフォンなど、デバイスを接続していない別の端末からアクセスして操作するとちょっと楽しいと思います(楽しさの感じ方は人によります!)。

なお、同じネットワーク内にいる他人にアドレスがバレると、いたずらされる可能性があるので、程々に遊んだら片付けるのが安全でしょう。ちなみに私はインターネットに公開してURLをSNSで共有し、10分くらいマウス操作を開放して遊びました。操作している人たちは私のPCのカーソルがどうなっているか見えてもいないのに、なぜかとても楽しそうだったので何よりです。

まとめ

WIZnetのEthernet拡張を使用してWebサーバーを立ち上げて、マウスカーソル移動をWeb API化する例を紹介しました。

Raspberry Pi Picoでネットワーク接続と言えば、現在ではPico Wがあるため、無線LANでいいという考え方もできます。ただ、無線LANが不安定な環境だったり、そもそも無線LANがない環境で使いたい場合などには、やはり有線LANがあると嬉しいですよね。

WIZnetのEthernetモジュールは、ライブラリが揃っていて扱いやすい印象です。今回したCircuitPython以外に、MicroPythonでも使用可能です。難点は、MACアドレスを持っていないので自分で定義が必要な点と、EVB-Picoボードでは通電LEDが目障りになりがちな点でしょうか……。通電LEDは、いざとなればテープや引っ付き虫などで隠してしまっても良さそうです。

今回作成したコードは、諸々整えた状態で以下に公開してあります。

https://github.com/Akkiesoft/akkiesoft-pico/tree/main/CircuitPython/web_mouse

実は、ほぼ同じノリでマクロキーボードAPIというものを以前作っているのですが、こちらで使用していたadafruit_wsgiモジュールでは通信速度が非常に遅く、今回adafruit_httpserverモジュールで書いてみたら高速で転送できるようになったので、マクロキーボードAPIもそのうち書き直したいですね。

Raspberry Pi 5公式ケースが届いたのでレビュー

あっきぃです。

Pimoroniで予約していたケース””だけ””が届きました。PiBowと公式ケースで、いずれもサンプルではなく、いずれRaspberry Pi 5の技適が通った時のために個人用に購入したものです。……私はPi 5を2台買うんだろうか🤔ちなみに、写真のPi 5はサンプルですが。今回は話題的に通電しない済むので技適等は無関係ですね。

PimoroniのPiBowはすでにMaker Faire Tokyo 2023・OSC2023 Tokyo/Fall・Raspberry JAM 2023.10で展示済みですが(が、どれもレポートを書いていないですね……)、公式ケースを自分で触って組み立てたりするのは今回が始めてなので、ゆるりとレポートをしていきます。ちなみにこちらがPiBowの組み立てた様子。公式のActive Coolerを組み合わせる前提の作りで、今回もPimoroniらしい出来栄えですが、組み立て手順が少し複雑になり、下からレイヤー0〜2、Pi 5、レイヤー3、ActiveCooler、レイヤー4の順に重ねるようなりました。

それでは公式ケースについて見ていきましょう。

一周見渡す

まずは外観。電源ポート周りの面はPi 4と比べると、3.5mmプラグを差す場所がなくなり、少しスッキリとしました。LAN・USBの配置はPi 1B+〜Pi 3B+までを彷彿させる配置ですが、他の面が全く違うので互換はありません。

先に互換の話をしておくと、これまでの公式ケースで過去のモデル間で互換性があったものは、実はありません。毎回変わっています。サードパーティの互換は諸説あるかも知れませんが、公式はそう言う感じです。iPhoneも毎回ビミョウに寸法が変わって互換がある回はあまりありませんよね。

ケースを真横から見ると、フタと本体の間に隙間が空いていることがわかります。中にはファンが標準添付されていて、このファンのエアフローとなるためです。

SDカード・LEDランプ側です。Pi 4のケースでは、SDカードを差し込んだまま本体を取り出そうとするとSDカード破損などの可能性がありましたが、Pi 5のケースではそれが改善されており、SDカードを差し込んだままの本体を出し入れ可能です。

また、電源ランプは電源ボタンも兼ねて降り、ここを押すことで電源の入り切りが可能です。便利ですね。

底面。公式ケースで初めて、HATの位置に合わせて穴が開けられました。この穴とボルト・ナットを組み合わせて活用すると、ケースを連結して使うこともできるようです。また、放熱用の穴も今回初の改善ですね。

中を見ていく

上の白いフタを外すと、真ん中の白いカバーと、それにはまる形で取り付けられた、ファン付きの半透明のプレートが現れます。

真ん中のカバーを外すと、赤いボトムに小さい紙袋が挟まるようにして入っています。これにはゴム足と、SoCに貼り付けるヒートシンクが入っています。

ヒートシンクは、Active Coolerと比較するとだいぶささやかなサイズ感ですね。ちなみに、もうお気づきかも知れませんが、ケースを使用するときはActive Coolerは不要です。

Active CoolerをつけたPI 5をケースに入れることも可能ですが、この場合は真ん中の白いカバーとから半透明の部分取り外せば運用可能です。

真ん中の白いカバーと半透明の部分は、ツメで固定されているだけのため、簡単に取り外し可能です。

半透明の部分を取り外すと、HATボードを取り付けたまま真ん中のカバーを取り付けることもできます。以前の公式ケースではHATをつけたままケースに収めることができたりできなかったりしたため、これも嬉しいアップデートの一つといえます。

半透明の部分にはGPIOの穴が開いているため、Booster Header( https://shop.pimoroni.com/products/booster-header )などを使用すれば、ファンとHATボードを同時に取り付けることも可能です。以下は、Booster Headerを1つ使用してHATボードを搭載した様子です。上のフタはできなくなりますが、半透明のパーツのおかげで開放感はなく、ケースとしてまとまっているように見えて良いですね。

本体を入れてみる

上の写真のいくつかではもう入ってしまっていますが、Pi 5本体をケースに入れてみます。と言っても、赤いボトムパーツにPi 5をポンと載せるだけ。簡単です。

ファンは、USB2.0ポートの後ろにファン用のコネクターがあるので、こちらに接続します。

あとはフタを乗せて完成です。簡単ですね。

Pi 5を入れた状態の外観はこちら。おしゃれです。

Pi 4のケースと比べてみると

Pi 5のケースを手に持ってみると「もしかして、大きくなった……?」という気持ちがしたので、Pi 4のケースと並べてみました。たしかに、一回り大きそうですね。

側面から。高さもPi 4のケースより少し高くなったようです。ただ、SDカードをつけたまま着脱可能、HATを載せたままフタ可能、ファンのエアフロー確保など、数々の機能性向上を考えると、少し大きくなってでも必要な設計なのではないかと推察します。

まとめ

Raspberry Pi 5 公式ケースのレビューでした。

今までの公式ケースはGPIOやカメラへのアクセスがイマイチで個人的にはずっとPimoroniのPiBowケースを推してきましたが、Pi 5のケースこそは(?)便利そうな印象を受けたので、両方を買ってみた次第です。

9月にイギリスに行った際には軽く触っていましたが、実際に改めて触ってみても、とても使い勝手が良さそうな印象なので、早く技適取得済みのPi 5をケースに入れて使いたいな……!!と思いましたし、Ltdの中の人がデモをしていたケースのスタックも興味があるので、公式ケースの買い増しももう検討が必要そうです。え、Pi 5を3台も……??

ちなみに、公式ケースはPi 4のときと同じく、グレー/ブラックのカラーもすでに登場していて、Pimoroniなどで予約を受け付けているようです。

オープンソースカンファレンス2023 Tokyo/Fallに出展します

10月21日(土)に開催される、オープンソースカンファレンス2023 Tokyo/Fallに、Japanese Raspberry Pi Users Groupが出展予定です。

基本的にはMaker Faire Tokyo 2023にて展示した内容とほぼ同等ですが、一部違う作例も持ち込み予定です。

また、Raspberry Pi 5本体も展示しますので、この機会にぜひご覧ください。

https://event.ospn.jp/osc2023-fall/

Raspberry JAM Tokyo 2023.10を開催します

Raspberry Pi ユーザーズグループ、及び関係者の皆様、

8月に引き続き10月もギリギリの告知で大変恐縮ですが、24日の夜にミドクラ様のオフィスをお借りしまして、『Experience Raspberry Pi 5』と題してRaspberry Pi 5についてお話をさせていただければと思っております。

また、Raspberry Pi LTD CEO Eben Uptonから日本のユーザー向けのビデオメッセージの紹介も予定しております。

当日はRaspberry Pi 5本体も展示を行う予定です。Maker Faire Tokyo 2023に来れなかった方は、この機会にぜひご覧ください。

なお、セッション後は懇親会とライトニングトークを予定しております。どうぞよろしくお願いいたします。

参加登録について

参加登録はConnpassにて受け付けております。ご参加をお待ちしております。

https://connpass.com/event/298593/

Raspberry Pi 5の電源回りを確かめてみる

あっきぃです。

Raspberry Pi 5が出たら多分騒ぎになるのかな……?と思っていた電源周りが、やはり騒ぎになっているようです。

最小要件が5V/3Aなのはまだ良いのですが、推奨要件(USBとか諸々電気を使う場合)の5V/5AのUSB-C PD電源という点がなかなかのクセモノになりそうです。

5V/5Aに対応したPD電源アダプターは世の中にほぼ存在せず(オフィシャル電源アダプターもカスタムPDOというもので実装しているようです)、USB PD3.1のEPRに沿えば5V/5Aの出力が可能になるように見えます(※)。PDについては私も詳しくなく、検索などで追って徐々に理解している段階です。

※参照元はこちら。ただ、他の記述を見つけられず、本当なのかどうか……?
https://www.graniteriverlabs.com/ja-jp/technical-blog/usb-power-delivery-specification-3-1

とは言え、5V/5Aが必須なわけではなく、あくまで推奨の話だと思いたいですよね。もちろん、USB SSDを接続したり、将来的にリリースされるM.2 HATを搭載したりすれば、5V/5Aが必要なのは想像できますが、一旦置いといて、ここでは最小要件の3Aでどこまで問題なく使用できるかを確認してみたいと思います。合わせて、消費電力や、発熱、サーマルスロットリングや電圧低下の起こり具合についても見ていきます。

構成

前回の性能検証の記事を書いた時点で作ればよかったのですが、ドタバタしていましたので、ここで改めて検証の構成を解説します。

日本では技適の取得が完了していないため、検証を行うには、シールドボックスに投入して電波を十分に減衰させるか、「技適未取得機器を用いた実験等の特例制度」を用いて180日間内で検証する方法があります(※)。ユーザー会では、以前よりスイッチサイエンスさんからお借りしているシールドボックスがありますので、シールドボックスに入れて検証を行っています。

※検証後は廃止手続き(電波の発射を防止するために必要な措置を講じる、つまり電源を入れないようにする。額縁に入れて飾るとかでしょうかね?)が必要です。また、技適取得前に入手したものについては技適マークが無いため、今後技適の取得が完了したとしても利用可能にはならない点にも注意が必要です。基本的には技適の取得が完了して国内リセーラーが発売するまで購入は待ちましょう。

シールドボックス内外の接続は以下の図の通りです。

Raspberry Pi 5をシールドボックスに入れてながら使用するための電源・USB・ネットワークなどの接続図

電源は、市販のUSB-AC電源(Anker 735)と、USB PDに対応したケーブルを使用しました。ボックス外は、ワットモニターに接続して消費電力が計測できるようにします。

ネットワークは、ボックス内でUSB3.0-LAN変換アダプターを使用して接続し、ボックス外に出るためのUSB端子に接続します。ただし、ボックスのUSB端子はUSB2.0のため、性能は480Mbps内に制限されます。ボックス外で、Raspberry Pi 4で作ったネットワークブリッジにUSB接続し、LANに接続可能としています。iperf3での実測は200Mbps程度でしたが、ログインしたりテストに必要なパッケージを取得する程度ならなど十分でしょう。もしGbEのテストをするときは、ボックス内にPi4などを追加で投入してテストすれば対応可能です。

ボックスのもう一つのUSB端子には、Rspberry Pi Debug Probeを接続しています。これを用いることで、OS起動前の情報が取得できますし、OS起動後もシリアル通信でログインして操作することが可能です。

まずは小さいヒートシンクだけでSDカード起動してみる

いままでのRaspberry Piなら許された、適当な小さいヒートシンクと、MicroSDカード(Samsung EVO Plus 64GB)の組み合わせで起動してみます。シールドボックスの様子はこちら(Debug Probeが光っていますが、これは端末からの給電のためで、Raspberry Pi 5にはまだ通電していません)。

シールドボックに、MicroSDカードを挿入したRaspberry Pi 5、USB-LANアダプター、Raspberry Pi Debug Probe、USB-AC電源を入れ、接続を済ませた様子。

シリアル接続しながら通電を開始すると、以下のようなメッセージが表示されます。

RPi: BOOTSYS release VERSION:3094eda5 DATE: 2023/09/21 TIME: 17:58:43
BOOTMODE: 0x06 partition 0 build-ts BUILD_TIMESTAMP=1695315523 serial ******** boardrev d04170 stc *******
AON_RESET: 00000003 PM_RSTS 00001000
RP1_BOOT chip ID: 0x20001927
PM_RSTS: 0x00001000
part 00000000 reset_info 00000000
PMIC reset-event 00000000 rtc 00000004 alarm 00000000 enabled 0
uSD voltage 3.3V
Initialising SDRAM 'Micron' 32Gb x2 total-size: 64 Gbit 4267
DDR 4267 1 0 64 152
RP1_BOOT chip ID: 0x20001927

RP1_BOOT chip ID: 0x20001927
RP1_BOOT: fw size 25968
PCI2 init
PCI2 reset
PCIe scan 00001de4:00000001
RP1_CHIP_INFO 20001927

RPi: BOOTLOADER release VERSION:3094eda5 DATE: 2023/09/21 TIME: 17:58:43
BOOTMODE: 0x06 partition 0 build-ts BUILD_TIMESTAMP=1695315523 serial ******** boardrev d04170 stc *******
AON_RESET: 00000003 PM_RSTS 00001000
 status
USB_PD CONFIG 0 41
Boot mode: SD (01) order f4
SD HOST: 200000000 CTL0: 0x00800f02 BUS: 400000 Hz actual: 390625 HZ div: 512 (256) status: 0x1fff0000 delay: 276
SD HOST: 200000000 CTL0: 0x00800f02 BUS: 400000 Hz actual: 390625 HZ div: 512 (256) status: 0x1fff0000 delay: 276
OCR c0ff8000 [313]
CID: 001b534d454331533530d5186366a166
CSD: 400e00325b590001dd7f7f800a400000
SD: bus-width: 4 spec: 2 SCR: 0xeeeeeefe 0xeeeeefef
SD CMD: 0x333a0010 (51) 0x59b40000 0x1fff0206
Failed to open device: 'sdcard' (cmd 333a0010 status 1fff0206)
Retry SD 1
SD HOST: 200000000 CTL0: 0x00800000 BUS: 400000 Hz actual: 390625 HZ div: 512 (256) status: 0x1fff0000 delay: 276
SD HOST: 200000000 CTL0: 0x00800f00 BUS: 400000 Hz actual: 390625 HZ div: 512 (256) status: 0x1fff0000 delay: 276
OCR c0ff8000 [2]
CID: 001b534d454331533530d5186366a166
CSD: 400e00325b590001dd7f7f800a400000
SD: bus-width: 4 spec: 2 SCR: 0x02058083 0x00000000
SD HOST: 200000000 CTL0: 0x00800f04 BUS: 50000000 Hz actual: 50000000 HZ div: 4 (2) status: 0x1fff0000 delay: 2
MBR: 0x00002000, 1048576 type: 0x0c
MBR: 0x00102000,124116992 type: 0x83
MBR: 0x00000000,       0 type: 0x00
MBR: 0x00000000,       0 type: 0x00
Trying partition: 0
type: 32 lba: 8192 'mkfs.fat' ' bootfs     ' clusters 261116 (4)
rsc 32 fat-sectors 2040 root dir cluster 2 sectors 0 entries 0
FAT32 clusters 261116
[sdcard] autoboot.txt not found
Trying partition: 0
type: 32 lba: 8192 'mkfs.fat' ' bootfs     ' clusters 261116 (4)
rsc 32 fat-sectors 2040 root dir cluster 2 sectors 0 entries 0
FAT32 clusters 261116
Read config.txt bytes     1229 hnd 0xfef7
[sdcard] pieeprom.upd not found
usb_max_current_enable default 0 max-current 3000
Read bcm2712-rpi-5-b.dtb bytes    71797 hnd 0xcb56
dt-match: compatible: raspberrypi,5-model-b match: brcm,bcm2712
dt-match: compatible: brcm,bcm2712 match: brcm,bcm2712
PM_RSTS 00001000
Selecting USB low current limit

Raspberry Pi 5内の各デバイスの初期化に関するメッセージや、ブートデバイスを探して起動しようとするメッセージが見られます。そして最後の「Selecting USB low current limit」が、5V/5A電源を検出できず、USBポートの供給は600mAまでとして起動しますよ、というメッセージですね。

起動中にワットモニターが表示した消費電力は、3〜6Wの範囲でした。

このあとのシリアルの出力はOSに変わり、少しするとOSのログインプロンプトが出力されます。

NOTICE:  BL31: v2.6(release):v2.6-239-g2a9ede0bd
NOTICE:  BL31: Built : 14:26:57, Jun 22 2023
[    0.902716] spi-bcm2835 107d004000.spi: no tx-dma configuration found - not using dma mode

Debian GNU/Linux 12 pios5 ttyAMA10

pios5 login: 

起動が完了したあとの消費電力は3.3W〜3.5Wくらいで安定しました。つまり0.66Aくらいですね。また、しばし放置してから vcgencmd measure_temp コマンドでCPU温度を取得すると56度ほどでした。空気がこもるシールドボックス内での測定のため、通常の室内などではもう少し低く推移する可能性が考えられます。

yes >/dev/null & を4つ投入して、CPUを全部100%にしてみます。消費電力を観察しつつCPU温度も確認したところ、10Wまで消費電力が上昇しますが、CPU温度が85度に達したところで、消費電力が7.5〜8Wくらいまで下がりました。サーマルスロットリングが働いたことがわかります。また、電圧低下も時々発生していました。アイドル時の56度からyesコマンドを実行してサーマルスロットリングが働くまでの時間は、40秒ほどでした。

Alasdair Allan氏(Raspberry Pi Ltdの方)が公開している、スロットルを確認するスクリプトでも、電圧低下・スロットル・周波数のキャッピングが発生したことが確認できました。

https://gist.github.com/aallan/0b03f5dcc65756dde6045c6e96c26459

$ ./throttled.sh 
Status: 0xf0008
Undervolted:
   Now: NO
   Run: YES
Throttled:
   Now: NO
   Run: YES
Frequency Capped:
   Now: NO
   Run: YES

ヒートシンクのみ、SDカードブートの環境では、アイドル時の消費電力3.3W・CPU温度56度、負荷をかけると消費電力10W・CPU温度は最大85度(以降はサーマルスロットリングで温度維持を優先した周波数以下などが発生)となりました。

小さいヒートシンクにファンを加えてSDカード起動

本来はオフィシャルのケースもしくはActive Coolerがあればよかったのですが、あいにくこちらのサンプルは無いため、先述の小さいヒートシンクで対応しています。ここにPimoroniのFan Shimを追加して、ヒートシンクを空冷しながら動かすとどうなるか確かめます。

Pimoroni Fan Shimを接続したRapberry Pi

まずはアイドル状態。ファンの動作が増えるため、消費電力は3.8W前後に変化します。一方、CPU温度は40度前後で安定しました。

続けてyesコマンドで負荷をかけます。1分ほどかけて65度近くまで上昇しますが、その後は上昇が緩やかになります。2分程で電圧低下とスロットルが検知されますが時々瞬間的に起こるだけのようで、周波数のキャップは発生せずに温度上昇を緩やかに続け、最終的に70度で一旦安定しました。消費電力は10W前後を維持していたため、スロットリングによる性能低下は防げていそうです。おそらく、これ以降は続けてもシールドボックス内の温度上昇次第になりそうなので負荷かけは停止しました。

ヒートシンク+ファンと、SDカードブートの環境では、アイドル時の消費電力3.8W・CPU温度40度、負荷をかけると消費電力10W・CPU温度は70度前後となりました。

ヒートシンク+ファンでUSB SSDブート

USB SSDブートにするとどうなるか確かめます。NVMe SSDをUSBに変換するケースに入れたものをUSB3.0ポートに接続して起動します。M.2 HATが発売されたら、USB3.0ではなく直接PCI Expressで接続できるようになりますね。USBとPCIeでの速度の違いを確かめたりするのが楽しみです。

MicroSDの代わりにNVMe SSDをUSB変換したデバイスから起動しようとするRaspberry Pi 5

通電すると、シリアル通信で以下のメッセージが表示されました。

***
USB boot requires high current (5 volt 5 amp) power supply.
To disable this check set usb_max_current_enable=1 in config.txt
or press the power button to temporarily enable usb_max_current_enable
and continue booting.
See https://rptl.io/rpi5-power-supply-info for more information
***

USBブートの場合、3Aのモードでの起動はサポートされないため、以下のいずれかの対応が必要になります。

  • 5V/5Aの電源を接続する(Raspberry Pi 公式の推奨)
  • usb_max_current_enable=1 を /boot/config.txt に投入して無視する
  • 電源ボタンを1回押して、今回だけ無視する

シールドボックスを開けてボタンを押すのはよろしく無いので、一旦電源を切り、config.txtに設定を投入しました。再度起動すると、起動時のメッセージに、以下のようにメッセージが表示され、無理やりUSB SSDブートが開始します。ただ、やはり無理矢理なので、起動時にさっそく電圧低下が表示されてしまいました。

usb_max_current_enable forced to 1
(中略)
[    6.112188] hwmon hwmon2: Undervoltage detected!

Debian GNU/Linux 12 pios5 ttyAMA10

pios5 login: 

起動が終わってアイドル状態の消費電力は5.3Wほどでした。ここでやっと1Aを超えましたね。CPU温度はファン付きのため38.9度前後でした(設定変更などでボックスを開け閉めしたため下がった様子)。

yesコマンドで負荷をかけます。すると、消費電力は先程より低く9W前後、温度上昇もやや緩やかでした。先程のスクリプトを実行すると、電圧低下とスロットルがオンになりっぱなしになっていました。周波数キャップにはなっていないものの、さすがに電圧不足が出たままになってしまうようです。

./throttled.sh 
Status: 0x50005
Undervolted:
   Now: YES
   Run: YES
Throttled:
   Now: YES
   Run: YES
Frequency Capped:
   Now: NO
   Run: NO

yesコマンドを停止すると、電圧低下もスロットルもすぐにオフに変化しました。

5Aを供給していない環境で、警告を無視してUSBブートした環境では、負荷が高い処理をかけると電圧低下になりやすいことがわかりました。

動作自体が極端に不安定になるわけではないですが、aptでパッケージを入れる程度でも電圧低下が発生するため、USB SSDブートをしたい場合は公式の電源(5V/5A電源)が必須と言えそうです。

まとめ

MicroSDカードから起動する場合は、5V/3A出力の電源アダプターでもおおむね問題なく動作しました。

USB SSDから起動する場合は、3Aで無理やり起動すること自体は可能ですが、電圧低下が発生しやすいため、公式の推奨通り公式の電源アダプターが必要そうです。

消費電力は、アイドル時であれば3.3Wなど、それほど気になる消費電力ではありませんでした。また、負荷をかけてもSDカード環境であれば10W(2A)程度などで済むようでした。

また、温度に関しては、ヒートシンクのみであればおそらく60度以下で動作します。むき出しの状態かつ常に手に握りしめながら使うなどしなければおそらく問題はありません。ただ、負荷が大きくかかり続ける環境等では厳しくなる可能性があるため、安定動作させるにはファンがあると安心でしょう。

もちろん、カメラなどのデバイス、GPIOやDSI接続などのディスプレイや、センサーなどのモジュールなどを搭載した場合、また、ソフトウェアでシステムにかかる負荷などによっては、5V3Aでは電圧が不足するなどの可能性が考えられます。これらを考慮すると公式の電源アダプターが必要になる場合も考えられそうです。USBに関しては、セルフパワータイプのハブを使ったらどうなるかなどは検証してみても良いかもしれませんね。

あともうひとつ、Raspberry Pi 4と同様にブートローダーEEPROMイメージをアップデートできる仕組みがあるため、今後の改良次第では電源周りにも挙動の改善が見られる可能性はあるかもしれません。

https://github.com/raspberrypi/rpi-eeprom

公式の電源アダプターと言われても……PSEマークの取得は?

電源アダプターにも技適のように、PSEマークという認証マークが存在します。このマークが無ければ国内での販売はできません。

これまで歴代のRaspberry Piにも公式の電源アダプターが存在しましたが、残念ながらPSEマークを取得したものは存在しません。代わりに、リセーラー各社が独自の電源アダプターを用意、販売してきました。今回こそは公式のものが発売されないとまずそうに見えますが、果たして発売されるでしょうか……?個人的には、ある意味で技適の件よりもどきどきハラハラしながら見守る次第です。