はじめに
Jetson Orin NanoをJetson Nanoの後継機種として検討していますが、次の要素として、GPIO制御について確認してみましたので、それについて紹介したいと思います。
既に、「NVIDIA JetsonにおけるGPIO制御(C言語版)」で、Jetson Xavier NXでGPIO制御を確認したときのお話しを書いていますが、今回は、その続編的なお話しですので、その記事を更新しようかとも思いましたが、ちょっと時期もかなり異なっていて、書く内容も変わってきそうなので、別記事にしてみます。
別記事にはしますが、あの記事で紹介しているサンプルプログラムをJetson Orin Nanoにポーティングするまでの経緯を紹介した形になったかな、と思います。
/sys/class/gpioがない?
まず、GPIOとして使用している40ピンのヘッダのところのピンを2、3確認してみようと思って、Jetson Nano時代でよく使用していた/sys/class/gpioにcdして、あれ?ない。
Linux Kernel Driver DataBase: CONFIG_GPIO_SYSFS: /sys/class/gpio/... (sysfs interface)あたりを見ると、Kernel 5.15でもサポートが残ってそうなので、、、
ここで、カーネルのコンフィグを変更するなどして/sys/class/gpioを使えるようにできないかと少し試行錯誤しましたが、そのお話しはまた別途、機会があれば紹介します。
Stop using /sys/class/gpio – it’s deprecated - The Good Penguinあたりをサラッと読むと、コマンドとしてはgpiodetect/gpioinfo/gpioset/gpiogetを、そして、自分のプログラムではlibgpiodを使用する、というのが今の流れでありおすすめ、ということでしょうか。
NVIDIAのGPIO関連資料を確認する
Jetson Download Centerで、Jetson Orin NanoのCarrier Board SpecificationやPinmuxを探せば、以下の資料が見つかります。
Jetson Orin Nano Developer Kit Carrier Board Specification
Jetson_Orin_Nano_DevKit_Carrier_Board_Specification_SP-11324-001_v1.1.pdf
Jetson Orin NX Series and Jetson Orin Nano Series Pinmux
Jetson_Orin_NX_series_and_Orin_Nano_series_Pinmux_Config_Template.xlsm
Carrier Board Specificationの3.3 40-Pin Expansion Headerを見てみましょう。
例えば、以下の3本のピンに着目します。
- Pin12(I2S0_SCLK)
- Pin31(GPIO11)
- Pin40(I2S0_DOUT)
PinmuxのExcelを見てみると、、、
- I2S0_SCLKは...Customer Usageの列が...GPIO3_PH.07
- GPIO11は...GPIO3_PQ.06
- I2S0_DOUTは...GPIO3_PI.00
Carrier Board SpecificationのTable 3-3にも、十分な情報が載っていました。
- Pin12は...SoC Port #の列が...PH.07
- Pin31は...PQ.06
- Pin40は...PI.00
PH.07などの表記とline番号との対応関係は、gpioinfoで分かりました。
$ gpioinfo |grep PH.07
line 50: "PH.07" unused input active-high
$ gpioinfo |grep PQ.06
line 106: "PQ.06" unused output active-high
$ gpioinfo |grep PI.00
line 51: "PI.00" unused output active-high
つまり、Pin12がline 50、Pin31がline 106、Pin40がline 51、ということになります。
試しに手動でHigh/Low検知
Pin12を使って、試しに、そのポートがHighかLowかを確認してみましょう。
$ gpioget gpiochip0 50
0
では、Pin12とPin1(=3.3V)とを接続してみると、
$ gpioget gpiochip0 50
1
と、Pin12がHigh状態であることが確認できます。同様に、Pin12とPin9(=GND)とを接続してみると、
$ gpioget gpiochip0 50
0
と、Pin12がLow状態であることが確認できます。入力はできてそうですね。
次に、Pin31にHigh/Lowを出力してオシロで確認してみます。
$ gpioset --mode=wait gpiochip0 106=1
と実行すると、実行時にPin31がHighになり、ENTERキーを押すとその実行が終了し、またLowに戻る、という振る舞いをするようです。
ただし、デフォルトの状態では、Pin31に出力することができませんでした。別記事でも紹介している、JetsonIOを用いて、Pin31をマークして生成したDevice Tree Overlayを用いると、Pin31に物理的に出力できたようです。
サンプルプログラム
前のセクションで着目した、
- Pin12(I2S0_SCLK)
- Pin31(GPIO11)
- Pin40(I2S0_DOUT)
の3つのピンは、別記事「NVIDIA JetsonにおけるGPIO制御(C言語版)」にて紹介したサンプルプログラムで使用しているポートでした。
そのサンプルプログラムですが、今回、Jetson Orin Nanoに対応させた形で、GitHubのJetsonに置いておきました。
振り返ってみて...
プログラムでポートを使用していると、別ターミナルなどでgpiogetでReadしようとしてもエラーになってしまうようで、それがいまいちな気がします。私のやり方が悪いのかもしれませんが。
ということで、今のところ、昔の/sys/class/gpioの方が色々と使い勝手がいいような気がしますが、gpiodetect/gpioinfo/gpioset/gpioget系のコマンドでも同等に使用できるはずかと思いますので、そのあたりはまた別途調べることになるかと思います。
おわりに
ちょっとまだ書きかけな感じですが、ごめんなさい、もう公開してしまって、後でできる範囲で補足や訂正します。