July 01, 2009

SWIGでiostreamを引数にとる関数のラップ(Rubyの場合)

とあるC++プログラムをRubyから使いたいということになりました。こんな時はCまたはC++のプログラムを、スクリプト言語から呼び出せるよう、ほぼ全自動でラッパーを生成してくれるSWIGの出番です。このSWIGはかなり賢いので、そんじゅそこらのプログラムでしたら、2,3行のインターフェイスファイルを書くだけで、スクリプト言語とC/C++の間を取り持ってくれます。
しかしながら困ったことに、今回はiostreamを引数にとる関数に遭遇してしまいました。intやchar *といった基本的な型であれば、スクリプト言語のオブジェクトを自動的にそれらの型に変換してくれるのですが、iostreamともなると少々手を入れてやる必要がありました。
なお、C++のiostreamをスクリプト側から使いたいという要望でしたら、こちらは簡単で、標準添付のstd_iostream.iというインターフェイスファイルが要望を満たしてくれます。

まずはじめに、実装が完成した際のプログラムのコードが、こんなにもエレガントになるということを語らせてください(笑)。以下に例を示します。invoked.hがSWIGでラップされる側、invoker.rbがそれを呼び出すRubyのコードです。

// invoked.h
#include <iostream>
struct InvokedCppClass {
    void stream_op(istream &in, ostream &out){
        // read from in and write to out ...
    };
};

// invoker.rb
require 'invoked.so'
invoked = Swig_Wrapped_Module::InvokedCppClass::new
open(src_file){|src|
    open(dist_file, 'w'){|dist|
        invoked.stream_op(src, dist)
    }
}

Rubyの文法と融合しているのが素敵だと思いませんか? 少なくとも僕は満足しています(笑)。

このようにラップをするためには、残念ながらSWIGで水面下でバチャバチャする必要があります。基本方針としては、typemapで呼び出し時に自動的にRubyのIOオブジェクトがiostreamに変換されるようにすることです。そのために、iostreamを生成するのに必要となるstreambufを使ってRubyのIOオブジェクトをラップするクラスを作成しました。この主要な部分をインターフェイスファイルに記述した結果、arg_std_iostream.iのようになりました。

使い方としては以下のようなインターフェイスファイルを作成してSWIGで処理をします。

// invoked.i
%module Swig_Wrapped_Module
%{
#include "invoked.h"
%}

%include arg_std_istream.i
%include invoked.h

確認した限りではファイルをストリームの元とする際は正常に動作しています。しかしcygwinのRubyにおいて、IO::pipeで作成したストリームでは読み書きするデータ量が多いとハングしてしまう問題を発見しました。おそらくcygwinならびにM$特有の問題だと思われるので、今回のコードが悪さをしているのではないと信じたいです。

またSWIGのRubyは多重継承を完全にはサポートしていないようで、ストリームはistreamまたはostream、すなわち読み書きのどちらか一方に絞る必要がありました。この記事のタイトルを正確に書くならば『...istreamまたはostreamを引数にとる...』ですね。

23:59 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/708

July 08, 2009

Super Sylphide 進捗状況(25) -- DSP航法ファームウェア バク取れた

前回の進捗記事で航法ファームウェアの開発遍歴についてふれたオートパイロットシステム Super Sylphideのその後のお話です。航法計算が正確に動くことは開発の過程で実証できていたのですが、最終的に組み合わせてリアルタイム動作させてみると色々と問題が発生しました。特にかなり以前の記事で書いた『McBSP(SPI)におけるCPU割込とEDMAの協調』の部分が強敵で、GPSやセンサなどの周辺機器を取り仕切っているマイコンC8051と、それからの情報を使って計算するDSP間の通信エラーが多発するという問題が発生していました。

結論から言うと、通信のタイミングの問題でした。以前の記事にもあるとおり、DSPは通信においてスレーブ、すなわち主導権を握っていない側であり、はじめの通信を受信割り込みで処理し、そこから得られた情報を元に以後自動的に送受信を行ってくれるEDMAを起動する設計としました。こうすることで通信によるDSPの負荷を軽減すること、ならびに可変長通信が可能になることを実現できました。しかしこの設計ではDSPの計算負荷が高いと、最初の割り込みからEDMAが起動されるまでに、より多くの時間がかかるようでした。そこで通信の主導権を握っているマイコンC8051側で、はじめの送信が終わった後にウェイトをいれて、送受信内容が破棄されないようにする必要がありました。

McBSP_EDMA_time_chart.png
タイミングチャート(Master=C8051, Slave=DSP)

結論を書いてしまうと、なんだそんな程度のことなのか、と思われるかもしれませんが、解決には相当の長い時間を要しました。通信は目に見えない部分、言い方を換えるとデバッカを使っても見えない部分であることがほとんどなので、大変恐ろしいものだということを改めて思い知らされました。今後の具体的な通信のトラブル事例に適用できるであろう、いくつかの指針を戒めとして残しておきたいと思います。

1) 割り込みはとにかく短く、とにかく短く
割り込みルーチン内での処理は、可能な限り短くする必要があります。実行時条件を同じにして分岐を少なくする、同期の問題はできるだけ割り込み外で処理するのが有効です。特に同期についてRTOSを使っている場合、割り込み内で使うにはコストが高すぎることがあるので注意です。

2) 割り込みの前と後で何が行われているか、よく調べる
割り込みに入る前ではレジスタの退避、後では復帰が行われるのが一般的ですが、今回のDSPで使ったRTOSのDSP/BIOSでは、dispatcherという機構を使うことで割り込み内での別の割り込みの可不可までも管理してくれます。しかしdispatcherに管理をお任せすると、割り込みルーチン内で別の割り込みの可不可を設定しても、割り込みから抜ける際に上書きされてしまうという仕様(spru423f.pdfの4-23、dispatcherはHWI_enterとHWI_exitで同じIERのMASKを取ると思われる)なのでした。

3) 通信のクロック速度を上げ下げしてみる
通信の速度を遅くしてみると、問題が解決することがよくあります。これが問題解決の糸口になるかもしれません。

4) DMAは気まぐれ
計算負荷があがると、キャッシュとメモリの間での転送量があがることが予想されます。ということはキャッシュとメモリ間での転送がDMAによって自動的に行われている場合、ユーザサイドで設定したDMAはどのタイミングで実行されることになるか、優先順位が高く設定できない場合は注意が必要ということです。

最後に完成したDSPファームを晒しておくことにします。リアルタイム50Hzで航法計算ができることを確認しました。いつの日か、もっと整理された解説記事を書きたいところです。

※その後、飛行試験の様子を書きました。

23:59 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/709

July 15, 2009

VS6724の調達

各種機能を改善した猫カメラ Ver.2をそのうち仕上げようと考えていますが、カメラモジュールをToshiba TCM8240からSTMicro VS6724へ変更する予定です。それというのもTCM8240はそのデータシートが正規のルートでは入手困難で、モジュールに内蔵されたjpegエンコーダの素性がわからずじまい、画像のデータ量を小さくすることが困難だったため、同等の性能で、かつ、データシートが公開されているVS6724に乗り換えることにしました。

ところがVS6724は入手が困難で、色々な手段、例えば海外のデットストックを探してみる、とか、某携帯のリペアパーツ(一説によるとNokiaの携帯に採用されていたらしいです)を探してみるとかしたのですが、なかなか購入最低個数等の条件で折り合いをつけてくれるところがなく迷走していました。しかし最近になって国内のchip1stopで扱っていることが判明し、xx個というまとまった個数ながら比較的良心的な単価であったので、清水の舞台が飛び降りたつもり(笑)で大人買いをしました。下はその画像です。

many_VS6724.jpg
いっぱい!!

実は関連するソケット(SMK製 CLE9124-1501FとCLE9124-1401F、リンクは先PDF)も発注をかけています。こちらはVS6724を上回るさらに大人買いになってしまったのですが、カメラモジュールは熱に弱く直接半田はお奨めできないとの噂も聞きますので、必要経費ということであきらめています。受注生産とのことなので、ソケットはもう少し時間がかかりそうです。

カメラモジュール、ソケットととも僕自身が使う予定の個数よりも発注数は多いので、もし興味がある方がいましたら、そのうち実費にて配布をしようかなと考えています。その場合はこのページでアナウンスいたしますので、のんびりお待ちください。

※(2009/8/25追記)ソケットが到着したので、写真を掲載してみました。

23:59 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (0) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/710

July 20, 2009

勇者Twitter Bot作りました

ドラクエ9の発売に伴い色々な動きがあるようですが、それに便乗してみることにしました。ミニブログ的なサービスであるTwitter上でメッセージをやり取りしながら、ドラクエを象徴する敵であるスライムと対戦できる『スライムTwitter Bot』というものがあるのですが、それと自動対戦を行う勇者Botというものを作ってみました。

スライムBot上では、打ち込んだメッセージは何でも"呪文"として認識されるので、Twitter上で流行っているキーワードを抽出するbuzztterから"呪文"を作ることにしました。

対戦の模様、実装の詳細は続きをどうぞ。

続きを読む "勇者Twitter Bot作りました"
20:04 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (2) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/711

July 28, 2009

電池変り種、BR435

とあるものに電子機器を組み込むため、非常に細長い電池を探していましたのですが、見つけることができました。

BR435.jpg
BR435、直径約4mm、スペックは 3V 50mAh。

この電池、釣りウキ用の電源として使われているそうです。その他、ペンライト等にも採用されているそうです。他にもBR425/CR425/CR435/CR535といった仲間がいるようです。電池自体の入手性は意外とよく、大手家電量販店で買うことができました。

端子は中央のピンとケースで+と-が形成されています。ホルダーが簡単に手に入るかどうか、またその大きさが問題になる可能性があるので、今後固定のためのアイデアを考える必要がありそうです。

※(2009/8/2 追記) この電池と一緒に使う予定の基板を設計してみました。

21:20 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | コメント (6) | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/712