lp6m’s blog

いろいろかきます

DNNDKとの死闘(負け)

やりたいこと

DNNDK+yolov3 on Ultra96が搭載されたロボットに組み込みたい。
ロボットにはPCamが搭載されており、fixstarsさんの記事の方法で画像を取得・FPGAでの前処理を行っている。
希望する構成は「PCam + USBカメラ + DNNDK on Ubuntu

いずれもUltra96v1で試しています。

Linux Kernel+Device Tree xlnx-linux version Rootfs DPU Driver Load yolo+画像 yolo+USBカメラ PCam
Petalinux xlnx_rebase_v4.14_2018.2 petalinux OK OK OK NG
Petalinux xlnx_rebase_v4.14_2018.2 ubuntu OK OK OK NG
自前ビルド xilinx-v2018.2 ubuntu NG - - OK
自前ビルド xilinx-v2019.1 ubuntu OK OK NG OK
自前ビルド xlnx_rebase_v4.14_2018.2 ubuntu OK OK NG OK
  • 自前ビルドはikwzmさんのビルド手順https://github.com/ikwzm/ZynqMP-FPGA-Linuxを参考にしています。パッチはいずれも当てています。
  • yolo+画像が動くのに、yolo+USBカメラが動かないのは電源の問題のようです。yolo+画像を無限ループで動かした状態で、別プロセスでカメラのキャプチャを起動すると数秒動いた後、システムが固まります。(再起動はしない)
  • PCamが動かないのは、fixstarsさんのMIPI V4L2ドライバをロードしたときに以下のような割り込み登録に関する警告が表示される。画像取得テストを行うと割り込みが発生しないためにフレームが来ず、タイムアウトしてしまう。

カーネルイメージとデバイスツリーを、自前ビルドからPetalinuxに変えるだけで、耐えうる電流?が変わるのか、USBカメラが使用できるのが不思議。デバイスツリーの仕業?
 (デバイスツリーだけを差し替える実験もしてみたけどうまくいかなかった、何をやったかは記憶が曖昧)

自前ビルドのカーネルではfixstarsさんのV4L2が動くのにPetalinuxのカーネルにすると動かなくなるのも意味不明。。

参考

  • PetalinuxでLinux Sourceを生成する方法

https://forums.xilinx.com/t5/Embedded-Linux/How-to-build-kernel-Headers-with-Petalinux/td-p/832641
これをやるとpythonがないとか怒られたので以下の方法でpythonも組み込む。
https://forums.xilinx.com/t5/Embedded-Linux/petalinux-python-adding-modules/td-p/981153

  • Linux Kernel 4.19以降でカメラが2つ見える

USBカメラを1つしか入力していないのに2つ(/dev/video0と/dev/video1)見える。どうやら/dev/video1はmetadataらしい。
はじめはUSBカメラを使えない理由がこれかと思ったが、電源が足りないだけだった(カメラ単体のキャプチャは動く・DPUど同時に使用すると固まる)
USB Webcam Appears as 2 Devices - Raspberry Pi Forums

つらい

11月の頭からずっとやってきたが動かない。片方動いたら片方動かない・・
どうせDNNDKをUltra96で動かしても3fpsくらいしかでない
いつもアドバイスをくれる方々、本当にありがとうございます。

11/20追記

Petalinuxでビルドしたカーネルイメージを使用した際にfixstarsさんのV4L2ドライバが割り込み登録に失敗する問題は、VDMAやdemosaicの回路をXilinxのドライバが操作するように、Petalinuxによって自動的にデバイスツリーが生成される(pl.dtsi)ことが原因のようだ。自前でビルドしたときとのdmesgを比較することで判明した。

Petalinuxではsystem-user.dtsiファイルを記述することでデバイスツリーの上書きができる。fixstarsさんのV4L2ドライバは、ドライバのプログラムにHWのアドレス情報を埋め込んだものになっているので、アドレスなどをデバイスツリーで指定する必要がない。VDMAやdemosaicの回路を、存在しないドライバ名に上書き(compatible="lp6m,dummy")した。
するとdmesgで見る限り割り込みの登録には成功した。しかし、画像の取得テストプログラムは1回目のDMA割り込みが発生した後、2回目の割り込みが起きず、動作しなかった。(1枚目も正しい画像ではなく、DMAバッファに残っていた画像?が保存される)

Xilinxのドライバが、fixstarsさんのV4L2ドライバを邪魔しているのではないか、ということからデバイスツリーオーバレイをPetalinuxでも使用することにしてみた。
以下を参考にした。
電気回路/zynq/Device Tree Overlay - 武内@筑波大
デバイスツリーにシンボル情報を埋め込む - Qiita
petalinux-config -c kernelでDevice Tree Overlayを有効に。petalinux-config --get-hw-descriptionで指定する、ブートローダによってコンフィギュレーションされる初期回路は、自前ビルドの時に使っていたikwzmさん製の回路(「GPIOの回路」と呼ぶことにする)にした。
すると、V4L2ドライバは動作したが、DPUのドライバが初期化に失敗した。
オーバレイする前の回路を、DPUが載っている回路にしたところ、DPUドライバはV4L2ドライバは動作しなかった。
まとめると、

オーバレイ前の回路 V4L2ドライバ初期化 PCam取得 DPUドライバ初期化
GPIO回路 OK OK NG
DPU回路 OK NG OK

のようになった。

2つのケースの違いはどこにあるのか考えてみたが、FSBLによって設定されるPSのAXIの設定やクロックの設定くらいしか思いつかなかった。ブロックデザインをつくるtclファイルのdiffを取ったが、AXIのIFの無効・有効とそのビット幅しか違いがなかった。
tclファイルだけでなく、Export Hardwareをしたときにでてくるhdfファイルの中身(zipファイルなので解凍すればpsu_init.c等が出てくる)の差分をみた。
hdfファイルに入っているpsu_init.c等はFSBLのビルド時に使用されるので、ソースコードの差分を取ればどのような設定の違いがあるかわかる。やはりAXIの部分以外に相違がなかった。
f:id:lp6m:20191120195619p:plain:w700
AXIのインタフェースのビット幅に関してはUltra96 向け Debian GNU/Linux でAXI I/F のデータのビット幅を変更する - Qiitaの方法でオーバレイで設定できるはずなのだ。現に一番上の表の通り、自前ビルドでxilinx-v2019.1を使用した際はPCamからの画像取得もDPUの使用もできている。

結局今は、

  • Petalinuxでオーバレイする前の回路が違うだけでDPUが使用できたり、PCamが使用できたりする。(片方しか無理)
  • PetalinuxでビルドしたカーネルではUSBカメラ+DPUの同時使用ができるが、自前ビルドでは電流が足りないのか固まる(使用しているxlnx-linuxのバージョンは同じなのに、何が違う?)

2つの謎が残ることになった。2つめのほうはデバイスツリーを眺めると何かわかるのかも、?