あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

マジカルミライ2020 in TOKYOに行ってきた

金曜日にお休みをいただいて、幕張までマジカルミライ2020の企画展に行ってきました。土日もやってますけど、平日なら空いてて行きやすいかなと思った次第。実際まあまあ空いていたので良かったですね。

f:id:Akkiesoft:20201219224455j:plain

まず海浜幕張駅ニューデイズからミクグッズに釣られるオタク。ポカリスエット2本でマルチクリアケースがもらえます。マスクを入れるのにピッタリでした。

f:id:Akkiesoft:20201219224557j:plain

お出かけに連れ歩いてるいつものミクともうひとりふやしたミクで参戦。しかしガチ勢はデカいふわミクさんたちを抱いて会場を歩いていたりするので、マジミラはぬいを連れ歩いていても普通といったいわば楽園的な場所でした。

f:id:Akkiesoft:20201219224744j:plain

ミクマスク(自作)

f:id:Akkiesoft:20201219224952j:plain

今年の冬バージョンの等身大フィギュア。美しい…。

f:id:Akkiesoft:20201219225015j:plain

ピアプロのボードはホワイトボードペンを置かない代わりに、入場者の配布物がクレヨンになっていて、これで描けるようになってました。描いてきましたで。

f:id:Akkiesoft:20201219225040j:plain

メッセの外でミク。あたらしい子はメルカリでポチポチしてお迎えしたんですけど、足とかグネってたりしていてアレなんですが、これはこれで個性……なんかな?かわいいね。

f:id:Akkiesoft:20201219225150j:plain

1時間半かけて行って、1時間ちょっと見て、また1時間半かけて帰るという、移動のほうが多いお出かけでしたが、久々に電車もガッツリ乗れてよかったですね。帰りは鷺沼で急行に乗り換えたら2139Fが来たので、ミクと撮影しました。

f:id:Akkiesoft:20201219225358j:plain

240px四方の1.3インチLCDで遊ぼうとしたら闇を見た(追記で動いた!)

Raspberry Pi Advent Calendar 2020の18日目です。

adventar.org

今日はいよいよCM4から脱して、こないだ買った240px四方の1.3インチLCDで遊ぼうと思います。

(追記)追記を繰り返したのでTwitterのような動くまでの過程をお楽しみいただける長編になっていますがご容赦ください。

こないだの

12日目に書いた記事でちらっと書いてたやつです。

akkiesoft.hatenablog.jp

Breakout Gardenに差し込める240px四方の1.3インチIPS LCDモジュールです。

1.3" SPI Colour LCD (240x240) Breakout – Pimoroni

写真の右側がモジュールです。なお、このディスプレイはPirate Audioシリーズでも使われています。

f:id:Akkiesoft:20201217223615j:plain

Pythonで使う

これは非常にかんたんで、ここにPimoroniのPythonライブラリが存在するので、適当にインストールしてサンプルを動かすと動きます。

github.com

これは画像を動かすサンプルで、サンプル画像を表示したなんのひねりもない写真です。

f:id:Akkiesoft:20201217223904j:plain

コンソール画面とかでたら便利じゃね、と思って調べたら闇を見た

そう思って調べ始めたら、fbtftとかなんとかが色々でてきて、そういえば昔PiTFTあたりでやってたかな?こう言うの、というところまでは思い出したのですが、どうも今年の途中でLinuxカーネルが5.4に切り替わったあたりでfbtft周りがまともに動かなくなる事象が起きているようです。ディスプレイ系モジュールを販売しているところが順次対応を進めているっぽいですが、わりと最近でも動く動かないをギャーギャーやっているっぽく、これは難易度が高そうです。

いくつか調べると、DeviceTreeをいい感じに差し替えると動いたという話を数件見かけましたが、どちらを試しても私の環境では動かず、みんなどうやって動かしてるんでしょ?状態です。DeviceTreeはなんもわからぬ……。

PirateAudioのディスプレイ部分でやろうとしている人の書き込みは、4.9系で動かせとのこと。いやさすがになあ。うかつにapt upgradeしたらしんじゃうし。

forums.pimoroni.com

Raspberry Piのフォーラムでは2件ほどヒットしたもののこれでも動かず。DRAgon715205という人がここ数日チャレンジしているっぽいのですが、めちゃくちゃマルチポストしていて中の人にたしなめられています……。fbtftのIssueにもいました。気持ちはわかる。

replacement for fbtft "init=" section in 5.4+? - Raspberry Pi Forums

1.54LCD ST7789v fbtft display at kernel 5.4 - Raspberry Pi Forums

Raspberry Piのフォーラムの方はピンアサインがPiTFT向けになっているので、適宜差し替えはしてみましたが、dmesgで見るとなんか初期化に失敗しているのでダメそうでした。Pimoroni方はfb0として見えて入るようですが、画面にはなにもでず。

[    5.507913] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[    5.511267] fb_st7789v: module is from the staging directory, the quality is unknown, you have been warned.
[    5.512061] fbtft_of_value: height = 240
[    5.512079] fbtft_of_value: regwidth = 8
[    5.512096] fbtft_of_value: buswidth = 8
[    5.512118] fbtft_of_value: debug = 0
[    5.512134] fbtft_of_value: rotate = 0
[    5.512153] fbtft_of_value: fps = 25
[    5.512169] fbtft_of_value: txbuflen = 32768
[    5.868243] Console: switching to colour frame buffer device 30x30
[    5.868931] graphics fb0: fb_st7789v frame buffer, 240x240, 112 KiB video memory, 32 KiB buffer memory, fps=25, spi0.0 at 40 MHz

fbiコマンドと言うので画像を直接表示するという方法があったので、試してみましたが特にでず。

07. ラズパイでフレームバッファ #1 :: bitset

pi@usbpi:~ $ sudo LANG=C fbi -d /dev/fb0 -T 1 -a --noverbose --noedit st7789-python/examples/cat.jpg 

ソースコードになにか問題がある可能性はあるのかも?

Adafruitのドライバーに頼ってみる

Adafruitが同じディスプレイモジュールを使ったアイテムを売っており、どうもこちらは対応が進んでいるようなので、この辺のコードをベースに移植するのが近そうです。

www.adafruit.com

www.adafruit.com

リポジトリはこの辺に。

github.com

AfafruitはDC=25,LED=26で、PimoroniはDC=9,LED=13らしいので、DeviceTreeのdtsを書き換えてコンパイルして挑戦。しかし、なんかGPIO9がもう使われているどうとかで怒られる始末。

$dmesg|less

[    5.426689] fb_st7789v: loading out-of-tree module taints kernel.
[    5.427474] pinctrl-bcm2835 fe200000.gpio: pin gpio9 already requested by fe204000.spi; cannot claim for spi0.0
[    5.427493] pinctrl-bcm2835 fe200000.gpio: pin-9 (spi0.0) status -22
[    5.427512] pinctrl-bcm2835 fe200000.gpio: could not request pin 9 (gpio9) from group gpio9  on device pinctrl-bcm2835
[    5.427529] fb_st7789v spi0.0: Error applying setting, reverse things back
[    5.427573] fb_st7789v: probe of spi0.0 failed with error -22

Pimoroniのdtsを眺めていて気づきました。もしかしてfragment@3のこれがpin gpio9 already requestedを回避するやつかな?

	fragment@3 {
		target = <&spi0_pins>;
		__overlay__ {
			brcm,pins = <10 11>; /* exclude BCM 9 from SPI to use it as DC in fbtft driver */
			brcm,function = <4>; /* alt 0 */
		};
	};

あたりでした。

[    5.489767] fb_st7789v: loading out-of-tree module taints kernel.
[    5.490621] fbtft_of_value: width = 240
[    5.490639] fbtft_of_value: height = 240
[    5.490659] fbtft_of_value: buswidth = 8
[    5.490681] fbtft_of_value: debug = 0
[    5.490697] fbtft_of_value: rotate = 0
[    5.492732] ST7789 adafruit fbtft driver
[    5.492747] Size: (240, 240)
[    5.664195] Rotation 0 offsets 0 0
[    5.742520] Console: switching to colour frame buffer device 30x30
[    5.743203] graphics fb0: fb_st7789v frame buffer, 240x240, 112 KiB video memory, 4 KiB buffer memory, fps=20, spi0.0 at 32 MHz

しかしコンソールは表示されず。うーむ!

まとまらない

アレな時期にちっさいディスプレイでコンソールをやりたいと思ってしまったようで、大敗北しました。もしこれやったらうまくいくで、という情報があったらぜひお願いしたいです。ツイッターエゴサはしています。

たまには動かない記事でも……いっか!(適当)

(追記1)バックライトはピンアサインが違う

これはメモですが、バックライトのGPIOピンアサインは、BreakoutGardenとPirateAudioで違いました。BreakoutGardenは場所によってBCM18かBCM19、PirateAudioは上にあるとおりBCM13です。多分ここができてもコンソールがでないところは変わらないですが……。

Breakout Garden for Raspberry Pi (I2C + SPI) – Pimoroni

小さい方はBCM19。

https://shop.pimoroni.com/products/breakout-garden-mini-i2c-spi

なんか他のピンアサインもちょっと違ったりしていないか気になってきたのでもっとコードを読まないとダメそうです。

(追記2)動いた!!

他のピンアサインもちょっと違ったりして

特にCSがPimoroniではCE1(BCM7)を使っているのが気になっていて、パラメータを探っていたのですが、StackOverflowにヒント発見。

Raspberry Pi - SPI device tree changes - Stack Overflow

regがCS(CE)の値だったのかよ!

reg = <0>;  /* CE0 */
(略)
reg = <1>;  /* CE1 */

というわけでregの値を1にした結果、動いた!!

f:id:Akkiesoft:20201218005406j:plain

そうすると、おそらく冒頭のPimoroniのフォーラムにあったDeviceTreeのソースも、regを書き換えたら動きそうな気配です。そのあたりの検証とか、状況を整理して、22日あたりのAdvent Calendarでまとめていきましょう。

Compute Module 4のIOボードについてるRTCをさわる

Raspberry Pi Advent Calendar 2020の17日目です。19日目にまめもさん、21日目にgyaboが入ってくれたので、明日書いたら次回は22日目までゆっくり次のネタを考えられそうです。

adventar.org

いつまで引っ張るんだCompute Module 4ネタと言う感じですが、機能的にはまだ色々あるのでネタもたくさんあります。カメラとかまだつないでないしね。で、今日はRTCモジュールを触ります。

RTC

RTCはReal Time Clockの略で、要するに時計機能です。普通のPCにはRTCがついています(ボタン電池がPCのシステムボードにあるのはこれの時刻を維持するためです)が、Raspberry PiにはRTCが搭載されていないので、インターネット接続なしに起動するとfake-hwclockというサービスが前回のシャットダウンした時間に復元します。

Raspberry Piの初期の頃からI2C接続RTCモジュールなどが販売されていて、それを使えばRaspberry Piでも時刻の維持はできていました。

CM4のIOボードにRTCがついた

何の気まぐれかは不明ですが、Compute Module 4のIOボードにはRTCが実装されています。今までCompute ModuleのIOボードにはなかったので、今回が初です。電池はそこらで普通に買えるCR2032が使えるように電池スロットが用意されています。

f:id:Akkiesoft:20201216193736j:plain

電池の横にあるRTCチップの数字を読み取って検索するとPCF85063Aというものが使われていました。検索ワードに更にRaspberry Pi Compute Module 4を足すと、10日前のフォーラムの記事が出てきました。

www.raspberrypi.org

曰く、中の人がこのチップが採用されたことに気づいておらず、チップのドライバーが現在のカーネルに組み込まれていないので、組み込まれるまでは自分でソースをコンパイルするか、rpi-updateをするか、aptでカーネルが降ってくるまで待ってほしいとのこと。ワロタ。誰も使ってなかったのかよ。

数日前にPCIeデバイスのために実行したrpi-updateで降ってきたカーネルではすでに使えるようになっていたため、この環境で設定をやってみます。

設定する

設定の前に、現在はRTCがないことをtimedatectlコマンドで確認します。RTC timeがn/aになっているのでなさそうですね。

pi@m2ssd:~ $ timedatectl
               Local time: 水 2020-12-16 19:58:01 JST
           Universal time: 水 2020-12-16 10:58:01 UTC
                 RTC time: n/a
                Time zone: Japan (JST, +0900)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no

それでは設定していきます。PCF85063AはI2C接続なので、I2Cを有効にしておきます。

pi@m2ssd:~ $ sudo raspi-config nonint do_i2c 0

/boot/configに設定を追加します。最新のEEPROM(beta版2020-12-11 == stable版2020-12-14)を適用済みなら[cm4]セクションを作ってその中に書くと良いですが、そうでなければ最後の[all]のあとに書いても良いでしょう。おすすめは前者ですかね。

pi@m2ssd:~ $ sudo vi /boot/config.txt 
(ファイルの最後の方に移動して)

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

# ここから
[cm4]
dtparam=i2c_vc=on
dtoverlay=i2c-rtc,pcf85063a,i2c_csi_dsi
# ここまで

[all]
#dtoverlay=vc4-fkms-v3d
#EEPROM適用前ならここにdtparamとdtoverlayの2行をここに書く

設定を書けたら再起動して、再度timedatectlコマンドを実行します。おーRTC timeに時刻が入ってますね。

pi@m2ssd:~ $ timedatectl 
               Local time: 水 2020-12-16 19:56:22 JST
           Universal time: 水 2020-12-16 10:56:22 UTC
                 RTC time: 水 2020-12-16 10:56:23
                Time zone: Japan (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

フォーラムの記事曰く、dmesgでこのあたりを確認するのも良さそうです。

pi@m2ssd:~ $ dmesg | grep rtc
[    8.659511] rtc-pcf85063 10-0051: registered as rtc0

まとめ

Compute Module 4のIOボードについてるRTCを使う方法を紹介しました。

LANに接続されていて、インターネットにアクセスできるか、出られなくてもLAN内にNTPサーバーがあるような環境であれば、RTCがなくてもRaspberry Piが起動する時に自動的に時刻が同期されて問題なく利用できますが、そうでない環境であればRTCは有効な時刻保持手段となります。

とはいえ私も基本的にネットワークに接続して使うので、とりあえず電池を突っ込んではみたもののあまり意味はない感じです。まあ、ついてたのでやってみたかったんです。

まああとは、そんな感じの需要だから、発売後ややしばらく経ってから、実はドライバーがカーネルに含まれてねえという話が出るのかもしれませんが。apt upgradeで降ってくるカーネルにドライバーが含まれるようになるのは数週間後とのことなので、年明けにはカーネル周りの云々をせずとも、すっと設定できるようになっているかと思います。

Raspberry Pi Compute Module 4でPCI Expressデバイスを動かす(10GbE NIC編)

Raspberry Pi Advent Calendar 2020の16日目です。

adventar.org

15日目はtakiponeさんのRaspberry Pi Zero 2台とB+をUSBで繋いでLinuxルーター検証環境でした。私が7日にL2スイッチを作っていたので、これでL3もカバーされましたね!

さて今日はついに!CM4で10GbE NICです。

試すNIC

今回試すのは、自前の10GbEカード「SolarFlare SFN5122F」と会社から借りてきた「Intel X520DA-2」の2枚。結果から言うとSolarFlareのNICが使えて、メジャーなはずのX520は一瞬しかリンクアップせず使えない結果となりました。

(追記)X520は自宅の10GbEスイッチとの相性でリンクしないだけで、動作しました。

カーネルコンパイル

コンパイル作業は例によってCM4ではなくPi4 8GBRAMモデルを使用し、ストレージもUSB SSDUSB3.0接続して爆速でコンパイルしていきます。クロスコンパイル……知らない子ですね。あと、カーネルコンパイル環境の用意の方法はGbE編で紹介済みです。

Raspberry Pi Compute Module 4でPCI Expressデバイスを動かす(GbE NIC編) - あっきぃ日誌

今回は、Raspberry Piカーネルコンパイルのドキュメントに従って、CONFIG_LOCALVERSIONを付け足すようにしました。これとkernel7l.imgのバックアップをやっておけば、なんかミスっても切り戻し可能です。

Kernel building - Raspberry Pi Documentation

pi@usbpi:~/linux $ vi .config

# -pcitestを足した
CONFIG_LOCALVERSION="-v7l-pcitest"

SolarFlareのカーネルオプション

make menuconfigで入ったら、「Device Drivers」→「Network device support」→「Ethernet driver support」 の順に辿り、IntelとSolarFlareのオプションを有効にします。

<M>     Intel(R) 10GbE PCI Express adapters support              
[*]       Intel(R) 10GbE PCI Express adapters HWMON support (NEW)

[*]   Solarflare devices  
<M>     Solarflare SFC9000/SFC9100/EF100-family support               
[*]       Solarflare SFC9000/SFC9100-family MTD support (NEW)         
[*]       Solarflare SFC9000/SFC9100-family hwmon support (NEW)       
[*]       Solarflare SFC9000/SFC9100-family MCDI logging support (NEW)
<M>     Solarflare SFC4000 support                                    
[*]       Solarflare SFC4000 MTD support (NEW)  

あとは保存してコンパイルします。所要時間は1時間くらいでした。

pi@usbpi:~/linux $ make modules_prepare
(必要に応じてscreenなどを張って)
pi@usbpi:~/linux $ make -j 4

コンパイルできたら、成果物をインストールしていきます。モジュールはmakeコマンドで、カーネルイメージとDeviceTree周りはバックアップしつつコピーします。

# モジュール
pi@usbpi:~/linux $ sudo make modules_install

# カーネルイメージ。バックアップは2回目以降は適宜工夫を
pi@usbpi:~/linux $ sudo cp /boot/kernel7l.img /boot/kernel7l.img.bak
pi@usbpi:~/linux $ sudo cp arch/arm/boot/zImage /boot/kernel7l.img

# DeviceTree
pi@usbpi:~/linux $ sudo mv -a /boot/overlays /boot/overlays.bak
pi@usbpi:~/linux $ sudo mkdir /boot/overlays
pi@usbpi:~/linux $ sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
pi@usbpi:~/linux $ sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/

ここまでできたら一旦再起動します。

Solar Flareの10GbE NICを動かす!

ではいよいよ10GbE NICを動かします。一式をつなぎ込んで電源ON!!

f:id:Akkiesoft:20201216123612j:plain

lspci、lsmod、ethtoolの情報は異常なしです。

pi@usbpi:~ $ lspci
00:00.0 PCI bridge: Broadcom Limited Device 2711 (rev 20)
01:00.0 Ethernet controller: Solarflare Communications SFC9020 [Solarstorm]
01:00.1 Ethernet controller: Solarflare Communications SFC9020 [Solarstorm]

pi@usbpi:~ $ lsmod | grep sfc
sfc                   286720  0
mdio                   16384  1 sfc
mtd                    69632  8 ofpart,sfc

pi@usbpi:~ $ ethtool -i eth1
driver: sfc
version: 5.10.0-rc7-v7l-sfc1+
firmware-version: 3.3.2.1000
expansion-rom-version: 
bus-info: 0000:01:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no

IPアドレスが取得できているか確認します。以前はカーネルコンパイル周りの経験値が足りず、DHCPのアドレス取得に失敗したり、取得できていてもうまく疎通できなかったりしましたが、今回は成功しています。きたー!

3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0f:53:**:**:** brd ff:ff:ff:ff:ff:ff
    inet 192.168.29.141/24 brd 192.168.29.255 scope global dynamic noprefixroute eth1
       valid_lft 14390sec preferred_lft 12590sec
    inet6 (略) scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 14390sec preferred_lft 12590sec
    inet6 (略) scope link 
       valid_lft forever preferred_lft forever
4: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 00:0f:53:**:**:** brd ff:ff:ff:ff:ff:ff

X520

先に動かないと書いてしまいましたが、X520の方も動作検証をします。認識の具合は普通でした。

pi@usbpi:~ $ lspci
00:00.0 PCI bridge: Broadcom Limited Device 2711 (rev 20)
01:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
01:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)

pi@usbpi:~ $ lsmod | grep ixgbe
ixgbe                 266240  0

pi@usbpi:~ $ ethtool -i eth1
driver: ixgbe
version: 5.10.0-rc7-v7l-pcitest+
firmware-version: 0x000161ae
expansion-rom-version: 
bus-info: 0000:01:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

ケーブルは繋いでいますが、リンクダウンしています。

pi@usbpi:~ $ ip a
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 90:e2:ba:**:**:** brd ff:ff:ff:ff:ff:ff
4: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 90:e2:ba:**:**:** brd ff:ff:ff:ff:ff:ff

dmesgでケーブルをさしこんだときのログを見ると、すぐにリンクダウンしている様子が確認できました。カードを見ると、LINKとACTのランプが高速で点滅していて、動作が怪しいです。まあ、動作NGと見るのが妥当でしょう。

[  176.263616] ixgbe 0000:01:00.0 eth1: detected SFP+: 3
[  176.421193] ixgbe 0000:01:00.0 eth1: NIC Link is Up 10 Gbps, Flow Control: RX/TX
[  176.421490] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
[  177.422576] ixgbe 0000:01:00.0 eth1: NIC Link is Down

ちなみに、DellのSFP+モジュールを差し込んだらunsupportedと怒られました。

[  564.014629] ixgbe 0000:01:00.0: failed to initialize because an unsupported SFP+ module type was detected.
[  564.014650] ixgbe 0000:01:00.0: Reload the driver after installing a supported module.

このX520カードもDell OEMっぽいシールがはられているんですが……。そう、一点気になるとすれば、そのあたりのOEMによるファームウェアの違いとかがあります。とにかくCM4でこのX520カードはダメでした。いちおう会社に純正のもあるんですが使用中なので、空いたらリトライしたいところです。

追記

Twitterでコメントを もらいました。うちのQNAPのハブQSW-308-1CにはX520と相性問題があるそう。マジか

というわけでつなぎ先をスイッチからラックサーバー×SolarFlareに変えてテストしようとしたら、このタイミングでラックサーバーが死亡こっちはこっちで相性問題が発生して起動せず……。自宅サーバーで稼働中のSolarFlareに差し込んで無事リンクまで確認できました。

iperf3でベンチマーク

X520は動かなかったのでラックサーバーに入ってもらって、これとCM4のSolarFlareとでiperf3で測定します。どちらの10GbENICも直結してIPアドレスを固定した上で測定しました。長ったらしいですが、全部の出力を貼ります。ところでラックサーバーではX520は動きましたね。また、ラックサーバー側はUbuntu Server 20.04です。

f:id:Akkiesoft:20201216202758j:plain
(追記)ベンチマークの様子の写真を貼り忘れてたので貼りました

まずはCM4をサーバーにした方の結果。

pi@usbpi:~ $ iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.0.1, port 57926
[  5] local 192.168.0.2 port 5201 connected to 192.168.0.1 port 57928
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   300 MBytes  2.52 Gbits/sec                  
[  5]   1.00-2.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   2.00-3.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   3.00-4.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   4.00-5.00   sec   313 MBytes  2.63 Gbits/sec                  
[  5]   5.00-6.00   sec   313 MBytes  2.63 Gbits/sec                  
[  5]   6.00-7.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   7.00-8.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   8.00-9.00   sec   313 MBytes  2.63 Gbits/sec                  
[  5]   9.00-10.00  sec   313 MBytes  2.63 Gbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  3.04 GBytes  2.61 Gbits/sec                  receiver

---

akkie@rackme:~$ iperf3 -c 192.168.0.2
Connecting to host 192.168.0.2, port 5201
[  5] local 192.168.0.1 port 57928 connected to 192.168.0.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   306 MBytes  2.57 Gbits/sec    0    724 KBytes       
[  5]   1.00-2.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   2.00-3.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   3.00-4.00   sec   314 MBytes  2.63 Gbits/sec    0    724 KBytes       
[  5]   4.00-5.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   5.00-6.00   sec   314 MBytes  2.63 Gbits/sec    0    724 KBytes       
[  5]   6.00-7.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   7.00-8.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   8.00-9.00   sec   314 MBytes  2.63 Gbits/sec    0    724 KBytes       
[  5]   9.00-10.00  sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  3.05 GBytes  2.62 Gbits/sec    0             sender
[  5]   0.00-10.00  sec  3.04 GBytes  2.61 Gbits/sec                  receiver

iperf Done.

次にラックサーバーをサーバーにした方の結果。

akkie@rackme:~$ iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.0.2, port 34584
[  5] local 192.168.0.1 port 5201 connected to 192.168.0.2 port 34586
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   304 MBytes  2.55 Gbits/sec                  
[  5]   1.00-2.00   sec   322 MBytes  2.70 Gbits/sec                  
[  5]   2.00-3.00   sec   320 MBytes  2.69 Gbits/sec                  
[  5]   3.00-4.00   sec   322 MBytes  2.70 Gbits/sec                  
[  5]   4.00-5.00   sec   321 MBytes  2.70 Gbits/sec                  
[  5]   5.00-6.00   sec   323 MBytes  2.71 Gbits/sec                  
[  5]   6.00-7.00   sec   317 MBytes  2.66 Gbits/sec                  
[  5]   7.00-8.00   sec   321 MBytes  2.69 Gbits/sec                  
[  5]   8.00-9.00   sec   320 MBytes  2.68 Gbits/sec                  
[  5]   9.00-10.00  sec   320 MBytes  2.69 Gbits/sec                  
[  5]  10.00-10.02  sec  5.97 MBytes  2.76 Gbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.02  sec  3.12 GBytes  2.68 Gbits/sec                  receiver

---

pi@usbpi:~ $ iperf3 -c 192.168.0.1
Connecting to host 192.168.0.1, port 5201
[  5] local 192.168.0.2 port 34586 connected to 192.168.0.1 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   312 MBytes  2.62 Gbits/sec    0   1.27 MBytes       
[  5]   1.00-2.00   sec   322 MBytes  2.71 Gbits/sec    0   1.27 MBytes       
[  5]   2.00-3.00   sec   320 MBytes  2.68 Gbits/sec    0   1.27 MBytes       
[  5]   3.00-4.00   sec   322 MBytes  2.71 Gbits/sec    0   1.27 MBytes       
[  5]   4.00-5.00   sec   321 MBytes  2.69 Gbits/sec    0   1.27 MBytes       
[  5]   5.00-6.00   sec   322 MBytes  2.71 Gbits/sec    0   1.27 MBytes       
[  5]   6.00-7.00   sec   318 MBytes  2.66 Gbits/sec    0   1.27 MBytes       
[  5]   7.00-8.00   sec   321 MBytes  2.69 Gbits/sec    0   1.27 MBytes       
[  5]   8.00-9.00   sec   320 MBytes  2.69 Gbits/sec    9   1.27 MBytes       
[  5]   9.00-10.00  sec   320 MBytes  2.68 Gbits/sec    0   1.27 MBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  3.12 GBytes  2.68 Gbits/sec    9             sender
[  5]   0.00-10.02  sec  3.12 GBytes  2.68 Gbits/sec                  receiver

iperf Done.

上記から、大体2.6Gbps、MB単位ではで300MB/sくらい出ることが確認できました。Raspberry Pi4のPCI Expressは2.0 x1規格で理論値は500MB/sくらいのようなので、3/5くらいの性能が出る、ということになります。

また、先日のNVMe SSDの測定結果も270MB/s前後だったことから、なんとなく実測性能は300MB/s前後、と見ることができそうです。

まとめ

Raspberry Pi Compute Module 4で10GbE NICがついに動作させられました。ブログなので動くように手順が整理していますが、手探りしながら動いた瞬間「うおお!!」って叫びました。

測定の結果から、Pi4のUSB3.0ポートに2.5GbE NICでもさしておけば性能的にはOKという見方もできます。ただ、ここにUSB SSDもつないでローカルストレージにすると300MB/sの帯域を奪い合うことになるので、やるならどっちかになりそうな感じです。まあ、SSDですね。

ヤフオクで粘っていればたまに安価にカードが拾えるので、速度よりも男のロマン的に動かしてみるのも良いですね。

さて、このあとはGPUも……と生きたいところですが、こちらはドライバー以前に起動中にカーネルパニックでコケるレベルなので、おそらくブログネタにはできなさそうです。もしかするとCM4のRAMが足りないとか、そっち方面の問題が出てるかなあと想像しているところです。わからないですけどね。ちなみに、x1スロット形状でHDMIが4つ出るGT710カードは使えているという話が財団の中の人から出てるっぽいです。が、そこまでして動かしたいわけでもなく……🤔。

あとは、SolarFlareを動かしている様子の写真に写り込んでいたUSB3.0SATAのコンボカードもあるのですが、これもどうもコンボにするためのスイッチチップが怪しいのかどちらも動作が不安定です。VL805チップなUSB3.0カードはAliExpressでポチポチしたので、届いたらテストしていくつもりですが、これは多分Advent Calendarが終わったあとになりそうです。

Raspberry Pi Compute Module 4でPCI Expressデバイスを動かす(NVMe SSD編)

Raspberry Pi Advent Calendar 2020の14日目です。

adventar.org

今回はCM4でNVMe SSDを動かす話。どうもNVMe SSDはドライバーコンパイルをしなくても動きそうなので、先日のrpi-updateした環境でテストをしてみます。

NVMe SSDの検証には、LenovoのM75q-2についているSSDを使おうと着弾前から企んでいたのですが、いざ到着して開けてみたらまさかの聞いたこともない謎SSDが実装されており、一抹の不安を感じます。写真はM75q-2の記事からの再掲。M75q-1のときは(128GBだからかもですけど)KIOXIAだったのに。Union Memory完全に知らん子ですわ……。

f:id:Akkiesoft:20201212224733j:plain

気を取り直してCM4に接続していきます。変換アダプターはこないだ自宅サーバーのSSD移行をするときに使ったものを使いました。上の空きスロットはM.2 SATA SSDSATAネクターに出すときに使うやつです。

f:id:Akkiesoft:20201213173458j:plain

起動したらlspciを実行し……応答がないと思ったらやべー感じのメッセージが出ました。もうダメそうです。

pi@raspberrypi:~ $ lspci

Message from syslogd@raspberrypi at Dec 13 16:54:19 ...
 kernel:[   50.923847] Internal error: : 1211 [#2] SMP ARM

Message from syslogd@raspberrypi at Dec 13 16:54:19 ...
 kernel:[   50.924746] Process lspci (pid: 551, stack limit = 0x85eeec38)

Message from syslogd@raspberrypi at Dec 13 16:54:19 ...
 kernel:[   50.924769] Stack: (0xc3149dd0 to 0xc314a000)

dmesgでもダメっぽそうな感じのtraceとかが出ていたので、ダメそうです。

[    1.134519] brcm-pcie fd500000.pcie: host bridge /scb/pcie@7d500000 ranges:
[    1.134569] brcm-pcie fd500000.pcie:   No bus range found for /scb/pcie@7d500000, using [bus 00-ff]
[    1.134672] brcm-pcie fd500000.pcie:      MEM 0x0600000000..0x063fffffff -> 0x00c0000000
[    1.134781] brcm-pcie fd500000.pcie:   IB MEM 0x0000000000..0x003fffffff -> 0x0400000000
[    1.195599] brcm-pcie fd500000.pcie: link up, 5.0 GT/s PCIe x1 (SSC)
[    1.195998] brcm-pcie fd500000.pcie: PCI host bridge to bus 0000:00
[    1.196035] pci_bus 0000:00: root bus resource [bus 00-ff]
[    1.196071] pci_bus 0000:00: root bus resource [mem 0x600000000-0x63fffffff] (bus address [0xc0000000-0xffffffff])
[    1.196179] pci 0000:00:00.0: [14e4:2711] type 01 class 0x060400
[    1.196438] pci 0000:00:00.0: PME# supported from D0 D3hot
[    1.199662] PCI: bus0: Fast back to back transfers disabled
[    1.199704] pci 0000:00:00.0: bridge configuration invalid ([bus ff-ff]), reconfiguring
[    1.200000] pci 0000:01:00.0: [1cc4:17ab] type 00 class 0x010802
[    1.200097] pci 0000:01:00.0: reg 0x10: [mem 0x00000000-0x00003fff 64bit]
[    1.200495] pci 0000:01:00.0: PME# supported from D0 D3hot
[    1.200609] pci 0000:01:00.0: 4.000 Gb/s available PCIe bandwidth, limited by 5.0 GT/s PCIe x1 link at 0000:00:00.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)
[    1.203721] PCI: bus1: Fast back to back transfers disabled
[    1.203758] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    1.203851] pci 0000:00:00.0: BAR 8: assigned [mem 0x600000000-0x6000fffff]
[    1.203892] pci 0000:01:00.0: BAR 0: assigned [mem 0x600000000-0x600003fff 64bit]
[    1.203959] pci 0000:00:00.0: PCI bridge to [bus 01]
[    1.203999] pci 0000:00:00.0:   bridge window [mem 0x600000000-0x6000fffff]
[    1.204423] pcieport 0000:00:00.0: enabling device (0140 -> 0142)
[    1.204652] pcieport 0000:00:00.0: PME: Signaling with IRQ 62

(中略)

[    4.279373] nvme nvme0: pci function 0000:01:00.0
[    4.279465] nvme 0000:01:00.0: enabling device (0000 -> 0002)
[    5.467617] 8<--- cut here ---
[    5.467651] Unhandled fault: asynchronous external abort (0x1211) at 0x00000000
[    5.467681] pgd = (ptrval)
[    5.467701] [00000000] *pgd=80000000004003, *pmd=00000000
[    5.467746] Internal error: : 1211 [#1] SMP ARM

10GbEといいUSB3.0カードといい、変換アダプターをつかうカードがことごとくダメなので、疑心暗鬼に陥りかけましたが、先人JeffがNVMe SSDについてもレポートしていました。

The Raspberry Pi Compute Module 4 Review | Jeff Geerling

曰く、「XPG SX6000(ADATA)だと動かなくて、複数アダプターを買って確かめても変なメッセージがでてダメだった。Samsung 970 EVO Plusに変えたら認識した。早いぜヒャッホー!!」とのこと。UnionMemoryのSSDもおそらくこのパターンでは……。

Samsung 970 EVO Plusは自宅サーバーで使用中ですがサーバーは止められないので、メインPCからSamsung 950 PROを取り外すことにしました。MiniITXの自作機だからマザーボードの裏にあって外すのが面倒なんだぞ……!しかも開けたらホコリまみれでついでに大掃除が発生しました。極力配線を外さないように無理やりNVMe SSDを取り外しました。

f:id:Akkiesoft:20201213174614j:plain

というわけでUnionMemoryにはご退場いただいて、Samsung 950 PROでやっていきます。

f:id:Akkiesoft:20201213174725j:plain

CM4に接続。

f:id:Akkiesoft:20201213174917j:plain

起動したらlspciで確認。おっ!ちゃんと結果が出る!

pi@raspberrypi:~ $ lspci
00:00.0 PCI bridge: Broadcom Limited Device 2711 (rev 20)
01:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller (rev 01)

Jeffのレポート曰く、NVMe のドライバーを読み込み直す必要があるみたいなことが書かれていましたが、パーティションが見えているので、読み込みの必要はなさそうでした。rpi-updateでバージョンが変わっているからかもしれません。

pi@raspberrypi:~ $ cat /proc/partitions 
major minor  #blocks  name
(中略)
 179        0   60751872 mmcblk0
 179        1     262144 mmcblk0p1
 179        2   60485632 mmcblk0p2
 259        0  250059096 nvme0n1
 259        1    5242880 nvme0n1p1
 259        2  169869312 nvme0n1p2
 259        3   66463744 nvme0n1p3
 259        4    8479744 nvme0n1p4

fdiskもちゃんと見えてますね。

pi@raspberrypi:~ $ sudo fdisk -l /dev/nvme0n1
Disk /dev/nvme0n1: 238.5 GiB, 256060514304 bytes, 500118192 sectors
Disk model: Samsung SSD 950 PRO 256GB               
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: (略)

Device             Start       End   Sectors  Size Type
/dev/nvme0n1p1      2048  10487807  10485760    5G EFI System
/dev/nvme0n1p2  10487808 350226431 339738624  162G Linux filesystem
/dev/nvme0n1p3 367185920 500113407 132927488 63.4G Microsoft basic data
/dev/nvme0n1p4 350226432 367185919  16959488  8.1G Linux swap

Partition table entries are not in disk order.

このSSDにはUbuntuが入っていてLinuxパーティションがあるのでマウントもしてみました。問題なさそうです!

pi@raspberrypi:~ $ sudo mount /dev/nvme0n1p2 /mnt
pi@raspberrypi:~ $ ls /mnt
bin   cdrom  etc   lib    lib64   media  opt   root  sbin  srv       sys  usr
boot  dev    home  lib32  libx32  mnt    proc  run   snap  swap.img  tmp  var

そしてhdparm。ちょっと不穏なメッセージが出ていますが、計測はできています。CM4のPCIe性能がボトルネックになるので、NVMeとはいえ270MB/s程度しか出せませんが、Raspberry Piで270MB/s出るので、これは早いですね!

pi@raspberrypi:~ $ sudo hdparm -t /dev/nvme0n1

/dev/nvme0n1:
 HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device
 Timing buffered disk reads: 812 MB in  3.00 seconds = 270.36 MB/sec

まとめ

Jeffの言う通り、SamsungのNVMe SSDならCM4で認識させて使うことができました。これでどのSSDも使えなかったら(ブログのネタ的に)どうしようかと思いました。検証用にNVMe SSDがあったほうがいいなと思ったので、メルカリで適当に中古をポチポチしちゃいました。昨日仕事ついでにアキバに寄っていてNVMe SSDを物色しながら買うのをやめていたので、買っておけばよかった……!

ただし、こちらもJeffが言う通り、NVMe SSDをPCIeから直接ブートできないので、ブートに使いたいときは(たぶんVL805の)USB3.0ポートを経由する必要があります。で、USB3.0を経由するなら帯域的にSATA SSDで事足りると思われるので、NVMeほど気合をいれなくてもOKという感じになりそうです。

さて、次は今度こそ10GbE NICの話を書きたいところですが、まだ動かせていないと言うか、コンパイルがうまくできていなくて、ぐぬぬとなっています……。明日のカレンダーはtakiponeさんという方にご参加いただけそうなので、その間にがんばります!