C
mruby
mruby_c
PSoC

mruby/cをPSoC5で動かす

More than 3 years have passed since last update.

この記事では,mruby/cのα版をPSoC5 Prototyping Kit(CY8CKIT-059)で動かす手順を示します.


PSoC4 Prototyping Kit(CY8CKIT-049)も同様の手順で可能です.


mruby/cは,実行時に必要な資源が少なくなるようにした mrubyの実装です.64KB以下での動作を想定しています.現在,α版を配布しております.

mruby/c α版の入手については,しまねソフト開発センター(ITOC)mruby/c の取り組みをご覧ください.


必要なもの


  • CY8CKIT-059

  • PSoC Creator

  • mruby/c α版

  • mruby OSS版(mrubyフォーラムからダウンロードできます)


全体の流れ


  1. 簡単なCのプログラムのプロジェクトを作成する

  2. 1のプロジェクトにmruby/cを追加する

  3. mrubyプログラムをコンパイルして,2に組込む


プロジェクト作成

空のプロジェクトを作成します.

img01.png

もし「Target hardware」に「CY8CKIT-059」が出てこない場合は,「Target device」で「CY8C5888LTI-LP097」を選択します.


PSoC4の場合は「CY8CKIT-049」または「CY8C4247AZI-M485」になります.


次の画面では「Empty Schematic」を選択します.次に,プロジェクト名などを入力します.ここではプロジェクト名を「mrubyc_sample」としています.

img02.png


LEDを点滅させる

回路図にDigital Output Pinを追加します.

img03.png

このPinをダブルクリックして,設定します.

img04.png


  • 「Name」を「LED」にする

  • 「HW connection」のチェックを外す


ピンを設定する

<プロジェクト名>.cydwr ファイルを開き,LEDのポートを「P2[1]」に設定します.

img05.png


PSoC4の場合は,LEDのポートは「P1[6]」になります.



ビルドする

ここでプロジェクトをビルドします.

ビルドすることで,先ほど設定したLEDの出力に関するコードが自動生成されます.


Cプログラムの作成

main.cのmain関数を次のように作成します.


main関数

int main()

{
CyGlobalIntEnable; /* Enable global interrupts. */

/* Place your initialization/startup code here (e.g. MyInst_Start()) */

for(;;)
{
/* Place your application code here. */
LED_Write(1);
CyDelay(200);
LED_Write(0);
CyDelay(200);
}
}



実行

ビルドを行い,[Debug]-[Program]でボードに書き込まれます.ボード上のLEDが点滅すればOKです.



mruby/c のファイルをコピーする

mruby/c α版を解凍して得られる srcフォルダ内の以下のすべてのファイル(xxx.cとxxx.h)を,PSoC Creatorのプロジェクトフォルダ(main.cがあるフォルダにコピーします).


プロジェクトにファイルを追加する

[Project]-[Existing Item...]で,mruby/c α版のファイル(xxx.c)を追加します.複数のファイルを選択して,一度に追加できます.


メソッドの追加

Cのプログラムで使用したLED_Write関数とCyDelay関数を,mrubyから利用できるようにします.Objectクラスにそれぞれのメソッドを追加します.

class.cファイルを開き,以下を追加,修正します.


追加するヘッダファイル

#include "LED.h"

#include "CyLib.h"


追加する関数

mrb_value c_led(struct VM *vm, mrb_value v)

{
LED_Write( v.value.i );
return v;
}

mrb_value c_delay(struct VM *vm, mrb_value v)
{
CyDelay(v.value.i);
return v;
}



mrb_init_class_object関数を書き換える

static void mrb_init_class_object(void)

{
// Class
static_class_object = mrb_class_alloc("Object", -1);
// Methods
mrb_define_method(static_class_object, "led", c_led);
mrb_define_method(static_class_object, "delay", c_delay);
}

mrb_init_class_object関数内のmrb_define_method関数により,Cの関数とmrubyのメソッドを対応付けます.



mrubyプログラムの作成

次のmrubyのプログラムを sample.rb として作成します.Cで作ったプログラムと違うタイミングでLEDが点滅します.


sample.rb

led 1

delay 100
led 0
delay 900


mrbcによるコンパイル

sample.rb を mruby(OSS版)でコンパイルして sample.c を作成します.sample.cをPSoCのプロジェクト内のmain.cと同じフォルダにコピーしておきます.

  mrbc -E -Bary sample.rb 


main.c を書き換え,Cからmrubyプログラムを呼び出す

main.cに以下を追加します.


ヘッダファイルの追加

#include "vm.h" 

#include "load.h"
#include "errorcode.h"
#include "static.h"
#include "sample.c"

mrubyc関数を追加します.


mrubyc関数

int mrubyc(void)

{
struct VM *vm;

init_static();

vm = vm_open();
if( vm == 0 ){
printf("VM open Error\n");
return -1;
}

int ret = loca_mrb_array(vm, ary);
if( ret != NO_ERROR ){
printf("MRB Load Error (%04x_%04x)\n", ret>>16, ret&0xffff);
return -1;
}

vm_boot( vm );

int keep_execute = 1;
while( keep_execute ){
if( vm_run_step(vm) < 0 ){
keep_execute = 0;
}
}

vm_close( vm );

return 0;
}



main関数

int main()

{
CyGlobalIntEnable; /* Enable global interrupts. */

/* Place your initialization/startup code here (e.g. MyInst_Start()) */

for(;;)
{
/* Place your application code here. */
mrubyc();
}
}



ビルドと実行

ビルドを行い,[Debug]-[Program]でボードに書き込まれます.ボード上のLEDが点滅すればOKです.


少々長い説明となりましたが,以上で mruby/c α版を PSoC5で動かすことができます.