ホームページ>mini2440>その6・CMOSカメラモジュールを使う
目次
その6・CMOSカメラモジュールを使う
はじめに
mini2440用のCMOSカメラモジュール(モジュール名:C-130、チップ名:OV9650)の利用について、試行しました。
なお、今回は主にUbuntu 14.04マシンを使用しました。(MacはQtアプリ作成のみ:Mac mini mid 2010、OSX 10.11.3、Qt 4.8.6、Qt Creator 3.2.1)
また、各バージョンは試行時のもので、最新版とは異なる場合があります。
経緯
オリジナルのQtopiaではカメラモジュールが使えていたことと、現用カーネルの起動オプションにカメラがあったことから、当初は簡単に考えていました。
ですが、カメラオプションを指定しただけでは使えない、というより、現用カーネルがカメラに対応していないことが判明して、結局、オリジナルカーネルとのハイブリッド版にした上に、サードパーティ製のカメラドライバを導入することで、ようやく使えるようになりました。
なお、今回はカーネルに特化した話であり、ファイルシステムは全ケースとも、前回作成したDebian 7.0 wheezyを使っています。
注) 現用カーネル:参考サイト(1)からダンロードさせて頂いたもの。
オリジナルカーネル:本体同梱のDVD収録のもの。または参考サイト(2)で公開されているもの。
現用カーネルとオリジナルカーネルを使う(失敗)
まずは順序として、現用カーネルの利用を試みました。
オリジナルカーネルでは、カメラモジュールはデバイスドライバとして/dev/cameraを使用するのですが、現用カーネルで確認してみるとこれがありません。
カーネルのソースを調べると、カメラモジュール関連のソース一式がありませんでした。
あれ、と思って、オリジナルカーネルを見てみると、ソース一式がありました。
この時、初めて現用カーネル(のソース)がオリジナルカーネル(のソース)と異なることに気付きました。(道理で、ググった時に見慣れないコードが引用されていた訳だ。)
現用カーネルの起動コマンドには、カメラを有効にするオプションがあるのに何故?と思って当該ソースを見ると、TODOと書いてありました。
どうも現用カーネルは、カメラを使うことができなそうな雰囲気です。
ということで、続いてはオリジナルカーネルを試してみることにしました。
オリジナルカーネルはW35にも対応しているので「cp config_mini2440_w35 .config」してから、menuconfigを起動後、Device Drivers>Multimedia supportと辿ると、現用カーネルにはなかった「OV9650 on the s3c2440 driver」オプションが表示されるようになったので、yesに設定しました。
あと、オリジナルカーネルのファイルシステムはYAFFS2になっていますので、これをext3に変更しました。(この辺は、現用と両方のメニューを表示して合わせ込むのが簡便です。)
ビルド後に動かしてみると、カーネル自体には問題がありましたが、/dev/cameraがあることが確認できました。
カーネル自体の問題(というよりファイルシステムとの齟齬?)は、(1)tty端末がログイン可能状態にならない、(2)ネットワーク接続できない、というもので、本体に接続したUSBキーボードからは操作可能。早速、カメラテスト用に作成したQtアプリを起動すると、以下のメッセージが表示されました。
単純に解釈すると「メモリが足りない」となりますが、カメラが必要とするメモリ量は300KB程度の筈なので、額面通りに受け取ってよいものか、よく分からない状況となりました。root@mini2440:/root# Camera1: page allocation failure. order:10, mode:0xd1 (以下、ダンプメッセージ)
ハイブリッドカーネルと代替ドライバを使う(成功)
カメラドライバについてこれ以上調べるのに、本体ディスプレイとキーボードしか使えないのはあまりに不便なので、まずはここから手をつけることにしました。
この件(と、あわよくばカメラドライバの両方)を解決する(可能性のある)最も手っ取り早い方法は、現用カーネルとオリジナルカーネルのハイブリッド版を作ってみることです。
即ち、現用カーネルのkernel/mini2440/drivers/media/以下を、オリジナルカーネルのmediaで置き換える、というものです。
(mediaを選択した理由は、ここのKconfigがカメラモジュール関連のオプション情報を持っているため。)
この状態でmenuconfigを起動すると、「OV9650 on the s3c2440 driver」オプションが「M」になっていました。
Mはモジュールの事で、ドライバがカーネル内部にビルトインされて常時起動するのではなく、外部に置かれて必要な時に読み込まれる、ということのようです。
(今回の件では、Mしか選択できなかったのですが、必要に応じてというより、依存関係が解決されて、可能であれば読み込まれる、ということのようです。後述)
モジュール化されることは特に問題ない(というか、これも後述しますが、実はそうでないと困る)ので、そのままビルドしました。
この時、もう一点気をつけることがあって、それはmenuconfigのDevice Drivers>Multimedia supportにある「Video For Linux」が「M」になっていること。(多分、最初からMになっている筈。これも後述)実機に持って行って起動したところ、tty端末/ネットワーク接続とも、問題なく使えることを確認しました。
肝心のドライバはというと、/dev/cameraが見当たりません。どうもデフォルトではモジュールが起動しないようです。
そこで、ドライバのディレクトリに入って、「insmod s3c2440camera.ko」としてやると、起動はしました。(/dev/cameraも出来ました。)
もしかして、と思って上述のカメラアプリを起動してみたのですが、やはりというか、同じメッセージが表示されて動きませんでした。
オリジナルカーネルはもともと、YAFFS2と組み合わせて本体内のNAND Flashに載せて使うものなので、メモリの使い方が異なる可能性もあります。
何れにしても、これ以上はメモリマップの確認等、ドライバ内部の検証に入らざるをえず、自分にとってはなかなかハードルが高いです。
という訳で、ここは先人達を頼らさせて頂こうとググってみたところ、以下がヒットしました。
参考サイト(3):s3c2440camera - Linux driver for S3C2440 camera interface - Google Project Hosting
これは、代替ドライバモジュールで、純正ドライバモジュールと差し替えて使うものです。
これですと、ソースを変更したい時も、モジュールをリビルドするだけで、カーネル本体はノータッチで済む訳です。
(幸いというか、ハイブリッドカーネルは既にカメラドライバがモジュール化されているので、そのまま使える。)
このドライバは、純正がキャラクタドライバである(日昇テクノロジー2011/08/25版マニュアル、P89)のに対し、V4L2準拠のようで、異なる結果が期待できます。
早速、これを使わせて頂いてテストしてみました。
上記サイトでは使い方も説明されていますが、端折られている部分もあるので、改めて手順を纏めておくことにしました。
同梱のテストアプリを起動したところ、正常終了して、輝度のファイルと色相彩度のファイルが作成されました。
- カーネルは上述のハイブリッド版(のコピー)を使用。(カメラドライバとVideo For Linuxをモジュールで組み込む設定済のもの)
- 参考サイト(3)からs3c2440camera-r5.tar.gzをダウンロードして解凍。(解凍先ディレクトリ名:s3c2440camera-r5)
- s3c2440camera-r5ディレクトリをカーネルのkernelディレクトリ内に置く。(mini2440ディレクトリと同じ階層)
- mini2440ディレクトリ内で、カーネルをmakeする。(念のため実行しておいた。なお、コンフィグは既に実行済なので、mini2440_defconfigは行わない。)
CROSS_COMPILE=arm-linux- ARCH=arm make prepare O=../kernel-bin/ CROSS_COMPILE=arm-linux- ARCH=arm make O=../kernel-bin/
- s3c2440camera-r5ディレクトリに移動し、makeする。(ポイントはKERNELDIRをソースディレクトリではなく、O=で指定したバイナリの方にする点)
KERNELDIR=../kernel-bin CROSS_COMPILE=arm-linux- make
- テストアプリが同梱されているので、同様にmakeする。(自分の環境では素直にmakeすると、ホスト用の実行ファイルが作られてしまうので、CCを変更した。)
KERNELDIR=../kernel-bin CC=arm-linux-cc make test_capture
- 出来上がったs3c2440camera.koとtest_captureを実機にコピー。(場所はどこでも。ここでは/root)
- 起動の順番は以下の通り。(s3c2440camera.koはvideodev.koに依存し、videodev.kはv4l1-compat.koに依存しているので、順に起動する。)
insmod /lib/modules/2.6.32-rc8/kernel/drivers/media/video/v4l1-compat.ko insmod /lib/modules/2.6.32-rc8/kernel/drivers/media/video/videodev.ko insmod s3c2440camera.ko
- /devにvideo0ができていることを確認。(このドライバではcameraではなく、video0が作られる。)
このうち、輝度のファイルはホスト上の画像ビュアーで表示できました。(輝度だけなのでモノクロ)
以上、例によってのドタバタでしたが、ひとまず動作する環境は整えられました。
Qtでカメラアプリ(簡易版)を作ってみる
カメラにアクセスできるようになったので、簡単なQtアプリを作ってみることにしました。
デバイスドライバからのデータの取得は今までやったことがなかったので、どうやるかが不明だったのですが、調べてみると、基本的にファイルから読むのと同じ、ということ(前項のテストアプリもそんな感じ)でしたので、まずこの点はクリアできました。
次は取得データのフォーマットですが、以下のデータシートに記載されていました。
参考サイト(4):[PDF] OV9650 Color CMOS SXGA(PDFファイルへのリンク)
これによると、「YUV/YCbCr / GRB / RGB565 / RGB555 / Raw RGB」とのこと。
扱いやすいのはRaw RGBと思われますが、それにはレジスタの操作が必要で、不確定要素が増えてしまうため、これは次に回すとして、まずは(前項のテストアプリ同様)デフォルトのYUV/YCbCrでいくことにしました。
なお、YUV/YCbCr(YUV422p)のバイトストリームは、以下に示されています。
参考サイト(5):V4L2_PIX_FMT_YUV422P ('422P')
モノクロでよければ、前半の輝度部分のみをそのまま書き出せばよい(前項のテストアプリがそうしている)のですが、カラーの場合はYUV/YCbCrをRGBに変換する必要があります(注1)。この辺は、画像処理の一般的なマターなので情報は充実していて、例えば以下が参考になります(注2)。
参考サイト(6):YUV - Wikipedia
注1:今回使用するQImageクラスはYUVに対応していない。(QVideoFrameクラスは対応しているようだが。)あとは、QtのAPIを使ってPNGやJPEGに書き出す処理を追加してやれば、簡単なキャプチャアプリが出来上がりそうです。
注2:細かく見ていくと、いくつかバリエーションがあるようだが、あくまでテストなのでここでは深入りせず、アプリとしてまとめることを優先する。
取り敢えず、以下の仕様で作ってみました。
起動と同時にキャプチャするだけのアプリですが、動作はしました。
- 解像度はVGA(640x480)とする。
- カメラの初期化とYUV/YCbCrデータの取得部分は、サンプルプログラムの当該部分を使わせて頂く。
_(..)_
- YUV/YCbCrからRGBへの変換式は、ひとまず参考サイト(6)の「YUV (PAL, SECAM)」式とする。
(色相彩度値は-128、輝度値はそのまま使用し、計算値が255を超えたら255とした。おそらくなんらかの補正が必要と思われるが、テスト目的なのでこうした。)- 最初の数枚は画質が安定しないので、5枚撮って5枚目を使う。
- 出力の形式はPNGとする。(QImageクラスのsaveメソッドを使用。当初、PNGへの書き出しに時間が掛かり過ぎていたが、これは圧縮の時間のようで、ファイルサイズとの兼ね合いから、結局80に落ち着いた。)
参考サイト(7):qt - How can I decrease the amount of time it takes to save a png using QImage? - Stack Overflow
注)50%縮小後にJPEGに変換している。
おわりに
OV9650には様々なオプションがあるようで、それらをいじってみるのも面白そうです。
それと、これはカメラ自身のことではありませんが、
があると便利なのですが、さて、どうするか。
- ACアダプタだと室内しか撮れないので、外に持ち出すためのバッテリシステム
- カメラの向きを逆にするための延長ケーブル(本体に直付けだと、カメラがディスプレイと同じ方を向いてしまって使い勝手が悪い。)
(モバイルバッテリとUSB-DCplugケーブル、2mmピッチのピン/ソケットは手に入るようなので自作すれば、なんとかなりそうではありますが…)
お世話になったサイト
有用なソフトウェアおよび貴重な情報をご提供頂いている皆様に、お礼申し上げます。(以下、順不同)
参考サイト(1):mini2440にDebian環境をインストール
参考サイト(2):Index of /download/ARM9-2440-DVD/Linux
参考サイト(3):s3c2440camera - Linux driver for S3C2440 camera interface - Google Project Hosting
参考サイト(4):[PDF] OV9650 Color CMOS SXGA(PDFファイルへのリンク)
参考サイト(5):V4L2_PIX_FMT_YUV422P ('422P')
参考サイト(6):YUV - Wikipedia
参考サイト(7):qt - How can I decrease the amount of time it takes to save a png using QImage? - Stack Overflow
更新履歴
2016.02.10 章番号を変更。
2016.01.30 新規作成
[Home] [MacSoft] [Donation] [History]