こんにちは、satoです。
いま、こんな感じでRaspberry Pi MouseにJetson Nanoを載せて新しいことができないかなーと試行錯誤中です。試行錯誤の過程でデフォルトでは無効になっているSPI(SPI1)を有効にする必要がありましたので、今回はJetson NanoをにインストールしているUbuntuのデバイスツリーを編集してSPIを有効にする方法をご紹介します。
JetBotとアールティのラズパイマウスのベースロボットの組み合わせJetson Nano Mouse(仮称)?
— Y.Nakagawa (@ykknkgw) 2019年4月4日
さて、デバドラ書くか。#JetBot pic.twitter.com/Au7h8O57u4
注意点
今回ご紹介する方法は、2019年5月16日現在、公式のドキュメントには書かれていない内容です。手元のJetson Nanoでは動作確認をしていますが、このページ内で紹介する方法については責任を負いかねます。またJetson NanoにはL4T(Linux for Tegra) R32.1があらかじめインストールしてあり、起動できるようになっている前提で説明します。
作業手順
以下の手順に沿って作業を進めていきます。
- SPIが有効になっているか確認
- SPI用のカーネルモジュールである
spidev
がロードできる状態か確認 - デバイスツリーの再構築
必要なもの
SPIを有効にするには以下のものが必要です。
- Jetson Nano
- microSDカード
- Jetson Nanoの起動用に用います
- 以下のどちらのイメージでも問題ありません
- NVIDIA SDK MANAGER(https://docs.nvidia.com/sdk-manager/index.html)を用いて書き込むL4T R32.1
- Getting Startedのページに公開されている(https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-devkit#write)L4T R32.1のイメージ
- NVIDIA SDK MANAGER(https://docs.nvidia.com/sdk-manager/index.html)を用いて書き込むL4T R32.1
- Ubuntuがインストールされた作業用PC
- 仮想マシンではうまくいかない場合があるようです
- 空き容量が最低でも5GB以上必要そうです
- microUSBケーブル
- PCとJetson Nanoを接続するために用います
- 2.1mmプラグ出力のDC 5V電源
- Jetson Nanoへの電源供給に用います
- ジャンパピン x2
- Jetson Nanoのピンをショートしてリカバリーモードに設定するのに用います
- HDMI接続可能なディスプレイ
- HDMIケーブル
- キーボード
SPIが有効になっているかの確認
まずはじめに、SPIが有効になっているか(デフォルトでは無効になっているようです)を確認します。Jetson Nano上で作業します。
端末を開き、sudo cat /sys/kernel/debug/tegra_gpio
を実行することでJetson Nanoのalternate special functionの状態を確認できます。以下のようにC
の列が1f
になっているとSPIは有効になっていないことがわかります(https://elinux.org/Jetson/TX1_SPI)。
$ sudo cat /sys/kernel/debug/tegra_gpio
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
A: 0:0 64 40 40 04 00 00 000000
B: 0:1 f0 00 00 00 00 00 000000
C: 0:2 1f 00 00 00 00 00 000000
D: 0:3 00 00 00 00 00 00 000000
E: 1:0 40 00 00 00 00 00 000000
F: 1:1 00 00 00 00 00 00 000000
G: 1:2 0c 00 00 04 00 00 000000
H: 1:3 fd 99 00 60 00 00 000000
I: 2:0 07 05 00 02 00 00 000000
J: 2:1 f0 00 00 00 00 00 000000
K: 2:2 00 00 00 00 00 00 000000
L: 2:3 00 00 00 00 00 00 000000
M: 3:0 00 00 00 00 00 00 000000
N: 3:1 00 00 00 00 00 00 000000
O: 3:2 00 00 00 00 00 00 000000
P: 3:3 00 00 00 00 00 00 000000
Q: 4:0 00 00 00 00 00 00 000000
R: 4:1 00 00 00 00 00 00 000000
S: 4:2 a0 80 00 00 00 00 000000
T: 4:3 01 01 00 00 00 00 000000
U: 5:0 00 00 00 00 00 00 000000
V: 5:1 03 00 00 02 00 00 000000
W: 5:2 00 00 00 00 00 00 000000
X: 5:3 78 08 08 70 00 60 606000
Y: 6:0 06 00 00 02 00 00 000000
Z: 6:1 0f 08 08 04 00 06 020600
AA: 6:2 00 00 00 00 00 00 000000
BB: 6:3 01 00 00 00 00 00 000000
CC: 7:0 12 00 00 10 00 12 121200
DD: 7:1 01 00 00 00 00 00 000000
EE: 7:2 00 00 00 00 00 00 000000
FF: 7:3 00 00 00 00 00 00 000000
SPIが有効になっていると以下ようにC
の列が00
の結果を取得できます。
$ sudo cat /sys/kernel/debug/tegra_gpio
Name:Bank:Port CNF OE OUT IN INT_STA INT_ENB INT_LVL
A: 0:0 64 40 40 04 00 00 000000
B: 0:1 f0 00 00 00 00 00 000000
C: 0:2 00 00 00 00 00 00 000000
D: 0:3 00 00 00 00 00 00 000000
E: 1:0 40 00 00 00 00 00 000000
F: 1:1 00 00 00 00 00 00 000000
G: 1:2 0c 00 00 04 00 00 000000
H: 1:3 fd 99 00 60 00 00 000000
I: 2:0 07 05 00 02 00 00 000000
J: 2:1 f0 00 00 00 00 00 000000
K: 2:2 00 00 00 00 00 00 000000
L: 2:3 00 00 00 00 00 00 000000
M: 3:0 00 00 00 00 00 00 000000
N: 3:1 00 00 00 00 00 00 000000
O: 3:2 00 00 00 00 00 00 000000
P: 3:3 00 00 00 00 00 00 000000
Q: 4:0 00 00 00 00 00 00 000000
R: 4:1 00 00 00 00 00 00 000000
S: 4:2 a0 80 00 00 00 00 000000
T: 4:3 01 01 00 00 00 00 000000
U: 5:0 00 00 00 00 00 00 000000
V: 5:1 03 00 00 02 00 00 000000
W: 5:2 00 00 00 00 00 00 000000
X: 5:3 78 08 08 70 00 60 606000
Y: 6:0 06 00 00 02 00 00 000000
Z: 6:1 0f 08 08 04 00 06 020600
AA: 6:2 00 00 00 00 00 00 000000
BB: 6:3 01 00 00 00 00 00 000000
CC: 7:0 12 00 00 10 00 12 121200
DD: 7:1 01 00 00 00 00 00 000000
EE: 7:2 00 00 00 00 00 00 000000
FF: 7:3 00 00 00 00 00 00 000000
SPI用のカーネルモジュールの確認
SPI用のカーネルモジュールであるspidev
がビルドされているかを確認します。Jetson TX1やTX2のドキュメントを確認すると、以前はこのカーネルモジュールも手動でビルドする必要があったようです。Jetson Nanoの端末上でmodinfo spidev
を実行し、SPI用のカーネルモジュールが存在するかを確認します。すでにビルドされていれば以下のようにspidev.ko
までのファイルパスが取得できます。
$ modinfo spidev
filename: /lib/modules/4.9.140-tegra/kernel/drivers/spi/spidev.ko
alias: spi:spidev
license: GPL
description: User mode SPI device interface
author: Andrea Paterniani, <a.paterniani@swapp-eng.it>
alias: of:N*T*Clineartechnology,ltc2488C*
alias: of:N*T*Clineartechnology,ltc2488
alias: of:N*T*Crohm,dh2228fvC*
alias: of:N*T*Crohm,dh2228fv
alias: of:N*T*CspidevC*
alias: of:N*T*Cspidev
depends:
intree: Y
vermagic: 4.9.140-tegra SMP preempt mod_unload modversions aarch64
parm: bufsiz:data bytes in biggest supported SPI message (uint)
デバイスツリーの再構築
Jetson Nanoの準備
デバイスツリーの再構築にあたり、まずはJetson Nanoをリカバリーモードで起動する必要があります。電源を切った状態のJetson NanoのJ48とJ40の3, 4番ピンをジャンパピンを用いてショートします(https://developer.nvidia.com/embedded/dlc/jetson-nano-dev-kit-user-guide)。
この状態でJ25にDC 5Vを供給します。電源を接続したあとはJ40のピンは外しても付けたままでもどちらでも問題ありません。J48は電源供給状態切り替えのためのピンなので外すことはできません。リカバリーモードで起動できているとHDMIで接続したディスプレイには何も出力されません。最初にリカバリーモードで起動したときは不安になるかもしれませんが、そういう仕様のようです。
デバイスツリーの再構築とJetson Nanoへの書き込み
ここから先はUbuntuがインストールされた作業用PCを用いて作業をしていきます。作業用PCにはUbuntu 16.04.5のマシンを使用してテストしました。作業に必要なコードはGitHub(https://github.com/rt-net/JetsonNano_DT_SPI)に公開しています。公開したコードを用いてデバイスツリーの再構築をします。
git
コマンドでGitHubからリポジトリをダウンロードします。
$ git clone https://github.com/rt-net/JetsonNano_DT_SPI.git
ダウンロードしたリポジトリの中は以下のような構成になっています。
$ cd JetsonNano_DT_SPI && tree
.
├── LICENSE
├── README.md
├── run.sh
└── tegra210-p3448-0000-p3449-0000-a02.dts
LICENSE
とREADME.md
はGitHubに公開する際に追加したドキュメントです。今回は使用しません。run.sh
がNVIDIAのサイトからJetson Nanoへのファイル書き込みに必要なファイルをダウンロードしてJetson Nanoへファイルを書き込むためのツール、tegra210-p3448-0000-p3449-0000-a02.dts
がSPI1を有効にするためのデバイスツリーのソースです。
SPI1を有効にしたtegra210-p3448-0000-p3449-0000-a02.dts
をコンパイルして書き込むためには、リカバリーモードで起動したJetson Nanoと作業用PCをUSBケーブルで接続し、作業用PC上の端末で
$ ./run.sh
と実行すれば完了なのですが、今回はrun.sh
について少し説明します。
以下に7〜15行目を抜粋します。ここではQuick Start Guide(https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fquick_start.html%23)に沿ってファイルをダウンロードし、ファイルを配置しています。
以下に16〜20行目を抜粋します。ここでは先ほどの13行目でダウンロードしたL4Tのソースファイルのうち、デバイスツリーのバイナリの一部についてバックアップをとり、JetsonNano_DT_SPI
に公開されているデバイスツリーのソース(tegra210-p3448-0000-p3449-0000-a02.dts
)をコンパイルしたものと置き換えています。
以下に21行目を抜粋します。ここではこのあとで実行するスクリプトのためにファイルの所有権をroot
に書き換えています。
以下に24〜27行目を抜粋します。ここではNVIDIA user space librariesを書き込むディレクトリにコピーし(https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Frootfs_custom.html%23wwpID0E0NB0HA)、デバイスツリーのみをUSBケーブル経由でJetson Nanoに書き込んでいます(https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fflashing.html%23wwpID0E0LB0HA)。
以下に6行目を抜粋します。ここではJetson Nanoに書き込むファイルがすでに用意されているかを確認しています。このおかげで2回目にrun.sh
を実行する際は7〜21行目までのスクリプトは実行されず24〜27行目のみ実行されます。
ruh.sh
からflash.sh
を実行して無事に書き込みができると、作業用PCの端末上に*** The [DTB] has been updated successfully. ***
と表示され、Jetson Nanoが再起動します。ここでJetson Nanoで端末を開いて以下のように「SPIが有効になっているかの確認」で紹介したコマンドを実行することでデバイスツリーの再構築ができていることを確認できます。
$ sudo cat /sys/kernel/debug/tegra_gpio | grep " C:"
C: 0:2 00 00 00 00 00 00 000000
$ ls /dev/spi*
/dev/spi0.0
2019年6月29日追記
本記事公開時は/dev/spi1.0
としていましたが、/dev/spi0.0
と表示されますので記事内の表記を修正しました。
以上でJetson Nanoのデバイスツリーの再構築は完了です。
今回取り扱うデバイスツリーのバイナリ(*.dtb
)についてはkernelディレクトリに入っており、デバイスツリーのソース(*.dts
)は ダウンロードしたJetson-Nano-Tegra210_Linux_R32.1.0_aarch64.tbz2
を展開すると得られるLinux_for_Tegra/source_sync.sh
を実行することでLinux_for_Tegra/sources
以下にダウンロードすることができます(https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fmanifest_jetson_nano.html%23wwpID0E0KB0HA)。具体的には今回編集するtegra210-p3448-0000-p3449-0000-a02.dtb
のソースはLinux_for_Tegra/sources/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-p3448-0000-p3449-0000-a02.dts
にダウンロードできます。このファイルはGPL v2ライセンスで公開されています。
SPI2を有効にする方法については参考サイトで紹介しているNVIDIA Developer Forums(https://devtalk.nvidia.com/default/topic/1050427/jetson-nano/enabling-spidev-on-the-jetson-nano-is-hanging-when-flashing/post/5338398/#5338398)でjas-mxさんが公開しています。今回のSPI1を有効にするスクリプトとデバイスツリーのソースはjas-mxさんが公開している情報を元に作成されました。
SPI1とSPI2が割り当てられているピンは以下のサイトから確認できます。
まとめ
Jetson NanoのSPI(SPI1)を有効にするためのスクリプトをGitHub(https://github.com/rt-net/JetsonNano_DT_SPI)に公開したので、スクリプトの内容とその使い方を紹介しました。使用するデバイスツリーのソースはGPL v2ライセンスで公開されており、ダウンロード用のスクリプトを実行することで、ダウンロードすることができます。
参考サイト
NVIDIA Developer Forums
Enabling spidev on the jetson nano is hanging when flashing – NVIDIA Developer Forums(2019年5月16日閲覧):
NVIDIA Tegra Linux Driver Package Development Guide
Flashing a Specific Partition – L4T Development Guide(2019年5月16日閲覧):