2013年8月17日土曜日

MIPI CPI カメラモジュール

PandaBoardTexas Instruments OMAP4430Raspberry PiBroadcom BCM2835MarsBoardAllwinner A10WandboardFreescale i.MX6、、、これらはスマートフォンやタブレットなど、いわゆるスマートデバイスに搭載されることを前提として設計されたSoCです。スマートデバイスに必要とされる機能は、
  • オーディオやビデオの再生を担うマルチメディア処理
  • Wi-FiやBluetooth、3G、LTEなどのワイヤレス通信
  • LCDや外部HDMIディスプレイへの表示
  • ボタンやタッチパネルからの入力
  • 電源の管理
  • SDカードなどのストレージ
と、実に多様であり、SoCにはCPUの他にそれらを実現するためのさまざまなデバイスコントローラがペリフェラルとしてワンチップに収められています。

カメラ機能もその一つ。

したがって、スマートデバイス向けのSoCにはイメージセンサモジュールと接続するためのインタフェースが必然的に用意されることになります。

今日、それらのSoCを作っているメーカーとイメージセンサモジュールを作っているメーカーは別々であり、それぞれの市場に複数の企業がひしめいています。したがって、SoCを使ってカメラ搭載のスマートデバイスを作るメーカー(OEM)は、両のデバイスを選択のうえ調達して接続しなければならず、故にSoCとカメラの間には共通化されたインタフェースの存在が望まれることになります。

このような背景はカメラに限ったことではありません。SoCのさまざまな周辺機能にとって、 ハードウェアからソフトウェアまで含むインタフェースの共通化は主要な要求です。これに応じてMIPI Allianceという非営利団体でモバイルプラットフォームにおける内部インタフェースの共通化が行われています。モバイルデバイス関連産業から多くの企業をメンバーに集めるこの団体では、カメラモジュール用の共通インタフェース仕様も提供しています。

それが、MIPI CSI (Camera Serial Interface) と呼ばれるもの。

CSI-1、CSI-2、CSI-3の3種類があり、CSI-2とCSI-3が現行で活用(Active)の状態に指定されています。

仕様に準拠したSoCには、この共通化されたカメラインタフェースが存在します。そのSoCをベースにして作られたボードにも、カメラインタフェースが用意されることになるわけです。



たとえばRaspberry Piには、S5コネクタにCSI-2のインタフェースが用意されています(上画像)。このコネクタにフレキで接続し最大500万画素の静止画と1080pの動画が撮影できるカメラモジュールが、ModMyPi(£23.95)adafruit($29.95)日本のRSコンポーネンツ(2,400円)などで購入できます。モジュールそのものはOmniVision製OV5647です。

またWandBoardであれば、ユーザーガイド(SOLO/DUAL REV A1[pdf]QUAD REV B1[pdf])の5ページ、8ページに記載されているように、CPUが搭載されたEDMボードの端にある白いCAMERA1コネクタにCSI-2インタフェースが用意されています。WandBoardと同じi.MX6ベースのSABRE Liteボードなら、E-conのOV5640搭載カメラモジュールe-CAM50IMX6が適合するとLinuxGizmos.comの記事で紹介されています。WandBoardのコネクタとコンパチブルかどうかは記事や製品ページからはわかりませんが、OV5640をWandBoardに接続するためのアダプタを自作しちゃった猛者もいるらしいので、回路図を眺めながらチャレンジしてみるのもいいかもしれません。

2013年8月14日水曜日

Octaveでゆらぎ

とあるグラフィックプログラミングフレームワークで星のきらめきというか、瞬きというようなものを表現したいなぁ、と考えていて、その星の瞬きをもたらす「大気の揺らぎ」をどうやったら表現できるか考えていました。

揺らぎというのはいろいろな物理現象に見られる、物理量の平均値からの変動(分散)のことだそうです。いわゆる1/fゆらぎと呼ばれる、周波数に反比例するスペクトルを示す揺らぎが、自然現象で多く観測されるというのが有名です。

離散的に表現できる数式さえわかってしまえば、あとはプログラムに組み込むのはやっつけ仕事です。ただ、描画ループに組み込んで毎フレーム計算することは、場合によってはパフォーマンス低下につながります。そのためプログラム起動時にあらかじめ計算したテーブル(配列)を用意しておき、描画ループでは時刻をインデックスにしてそれを読み出すに留めます。

そこで、あらかじめどんなテーブルを作るか、グラフにプロットして確認したいと思います。

Octave、という数値解析ソフトがあります。同様のソフトではMATLABが有名ですが、OctaveはGNUプロジェクトによりフリーソフトウェアとして提供されています。WindowsやMac向けには、ここからインストーラがダウンロードできます。

昔、大学の信号処理の講義で触って以来使うことがなかったので、今回は数年ぶりの復習となりました。なので、下記は操作学習メモまで。

なおOctaveの操作方法はこちらのページでわかりやすく説明されています。 今回ヘビーローテで拝見させていただきました。

Octaveのコンソールを起動したら、まずは関数定義します。関数はこちらのページの記述を参考にしました。


nは元ページの数式で言うところの10、Σによる総和の回数です。 
一行ごとに改行を打ち込みます。一つ目のendでforループが閉じ、二つ目のendで関数が閉じたところで、次のコマンドのプロンプトになります。

次にx軸の入力値のベクトルを作ります。


piは円周率のπです。上記はマイナスπからプラスのπまでの間を0.02ずつとるベクトルになります。こうして一度定義された変数は、コマンドラインを終了するか、clearコマンドを入力するまで有効です。このxxを先に定義したfluc関数に入力して、計算結果のベクトルを得ます。


これでyyに計算結果が入りました。では、二次元グラフにプロットしてみます。



でけたー。gnuplotによるグラフが得られました。

こんな感じで実際の揺らぎ感が確認できます。

もう少しパラメータをいじりながら、いい感じの揺らぎ感を見つけたいですな (`・ω・´)

2013年6月1日土曜日

Raspbianのカーネルコンフィギュレーションを調べる

RaspberryPiで実行中のRaspbianのカーネルコンフィギュレーションを調べる方法。

2013年5月21日火曜日

ARM QEMUでDhrystoneを動かしてみる

整数演算の処理速度を評価する指標として知られるDhrystone(ドライストーン)ですが、コンパイラ効率やlibcの性能にも影響を受ける点も指摘されており、総合的に見るとプロセッサ単体の性能というよりはプラットフォーム全体の能力を反映したものと言えそうです。切り分けのためにはあまりよくない特性で、ベンチマークとして他の指標も見ないとよい評価はできないかもしれませんが、とりあえず手元でぱっと動かせると便利なものの一つには変わりないでしょう。

そこで今回はDhrystoneをARMコンパイルしてQEMUで動かす手順を確認。

1. ソースコードのダウンロード


ここからソースコードのアーカイブをダウンロードして解凍します。

2. Makefileの編集


エディタを使って、解凍したソースコードに同梱されているMakefileを環境に合わせて編集します。
下記のエントリを編集。同じ名前のエントリは一番最後に書いた行が有効になりますが、紛らわしければコメントアウトしたり消してしまったりしても構いません。

3. ビルド


ARMクロスコンパイラでコンパイルします。ツールチェインのインストールについてはこちら2を参照。
ツールチェインへのパスを通しておいて
でおk。

4. 実行


QEMU ARMを使って実行してみます。QEMU ARMのインストールはこちら1を参照。
実行回数の指定を求められます。試しに1000000回を指定。多いほど時間はかかりますが、少なすぎると失敗します。

実行が終わると、下記のように処理結果が表示されます。
Dhrystoneによるベンチマーク指標であるDMIPS値を得るには、Dhrystones per Secondを1757で割る必要があります。1MIPSの基準マシンとされているVAX 11/780のDhrystones per Second値との比を取るためです。この演算より、

250000 / 1757 = 142 DMIPS

が得られます。

実際にはMakefile中のHZエントリを編集してターゲットプラットフォームに合わせたメモリクロック(MHz)を設定しなければならないため、 上記の値は意味ナシです(初期値の60で算出されています)。

いろいろなプロセッサのDMIPS値と比べてみるのも面白いです。Cortex-A9あたりだと、1GHzで2500DMIPSになるようですね。

参考情報

Dhrystone howto
Dhrystone - Wikipedia


2013年5月20日月曜日

MarsBoard A10開封の儀

カードサイズのARMボードを性懲りもなくまた買ってみました。Allwinner A10搭載のMarsBoard A10です。コアは1.2GHzのCortex-A8、同クラスのボードには最近発売されたBeagleBone Blackや、何やら名前の良く似たMarS Boardあたりもありそうですが、MarsBoardの特徴はSATAコネクタが実装されていること。ちょっとしたNASなんかも作れてしまうかもしれません。

この辺のボードはいずれも
  • MarsBoard A10: $49.99
  • BeagleBone Black: $45
  • MarS Board: $99
と一般的なLinuxボードと比べてローコストなのが魅力です。

まずは荷姿。新書を4冊くらい重ねた程度の小さな段ボール箱。飾らない外装です。ちなみに送料は本体価格に込み、10日から2週間くらいで着きました。


中身もシンプル。


ケーブル類はボードの下にありました。


ボードA面。 左側のUSBコネクタとEternetジャックあたりの配置はRaspberryPiにも似ていますが、実装面積の大きいA10チップとROM、DDR3が存在感ありです。電源電圧は5V、右上にDCジャックもありますが、左下のUSB Mini-Bからも供給可能です。あとは右側にHDMI Type C、SATA、microSD。ピンは2mmピッチです。RaspberryPiとはいろいろな規格が違いますね。
SATAの隣の白いスイッチは、回路図を確認するとRECOVERという名前で、UBOOTという信号線につながっていますが、リセットか、あるいはブートセレクタでしょうか。


B面にはヘッドフォンジャック。


後はこの辺のイメージをいろいろ動かしてみたいですが、とりあえずまた今度。

2013年5月18日土曜日

RaspbianをインストールしてRaspberryPiをWebサーバにする

DebianのRaspberryPi移植版であるRaspbianの公式で、Raspbian Installerというツールが配布されています。SDカードに書き込んでRaspberryPiから起動すると、対話式のインストーラでRaspbianをSDカードに上書きしてくれるというものです。これを使ってRaspbianをインストールし、Webサーバを動かしてみます。

1. SDカードのフォーマット

今回は手元にあった8GBを使いました。インストール中に上書きされてしまいますが、最初にインストーラのバイナリを書き込むためにフォーマットします。ファイルシステムはFAT32で、パーティションは一つ。Linuxでfdiskを使ってもOKだと思います(手順はこちら)。

2. インストーラのコピー

ここからインストーラのzipアーカイブをダウンロードして展開します。
  • bootcode.bin
  • cmdline.txt
  • kernel.img
  • loader.bin
  • README.txt
  • start.elf
の6つのファイルが展開されるので、それらをフォーマットしたSDカードへコピーします。このとき必ずbootcode.binを最初にコピーし、後から他のファイルのコピーをします。こうしないと、bootcode.binがカードの先頭アドレスに書き込まれないため、十分なファイルシステムを実装されていない最小構成のファーストステージブートローダでは見つけて読み出すことができません。(RaspberryPiのブートシーケンスはここ参照)

3. ネットワークの準備

Raspbian Installerはネットワークインストーラなので、正しくインターネット接続されている必要があります。またDHCPによる自動IP割り当てを利用するため、DHCP機能の付いたルータなどが必要です。

4. 起動

書き込んだSDカードをRaspberryPiのカードスロットに挿し、ディスプレイとキーボードを接続して電源を入れます。

5. 言語の選択

インストーラの表示言語を選択します。ここで選択した言語はインストール対象のDebianのデフォルトにもなります。


6. ロケーションの選択



7. キーボードの設定

接続したキーボードに合わせた言語を選択します。


8. ネットワークの設定

接続されるドメイン名とRaspberryPiのホスト名を設定します。


9. ミラーホスト選択

ここでは公式に記載のあるとおり、ミラーを自動選択してくれるmirrordirector.raspbian.orgを設定します。

ディレクトリは/raspbian/に変更。


HTTPプロキシは空白でOK。


10. インストールコンポーネントのダウンロード

「カーネルモジュールが見つかりませんでした。」というメッセージが出ますが、そのまま<はい>を選択します。


ダウンロードが始まります。


11.アカウントのセットアップ

rootおよび任意ユーザアカウントの設定をします。まずはrootのパスワード。


再入力。


次にユーザカウントのフルネーム。


ユーザアカウントのユーザ名。


ユーザのパスワード。


再入力。


12. パーティショニング

SDカードのパーティション作成を行います。


自動で推奨構成が設定されます。特に変更の必要がなければ、そのまま「パーティショニングの終了とディスクへの変更の書き込み」を選択。


変更の確認。<はい>を選択。


パーティションの初期化が始まります。暫し待つ。


13. システムのインストール

続いてベースシステムのインストール。暫し待つ。


「定義された APT ソースにインストール可能なカーネルが見つかりませんでした。」と表示されますが、そのまま<はい>


aptの設定。待つだけ。


利用調査の統計に協力するかどうか。任意で。


必要なソフトウェアの選択。SSH serverにチェックが入っているので、Web serverにもチェックを加えて、<続ける>


ブートローダなしで続ける」は、そのまま<続ける>


インストールの終了を待つ。


14. Webサーバの動作確認

ホストマシンのWebブラウザでRaspberryPiのIPアドレスを入力し、It works!というページが表示されればOKです。RaspberryPiのアドレスがわからない場合は、ディスプレイでログインしifconfigコマンドを入力します。


以上。

公式にもRaspbianのイメージがありますが、パーティションが2GB固定なので、apg-get update等するとすぐに容量がいっぱいになってしまいWebサーバのインストールができなくなります。容量の大きいSDカードに書き込んだ上で、gpartedでパーティションを拡張する方法もあると思いますが、今回はRaspbianインストーラーを使ってWebサーバを初期インストールしました。なお既存のRaspberryPiに後からWebサーバをインストールする方法はこちらのページに記載があります。

参考情報

Raspbian Installer


2013年5月12日日曜日

RaspberryPiのGPIOでLEDを点灯

RaspberryPiのGPIOを扱う練習で、LEDの点灯をしてみます。

1. LEDの接続


GPIOの出力を確認するためのLEDを接続します。SoCのGPIOに直接接続されるので、電流制限抵抗を付けるのを忘れないでください。ローコストのボードとは言え、あっさり壊してしまってはもったいないですからね。だいたい数百オームでOKだと思いますが、気になる場合は使用するLEDのVFを調べて、GPIOのソース電流に収まるよう抵抗値を決める必要があります。今回は根拠ナシですがとりあえず470Ωを選びました。


抵抗を接続する足はLEDのアノード側、カソード側どちらでもOKですが、足の長さがわからなくなるので、LEDの極性を忘れないように気をつけます。(なお画像のようにハンダ付けしなくても、ブレッドボードを使ってもOKです。)


LEDをRaspberryPiに接続します。基板上のGPIOコネクタのうち、GPIOとGNDが隣り合っている13ピン、14ピンを使います。LEDのアノード側を基板内側の13ピン(GPIO) 、カソード側を基板外側の14ピン(GND)に接続します。


私の使用しているRaspberryPiはRev.2.0なので、13ピンはSoCのGPIO27に接続されています。回路図こちらのWikiにリンクがあります。

2. コマンドで点灯してみる


DebianのRaspberryPi向け改変版のRaspbianでは、ファイル入出力を通してRaspberryPiのGPIOをコントロールすることができます。Raspbianを使うには、ここからRaspbianのイメージをダウンロードし、Win32 Disk ImagerなどでSDカードに焼いてから、RaspberryPiのカードスロットに挿して起動します。

起動したら、まずログイン。HDMIで画面表示してUSBキーボードを使ってもいいですし、LAN接続してSSHを使ってもいいです。 ユーザー名はpi、パスワードはraspberryになっています。

ログインしたら、下記のようにコマンドします。
まずsuでスーパーユーザーに変更。続いて、/sys/class/gpio/ディレクトリの下のexportファイルにピン番号を指定すると、対応するgpioのディレクトリが作成されます。directionファイルで入出力方向を指定した後、valueファイルへの入力でGPIOの出力をON/OFFすることができます。


このように、ファイル入出力で操作できることで、 コマンドだけでなく、およそファイル入出力の機能を持った言語であれば、CでもPythonでも、同様の操作を行うことができます。
次に、C++によるGPIO操作のプログラムを試してみます。

3. プログラムによる点滅


まずはソースファイルを作成しエディタでソースコードを入力。
ARM用のクロスコンパイラでビルドします。ツールチェインのインストールはこちらの記事の「2. ARMコンパイラのインストール」をご参照ください。コンパイルできたら、バイナリをRaspberryPiにロードします。RaspberryPiをホストマシンと同じLANに接続しておけばSSHが利用できるので、SCPでコピーします。
ロードされたバイナリをRaspberryPiで実行します。まずは実行可能なようにパーミッションを変更。続いてスーパーユーザーでバイナリを実行します。
LEDが点滅を始めます。


参考情報
Creating a "Blinking LED" project for Raspberry PI