fc2ブログ

TOPPERS/ASP3 で TECS 版サンプルアプリのビルドと QEMU 実行

TOPPERS/ASP3 から TECS が標準に同梱されるようになりました。

TOPPERS/ASP3 に TECS が同梱されましたが、従来と同様の使い方ができますので、とりあえず TECS に関する知識は不要です。
デフォルトで、システムログ機能が TECS 化されていますので、意識することなく TECS を利用することができます。

システムログ機能が TECS 化されたのは、システムログ機能はカーネルの一部として組み込まれますが、ターゲットごとにカスタマイズしたい部分だからです。
ソフトウェアプロダクトライン(SPL) では、可変部分をコンポーネント化しておいて、取り換える方式が、もっとも一般的な方法の一つとなります。
TECS によるコンポーネント化は、オーバーヘッドが小さいため、コンポーネント化による処理時間やフットプリントの増加は、ほぼありません。

また、TECS では TOPPERS/ASP3 の静的 API を自動生成することができ、カスタマイズすべきパラメータを TECS CDL (コンポーネント記述)ファイルにセンタライズすることができます。
従来であれば、マクロ定義や cfg ファイルの変更が必要であったことが、TECS CDL ファイルの記述を変更するだけで対応できます。

TECS ではインタフェースが明確であったり、コンポーネントの構造を可視化できるため、どのようにカスタマイズすればよいか、あるいはカスタマイズされているかを理解するのが容易になるというメリットも享受できます。

TOPPERS/ASP3 で TECS 版サンプルアプリのビルドと QEMU 実行

前書きがだいぶ長くなりました。
ここからが、今回の記事の本題になります。

TOPPERS/ASP3 では、システムログ機能の TECS 化だけでなく、TECS 化したアプリケーションを開発する場合のサンプルも含まれています。
今回の記事は、TOPPERS/ASP3 の TECS 版サンプルをビルドし、QEMU による ARM エミュレータで動作させるまでの手順を説明します。
とりあえずターゲットなしの、組込み開発です。

1. 環境

この記事では Windows 7 64bit でビルドし、実行する前提で説明を進めます。

1) cygwin 環境

Windows の cygwin 環境を利用します。cygwin は、 こちらからダウンロードできます。
cygwin では make と Ruby を実行できるように、ダウンロードします。

TOPPERS/ASP3 から、従来 perl スクリプトであった configure が Ruby で書き改められたほか、
cfg も Ruby に置き換えられましたので、Ruby は必須です。
TECS のジェネレータも Ruby を使用します。

  * cygwin 2.5.1
  * Ruby 2.2.4p230


cygwin や Ruby に関しては、安定していますので、多少のバージョン違いは問題ないはずです。

2) ARM 用 C コンパイラ

ARM 用 C コンパイラと QEMU は Cygwin では用意されていませんので、別にダウンロードする必要があります。
コンパイラは、こちら からダウンロードします。
     gcc-arm-none-eabi-4_8-2014q3-20140805-win32.zip

ARM 用 C コンパイラは、互換性のない変更が行われている場合があります。
エラーが出るようでしたら、正確にバージョンを合わせてみてください。

3) QEMU

QEMU は、こちらからビルド済みのものをダウンロードしました。
  qemu-w64-setup-20150811.exe

これは 64bit 版です。32bit 版は、別のディレクトリにあります。
上記に含まれているのは、qeumu のバージョン 2.4 になります。
2016年9月時点での最新版の qemu を試したところ、うまく動作しませんでした。
qemu は、バージョンにより変化しているようですので、異なるバージョンだとうまく動かせない可能性があります。

2. TOPOPERS/ASP3 をダウンロード

こちらのページ から asp3_ct11mpcore_gcc-20160515.tar.gz  をダウンロードします。

3. 解凍

次のコマンドで解凍できます。

tar xvzf asp3_ct11mpcore_gcc-20160515.tar.gz


4. ディレクトリの作成

cd asp3
mkdir OBJ



5. TECS 版アプリのコンフィグレーション

cd OBJ
ruby ../configure.rb -T ct11mpcore_gcc -O "-DTOPPERS_USE_QEMU" -A tSample2 -t



-O "-DTOPPERS_USE_QEMU" は、QEMU 用にビルドする場合指定します。
-A tSample2 が TECS 版サンプルアプリケーションの指定になります。このオプションを指定しないと sapmle1 になります。
-t は、tSmaple2.o を Makefile に含めない指定です。gen/Makefile.tecsgen に含まれるため、不要になります。

6.ビルド

make



以下のようなエラーが出た場合、ARM 用 C コンパイラ arm-none-eabi-gcc へのパスが通っていないことが考られます。

error: S1147 tecs_kernel.h: CPPに対する popen が失敗しました.



arm-none-eabi-gcc.exe へのパスを通してください。

7.QEMU の実行

以下のようにオプションを付加した状態で qemu 起動します。

qemu-system-arm -M realview-eb-mpcore -semihosting -m 128M -smp 1 -serial vc -kernel asp.exe



私は qeumu にパスが通っていない環境で実行していますので、フルパスで起動しています。cygwin の bash から起動しているので、こんな感じです。

/cygdrive/c/Program\ Files/qemu-2.4/qemu-system-arm -M realview-eb-mpcore -semihosting -m 128M -smp 1 -serial vc -kernel asp.exe



1) 起動した直後の画面は、こんな感じです
qemu起動直後

2) シリアル (serial) に切り替えます

serial の選択

3) sample の出力が出てきます

sampleの出力

r キーを押すと、タスクが切り替わります。
ctrl-C を押すと、終了します。

他にどんなキーが効くかは sample ディレクトリ下の tSample2.c を見てください。
以下のコンポーネント図の左側の 2/3 の部分が tSample2.cdl に現れるコンポーネントで、キーで操作する対象になります。
右側の 1/3 はシステムログ機能になります。

(クリックすると拡大します)
asp3-tecs-sample

スポンサーサイト



MrubyBrigePlugin の mruby V1.1.0 に対応について

MrubyBridgePlugin をご利用の方から mruby V1.1.0 と組み合わせてビルドすると mrb_float_value の引数個数が不一致でエラーとなるとの報告をいただきました。
調べたところ mruby V1.0.0 から V1.1.0 で引数個数が追加になったようです。

MrubyBridgePlugin パッケージを公開したのが、2013年6月のことで、その後の変化に対応できておらず、申し訳ございません。

基本的には、mrb_float_value の引数に mrb が追加されただけですので、そのように修正すれば対応できます。
以下に修正個所と、修正内容を記しますので、変更した版のリリースが待てない場合が、修正してみてください。

1) MrubyBridgePlugin.rb の修正

1082 行目
前) file.print " return mrb_float_value( ret_val );\n"
後) file.print " return mrb_float_value( mrb, ret_val );\n"



2) tecs/mruby/TECSPointer.h

474 行目
前) return mrb_float_value( pointerBody->buf[ subscript ] ); \
後) return mrb_float_value( mrb, pointerBody->buf[ subscript ] ); \


498 行目
前) return mrb_float_value( *pointerBody->buf ); \
後) return mrb_float_value( mrb, *pointerBody->buf ); \



3) tecs/mruby/TECSStruct.h

88行目
前) return mrb_float_value( st->MEMBER ); \
後) return mrb_float_value( mrb, st->MEMBER ); \



上記の内、2) は float や double へのポインタ型(または配列) を用いる場合に、 3) は構造体メンバーに float や double を用いる場合に必要です。
また、float や double を引数や戻り値に使用しない限り、上記の変更は不要です。

MrubyBridePlugin パッケージに MrubyBridePlugin-test というディレクトリが含まれており、一通りの試験はしております。
この範囲において mruby V1.1.0 で引っかかるのは上記だけでした。
(実は main 部分もうまくビルドできなくなってます。mruby on ev3rt+tecs に含まれる tMruby に置き換えるつもりです)

float や double を用いないのであれば、MrubyBridePlugin (2013年6月公開版) を mruby V1.1.0 で使い続けても問題ありません。
(他に、環境によって schar_t や uchar_t が引っかかる問題があるようですが)

TECSCDE (TECS Componet Diagram Editor) V0.5.0 一般公開開始

TECSCDE を一般公開開始しました。
通常であれば、TOPPERS プロジェクトの成果物は早期リリース後に一般公開となるのですが、TECSCDE は V0.5.0 という形で、最初から一般公開させていただくこととしました。

機能的に不十分ながら、既存の cdl ファイルから TECS コンポーネント図をおこすのに役立ちます。

この記事では、使い方や、編集した例について記載します。

準備

tecscde-MinGW-150607.tgz をダウンロードします。
MinGW 版となっており、Windows で動作するものとはなっていますが、本体部分は Ruby と GTK2 を使用しているため、Linux 上でも使用できます。
いずれにせよ、以下の方法で解凍します(Window においては cygwin を使用することを前提としています)。

% tar tvzf tecscde-MinGW-150607.tgz


tecscde-MinGW というディレクトリが作成されます。
MinGW 版の場合は、展開ディレクトリを実行パス (環境変数 PATH) に含めることで使用できます。
Linux や cygwin の X-Window を利用する場合には 展開ディレクトリ下の tecsgen ディレクトリを実行パスに含めるとともに TECSPATH も設定する必要があります。

MinGW 版を cygwin 上で使用する場合、Linux で使用する場合、cygiwn の X-Window で利用する場合のいずれにおいても、以下のコマンドで、実行パスや TECSPATH を適切に設定できます。

% source set_env.sh



set_env.sh のあるディレクトリ (tecscde-MinGW 下) で実行する必要があります。

使用方法1

TECS ジェネレータが生成する Makefile において、TECSGEN_EXE=tecwgen となっているところを、tecscde に置き換えるだけで、TECSCDE を起動できます。
例えば、次のようにします。

% make TECSGEN_EXE=tecscde tecs



もし、次のように表示された場合

make: Nothing to be done for 'tecs'.



次のコマンドでタイムスタンプファイルを削除してから make すれば、TECSCDE が開始します。

% rm tecsgen.timestamp



TECS のパッケージでは、Makefile の変数に TECSGEN_EXE ではなく、TECSGEN が使われていることがあります。
その場合は、次のようにしてください。

% make TECSGEN=tecscde tecs



Nothing to be done のメッセージが出た場合には、やはりタイムスタンプファイルを消せば起動できます。

ここまでの起動方法は tecsgen の代わりに tecscde を起動する方法でした。tecscde は、tecsgen と同じ引数を受け付けるため、このような方法で編集を開始できます。

編集結果を保存すると cde ファイルが作成されます。これは cdl ファイルの .cdl という拡張子を .cde に置き換えたものとなります。

使用方法2

使用方法1で作成した cde ファイルは、セルの位置情報の他に、tecsgen を起動した時のコマンドラインを記憶しています。
このため、cde ファイルだけを指定して tecscde を起動すれば、直ちに編集可能となっています。

例えば tecscde-MinGW/SimpleSample 下にある portarrya.cde であれば、以下のように起動できます。

% ../tecscde portarray.cde



このように tecscde へのパスを指定すれば tecscde を実行パスに通すことなく実行できます。

ここで、色塗されて、かつ枠線が青いセルと、白塗りかつ枠線が黒い線が見られます。

この場合、前者は、位置を変える、または受け口に結合を追加することしかできません。
このセルは、cdl ファイル由来のもので、変更操作ができないものとなります。

後者は cde ファイル由来で、セルを削除できますし、結合も削除できま、別のセルにつなぎなおすこともできます。

両者の差は、編集可能かどうかですが、編集対象となっている cde ファイルの内容のみが削除や属性値の変更が可能で、cde ファイルからインポートされている cdl ファイルの内容は、編集不可であるため、削除することも、属性値を変更することもできません。なお cde ファイルであってもインポートされている場合は、編集対象になりません。

実例

EV3+TECS+mruby サンプル
2015年6月9日に公開された LEGO mindstorms EV3 用 TECS パッケージ (mruby-on-ev3rt+tecs) に tEV3Sample.cde が含まれています。
この図を見るとすごく単純な構造しか見られません。
この例では TECS は、デバイスドライバレベルのコンポーネントを mruby に提供するだけになっていることがわかります。

EV3RT-TECS+mruby コンポーネント図


NXT+TECS サンプル
一方 LEGO mindstorms NXT 用に公開されている例では、TECS コンポーネントを組み合わせて実現されていることがわかります。タスクやセマフォなど重要な要素がどこにあるかわかります(タスク=能動セルは二重線で囲まれたセルです)。

NXT-TECS コンポーネント図

Windows(MinGW) で Ruby/GTK2 環境の構築

Ruby/GTK2 を使用して TECS コンポーネント図を作画するツール (tecscde: TECS Component Diagram Editor) を作り始めました。
最初は cygwin 版で開発し始めたのですが、後で説明する問題があって、MinGW 版へ移行することにしました。
なのですが、これがすんなりと MinGW 版 Ruby/GTK2 をインストールできませんでした。

ここでは MinGW 版の Ruby/GTK2 のインストールについて記します。
これが正しいか分からないですし、十分詳細な説明になっていないので、とりあえず私のメモになります。
(特に PATH 環境変数の設定に関する省略が多いです)
よりよい方法をご存知の方がいらっしゃいましたら、ご教授いただけると幸いです。

さて、それでは、私が MinGW 版 Ruby/GTK2 をインストールした手順を以下に示します。

■ MinGW のインストール
MinGW そのものは、必須とは言えないが、色々と役立つこともあるので、とりあえずインストールしておく。

以下の URL から mingw-get-setup.exe をダウンロードして起動する。

URL http://sourceforge.net/projects/mingw/files/

c:\MinGW へインストール. msys もインストールする。
このツールは、分かりやすいとは言えないが説明を割愛。

なお、PATH 環境変数は自動では設定されないようである。
コマンドプロンプトからならば PATH=c:\MinGW\bin;c:\MinGW\msys\1.0\bin;%PATH% のように設定を行う。

■ GTK+ のインストール
GTK+ の DLL が必要である。
以下の URL から GTK+ 2.x All-in-one をダウンロードする。

URL http://www.gtk.org/download/win32.php

all-in-one のファイル名は、以下の通り。

gtk+-bundle_2.24.10-20120208_win32.zip



解凍した内容は c:\MinGW の下へコピーしておく(ここへマージするのがよいか、MSYS の方へマージするのがよいか、よくわからないが、とりあえず gcc の include, lib に組み込まれるように、そのようにした)
なお、重複するファイルは、MinGW の方が新しいので、MinGW のものを残しておいた。

■ Ruby

MinGW 版の Ruby のバイナリは、以下からダウンロードできる。

URL http://rubyinstaller.org/downloads/
Ruby 2.0.0-p598

私がダウンロードした時点では、パッチレベルが p598 であった。
次項で説明するように、実際には V1.9.3 もインストールを行っている。


■ Ruby/GTK2


(1) Ruby 1.9.3 (mingw) では gem が正常に終わるが動かない

以下のコマンドで Ruby/GTK2 をインストールする。

% gem install gtk2



しかし、ここでインストールされた gtk2 を require しても、以下の例外が出てしまう。

`require': cannot load such file -- cairo.so (LoadError)



ネット上の情報から、この gem は Ruby2.0.0 用のもので、動かないとのことである。

参考情報
URL http://sourceforge.net/p/ruby-gnome2/mailman/message/30610030/
URL https://www.ruby-forum.com/topic/4487050

(2) Ruby 2.0.0 の gem は、以下のエラーが出てインストールできない

ということで Ruby 2.0.0 で gem install gtk2 を行うと、以下のようなエラーが出てしまった。

bash-3.1$ gem install gtk2
ERROR: Could not find a valid gem 'gtk2' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv3 read server ce
rtificate B: certificate verify failed (https://rubygems.org/latest_specs.4.8.gz)



ネット上には、この原因が書かれているページもありそうだが、深く追求していない。

(3) Ruby 2.0.0 に Ruby 1.9.3 の gem コマンドで取り込んだ .gem をインストール

さて、(2) を解決しないで、どのようにするかと言えば、以下の通りである。

まずは、別のコマンドプロンプトを開く。
その後、以下のように入力する。

% PATH=c:\Ruby200\bin;%PATH%
% cd c:\Ruby193\lib\ruby\gems\1.9.1\cache
⇒ このディレクトリには、1.9.3 の gem install gtk2 でダウンロードされた .gem ファイルが入っている
% gem install gtk2
⇒ カレントディレクトリに .gem がある場合、それがインストールされる



gem の本体は問題なくインストールできたが、ドキュメントのインストールで警告が色々と出てしまった。
これは、とりあえず無視した。

なお、直接以下から .gem をダウンロードする方法でも対応できるはずである。
ただし、たくさんの .gem を一つ一つダウンロードする必要があるので、今回は (1) でダウンロードしたものを利用した次第である。

URL https://rubygems.org/

必要な gem ファイル。

atk-2.2.3-x86-mingw32.gem gtk2-2.2.3-x86-mingw32.gem require_all-1.3.2.gem
cairo-1.14.0-x86-mingw32.gem gtksourceview2-2.2.3-x86-mingw32.gem
gdk_pixbuf2-2.2.3-x86-mingw32.gem pango-2.2.3-x86-mingw32.gem
glib2-2.2.3-x86-mingw32.gem pkg-config-1.1.6.gem



■ Ruby/GTK2 を Windows MinGW 上で動作させる理由

そもそもは cygwin 版の Ruby/GTK2 では、FileChooserDialog, FileChooserButton が SEGV でダウンしてしまうため MinGW 版へ移行することにしたのである (cygwin V1.7.27 での状況)。
cygwin は Windows 上で UNIX 系ファイルシステムをエミュレートしているため内部的にうまくいかないところが残っているのかもしれない。
念のため C++ で記述された FileChooserDialog のサンプルプログラムをビルドしても、やはり SEGV で落ちる。
Ruby/GTK2 の問題よりは、GTK+ の方の問題のようである。
(なお、何もメッセージが出てこないので SEGV で落ちていることは strace コマンドを使用して Ruby を起動して確認した)

ということで、cygwin 版の Ruby/GTK2 は深追いしないことにした。
cygwin 版は X Window 上で動作するため、X サーバーを起動する必要があるし、X サーバーを指定する環境変数を設定する必要もあり、UNIX 系に慣れていない人にとっては、cygwin のファイルシステムと同様にわかりにくいというのも、cygwin 版を早々にあきらめる理由ではある。

なお Ruby/GTK2 は Ubuntu Linux 上では、特に問題なく、すんなりとインストールできたし、動いてくれた。
やはり、元々が Linux 系なだけはある。

MacOS X も UNIX 系 OS + X Window のようなので、恐らく問題ないのだろう。

■ 終りに

以上は、すんなりとできたのではなく、色々とトライアンドエラーを繰返して、ようやく動作することができました。
ruby extconf.rb を起動してビルドも試みましたが、うまくいきませんでした。
Ruby/GTK2 の場合、Ruby, GTK, そして Ruby/GTK2 が関わってくる上、それぞれにもバリエーションがあるため、どの組み合わせがよいのか分からず、苦労しました。
やっぱ、ネット上に十分な情報がないと、なかなか辛いものがあります。
TECS も、そのような状況かもしれません。
うまくいかないとイライラもするけれど、ソフト開発には、粘り強さも必要ですね(フォローになっていないか 汗)。

さて TECS コンポーネント図エディタ (tecscde) は Ruby/GTK2 ベースとしたため、TECS ジェネレータとの合体が容易になりました。
このため TECS CDL ファイルを直接取り込んで TECS コンポーネント図化することができます。

TECS コンポーネント図にあって TECS CDL にはない情報は、セルや結合の位置情報です。
tecscde では TECS CDL でセルの情報を記録し、JSON 形式でセルのコンポーネント図上の位置を記録します。
こうしたことで、import する CDL ファイルのパスを変更するだけで、異なるプラットフォームのコンポーネント図を作ることができます(手直しは必要)。
目下のところ ET ロボコンで使っていただけることを目標として、開発を進めています。


TECS 版 HelloMruby (MrubyBridgePlugin の使い方)

「MrubyBridgePlugin のマルチ VM 対応」という記事を書き始めたのですが、その前に MrubyBridgePlugin の使い方を紹介する記事を書いていないことに気付きました。それで、改めて簡単なサンプルプログラム HelloMruby を作成して MrubyBridgePlugin の使い方を紹介することとしました。

なお MrubyBridgePlugin は、昨年(2013年) の TOPPERS カンファレンスに合わせて公開した MrubyBridgePlugin パッケージに含まれています。

それから、記事のタイトルを TECS 版 HelloMruby としましたが、TECS 版以外の HelloMruby があるわけではありません (恐らく英語的には HelloMruby with TECS な感じなのですが、日本語的にしっくりくる感じで選んだだけです)。

■ MrubyBridgePlugin の概要

さて MrubyBridgePlugin が何ものかですが、mruby のスクリプトから TECS のコンポーネントを操作するためのインタフェースコードを自動生成するものになります。このインタフェースコードは、TECS の側からみれば TECS のコンポーネントであり、mruby の側から見れば C 言語によるクラスの実装になります。

図1は、HelloMruby を例題とする MrubyBridgePlugin の効能を示すための概念図です。

図1
(クリックすると拡大します)

図1の右半分は TECS のコンポーネント図になっています。ブリッジセル(BuddyBridge) からターゲットセル(Buddy) へ結合しています。左半分は、何かの記法に従っているわけではありませんが、TECS コンポーネント図風に、mruby のスクリプトとブリッジセルの関係を示しています。mruby 上で、BuddyBridge と結合する mruby オブジェクトを生成します (細かいことを言うと BuddyBridge は、 MRB_TT_DATA な mruby オブジェクトの本体となります)。この mruby オブジェクトを介して、mruby のスクリプトから、シグニチャ sHello の関数 (myMessage, yourMessage) を呼出すことができます。

■ HelloMruby の構成

HelloMruby の例を使って、もう少し詳しく MrubyBridgePlugin の働きを見ていきましょう。
図2 は HelloMruby の TECS コンポーネント図にコメントを書き足したものです。ただし mruby から操作される BuddyBridge と CharPointer セルは、左半分を丸くしています。この丸く記す方法は、本来の TECS コンポーネント図にはない記法ですが、図1との対比を分かりやすくするために、そのように記しています。

図2
(クリックすると拡大します)

この図には TECS コンポーネント化された mrubyVM があります。図1との対比では、mruby VM の中でスクリプトが動作することになります。BuddyBridge と Buddy は図1にもありました。

MrubyBridgePlugin が自動生成するセルが三つあります。これらの役割りは、以下の通りです。

* TECS モジュールを登録する
* TECS モジュールの下に TsHello クラスおよびメソッドを登録する
* TECS モジュールの下に CharPointer クラスおよびメソッドを登録する

■ TECS CDL の記述

図2に対応する TECS CDL による記述を示します。

// HelloMruby.cdl
// (1) 必要なものを import
import( <cygwin_kernel.cdl> );
import( "MyMrubyVM.cdl" );

// (2) シグニチャ sHello
signature sHello {
    ER myMessage( [in,string]const char_t *buf );
    ER yourMessage( [out,string(len)]char_t *buf, [in]int32_t len );
};

// (3) セルタイプ tBuddy
celltype tBuddy {
    entry sHello eEnt;
};

// (4) セル Buddy
cell tBuddy Buddy
{
};

// (5) MrubyBridgePlugin の呼出し
generate( MrubyBridgePlugin, sHello, "" );

// (6) ブリッジセルの設置
cell nMruby::tsHello BuddyBridge {
    cTECS = Buddy.eEnt;
};

// (7) mrubyVM の設置
cell tPosixMrubyVmInTask MrubyVMTask{
    cInit = VM_TECSInitializer.eInitialize;

    argc = 2;
    argv = { "HelloMruby.exe", "HelloMruby.rb" };

    priority = 11;
    stackSize = 4096;
    taskAttribute = C_EXP( "TA_ACT" );
};



図2で示したものを TECS CDL で表していますので、登場するシグニチャ、セルタイプ、セルは既に見たものになります。しかし TECS コンポーネント図には、シグニチャの持つ関数やセルの持つ属性を表しませんので、それらが CDL の記述では加えられています。

それでは、順を追って、何が書かれているか、見てみましょう。

(1) で cygwin_kernel.cdl と MyMrubyVM.cdl をインポートしています。
cygwin_kernel.cdl は、cygwin または POSIX 環境でテストするときのテスト用のタスク、セマフォを提供します。cygwin_kernel.cdl で定義されているセルタイプは、機能、コード品質ともに高くなく、テスト専用とお考えください。

MyMrubyVM.cdl は、mruby VM のセルタイプ tPosixMrubyVmInTask (複合コンポーネント)を定義しています。ここでは詳細を割愛しますが、cygwin (POSIX) 環境でマルチ VM のテストを容易に行えるように mruby VM を TECS コンポーネント化したものです。

ここで <> と "" の相違ですが、C の #include と同様の使い分けです。TECS ジェネレータは、この相違に基づいて、セルタイプコードのテンプレートを生成するかどうか、判断しています。<> の場合には、既に開発済みと判断して、セルタイプコードのテンプレートを生成しません。不要なテンプレートを生成させないようにして、tecsmerge (テンプレートに変化があったとき、セルタイプコードにマージさせるツール) を使う場合の失敗を予防することができます。

(2) ~ (4) は、シグニチャ、セルタイプとセルの基本的な記述です。ここでは、説明を割愛します。一点だけ補足すると TECS の out 引数は呼び元が記憶域を用意する必要があります。

(5) は MrubyBdridgePlugin を呼出しています。TECS では、いくつかのプラグインの種類があるのですが、MrubyBridgePlugin はシグニチャプラグインというもので、genereate の第一引数はプラグイン名、第二引数はシグニチャ名、第三引数はプラグインのオプションです。プラグインのオプションは、後述するドキュメントにありますので、参照してください。

(6) は、ブリッジセルの設置です。MrubyBdridgePlugin は、ブリッジセルタイプを自動生成します。ブリッジセルは CDL 上に記述して生成する必要があります。このセルタイプ名は、TECS ジェネレータの以下のメッセージで確認できます。

    MrubyBridgePlugin: [signature] ::sHello => [celltype] nMruby::tsHello => [class] TECS::TsHello

このメッセージは MrubyBdridgePlugin から出力されるもので、(5) まで記述した状態で TECS ジェネレータを動かす必要があります。

(7) は、VM の設置です。ここで重要なのは、以下の記述です。

    cInit = VM_TECSInitializer.eInitialize;

これは、初期化セル VM_TECSInitializer への結合です。VM_TECSInitializer は、MrubyBridgePlugin により自動生成されます。このセル名は、TECS ジェネレータの以下のメッセージで確認できます。

    MrubyBridgePlugin: join your VM's cInitialize to VM_TECSInitializer.eInitialize

このメッセージは MrubyBdridgePlugin から出力されるもので、(6) まで記述した状態で TECS ジェネレータを動かす必要があります。
注意点ですが、cInit は、オプショナルな呼び口です。従って、何も結合しなくてもビルド時にエラーになりません。mruby に、思ったようにクラスが登録されていないときは、この箇所を疑ってみる必要があります。

ここで mruby VM のセルタイプ tPosixMrubyVmIntask ですが、cygwin などの POSIX 環境で動作させるように構成したもので、(1) で import した MyMrubyVM.cdl で composite されています。コマンドラインから .rb を引数として起動するもので、試験用に準備したものです。mruby on asp+tecs パッケージで使用されている VM とは、構成の仕方が異なります。

もう一つ CharPointer が何ものかを説明していませんでしたが、TECS の char * 引数を扱うためのものです。文字列引数の扱いとして mruby の文字列オブジェクトからポインタを取り出して使う方法もあったのですが、以下の理由でやめました。

* mruby の内部表現が TECS の要求するものと一致しない可能性がある

    本家 Ruby の文字列オブジェクトは、文字コードも理解しており、将来そのような方向に向かう可能性がなくはない

* TECS の out 引数では呼び元がデータの格納領域を準備する必要がある

    mruby に文字数を指定して文字列オブジェクトの領域だけを確保する手段が用意されていない。
    また mruby の文字列オブジェクトは、文字列本体を共有することができるようになっていて、その共有を解消する関数も用意されていたが static で呼出させなかった.
    (これは 2013 年の春頃の状況で、今は変わっているかもしれません)

* int8_t, int16_t などの配列を扱うものと同じコードにできる

TECS は、どちらかといえば制御系組込みに用いることが想定されているため、文字列を扱うことは多くなく、他の型のポインタ(配列) と同様に扱う方が簡単、ということもありました。

■ mruby スクリプト

上記をビルドした後で、実行する際のスクリプトを以下に示します。

# HelloTECS.rb
# Buddy セルを mruby から操作する

# (1) ブリッジセルを buddyBridge に割り付ける
print "[I create] buddyBridge.\n"
buddyBridge = TECS::TsHello.new( "BuddyBridge" )

# (2) CharPointer を生成 (長さ32の配列)
len = 32
buf = TECS::CharPointer.new( len )

# (3) buf にメッセージを設定
buf.from_s "Hello TECS! (from mruby)"

# (4) Buddy の myMessage を呼出す
buddyBridge.myMessage( buf )

# (5) Buddy の yourMessage を呼出す
buddyBridge.yourMessage( buf, len )
print "[I received] " + buf.to_s + "\n"
    # buf は out 引数.Buddy で設定されて戻る
    # len 引数は、冗長だが、buf の実際の長さより大きいと例外発生



(1) で、ブリッジセルを mruby オブジェクトとして生成します。
クラス名は TsHello になります。これは、ブリッジセルのセルタイプ名 tsHello の先頭を大文字としたものです。TsHello は TECS モジュールの下に作られますので TECS::TsHello.new となります。BuddyBridge はブリッジセルの名前です。若干冗長のようですが、セルタイプ名とセル名の両方を指定して、mruby 側のブリッジオブジェクトを生成します。

(2) は、char * 引数を扱うための mruby オブジェクトを生成します。
char * (文字列) を CharPointer クラスとして扱います。

(3) で、buf にメッセージを設定します。
メッセージを長くすると、32文字で切り捨てられます。
ここで .from_s を忘れて代入してしまうと、CharPointer クラスから String クラスに変わってしまい、(4) の呼出しで mruby 例外が発生します。

(4) で Buddy にメッセージが渡されます。
これは sHello にあった関数と同じ名前、同じ引数並びとなります。

(5) で、Buddy からのメッセージを受け取り表示します。
これも sHello の関数です。

■ HelloMruby のビルド

cygwin または Linux 環境でビルドおよび実行できます。HelloMruby のソースコードは、TOPPERS プロジェクトの Contributed Software としてアップしてあります。以下のコマンドで、ダウンロードできます。

svn co http://dev.toppers.jp/svn_user/contrib/HelloMruby/tags/HelloMruby-V1.0.0


HelloMruby-V1.0.0 は MrubyBridgePlugin パッケージ の mruby-master の下、MrubyBridge の並びに置いてください。あとは、以下の手順でコマンドを実行していくだけです。

> cd tecsgen # MrubyBridgePlugin のパッケージの直下から始めます
> source set_env.sh # PATH などの設定 (必ず set_env.sh のあるディレクトリで行うこと)
> cd ../mruby-master
> make # mruby のビルド (libmruby.a が必要)
> cd HelloMruby-V1.0.0
> make # HelloMruby のビルド
> ./HelloMruby.exe # テスト実行
starting task 'tPosixMrubyVmInTask_MrubyVMTask' 004011AC
[tTaskMain2PosixMain] calling main: HelloMruby.exe HelloTECS.rb
[I create] buddyBridge.
[Buddy received] Hello TECS! (from mruby)
[I received] Hello mruby! (from TECS)
exiting task 'tPosixMrubyVM_MrubyVMTask'


■ その他のファイル

以上の他に、tBuddy などのセルタイプコードと Makefile が必要になります。

tBuddy などのセルタイプコードは、通常の TECS コンポーネントの範囲です。src/tBuddy.c と gen/tBuddy_templ.c の diff を取ってみると、どのような記述を付け加えたか (ハンドコーディング) が分かります。

Makefile は、TECS ジェネレータによって gen ディレクトリの下に作成される Makefile.templ (テンプレート) の名前を Makefile に変更して、そのまま用いています。MrubyBridgePlugin により LDFLAGS に -lruby -lm が追加されているため、POSIX 環境で GNU のツール類を使うのであれば、何も変更する必要がありません。

■ ドキュメント

MrubyBridgePlugin の詳しい説明は MrubyBridgePluginPackage/mruby-master/MrubyBridge の下の mrubyBridge.txt にあります。ポインタや構造体に関する説明は、MrubyBridgePluginPackage/tecsgen/tecs/mruby の下に TECSPointer.txt と TECSStruct.txt があります。構造体は、TOPPERS/ASP のカーネル API に出てくるような構造体、すなわち構造体メンバーがスカラー値であるものに限られます。

■ おわりに

ところで、本来書くつもりであった「MrubyBridgePlugin のマルチ VM 対応」については、また時間があれば書くつもりです。マルチ VM 対応では、TECS が mruby VM を静的にコンフィグレーションするツールとなり、TECS の効果的な利用方法であることが、より明確になると思います。勘のよい人であれば、本論で用いた CDL の例を見れば、どのようにすればマルチ VM 化できるかがわかるかもしれません。しかし、アクセス制限の方法は、この例からは読み取れない部分がありますので、その点の説明を加えたいと思っています。

テーマ : ソフトウェア開発
ジャンル : コンピュータ

プロフィール

hiro22022

Author:hiro22022
TECS 開発ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード