mruby

GR-SAKURAでmrubyを使う

More than 5 years have passed since last update.

ルネサステクノロジのRX63Nを積んだArduino互換ボードGR-SAKURA

(http://japan.renesas.com/products/promotion/gr/index.jsp)

でmrubyを使用することが出来たので手順をメモ

mrubyのコンパイル手順はまんま

http://d.hatena.ne.jp/kyab/20130201

の通りですkyabさんthx

ステータスとしてはとりあえず動かしてみた程度で本格的に使えるところまで試してません。なのでメモリ不足等不具合が沢山あると思います

あくまでもasisでどうぞ

GR-SAKURAの開発環境はWebコンパイラでの提供です。これではmrubyがコンパイル出来ませんのでまずは、ローカルの開発環境を構築する必要があります。

なお、当方windows環境がないので手順はLinux(Ubuntu)とMacでの手順となります。KPITよりwindows版のgcc提供されていますのでこれを利用すれば使えるとはおもいますが、確認してません。

手順は次の通り

1. ローカルビルド環境の構築

2. webコンパイラ環境からGR-SAKURA用のライブラリを取得

3. mrubyのコンパイル

* 設定の記述

* build_config.rb

* include/mrbconf.h

4. ローカルビルド環境でmrubyをコンパイル

5. 作成したlibmruby.aとヘッダファイル郡をGR-SAKURA用ローカルビルド環境へコピー

6. GR-SAKURA用ローカルビルド用makefileの修正

7. rxduino.hファイルの修正 (C99対応)

===============================================


Build GCC Tool Chain for OS X and Ubuntu (RX版)

===============================================

Linux環境(Ubuntu)ではKPITよりRXシリーズのGCC toolchainはrpm形式のバイナリパッケージが提供されていますのでalienでパッケージをdeb形式に変換してインストールしたほうがいいです。その場合は以下のクロスコンパイルの構築手順は飛ばして下さい


クロスコンパイラのコンパイル準備

=======

必要なライブラリ、プログラム


  • mpfr

  • gmp

  • libmpc

  • libelf

  • texifo

が必要なのでインストールする


  • Homebrewを利用する場合は


$ brew install mpfr gmp libmpc libelf texinfo

でインストール


  • Ubuntuの場合

クロスコンパイラをソースからコンパイルする場合依存するパッケージを


$ sudo apt-get install curl flex bison libgmp3-dev libmpfr-dev texinfo libelf-dev autoconf build-essential libncurses5-dev libmpc-dev

でインストール

Macの場合さらにGCCが必要なのでGCCをインストールする

Homebrewの場合、標準のformulaにはgccがないのでdupsからインストールする必要がある


$ brew install https://raw.github.com/Homebrew/homebrew-dupes/master/gcc.rb --enable-all-languages --use-llvm

これでgccがgcc-{Version}で利用できる

コンパイル例:

$ gcc-4.7 hoge.c

以降でコンパイルはgcc-4.7使用環境での手順を記述します。

実際には使用する最新のGCCのバージョンで読み替えてください。

例えばコンパイルオプションのCC=gcc-4.7はCC=gcc-{実際のバージョン}のように


renesas RX用ツールチェインのダウンロード

===============================

renesasのRXシリーズのコンパイラの構築なので、

御本尊のGCCでなく開発元のKPITからソースコードをダウンロードします。(要開

発者登録)

(2012.10時点だと)


  • GNU v12.02

  • GDB v12.02

が最新なようです。


  • GDBRX v12.02 Source Code of GDB

  • GNURX v12.02 Source Code of GCC

  • GNURX v12.02 Source Code of Binutils

  • GNURX v12.02 Source Code of Newlib

をそれぞれダウンロードしますファイル名は各々


  • gdb-7.4.1_rx_v850_sh_h8_v12.02.tar.bz2

  • gcc-4.7.0_rx_v850_sh_h8_v12.02.tar.bz2

  • binutils-2.22_rx_v850_sh_h8_v12.02.tar.bz2

  • newlib-1.20.0_rx_v850_sh_h8_v12.02.tar.bz2

となります。


構築

=======

後は展開してコンパイルすればよいのですが...

はまりどころがあります

まず、gccのソースディレクトリでコンパイルを実行するとエラーがでます。


注意:コンパイルディレクトリとソースディレクトリが同一だとエラーになります

ソースディレクトリとは別ディレクトリでコンパイルする必要がありますので展開後コンパイル用のディレクトリを作成します。

またgccと一緒にnewlibをコンパイルするためnewlibのシンボリックリンクをgccに張ります。

ダウンロードしたディレクトリで

$ mkdir kpit

$ cp gdb-7.4.1_rx_v850_sh_h8_v12.02.tar.bz2 kpit
$ cp gcc-4.7.0_rx_v850_sh_h8_v12.02.tar.bz2
$ cp binutils-2.22_rx_v850_sh_h8_v12.02.tar.bz2 kpit
$ cp newlib-1.20.0_rx_v850_sh_h8_v12.02.tar.bz2 kpit

$ cd kpit
$ tar -jxvf gdb-7.4.1_rx_v850_sh_h8_v12.02.tar.bz2
$ tar -jxvf gcc-4.7.0_rx_v850_sh_h8_v12.02.tar.bz2
$ tar -jxvf binutils-2.22_rx_v850_sh_h8_v12.02.tar.bz2
$ tar -jxvf newlib-1.20.0_rx_v850_sh_h8_v12.02.tar.bz2

としてソースを展開します

私は複数のGNUツールチェインをインストールしておりMCUのアーキテクチャ毎にインストール先を変えています。今回はRXシリーズ用のディレクトリとして~/rx-toolsにインストールする様にします。

configureのオプション -prefix={インストールディレクトリ}でインストール先を指定します


binutils


まずはbinutils


$ cd binutils-2.22
$ ./configure -target=rx-elf -prefix=~/rx-tools -disable-werror CC=gcc-4.7
$ make
$ make install

コンパイル前にパスを通す

$ export PATH=$PATH:~/rx-tools/bin/


GCC



$ cd ..
$ cd gcc-4.7.0

ビルド用のディレクトリとシンボリックリンクの作成


$ mkdir build
$ ln -s ../newlib-1.20.0/newlib .
$ ln -s ../newlib-1.20.0/libgloss .
$ cd build

$ ../configure --prefix=~/rx-tools --target=rx-elf --enable-lnguages=c,c++ --disable-libstdcxx-pch --disable-multilib --with-newlib --disable-nls --disable-libgfortran CC=gcc-4.7

$ make
$ make install


newlib



$ cd ../../newlib-1.20.0
$ ./configure --enable-newlib-hw-fp --target=rx-elf --prefix=~/rx-tools

$ make
$ make install

$ cd ../gdb-7.4.1
$ ./configure --prefix=~/rx-tools --target=rx-elf --disable-werror

$ make
$ make install

.bashrcなどにパスを通しておく


$ export PATH=$PATH:~/rx-tools/bin/


参照元情報:

chibiegg日誌: http://blog.chibiegg.net/2009/04/09_12_288.htm

codingcipher: http://codingcipher.wordpress.com/category/compilers/

==============================================


webコンパイラ環境からGR-SAKURA用のライブラリを取得

==============================================

まずはローカル環境にWebコンパイラのProject_Rootと同じディレクトリツリーを構成し対応したファイルを非常に面倒くさいですが1つづつダウンロードしてローカル環境にディレクトリツリー再構成します。

再構成例: ~/src/sakuraディレクトリを作成して再構成した

src/sakura

|
+--gr_build
+--gr_common
+--include
+--rxduino
analogio.h
binary.h
delay.h
digitalio.h
interrupt.h
progmem.h
random.h
rtc.h
rxduino.h
serial.h
shiftout.h
tone.h
wiring.h
+--tkdnhal
boarddef.h
tkdn_dflash.h
tkdn_servo.h
brd_grsakura.h
tkdn_ether.h
tkdn_spi.h
brd_grume.h
tkdn_gpio.h
tkdn_timer.h
hwsetup.h
tkdn_hal.h
tkdn_tone.h
iodefine_gcc62n.h
tkdn_i2c.h
tkdn_usb.h
iodefine_gcc63n.h
tkdn_interrupt.h
tkdn_version.h
misc.h
tkdn_pwm.h
tkdnip.h
tkdn_adc.h
tkdn_rtc.h
tkusbhost.h
tkdn_dac.h
tkdn_sci.h
+--lib
libc.a
libgcc.a
librxduino.a
libstdc++.a
libtkdnhal.a
libg.a
libm.a
libsim.a
libsupc++.a
libtkdnip.a
r_sakura.gsi
intvect.h
intvect63n.h
lowlevel.c
gstart.o
intvect.c
intvect.o
lowlevel.o
makefile
gr_sketch.cpp

=====================


mrubyのコンパイル

=====================

mrubyをgithubより取得

$ git clone https://github.com/mruby/mruby.git


build_config.rbを編集

build_config.rbに次のコードを追加

以下例はmrubyは ~/work/mrubyに置き~/rx-toolsへクロスコンパイラをインストールしたとして記述

違う場合はTOOL_PATHを書き換えて下さい。

MRuby::CrossBuild.new('gr-sakura') do |conf|

toolchain :gcc

TOOL_PATH = "~/rx-tools/bin"

conf.cc do |cc|
cc.command="#{TOOL_PATH}/rx-elf-gcc"
cc.flags << "-Wall -g -O2"
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"

conf.linker do |linker|
linker.command="#{TOOL_PATH}/rx-elf-ld"
end
conf.archiver do |archiver|
archiver.command = "#{TOOL_PATH}/rx-elf-ar"
archiver.archive_options = 'rcs %{outfile} %{objs}'
end
end

conf.bins = []
end

include/mrbconf.hは特に書き換えなくてもコンパイルできますがメモリ使用量に影響しますので必要に応じて書き換えて下さい。

今回はそのままでいきます


コンパイル

$ cd ~/work/mruby

$ make clean
$ make

~/work/mruby/build/gr-sakura以下にGR-SAKURA用のmrubyライブラリがコンパイルされます。これらをgr-sakuraのローカル環境からリンクすることでmrubyが実行できます。

===================


作成したlibmruby.aとヘッダファイル郡をGR-SAKURA用ローカルビルド環境へコピー

===================

webコンパイラ環境からGR-SAKURA用のライブラリを取得で作成した

プロジェクトディレクトリへmrubyのライブラリ、ヘッダファイルをコピーします。

以下プロジェクトのディレクトリを~/src/sakuraとして説明します

プロジェクトディレクトリにmrubyディレクトリを作成し必要なファイルを~/work/mruby/build/gr-sakuraからコピーします

$ cd ~/src/sakura

$ mkdir mruby
$ cd mruby
$ cp ~/work/mruby/build/gr-sakura/lib/libmruby.a .
$ cp -r ~/work/mruby/include .

========


GR-SAKURA用ローカルビルド用makefileの修正

========

~/src/sakura/makefileを編集します

CCPATHにクロスコンパイラの実行パス~/rx-tools/bin/

LIBFILESに./mruby/libmruby.a

CCINCとCPPINCに-I./mruby/includeを追加します。

変更後のmakefile

CCPATH = ~/rx-tools/bin/

OBJFILES = ./gr_sketch.o ./gr_common/intvect.o ./gr_common/lowlevel.o
LIBFILES = ./gr_common/lib/libc.a ./gr_common/lib/libg.a ./gr_common/lib/libgcc.a ./gr_common/lib/libm.a ./gr_common/lib/librxduino.a ./gr_common/lib/libsim.a ./gr_common/lib/libstdc++.a ./gr_common/lib/libsupc++.a ./gr_common/lib/libtkdnhal.a ./gr_common/lib/libtkdnip.a ./mruby/libmruby.a
CCINC = -I./gr_build -I./gr_common -I./gr_common/include -I./gr_common/include/rxduino -I./gr_common/include/tkdnhal -I./gr_common/lib -I./mruby/include
CPPINC = -I./gr_build -I./gr_common -I./gr_common/include -I./gr_common/include/rxduino -I./gr_common/include/tkdnhal -I./gr_common/lib -I./mruby/include
TARGET = sketch
CC = $(CCPATH)rx-elf-gcc -Wall -g -O2 $(CCINC)
CPP = $(CCPATH)rx-elf-gcc -Wall -g -O2 $(CPPINC)
AS = $(CCPATH)rx-elf-as
LNK = $(CCPATH)rx-elf-ld
#CNV = $(CCPATH)rx-elf-objcopy --srec-forceS3 --srec-len 32 -O srec
CNV = $(CCPATH)rx-elf-objcopy -O binary
DMP = $(CCPATH)rx-elf-objdump
OBJS = ./gr_common/gstart.o $(OBJFILES) $(LIBFILES)
LFLAGS = -L./gr_common/lib/ -lrxduino -lstdc++ -lsupc++ -lc -lsim -lgcc -lm -ltkdnhal -nostartfiles
MAKEFILE = makefile
ROMSCRIPT=./gr_common/gr_sakura.gsi

make = make --no-print-directory

all: rom

rom: $(OBJS) $(MAKEFILE) $(ROMSCRIPT)
$(LNK) -Map ./gr_build/$(TARGET).map $(OBJS) -T $(ROMSCRIPT) $(LFLAGS) -o $(TARGET).elf
$(CNV) $(TARGET).elf $(TARGET).bin
rm -f *.o
rm -f $(TARGET).elf

#gstart.o: gstart.s
# $(AS) -o gstart.o gstart.s

.c.o:
$(CC) $(CFLAGS) -c $< -o $@

.cpp.o:
$(CPP) $(CFLAGS) -c $< -o $@

==============


rxduino.hファイルの修正 (C99対応)

==============

rxduino.hで定義されている型はc99ではstdint.h

とかで定義済み、mrubyはc99のヘッダファイルを使用しているので

型が二重定義となりそのままではコンパイル出来ない

~/src/sakura/gr_common/include/rxduino/rxduino.h

の型定義をコメントアウトする

rxduino.hの

//型の定義

のコメント行から

int64_tの定義行までコメントアウトする

===


Lチカでテスト

===

お決まりのLEDの点滅プログラムでテストする

下記のmrubyテストコードをled.rbという名前で保存する。

led.rb

HIGH = 1

LOW = 0

loop do
cdigitalWrite(100, HIGH);
cdelay(200);
cdigitalWrite(100, LOW);
cdelay(100);
cdigitalWrite(101, HIGH);
cdelay(200);
cdigitalWrite(101, LOW);
cdelay(100);
cdigitalWrite(102, HIGH);
cdelay(200);
cdigitalWrite(102, LOW);
cdelay(100);
cdigitalWrite(103, HIGH);
cdelay(200);
cdigitalWrite(103, LOW);
cdelay(100);
end

これをmrbcでC言語の配列としてバイトコンパイルする

~/work/mruby/bin/mrbc -Bcode led.rb

led.cが作成されるのでテスト用のスケッチにインクルードする

コンパイルするLチカスケッチは

gr_sketch.cpp

/*GR-SAKURA Sketch Template Version: V1.02*/

#include <rxduino.h>

#define CHANGE_HEAP_SIZE(size) __asm__ volatile ("\t.globl _min_heap_size\n\t.equ _min_heap_size, " #size "\n")

#include "mruby.h"
#include <mruby/irep.h>
#include <mruby/string.h>

#include "led.c"

CHANGE_HEAP_SIZE(100*1024); //ヒープサイズを100kbにする。

extern const char code[];

//digitalWrite function
mrb_value cdigitalWrite(mrb_state *mrb, mrb_value self){
mrb_int pin;
mrb_int val;

mrb_get_args(mrb, "ii", &pin, &val);
digitalWrite(pin, val);
return mrb_nil_value();
}

//delay function
mrb_value cdelay(mrb_state *mrb, mrb_value self){
mrb_int val;
mrb_get_args(mrb,"i", &val);
delay(val);
return mrb_nil_value();
}

void setup(){

pinMode(PIN_LED0,OUTPUT);
pinMode(PIN_LED1,OUTPUT);
pinMode(PIN_LED2,OUTPUT);
pinMode(PIN_LED3,OUTPUT);

mrb_state *mrb = mrb_open();

mrb_define_method(mrb, mrb->object_class, "cdigitalWrite", cdigitalWrite, ARGS_REQ(2));
mrb_define_method(mrb, mrb->object_class, "cdelay", cdelay, ARGS_REQ(1));

mrb_load_irep( mrb, code);

}

void loop(){

}

makeして出来たsketch.binをGR-SAKURAへ書き込んでボード上の4つのLEDが順番に点灯すればOKです。


最後に

実際mrubyが動くまでかなりの手間がかかります。しかもメモリもGR-SAKURA、RAM128Kでかなり厳しいですとてもインタラクティブに使うのは無理だと思います。事前にバイトコンパイルすることで何とか使うという感じです。でもCで一から書くことを考えればライブラリを揃えることでお手軽になるかなとういう期待で動かしてみました。

ここまで書いたところで

mrubyのボードが発売になるようです

http://enzi.cc/

これならRAMも1Mあるのでいいのではないでしょうか。実際に使うにはこれくらいのリソースとC言語でのライブラリが必要だと思います