目標

サイプレス社のマイコン評価ボード CY8CKIT-059で mruby/c を動作させて、LED点滅をさせる。
(mruby/c1.1、mrubyコンパイラ1.4を使用します)

準備するもの

作業手順

PSoC Creatorプロジェクトの作成

PSoC Creatorを起動します。

メニューから File > New > Project を選び、CreateProject Dialogを開きます。

20170105165043

Target device: 欄

  PSoC5LP - CY8C5888LTI-LP097を選びます。

最初はリストに同デバイスが表示されないと思うので、<Launch Device Selector>を選び、表示されたダイアログからCY8C5888LTI-LP097を選びます。

 20170105165051

Empty schematic を選びます。

 20170105165403

Workspace name欄を FlashLEDと書き換えます。

必要に応じて、Location欄を書き換えます。Location欄のパスに各種ファイルが作成されるので、このパスは覚えておきます。

出入力ピンの配置

  • 画面右 ComponentCatalog ペインから、Ports and Pins > Digital Output Pin をドラッグし、中央のペインへドロップします。
 20170105171102
  • 配置された Pin_1をダブルクリックし、Configure Dialogを開きます。
 20170105171151_1
  • Name欄を、LED1と書き換えます。
  • Type欄の HW connection チェックボックスのチェックを消します。

併せて、プッシュスイッチも配置しておきます。

  • 画面右 ComponentCatalog ペインから、Ports and Pins > Digital Input Pin をドラッグし、中央のペインへドロップします。
  • 配置された Pin_1をダブルクリックし、Configure Dialogを開きます。
20170105171508_1 
  • Name欄を、SW1と書き換えます。
  • Type欄の HW connection チェックボックスのチェックを消します。
  • Drive mode欄のプルダウンを、Resistive pull up に変更します。

画面左 Workspace Explorerペインの Pins をダブルクリックしてピンアサイン画面を表示します。

(表示されていない場合は、Project > Design Wide Resource 下にあるので、順に展開する)

右ペインの Port欄を以下のように設定します。

 20170105172324

 LED1 P2[1]

 SW1  P2[2]

ここまでの作業が正しいか確認

一旦ここまでの作業が正しくできているか、ビルドして確認します。

  • 左ペイン main.c をダブルクリックします。
  • C言語プログラムのひな形が作られているので、以下のように追記します。

 /* Place your initialization/startup code here (e.g. MyInst_Start()) */
for(;;)
{ /* Place your application code here. */ int sw1 = SW1_Read(); LED1_Write( sw1 ); }

  • メニューから Build > Build Design 01 を選びます。
  • Output欄へ、「--------------- Build Succeeded: ...」と表示されるのを確認します。
  • デバイスをUSBポートへ接続します。
  • メニューから Debug > Program を選択します。
  • Output欄へ、「Device 'PSoC 5LP CY8C5888LT*-LP097' was successfully programmed at ...」と表示されるのを確認します。
  • デバイス上でLED1(青色)が点灯し、プッシュスイッチ SW1を押すと消えるのを確認します。
写真1

mruby/c VMソースコードを、プロジェクトへ追加

  • mruby/cソースコードを展開します。
  • srcディレクトリ中の全ファイルをプロジェクトを作ったディレクトリDesign01.cydsnにコピーします。
  • hal_psoc5lpディレクトリを、halにリネームします。
  • PSoC Creatorの左ペイン Soruce Files 上で右クリックし、Add > Existing Item を選びます。
  • ファイルダイアログが表示されるので、コピーした srcディレクトリの全ての .c ファイルを選び開くボタンをクリックします。
 20170105175436

 

mrubyプログラムの作成

mrubyプログラムを作ります。以下のプログラムをsample1.rb として保存します。


led = 0
while true   if led == 1     led = 0   else     led = 1   end
  if sw1_read() == 0     led = 1   end
  led1_write( led )   sleep 1 end

mrubyプログラムのコンパイル

mrubyを動作させるやり方はいくつかありますが、今回はコンパイラ出力をC言語の配列で出力し、main.cへ includeする方法を採用します。

コンパイラで以下の通りコンパイルし、sample1.c ファイルを作ります。


mrbc.exe -E -Bsample1 sample1.rb
 

sample.c を表示して、どのように出力されたか確認しておくと良いでしょう。

main.c プログラムの変更

mruby/cを動作させるための変更、および、rubyプログラムから呼び出す関数を登録します。

#include <project.h>
#include "mrubyc.h"

#include "sample1.c"


#define MEMORY_SIZE (1024*30)
static uint8_t memory_pool[MEMORY_SIZE];

//================================================================
 /*! オンボードSW 現在状態の読み込み
*/
static void c_sw1_read(mrb_vm *vm, mrb_value *v, int argc)
{
  int sw1 = SW1_Read();
  SET_INT_RETURN(sw1);
}

//================================================================
/*! オンボードLED ON/OFF
*/
static void c_led1_write(mrb_vm *vm, mrb_value *v, int argc)
{
  LED1_Write(GET_INT_ARG(1));
}


//================================================================
/*! HAL (別途説明します)
*/
int hal_write(int fd, const void *buf, int nbytes)
{
  return 0;
}
int hal_flush(int fd)
{
  return 0;
}


int main()
{
  CyGlobalIntEnable; /* Enable global interrupts. */

  mrbc_init(memory_pool, MEMORY_SIZE);

  mrbc_define_method(0, mrbc_class_object, "sw1_read",   c_sw1_read);
  mrbc_define_method(0, mrbc_class_object, "led1_write", c_led1_write);

  mrbc_create_task( sample1, 0 );
  mrbc_run();

 return 0;
}



タイマー未使用の宣言

このチャプターでは、タイマー機能を使わないのでそれを宣言します。

  •  メニューから、Project > Build Settings を選び、Build Settingsダイアログを開きます。
  • 左ペインの Design01 > ARM GCC... > Compiler > General をクリックし右ペインの Preprocessor Definitions欄の初期値につづいて、"; MRBC_NO_TIMER" と追記します。
 20170106143333

または、右端にある [...] をクリックして表示されるダイアログを使っても、同様の事ができます。

クリーンビルドと実行

前項で宣言を追加したので、クリーンコンパイルをする方が安全です。

  • メニューから、 Build > Clean and Build Design01 を選びます。
  • Output欄へ、「--------------- Build Succeeded: ...」と表示されるのを確認します。
  • デバイスをUSBポートへ接続します。
  • メニューから Debug > Program を選択します。
  • Output欄へ、「Device 'PSoC 5LP CY8C5888LT*-LP097' was successfully programmed at ...」と表示されるのを確認します。
  • デバイス上でLED1(青色)が点滅し、プッシュスイッチ SW1を押すと点いたまま消灯しなくなる動作を確認します。

プログラム説明

mrubyプログラム(再掲)


led = 0
while true   if led == 1     led = 0   else     led = 1   end
  if sw1_read() == 0     led = 1   end
  led1_write( led )   sleep 1 end
  • 変数ledで、LED1の点灯(=1)、消灯(=0)を制御しています。
  • 全体ループの中で、0と1を都度反転させて、LEDを点滅させます。
  • ただし、スイッチ SW1が押されている(=0) 時には、強制点灯させます。
  • LED1を実際に点灯/消灯させた後、1秒待ってから次のループを行います。 

main.c

main関数で、mrubyからC言語へのwrapperを宣言します。

以下の文は、mrubyでsw1_readメソッドをコールしたとき、実際に呼ばれるC言語の関数へのマッピングを行っています。


  mrbc_define_method(0, mrbc_class_object, "sw1_read",   c_sw1_read);

実際に呼ばれるC言語の関数では、mrubyからの引数をGET_xxx_ARGマクロで取得し、SET_xxx_RETURNで値を返します。


  LED1_Write(GET_INT_ARG(1);
  SET_INT_RETURN(sw1);