June 01, 2013

mRubyとC++の親和性

オートパイロットシステムTinyFeathermRubyを載せて遊んでいます。最近はextend_sample.rbに示したようなRubyのコードで誘導制御の部分も動くようになりました。これはmRubyから既存のコードを呼び出すことで可能となったのですが、既存のコードの大半はC++で書いてあります。せっかくなので、mrubyをC++のオブジェクト指向を意識して融合することにしました。

mRubyはC言語で書いてあります。そういった事情からC++のオブジェクト指向的な方法でコードを融合するのは難しいのでは、もしかしたらmRuby自体の書き換えが必要かも、と思っていたのですが、そんなことはありませんでした。
結論から言ってしまうと、mrb_state構造体にあるvoid型ポインタ変数udが自由に使えるようになっており、この変数に必要なインスタンスへのポインタを格納すれば、mRubyの1インスタンスあたり、1つのオブジェクトを関連付けることができます。

mrb_state構造体の定義はmruby.hにあり、そこには/* auxiliary data */のコメントがあります。補助データ、ということでとても匂います。
さらに実際にこのudを自由に使っていいものか検証してみます。state.cの33行目付近を見ると、mrb_open_allocf()から呼び出されるメモリアロケータmrb_allocfに渡された引数の1つがudとして格納されています。それ以降、変数udの値を変更はしていないようです。またカスタムアロケータを使わず、通常のmrb_open()を使ってmrb_stateを初期化している場合、mrb_open_allocf()内で変数udにはNULLが指定されます(state.cの94行目)。ということで通常の手順であれば、mrb_open()の後に一度udにNULLが代入された後は、udは自由に使っても問題がないことがわかりました。

TinyFeatherではこれらのテクニックをshell.cppのかなり後の部分(930行目付近)で使っています。なおshell.cppはmRubyと既存のコードの糊として働いている部分です。

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

June 08, 2013

mRubyにおけるprintf的デバッグ

オートパイロットシステムTinyFeathermrubyを載せてみて動作確認をしています。mrubyは組み込み可能な軽量言語であり、組み込みといえばprintfデバッグなわけですが、それに相当するmrubyっぽいデバッグ方法を実装して動作確認に励んでいます。今回は備忘録がてら、その方法を紹介しようと思います。

mrubyの出力系メソッドとしては Kernel::p (引数オブジェクトの中身をinspect等で文字列化して出力) や Kernel::print (文字列を出力)、Kernel::puts (文字列を出力して改行)があります。これらのメソッドはmrubygemsのmruby-printを有効にすると使えるようになります。mruby-printで定義されるのはRuby拡張(print.rb)によるp/print/puts ばかりでなく、その低レイヤーとして働くC言語拡張(print.c)の Kernel::__printstr__ があります。
Kernel::__printstr__ を見ると、printstrというC言語関数で最終的にfwriteが標準出力(stdout)に出力をしていることがわかります。すなわち Kernel::p/print/puts の結果は stdout に Kernel::__printstr__ を通じて出力されています。

ここで組み込みではよくある標準出力以外、例えばファイルやシリアルポートに出力したければ、この Kernel::__printstr__ を再定義すると目的が達成されます。この方法で、TinyFeather内のmrubyのデバッグをUSBシリアルで可能なようにしました。詳しくはshell.cppの1028行目付近をご覧ください。

なおできれば近いうちにTinyFeatherのソースコード(研究用、また一部は権利関係のためソース非公開でバイナリ提供の予定)をある程度まとめた形で公開したいと考えています。

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

June 22, 2013

MAXIIとMAXVの比較

オートパイロットシステムTinyFeatherでは、CPLDとしてAltera MAXII EPM1270T144C5N(1270LE 144TQFP)を載せています。現在はMAXIIに比べ性能が向上したMAXVも入手が良くなってきているようなので、MAXIIをMAXVに置き換えられるよう、基板の一部を再設計してみています。特にMAXVに変更することによって、内蔵されているユーザフラッシュ(UFM)の書き換え回数がMAXIIが100回であったのが、MAXVになると1000回まで保証され伸びていることが僕にとっては魅力です。またMAXVの方がお安いです。

さて変更するにあたって、MAXII(EPM1270T144C5N)とMAXV(5M1270ZT144C5N)とが、どの程度ピン互換性があるのか調べてみました。以下のシートのとおりですが、結果からいうと11番ピン, 78番ピンがMAXIIがIOであったのがMAXVではGNDIOに変わっています。

その他としては、MAXVがVCCINT=1V8であることに注意すること、JTAG端子はVCCIOでH/Lレベル決定しているので特にMAXIIから移行する際に注意しなくてよいこと、が比較した成果として重要でした。

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