このブログは、株式会社フィックスターズのエンジニアが、あらゆるテーマについて自由に書いているブログです。
こんにちは、フィックスターズ新規事業推進室の大澤です。
新規事業推進室では、Halide と呼ばれるドメイン固有言語のコンパイラに関する研究開発を行っています。FPGA 向けのバックエンドを独自に開発しており、Halide で記述した IP を Xilinx の FPGA 開発ボード上で動作させたりしています。
この度、Ultra96 と MIPI 拡張ボードを組み合わせ、イメージセンサで取得した画像を FPGA で処理してから CPU 側で取得することができるようになりましたので、ソースコードを公開し、セットアップ方法の説明、簡単な解説を行いたいと思います。特定ボード、特定カメラでの情報ではありますが、少しでも皆様のお役に立てれば幸いです。
まず、今回はセットアップ方法についての説明です。
必要なものは、
です。
後、AVNET の USB to JTAG/UART ボードもあると便利、というかないと不便だと思います。
写真のようにカメラは J5 コネクタに差します。また、J13 ピンヘッダは写真と同じように 19 と 20, 21 と 22 をショートさせてください。同様に J15 ビンヘッダは 1 と 2 をショートさせてください。J14 ピンヘッダに関しては、写真と同じでなくても大丈夫と思います。
ちなみに、J13 ピンヘッダと J15 ピンヘッダのピン番号のアサインがどうなっているか、文書が見当たらないのですが、↓のようになっているようです。
Linux カーネルおよびファイルシステムは ikwzm さんご作成のものを使わせていただいています。ikwzm さん、どうもありがとうございます。https://qiita.com/ikwzm/items/975ab6997905700dd2e0 の通りに実行して、SD カードを作成してください。
作業は Vivado 上で行います。以下手順は全て Vivado 2018.2.2 Linux 版を使用して動作を確認しています。Windows 版でもいけると思いますが、試したことはありません。
ultra96 のボードファイルは https://github.com/Avnet/bdf から取得できます。取得したら /opt/Xilinx/Vivado/2018.2/data/boards/board_files/ に配置してください。
また、Xilinx が提供する MIPI IP を使用していますので、ライセンスをお持ちでない方は以下から評価ライセンスを取得し、インストールしてください。
https://japan.xilinx.com/products/intellectual-property/ef-di-mipi-csi-rx.html
以下の手順で github からソースコードを取得してください。
$ source
$ git clone https://github.com/fixstars/ultra96_design.git
$ cd ultra96_design
$ git submodule init
$ git submodule update
Vivado 2018.2 GUI を起動します。
$ source /opt/Xilinx/Vivado/2018.2/settings64.sh
$ vivado &
Vivado GUI の Tcl Console から
source ./script/create_project.tcl
を入力すると、プロジェクトが生成されます。プロジェクトが生成されたら、”Generate Bitstream” により bitstream を生成してください。まれに bitstream の生成が失敗する時があるようですが、もう一回 “Generate Bitstream” すると、たいていの場合は成功します。
生成された bitstream ファイルから bin ファイルを生成します。生成された bitstream は、ultra96_design/ultra96_design/ultra96_design.runs/impl_1/design_1_wrapper.bit です。
以下のような fpga.bif を用意して、
all:
{
[destination_device = pl] design_1_wrapper.bit
}
以下のコマンドを実行して fpga.bin を生成します。
$ bootgen -image fpga.bif -arch zynqmp -w -o fpga.bin
生成するファイル名は、fpga.bin としてください。ultra96_design のトップディレクトリから以下を実行することによって fpba.bin を生成することもできます。
$ ./script/bit2bin.sh
Vivado 2018.2 GUI にて、File -> Export -> Export Hardware… を実行し、続いて File -> Launch SDK を実行します。
SDK GUI が開いたら、File -> New -> Board Support Package を選択します。”Xilinx Board Support Package Project” 画面ではデフォルトのまま何も変更せず、Finish を押下します。
次の “Board Support Package Settings” 画面でも、そのまま OK を押下してください。standalone_bsp_0 プロジェクトが生成されます。
この Board Support Package は、次のカーネルドライバのビルド時に使用されます。
以下の手順により、カーネルドライバ v4l2.ko を生成します。
$ cd ultra96_design/src/linux/driver
$ make
以下の手順により、カメラ初期化 S/W である caminit を生成します。
まず、必要に応じて修正を行います。
ultra96_design/src/linux/caminit/src/main.cc に caminit() 関数呼び出しがあります。この関数の第1引数で、Raspberry Pi カメラ v2 か Pcam-5C カメラかを指定できます。Raspberry Pi カメラ v2 を使う場合は SENSOR_IMX219 を、Pcam-5C カメラを使う場合は SENSOR_OV5640 を指定してください。
修正後、以下を実行します。
$ cd ultra96_design/src/linux/caminit/build/
$ make
実機 Linux のユーザー名/パスワードは fpga/fpga, もしくは root/admin です。以下の手順は、基本的に root 権限が必要です。
実機 Linux 上に適当なディレクトリを作成してください。ultra96_design/overlay にある以下のファイルを作成したディレクトリにコピーしてください。
また、手順 4.3 で生成した
も同じディレクトリにコピーしてください。
/lib/modules/4.14.0-xlnx-v2018.2-zynqmp-fpga/kernel/drivers ディレクトリに v4l2 ディレクトリを作成し、手順 4.2 で作成した v4l2.ko を v4l2 ディレクトリにコピーしてください。その上で、以下を実行します。(任意のディレクトリ上で構いません。)
# depmod -a
最後に、3.4 で作成した fpga.bin を /lib/firmware ディレクトリにコピーします。
ここまできたら準備完了です。
./init_camera.sh を実行すると、FPGA コンフィギュレーション、V4L2 ドライバのロード、HW 初期化、カメラ初期化が行われます。
root@debian-fpga:~/fpga_manager# ./init_camera.sh
[ 8280.322752] fpga_manager fpga0: writing fpga.bin to Xilinx ZynqMP FPGA Manager
[ 8280.731570] fclkcfg: loading out-of-tree module taints kernel.
[ 8280.741059] fclkcfg amba:fclk0: driver installed.
[ 8280.745751] fclkcfg amba:fclk0: device name : fclk0
[ 8280.750852] fclkcfg amba:fclk0: clock name : pl0_ref
[ 8280.756118] fclkcfg amba:fclk0: clock rate : 99999999
[ 8280.761516] fclkcfg amba:fclk0: clock enabled : 1
[ 8280.766270] fclkcfg amba:fclk0: remove rate : 1000000
[ 8280.771570] fclkcfg amba:fclk0: remove enable : 0
[ 8280.799827] zynq_v4l2_init
[ 8280.802791] v4l2 amba_pl@0:v4l2: Device Tree Probing
[ 8280.807689] zynq_v4l2_probe
[ 8280.811046] zynq_v4l2_vdma_init
[ 8280.816000] zynq_v4l2_demosaic_init
[ 8280.819433] zynq_v4l2_mipicsi_init
ID = 0x2, 0x19
root@debian-fpga:~/fpga_manager#
opencv-3.4.1 をソースコードからビルドしておきます。highgui を使うので、libgtk-3-dev パッケージと libgl1-mesa-dev パッケージを apt-get install でインストールしてから opencv-3.4.1 をビルドしてください。
実機上に適当なディレクトリを作成し、ultra96_design/test にある以下のファイルをコピーします。
makefile 先頭の OPENCV_DIR を適当に修正し、make を実行してください。
OpenCV ライブラリを使用するので、LD_LIBRARY_PATH に OpenCV ライブラリがあるパスを追加してください。その上で rgbtest を実行します。実行すると、20 フレーム分の png 画像ファイルを生成します。
Pcam-5C カメラで取得すると自然な色合いですが↓
Raspberry Pi カメラ v2 で取得すると緑がかった色合いになります↓
test ディレクトリでビルドを行うと、他にもテストプログラムが生成されます。rgbvideo を実行すると、カメラ動画を表示させることができます。表示出力先として、X11 forwarding を利用して ssh 経由で作業 PC 上に X Window を表示させることができます。ただし、環境にもよると思いますが、1fps か 2fps くらいでしょうか、とても遅いです。
そこで、display port で繋いだ外部ディスプレイに直接出力しましょう。
以下の手順で、とりあえず外部ディスプレイに X window を出力することができます。
ただし、これをやると、その後の shutdown 時に drm_vblank_cleanup で Exception が発生してしまいます。回避策は今のところ分かりません。
デフォルトでは、RGB24 640×480 画像を出力するような設定にしています。
一応、
を出せるように用意をしています。
ただ、V4L2 の VIDIOC_S_FMT コマンドを使って動的に切り替える、なんてことはできません、スミマセン。変更するには、bitstream の再作成、SW の再ビルドが必要になります。
ultra96_design/ip/demosaic ディレクトリに、xilinx_com_hls_demosaic_root_1_0_[フォーマット][解像度].zip を置いています。
ultra96_design/ip/demosaic ディレクトリで必要な zip ファイルを unzip し、touch component.xml してください。
Vivado 2018.2 GUI から demosaic IP を upgrade した上で、”Generate Bitstream” により bitstream を再生成してください。bootgen を使って bit から bin に変換することを忘れずに。
ultra96_design/src/linux/driver/zynq_v4l2.h と ultra96_design/src/linux/driver/main.c を修正する必要があります。
出力フォーマットを変更する場合は、zynq_v4l2.h を修正します。
zynq_v4l2.h の 15行目、YUYVOUT 定義を有効にすれば YUYV 出力、無効にすれば RGB24 出力です。
解像度を変更する場合は、main.c を修正します。
main.c の 15行目、16行目、vdma_h_res, vdma_v_res が横、高さを決定します。
解像度の変更を行う場合のみ、修正が必要です。
ultra96_design/src/linux/caminit/src/main.cc に記述されている caminit の第2引数を変更します。
rgbtest, yuvtest, uvc_camera_test, rgbvideo いずれにも先頭付近に WIDTH, HEIGHT の定義がありますので、これを変更します。
と、一応用意はしてみたものの、Raspberry Pi カメラ v2 だとあまりまともに動いてくれないです、スミマセン。
出力フォーマット | 解像度 | FPS |
---|---|---|
RGB24 | 640×480 | 30 |
RGB24 | 1280×720 | 15 |
RGB24 | 1920×1080 | 15 |
YUYV | 640×480 | 30 |
YUYV | 1280×720 | 正常動作せず |
YUYV | 1920×1080 | 正常動作せず |
Pcam-5C カメラの場合は、どの組み合わせでも 30fps で動くと思います。
[解説編] に続きます。
コンピュータビジョンセミナーvol.2 開催のお知らせ - ニュース一覧 - 株式会社フィックスターズ in Realizing Self-Driving Cars with General-Purpose Processors 日本語版
[…] バージョンアップに伴い、オンラインセミナーを開催します。 本セミナーでは、...
【Docker】NVIDIA SDK Managerでエラー無く環境構築する【Jetson】 | マサキノート in NVIDIA SDK Manager on Dockerで快適なJetsonライフ
[…] 参考:https://proc-cpuinfo.fixstars.com/2019/06/nvidia-sdk-manager-on-docker/ […]...
Windowsカーネルドライバを自作してWinDbgで解析してみる① - かえるのほんだな in Windowsデバイスドライバの基本動作を確認する (1)
[…] 参考:Windowsデバイスドライバの基本動作を確認する (1) - Fixstars Tech Blog /proc/cpuinfo ...
2021年版G検定チートシート | エビワークス in ニューラルネットの共通フォーマット対決! NNEF vs ONNX
[…] ONNX(オニキス):Open Neural Network Exchange formatフレームワーク間のモデル変換ツー...
YOSHIFUJI Naoki in CUDAデバイスメモリもスマートポインタで管理したい
ありがとうございます。別に型にこだわる必要がないので、ユニバーサル参照を受けるよ...