コンピュータを楽しもう! RSSフィード Twitter

2014-01-23

[]mrubyでのバイナリの扱い その2 17:23

以前のブログ文字列でバイナリを扱えることを書きましたが、これを書いたことすら忘れてしまって、また、バイナリについて悩んでしまったので、さらに、防備録として書いておきます。

mrubyで.hexは使えない

Ruby 16進数 変換」で検索すると、16進数は.hexで変換できると出てきます。

print '80'.hex #=> 128 ただし、mrubyでは使えません。

これでいいのかと思って、mrubyで .hexを使ってみましたが使えませんでした。16進数表記は、0x を付ければいいだけ。

16進表記は0xを付ける

Rubyの場合もC言語などと同じで、頭に0xを付ければ16進数となります。

print 0x80 #=> 128

 より、詳しくは、先のブログで・・・。

2013-12-29

[]FDTを用いてGR-SAKURAmotファイルを書き込む E1経由編 17:26

E1を買った云々と書きながら、先にUSB編を書いてしまいました。ここではE1経由でGR-SAKURAmotファイルを書き込む方法を書きます。

FDT(Flash Development Toolkit)のダウンロードは、先のUSB編で書きましたのでそちらを見てください。

試しに、書いてみるGR-SAKURAの元ファーム「Gr_sakura_fw_rev1.mot」のダウンロードについても、先のUSB編で書きましたのでそちらを見てください。


E1経由のmotファイルの書き込み方法

E1を買った目的がHEWを使ってGR-SAKURAプログラムを作ったりデバッグしたりするということでしたので、ルネサスからe1e20rxfullv10300.exeとccrxv102r01_ev.exeダウンロードしてインストールします。ダウンロードについては西村さんのブログに詳しく書かれています。


GR-SAKURAとE1とUSBケーブルを接続する

GR-SAKURAJTAGのポートにヘッダピンを付けてE1と接続します。また、E1とUSBケーブルを接続します。FDTとE1E20RXが正常にインストールできていれば、Windows7の場合ですが、USBドライバは自動で認識されると思います。

f:id:tarosay:20131229163549j:image:w640


FDTの設定

FDTを起動して新規設定を選びます。初めての場合は、自動的に新規設定画面になるかもしれません。

f:id:tarosay:20131229153031j:image:w320

デバイスカーネルの選択は、一番下の「Generic BOOT Device」を選びます。「次へ」を押します。

f:id:tarosay:20131229154427j:image:w320

通信ポートの選択は「E1 Direct」を選びます。「次へ」を押します。

f:id:tarosay:20131229163800j:image:w320

電源の供給は、3.3Vを供給する場合は下のように設定して「OK」を押します。

f:id:tarosay:20131229163801j:image:w320

ピン設定は、GR-SAKURAの場合、MDはLOW、EMLEもLOW、UBもLOWなので、下図のような設定になります。チェックを入れたら「OK」を押します。

 io0 (EMLE)    - LOW
 io2 (PC7/UB)  - LOW
 io3 (MD)      - LOW

f:id:tarosay:20131229163802j:image:w320

E1と接続している場合は下のメッセージが出ます。「OK」を押します。

f:id:tarosay:20131229165834j:image:w320

E1のシリアルのようなものが表示されるので「OK」を押します。

f:id:tarosay:20131229165835j:image:w320

デバイスを聞いてくるので、RX600シリーズのLittieEndianで「OK」を押します。

f:id:tarosay:20131229165836j:image:w320

そうすると、汎用デバイスの確認がすべて通ります。

f:id:tarosay:20131229165837j:image:w320

OKするとクロックの設定画面が出ます。入力クロックは12MHz、メインクロックの逓倍比を 8、周辺クロックの逓倍比を 4として「次へ」を押します。

  入力クロック                 - 12.00MHz
  メインクロックの逓倍比(CKM)  - 8
  周辺クロックの逓倍比(CKP)    - 4

f:id:tarosay:20131229165838j:image:w320

接続タイプはこのままで「次へ」を押します。

f:id:tarosay:20131229165839j:image:w320

書き込みオプションはこのままで「次へ」を押します。

f:id:tarosay:20131229165840j:image:w320

リセットピンセッティングは何もせずにこのままで「完了」を押します。

f:id:tarosay:20131229165841j:image:w320

設定が終わって、E1接続が完了します。

f:id:tarosay:20131229165842j:image:w320


E1経由で書き込む

「File Selection」の 「User / Data Area」にチェックして右向き黒三角ボタンを押し、書き込むmotファイルを指定します。今回書き込むのは「Gr_sakura_fw_rev1.mot」です。

f:id:tarosay:20131229155656j:image:w320

スタートを押すと書き込みが始まります。38400bpsなので少し時間が掛かります。

f:id:tarosay:20131229172012j:image:w320

しばらくすると終わります。

f:id:tarosay:20131229172013j:image:w320

後は、デバイスとの切断を押すと下の画面が出て「OK」を押すとE1接続が切れます。

f:id:tarosay:20131229172014j:image:w320

接続が切れた画面

f:id:tarosay:20131229172015j:image:w320

これでmotファイルの書き込み終了です。E1コネクタを抜いてGR-SAKURAを起動してください。もしくはHEWを立ち上げてデバッグもできます。

[]FDTを用いてGR-SAKURAmotファイルを書き込む USB16:18

ずいぶん前に買ったルネサスのE1エミュレータがありまして、今まで箱から出していなかったのですが、GR-SAKURAにつないで遊んでみようと使い始めました。とりあえず、motファイルをGR-SAKURAに書き込むところを防備録として書いておきます。


FDT(Flash Development Toolkit)のダウンロード

FDT(フラッシュ開発ツールキット)の無償評価版をルネサスのサイトからダウンロードします。2013/12/29現在では「フラッシュ開発ツールキット V.4.09 Release 02」が最新でした。インストールしてください。


GR-SAKURAの元ファームを書きこんでみる

試しに、GR-SAKURAの元ファームである「Gr_sakura_fw_rev1.mot」を書き込んでみたいと思います。Gr_sakura_fw_rev1.motRenesas Rulzサイトに有ります。ダウンロードしてください。


E1を使わないmotファイルの書き込み方法

なんと、GR-SAKURAmotファイルを書き込むためには、E1が必要だと思っていたのですが、E1を使わなくてもUSB経由で書き込めることがわかりました。

ということは、間違ってGR-SAKURAに初めから入っているファームを壊してしまっても、ルネサスから無償のFDTをダウンロードしてくるだけで、元のファームに書き戻すことができるのですね。知りませんでした。


GR-SAKURAUSBケーブルを接続する

今まで謎だったGR-SAKURAについているスイッチの意味がわかりました。このスイッチを通常と反対側(写真参照)にスライドするとUSB経由でのファーム書き込みモードになります。回路的にはMDピンがLOWに落ちます。そして、GR-SAKURAUSBケーブルを接続します。FDTが正常にインストールできていれば、Windows7の場合ですが、USBドライバは自動で認識されると思います。

f:id:tarosay:20131229153030j:image:w320


FDTの設定

FDTを起動して新規設定を選びます。初めての場合は、自動的に新規設定画面になるかもしれません。

f:id:tarosay:20131229153031j:image:w320

デバイスカーネルの選択は、一番下の「Generic BOOT Device」を選びます。「次へ」を押します。

f:id:tarosay:20131229154427j:image:w320

通信ポートの選択は「USB Direct」を選びます。「次へ」を押します。

f:id:tarosay:20131229154428j:image:w320

GR-SAKURAと接続している場合は下のメッセージが出ます。「OK」を押します。

f:id:tarosay:20131229154429j:image:w320

GR-SAKURAのVID等が表示されるので「OK」を押します。

f:id:tarosay:20131229154430j:image:w320

デバイスを聞いてくるので、RX600シリーズのLittieEndianで「OK」を押します。

f:id:tarosay:20131229154431j:image:w320

そうすると、汎用デバイスの確認がすべて通ります。

f:id:tarosay:20131229154432j:image:w320

OKするとクロックの設定画面が出ます。12MHzで「次へ」を押します。

f:id:tarosay:20131229155654j:image:w320

書き込みオプションはこのままで「完了」を押します。

f:id:tarosay:20131229155653j:image:w320

設定が終わって、USB接続が完了します。

f:id:tarosay:20131229155655j:image:w320


USB接続で書き込む

「File Selection」の 「User / Data Area」にチェックして右向き黒三角ボタンを押し、書き込むmotファイルを指定します。今回書き込むのは「Gr_sakura_fw_rev1.mot」です。

f:id:tarosay:20131229155656j:image:w320

スタートを押すと書き込みが始まり、あっという間に終了します。

f:id:tarosay:20131229155657j:image:w320

後は、デバイスとの切断を押すと下の画面が出て「OK」を押すとUSB接続が切れます。

f:id:tarosay:20131229155658j:image:w320

後は、GR-SAKURAのスライドスイッチを元に戻せばファームの書き込み終了です。結構、簡単でした。

続けて、E1経由編を書きたいと思います。

2013-10-14

[]バイナリファイルをアップロードする 22:58

mrubyをいじり始めてRubyに興味を持ち、最近、Railsをいじり始めました。

Railsも難しくてなかなか勉強も捗りませんが、やったことを自分の防備録として書いておきます。

スマホなどからサーババイナリファイルをアップロードしたかったので、その方法を調べてようやくできたので書いておきます。

使用しているバージョンは下記です。

$ ruby --version
ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-linux]

$ rails --version
Rails 3.2.14

Railsアプリケーションを作る

今回はchotplusというアプリケーションを作成します。生成されたらフォルダに入ります。

$ rails new chotplus
$ cd chotplus

Gemfileの修正

ファイルのアップロードに'Carrierwave'を使うので、gem 'carrierwave'を追記します。後、gem 'therubyracer'のコメントを外します。

   gem 'therubyracer', :platforms => :ruby
  gem 'carrierwave'

Bundleする

Gemfileの修正が終わったら、bundle installします。

$ bundle install

Java Scriptを有効にする

Java Scriptを有効にするため/config/environments/production.rbを修正します。

config.serve_static_assets = true にします。

# Disable Rails's static asset server (Apache or nginx will already do this)
  config.serve_static_assets = true

バイナリアップロードする受け皿を生成する

バイナリアップロードときに指定するカラムを設定します。

$ rails g uploader runningrecord

runningrecordというカラムを設定しました。これにより、app/uploaders/にrunningrecord_uploader.rbが生成されています。

$ ls -l
合計 2
-rwxrwxrwx. 1 root root 1510 1014 12:13 2013 runningrecord_uploader.rb

runningrecord_uploader.rb の中身(コメントは省略)。CarrierWave::Uploader::Baseを継承したRunningrecordUploader クラスができて、保存される場所が書かれています。

# encoding: utf-8
class RunningrecordUploader < CarrierWave::Uploader::Base
  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
end

Controller、View、Modelを自動生成する

scaffoldを用いて、Controller、View、Modelを自動生成します。先に作成した「runningrecord」カラムは必ず必要です。logという名称にしました。

$ rails g scaffold log name:string title:string: datetime:string runningrecord:string temp:string

下記のようなデータベースが生成されることになります。

class CreateLogs < ActiveRecord::Migration
  def change
    create_table :logs do |t|
      t.string :name
      t.string :title
      t.string :datetime
      t.string :runningrecord
      t.string :temp

      t.timestamps
    end
  end
end

データベースを作成する

データベースを生成します。

$ rake db:migrate

モデルにmount_uploaderを追記する

app/models/log.rb に uploaderを追記します。RunningrecordUploader は、runningrecord_uploader.rbのクラス名です。

class Log < ActiveRecord::Base
  attr_accessible :datetime, :name, :runningrecord, :temp, :title
  mount_uploader :runningrecord, RunningrecordUploader
end

Viewの_form.html.erbを修正する

ファイルをアップロードできるように、app/views/logs/_form.html.erb を修正します。

<%= f.text_field :runningrecord %>を、<%= f.file_field :runningrecord %>に変更します。

  <div class="field">
    <%= f.label :runningrecord %><br />
    <%= f.file_field :runningrecord %>
  </div>

日本語ファイル名を扱えるようにする

CarrierWaveは、そのままでは日本語ファイル名を扱えないので扱えるようにします。config/initializers フォルダに carrierwave.rb というファイルを作成して、下記の1行の内容を書きます。

CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/

これで日本語ファイル名が扱えるようになります。

rails server

rails serverを起動して確かめます。

$ rails server

http://localhost:3000/logs にアクセスすると下記のような画面が出ました。

f:id:tarosay:20131014225042j:image

New Logをクリックすると入力画面になりました。

f:id:tarosay:20131014225043j:image



アップロードしたファイルをダウンロードする

試しにtest.logファイルをアップロードしました。

f:id:tarosay:20131014225044j:image

ダウンロードするには、runningrecord カラムにそのままのURLが表示されているので、それをhttpプロトコルで指定して呼び出せばOKです。

この場合は、http://localhost:3000/uploads/log/runningrecord/4/test.log を呼べばいいことになります。


以上、Railsでファイルのアップロードダウンロードを行う方法を防備録として書きました。

2013-10-11

[]mrubyでのバイナリの扱い 01:06

GR-SAKURAにmrubyを移植しているのですが、Rubyに関してそれほど詳しくないので、バイナリをどう扱えばいいのか分かりませんでした。

例えば、Cなどでよくある write関数(write(int handle, void *buf, unsigned n))などを実現したいとき、mrubyではどのように扱えばいいのか?

mrubyに詳しい方に聞いてみたところ分かりました。

mrubyは文字列バイナリも扱える

そう、mrubyは文字列バイナリも扱えました。結局、Luaと同じでした。

例えば、0x10 0x20 0x30 0xD0 0xE0 0xF0というバイナリデータを作りたいときは以下のように書けます。

bin = 0x10.chr + 0x20.chr + 0x30.chr + 0xd0.chr + 0xe0.chr + 0xf0.chr

たとえ、文字列に0が含まれていても大丈夫です。下記のようなバイナリ列もできます。

bin = 0.chr + 0.chr + 0.chr + 0.chr + 0.chr + 0.chr

chrはmrbgem扱い

ここで注意が必要です。chrはmrbgemになっており、ビルドするときにmruby-numeric-extをインクルードする必要が有ります。

mruby-numeric-extをインクルードするには、build_config.rbに下記を追加するだけです。

# Cross build for GR-SAKURA
MRuby::CrossBuild.new('grsakura') do |conf|
   toolchain :grsakura

   conf.gem "#{root}/mrbgems/mruby-numeric-ext"
end

バイナリ列を扱うmruby関数を作る

では、バイナリ列を扱うmruby関数を作るにはどうするか、それは単純に文字列を扱うメソッドを作成すればいいだけです。

例えば、GR-SAKURA関数にSerial.write(const unsigned char *buf,int len)というものが有ります。これをmrubyでラップするとすると以下のようになります。

ライブラリを定義します。int read() と write(const unsigned char *buf,int len)を作ってみます。

//**************************************************
// ライブラリを定義します
//**************************************************
void serial_Init(mrb_state *mrb)
{
	struct RClass *systemModule = mrb_define_module(mrb, "Serial");
	mrb_define_module_function(mrb, systemModule, "read", mrb_system_read, ARGS_NONE());
	mrb_define_module_function(mrb, systemModule, "write", mrb_system_write, ARGS_REQ(2));
}

read()は下記です。1文字読み込んでint型なので、mrb_fixnum_value()を使って戻しています。

//**************************************************
// シリアルから1バイト取得します: Serial.read
//  Serial.read()
// 戻り値
//	0x00〜0xFFの値、データが無いときは-1が返ります
//**************************************************
mrb_value mrb_system_read(mrb_state *mrb, mrb_value self)
{
int ret = -1;	
	if(Serial.available()){
		ret = Serial.read(); //1文字取得
	}
	return mrb_fixnum_value( ret );
}

write()は下記です。mrb_get_args()を"S"で受けて、RSTRING_PTR()で文字列ポインタを取得し、あとは通常のchar配列として扱います。

//**************************************************
// シリアルにデータを出力します: Serial.write
//  Serial.write( buf, len )
//	buf: 出力データ
//	len: 出力データサイズ
// 戻り値
//	出力したバイト数
//**************************************************
mrb_value mrb_system_write(mrb_state *mrb, mrb_value self)
{
int	len;
mrb_value value;
char	*str;
	mrb_get_args(mrb, "Si", &value, &len);
	str = RSTRING_PTR(value);
	int ret = Serial.write( (const unsigned char *)str, len );
	return mrb_fixnum_value( ret );
}

以上、防備録としてmrubyのバイナリの使い方を書いておきます。

2013-10-06

[][]GR-SAKURAでmrubyを動かす (4) 18:21

GR-SAKURAでmrubyを動かす (3)からの続きです。jjzakさんの「GR-SAKURAでmrubyを使う」にある例を参考に書いています。

今回のプロジェクトはGitHubにアップしています。https://github.com/tarosay/localcompile

rxduino.hの変更

この状態でmakeすると以下のようなエラーがでます。

/cygdrive/c/cygwin/usr/local/tkdn-20110720/rx-elf/bin/../lib/gcc/rx-elf/4.6.1/../../../../rx-elf/sys-include/stdint.h:41:21: error: conflicting declaration 'typedef signed char int8_t'
./gr_common/include/rxduino/rxduino.h:50:25: error: 'int8_t' has a previous declaration as 'typedef char int8_t'

stdint.h で定義されている型定義が、rxduino.hで二重定義となるようです。そこで、gr_common/include/rxduino/下にあるrxduino.hの型定義の部分をコメントアウトします。

/*
// 型の定義
typedef bool  boolean;           //!< @brief 真(true)か偽(false)を表す型
typedef unsigned char  byte;     //!< @brief 8bitの符号無し数値(0〜255)を表わす
typedef unsigned short word;     //!< @brief 16bitの符号無し数値(0〜65535)を表わす
typedef unsigned char  uint8_t;  //!< @brief 8bitの符号無し数値(0〜255)を表わす
typedef unsigned short uint16_t; //!< @brief 16bitの符号無し数値(0〜65535)を表わす
typedef unsigned int   uint32_t; //!< @brief 32bitの符号無し数値(0〜4294967295)を表わす
typedef unsigned long long uint64_t; //!< @brief 64bitの符号無し数値(0〜18446744073709551615)を表わす
typedef          char   int8_t;  //!< @brief 8bitの符号付き数値(-128〜127)を表わす
typedef          short  int16_t; //!< @brief 16bitの符号付き数値(-32768〜32767)を表わす
typedef          int    int32_t; //!< @brief 32bitの符号付き数値(-2147483648〜2147483647)を表わす
typedef          long long int64_t; //!< @brief 64bitの符号付き数値(-9223372036854775808〜9223372036854775807)を表わす
*/

gr_sketch.cppの作成

最後にgr_sketch.cppを作成します。mrb_open()して、cdigitalWriteメソッドを定義し、mrb_load_irep()でsample.rbのコンパイルコードを動かします。

/*GR-SAKURA Sketch Template Version: V1.08*/
#include <rxduino.h>

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

#include "sample.c"
extern const uint8_t 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();
}

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_load_irep( mrb, code);

 }
void loop(){
}

makeする

あとはmakeするだけです。これで作成したsketch.binをGR-SAKURAに書き込んで、端のLEDが点灯すれば成功です。

minao@tarosa8 ~/gr-sakura/localcompile
$ make
rx-elf-gcc -Wall -g -O2 -Wl,--no-flag-mismatch-warnings -fsigned-char -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./gr_mruby/include  -c -x c sample.c -o sample.o
rx-elf-gcc -Wall -g -O2 -Wl,--no-flag-mismatch-warnings -fsigned-char -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./gr_mruby/include  -c -x c++ gr_sketch.cpp -o gr_sketch.o
rx-elf-gcc -Wall -g -O2 -Wl,--no-flag-mismatch-warnings -fsigned-char -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./gr_mruby/include  -c -x c gr_common/intvect.c -o gr_common/intvect.o
rx-elf-gcc -Wall -g -O2 -Wl,--no-flag-mismatch-warnings -fsigned-char -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./gr_mruby/include  -c -x c gr_common/lowlevel.c -o gr_common/lowlevel.o
rx-elf-ld ./gr_common/gstart.o ./sample.o ./gr_sketch.o ./gr_common/intvect.o ./gr_common/lowlevel.o  ./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_mruby/libmruby.a   -Map ./gr_build/sketch.map -L./gr_common/lib/ -lrxduino -lstdc++ -lsupc++ -lc -lsim -lgcc -lm -ltkdnhal -nostartfiles --no-flag-mismatch-warnings -T ./gr_common/gr_sakura.gsi -o ./gr_build/sketch.x
rx-elf-ld: warning: section `.bss' type changed to PROGBITS
rx-elf-objcopy -O binary ./gr_build/sketch.x  sketch.bin
rx-elf-objcopy --srec-forceS3 --srec-len 32 -O srec ./gr_build/sketch.x  ./gr_build/sketch.mot
rm -f *.o

sample.rbを変更してみる

sample.rbのMath.sqrt(4)を変えてみたいと思います。Math.sqrt(3)にしてみました。

HIGH = 1
LOW = 0

cdigitalWrite(100, LOW);
cdigitalWrite(101, LOW);
cdigitalWrite(102, LOW);
cdigitalWrite(103, LOW);

k = Math.sqrt(3)
if k==2 then
    cdigitalWrite(100, HIGH);
else
    cdigitalWrite(101, HIGH);
end 

loop do
end

それでは、ビルドしてみます。

minao@tarosa8 ~/gr-sakura/localcompile
$ ~/gr-sakura/mruby/mruby-master/bin/mrbc -Bcode sample.rb

minao@tarosa8 ~/gr-sakura/localcompile
$ make
rx-elf-gcc -Wall -g -O2 -Wl,--no-flag-mismatch-warnings -fsigned-char -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./gr_mruby/include  -c -x c sample.c -o sample.o
rx-elf-gcc -Wall -g -O2 -Wl,--no-flag-mismatch-warnings -fsigned-char -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./gr_mruby/include  -c -x c++ gr_sketch.cpp -o gr_sketch.o
rx-elf-ld ./gr_common/gstart.o ./sample.o ./gr_sketch.o ./gr_common/intvect.o ./gr_common/lowlevel.o  ./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_mruby/libmruby.a   -Map ./gr_build/sketch.map -L./gr_common/lib/ -lrxduino -lstdc++ -lsupc++ -lc -lsim -lgcc -lm -ltkdnhal -nostartfiles --no-flag-mismatch-warnings -T ./gr_common/gr_sakura.gsi -o ./gr_build/sketch.x
rx-elf-ld: warning: section `.bss' type changed to PROGBITS
rx-elf-objcopy -O binary ./gr_build/sketch.x  sketch.bin
rx-elf-objcopy --srec-forceS3 --srec-len 32 -O srec ./gr_build/sketch.x  ./gr_build/sketch.mot
rm -f *.o

出来上がったsketch.binをGR-SAKURAに書き込むと、右から二番目のLEDが点灯しました。

これで、GR-SAKURAでmrubyスクリプトを動作させることができるようになりました。

次は、SakuLuaのLua部分をmrubyに置き換えていきたいと思います。

[][]GR-SAKURAでmrubyを動かす (3) 17:35

GR-SAKURA用の libmruby.a作成することができたので、 jjzakさんの「GR-SAKURAでmrubyを使う」にある例を参考に、GR-SAKURAプログラムを作成してみたいと思います。

mrubyフォルダを作成する

GR-SAKURA用のプロジェクトにmruby用のフォルダを作成します。今回はgr_mrubyというフォルダを作成しました。そこに build/grsakura/lib/にあるlibmruby.aをコピーしました。また、include/以下をそのままコピーしました。

minao@tarosa8 ~/gr-sakura/localcompile/gr_mruby
$ ls -l
合計 3528
drwxr-xr-x+ 1 minao None       0 106 16:54 include
-rwxr-xr-x  1 minao None 3609744 106 16:43 libmruby.a

rubyプログラムの作成

GR-SAKURAで動かすrubyのサンプルプログラムを作成します。sample.rbという名前で下記のようなrubyプログラムを作成しました。

HIGH = 1
LOW = 0

cdigitalWrite(100, LOW);
cdigitalWrite(101, LOW);
cdigitalWrite(102, LOW);
cdigitalWrite(103, LOW);

k = Math.sqrt(4)
if k==2 then
    cdigitalWrite(100, HIGH);
else
    cdigitalWrite(101, HIGH);
end 

loop do
end

cdigitalWrite()は、mrubyに追加するGR-SAKURA用の関数です。mrbgemのMathを組み込んだので、Math.sqrt(4)が正しく処理されて 2であれば、右端のLEDが点灯します。正しく処理されなければ、たぶん、ハングアップしてLEDは点きません。

sample.rbをコンパイルする

sample.rbをコンパイルして中間言語にし、それをGR-SAKURAビルドモジュールに組み込めるように、Cのソースに変換します。

変換には、mrubyをmakeしたときに生成されたmrbcを使います。mrbcはmrubyをmakeしたフォルダのbin/以下にあります。

$ ~/gr-sakura/mruby/mruby-master/bin/mrbc -Bcode sample.rb

Bcodeオプションは、コンパイル結果をcソースとして出力するオプションです。これでsample.cが作成されました。

以下がsample.cです。

#include <stdint.h>
const uint8_t code[] = {
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x31,0xcb,0xcf,0x00,0x00,0x01,0x39,0x4d,0x41,
0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x01,0x1b,0x30,0x30,
0x30,0x30,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xef,0x00,0x02,0x00,0x05,0x00,0x00,
0x00,0x29,0x01,0x40,0x00,0x03,0x01,0x00,0x00,0x12,0x01,0x3f,0xff,0x83,0x01,0x00,
0x00,0x92,0x01,0x00,0x00,0x06,0x01,0xc0,0x31,0x83,0x02,0x00,0x00,0x91,0x01,0x00,
0x81,0x20,0x01,0x00,0x00,0x06,0x01,0xc0,0x32,0x03,0x02,0x00,0x00,0x91,0x01,0x00,
0x81,0x20,0x01,0x00,0x00,0x06,0x01,0xc0,0x32,0x83,0x02,0x00,0x00,0x91,0x01,0x00,
0x81,0x20,0x01,0x00,0x00,0x06,0x01,0xc0,0x33,0x03,0x02,0x00,0x00,0x91,0x01,0x00,
0x81,0x20,0x01,0x00,0x01,0x91,0x01,0xc0,0x01,0x83,0x01,0x01,0x00,0xa0,0x00,0x80,
0x80,0x01,0x01,0x00,0x40,0x01,0x01,0xc0,0x00,0x83,0x01,0x01,0x40,0xb2,0x01,0x40,
0x02,0x99,0x01,0x00,0x00,0x06,0x01,0xc0,0x31,0x83,0x02,0x00,0x00,0x11,0x01,0x00,
0x81,0x20,0x00,0x40,0x02,0x17,0x01,0x00,0x00,0x06,0x01,0xc0,0x32,0x03,0x02,0x00,
0x00,0x11,0x01,0x00,0x81,0x20,0x01,0x00,0x00,0x06,0x01,0x80,0x03,0x40,0x01,0x01,
0x80,0x21,0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x04,
0x48,0x49,0x47,0x48,0x00,0x00,0x03,0x4c,0x4f,0x57,0x00,0x00,0x0d,0x63,0x64,0x69,
0x67,0x69,0x74,0x61,0x6c,0x57,0x72,0x69,0x74,0x65,0x00,0x00,0x04,0x4d,0x61,0x74,
0x68,0x00,0x00,0x04,0x73,0x71,0x72,0x74,0x00,0x00,0x02,0x3d,0x3d,0x00,0x00,0x04,
0x6c,0x6f,0x6f,0x70,0x00,0x00,0x00,0x00,0x1c,0x00,0x01,0x00,0x02,0x00,0x00,0x00,
0x02,0x00,0x80,0x00,0x05,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x45,0x4e,0x44,0x00,0x00,0x00,0x00,0x08,
};

makefileの修正

makefileにmrubyのライブラリとヘッダファイルの場所を追記します。

LIBFILESの最後に ./gr_mruby/libmruby.a を追記します。

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_mruby/libmruby.a 

CCINCの最後に -I./gr_mruby/include を追記します。

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./gr_mruby/include 

sample.cをコンパイルする必要があるので、OBJFILES に ./sample.oを追記します。

OBJFILES = ./sample.o ./gr_sketch.o ./gr_common/intvect.o ./gr_common/lowlevel.o 

続きます。

[][]GR-SAKURAでmrubyを動かす (2) 16:45

GR-SAKURAのローカルビルド環境で、mrubyをビルドしたいと思います。目的はGR-SAKURA用の libmruby.a を作成することです。

mruby最新版をダウンロードします

mrubyの最新版をgithubからダウンロードしてきます。右側にある「Download ZIPからダウンロードできます。

ダウンロードしたらcygwinのホームのどこかに解凍します。私は~/gr-sakura/mruby/mruby-master/以下に解凍しました。

minao@tarosa8 ~/gr-sakura/mruby/mruby-master
$ ls -l
合計 72
-rwxr-xr-x  1 minao None   452 104 15:27 AUTHORS
drwxr-xr-x+ 1 minao None     0 106 16:06 benchmark
drwxr-xr-x+ 1 minao None     0 106 16:06 bin
-rwxr-xr-x  1 minao None  2538 104 15:27 build_config.rb
-rwxr-xr-x  1 minao None   409 104 15:27 ChangeLog
-rwxr-xr-x  1 minao None  2219 104 15:27 CONTRIBUTING.md
drwxr-xr-x+ 1 minao None     0 106 16:06 doc
drwxr-xr-x+ 1 minao None     0 106 16:06 examples
drwxr-xr-x+ 1 minao None     0 106 16:06 include
-rwxr-xr-x  1 minao None   717 104 15:27 INSTALL
-rwxr-xr-x  1 minao None   176 104 15:27 LEGAL
-rwxr-xr-x  1 minao None   279 104 15:27 Makefile
-rwxr-xr-x  1 minao None 13088 104 15:27 minirake
-rwxr-xr-x  1 minao None  1073 104 15:27 MITL
drwxr-xr-x+ 1 minao None     0 106 16:06 mrbgems
drwxr-xr-x+ 1 minao None     0 106 16:06 mrblib
-rwxr-xr-x  1 minao None   343 104 15:27 NEWS
-rwxr-xr-x  1 minao None  3728 104 15:27 Rakefile
-rwxr-xr-x  1 minao None  4575 104 15:27 README.md
drwxr-xr-x+ 1 minao None     0 106 16:06 src
drwxr-xr-x+ 1 minao None     0 106 16:06 tasks
drwxr-xr-x+ 1 minao None     0 106 16:06 test
-rwxr-xr-x  1 minao None   326 104 15:27 TODO
drwxr-xr-x+ 1 minao None     0 106 16:06 tools
-rwxr-xr-x  1 minao None   135 104 15:27 travis_config.rb

省メモリを考えた設定をする

GR-SAKURAはRAMが128KBと少ないので、少ないRAMでも動くようにinclude/mrbconfig.hを修正します。

Floatを使うようにします。

/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */
#define MRB_USE_FLOAT

引数は6個までにします

/* argv max size in mrb_funcall */
#define MRB_FUNCALL_ARGC_MAX 6

ヒープページを32にします。

/* number of object per heap page */
#define MRB_HEAP_PAGE_SIZE 32

インスタンスの管理をハッシュ形式からセグメントリスト管理にします。

/* use segmented list for IV table */
#define MRB_USE_IV_SEGLIST

kハッシュテーブルのデフォルトサイズを2にします。

/* default size of khash table bucket */
#define KHASH_DEFAULT_SIZE 2

メモリプールのページサイズを256にします。

/* page size of memory pool */
#define POOL_PAGE_SIZE 256

以上の内容を書き換えます。


クロスコンパイル用コードの追加

build_config.rbに、GR-SAKURA用のクロスコンパイルコードを追記します。この追加コードでは、mrbgemのmruby-mathをインポートしています。また、toolchainにgrsakuraを作成する必要が有ります。

# Cross build for GR-SAKURA
MRuby::CrossBuild.new('grsakura') do |conf|
   toolchain :grsakura

#   conf.cc.flags << "-m32"
#   conf.linker.flags << "-m32"
#
#   conf.build_mrbtest_lib_only
#
#   conf.gem "#{root}/mrbgems/mruby-sprintf"
   conf.gem "#{root}/mrbgems/mruby-math"
#
#   conf.test_runner.command = 'env'
#
end

GR-SAKURA用のrakeファイルを作成する

tasks/toolchains/に、grsakura.rakeファイルを作成します。

MRuby::Toolchain.new(:grsakura) do |conf|
  toolchain :gcc

  TOOL_PATH = "/usr/local/tkdn-20110720/rx-elf/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

この内容は、 jjzakさんの「GR-SAKURAでmrubyを使う」を参考に作成しています。

makeする

これでmakeすればbuild/grsakura/フォルダができ、GR-SAKURA用のlibmruby.aが作成されます。

$ make
ruby ./minirake
(in /home/minao/gr-sakura/mruby/mruby-master)
CC    tools/mrbc/mrbc.c -> build/host/tools/mrbc/mrbc.o
CC    src/array.c -> build/host/src/array.o
CC    src/backtrace.c -> build/host/src/backtrace.o
CC    src/class.c -> build/host/src/class.o
CC    src/codegen.c -> build/host/src/codegen.o
CC    src/compar.c -> build/host/src/compar.o
...
Build summary:

================================================
      Config Name: host
 Output Directory: build/host
         Binaries: mrbc
    Included Gems:
             mruby-sprintf - 0.0.0
             mruby-print - 0.0.0
             mruby-math - 0.0.0
             mruby-time - 0.0.0
             mruby-struct - 0.0.0
             mruby-enum-ext - 0.0.0
             mruby-string-ext - 0.0.0
             mruby-numeric-ext - 0.0.0
             mruby-array-ext - 0.0.0
             mruby-hash-ext - 0.0.0
             mruby-range-ext - 0.0.0
             mruby-proc-ext - 0.0.0
             mruby-symbol-ext - 0.0.0
             mruby-random - 0.0.0
             mruby-object-ext - 0.0.0
             mruby-objectspace - 0.0.0
             mruby-fiber - 0.0.0
             mruby-toplevel-ext - 0.0.0
             mruby-bin-mirb - 0.0.0
               - Binaries: mirb
             mruby-bin-mruby - 0.0.0
               - Binaries: mruby
================================================

================================================
      Config Name: grsakura
 Output Directory: build/grsakura
    Included Gems:
             mruby-math - 0.0.0
================================================

以上です。

[][]GR-SAKURAでmrubyを動かす (1) 15:55

こんにちは、久々の更新になります。

ようやく、GR-SAKURAにmrubyを入れてみたので、防備録を兼ねて書いておきます。

GR-SAKURAのローカルビルド環境を作る

WindowsユーザなのでWindowsでの話しになります。

mrubyをWebコンパイラビルドするのは難しいので、先ず最初にローカル環境でビルドできるようにします。

ローカル環境でビルドするにはWindowscygwinインストールします。cygwinインストール方法は、過去にも記事にしているのでcygwinで検索してみてください。

cygwinではDevelとRubyが必要です。Develを入れるとRubyは入っているかもしれません。


次に、GR-SAKURAコンパイラを用意します。特殊電子回路株式会社さんのRX-MEGAボード/ダウンロードサイトから「RX用GNU C コンパイラ RX-ELF-GCC(Cygwin版)」ダウンロードします。

cygwinの環境作りは特殊電子回路株式会社さんのサイトにも書かれていました。


ダウンロードしたtkdn-20110720-gcc.tar.bz2をcygwin上で解凍します。

$ tar jxvf tkdn-20110720-gcc.tar.bz2

解凍したものを適当なところに置きます。私は/usr/local/に置きました。

$ mv tkdn-20110720 /usr/local/

そして、パスが通るように.bashrcに下記を追加します。

#GR-SAKURA
export PATH=$PATH:/cygdrive/c/cygwin/usr/local/tkdn-20110720/rx-elf/bin

これで、cygwinを再度立ち上げるか、source .bashrcすれば、GR-SAKURAビルド環境が出来上がります。

試しに、rx-elf-gcc --versionすると下記のようなメッセージがでると思います。

$ rx-elf-gcc --version
rx-elf-gcc (GCC) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

テストコンパイル

Webコンパイラからプロジェクトを持ってきて、試しにコンパイルしてみたいと思います。先ず新規にプロジェクトを作成します。

f:id:tarosay:20131006153657j:image:w480

一度、ビルドします。一度ビルドするのは、makefileを自動生成させるためです。

f:id:tarosay:20131006153658j:image

Down Load Zip Fileを選びます。

f:id:tarosay:20131006153659j:image

プロジェクト一式をダウンロードします。

f:id:tarosay:20131006153700j:image


これをcygwinのホームのどこかに展開します。私は~/gr-sakura/に展開しました。

$ cd ~/gr-sakura/localcompile/

minao@tarosa8 ~/gr-sakura/localcompile
$ ls -l
合計 44
drwxr-xr-x+ 1 minao None     0 106 15:49 gr_build
drwxr-xr-x+ 1 minao None     0 106 15:49 gr_common
-rwxr-xr-x  1 minao None   637 106 15:32 gr_sketch.cpp
-rwxr-xr-x  1 minao None  3249 106 15:43 makefile
-rwxr-xr-x  1 minao None 30020 106 15:43 sketch.bin

そして、makeします。

$ make
rx-elf-gcc -Wall -g -O2 -Wl,--no-flag-mismatch-warnings -fsigned-char -I./gr_build -I./gr_common -I./gr_common/include -I./gr_common/include/rxduino -I./gr_common/include/tkdnhal -I./gr_common/lib  -c -x c++ gr_sketch.cpp -o gr_sketch.o
rx-elf-ld ./gr_common/gstart.o ./gr_sketch.o ./gr_common/intvect.o ./gr_common/lowlevel.o  ./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   -Map ./gr_build/sketch.map -L./gr_common/lib/ -lrxduino -lstdc++ -lsupc++ -lc -lsim -lgcc -lm -ltkdnhal -nostartfiles --no-flag-mismatch-warnings -T ./gr_common/gr_sakura.gsi -o ./gr_build/sketch.x
rx-elf-ld: warning: section `.bss' type changed to PROGBITS
rx-elf-objcopy -O binary ./gr_build/sketch.x  sketch.bin
rx-elf-objcopy --srec-forceS3 --srec-len 32 -O srec ./gr_build/sketch.x  ./gr_build/sketch.mot
rm -f *.o

これで、新規に sketch.bin が生成されます。

GR-SAKURAのローカルビルド環境が整いました。