備忘録という意味合いが強いけど、いつの間にかmruby 安定版 v1.0.0がリリース
されていたこともあり、以前、PICrouterのwikiにメモした内容をこのv1.0.0向けに
手直しして書きます。
0.注意
mrubyでrubyに触り始めた初心者が書いていますので、訂正や助言頂けると嬉しいです。
1.準備
PICrouterでmrubyするために必要なものは次の通り。
wikiにも書いてありますが、mrubyでOSCやるのにオリジナルのPICrouterでは
さすがに厳しいです。MPLABXは特にバージョン指定ありませんし、特にIDEに
バグも無いので最新版で良いと思います。XC32コンパイラはフリー版でOKです。
ただし、v1.30とv1.31はPIC32のUSB HIDブートローダーとの兼ね合いでコンパイル
がこけるので、この問題が修正されるまではv1.22を使って下さい。どうしても、
v1.31が使いたいって人はこの辺を参考に自力対処して下さい。
あと、私の場合は、CygwinとVisual Studio Express 2013がインストール済みです。
mruby-1.0.0に併せて、mruby用のプロジェクトを更新し、mrubyから使うCの関数を
追加したりしたv0.2.1をgithubで公開してます。ソースは見づらいかもしれませんが、
少しずつ整理していきますので・・・。
2.build_config.rbの書き換え
まず、PICrouter用のlibmruby.aを作ります。そのために、mruby-1.0.0フォルダの
中にある「build_config.rb」にPICrouter用の記述を追加する必要があります。
まずは、末尾に以下を追記します。PATHは自身の環境に合わせて下さい。
また、これまではmrbconf.hを直接編集していましたが、ここでcc.definesを使う
ように変更しました。この方法が推奨のようです。
MRuby::CrossBuild.new("PICrouter") do |conf| toolchain :gcc PICROUTER_PATH = "C:/Users/shun/MPLABXProjects/PICrouter" XC32_PATH = "C:/Program Files (x86)/Microchip/xc32/v1.22" MRUBY_PATH = "C:/Users/shun/MPLABXProjects/PICrouter/mruby-1.0.0" conf.cc do |cc| cc.command="#{XC32_PATH}/bin/xc32-gcc.exe" cc.include_paths = ["#{PICROUTER_PATH}/PICrouter_795_mrb.X", "#{PICROUTER_PATH}/PICrouter_795_mrb.X/Include", "#{PICROUTER_PATH}/PICrouter_795_mrb.X/USB", "#{MRUBY_PATH}/include", "#{XC32_PATH}/pic32mx/include"] cc.flags << "-g -ffunction-sections -fdata-sections -mips16 -mprocessor=32MX795F512H -O1 -Wl,--defsym=__MPLAB_BUILD=1," + "-Map=\"dist/default/production/PICrouter_795_mrb.X.production.map\",--defsym=_min_heap_size=102284,--defsym=_min_stack_size=1136,--gc-sections," cc.compile_options = "%{flags} -o %{outfile} -c %{infile}" cc.defines << %w(MRB_HEAP_PAGE_SIZE=64) cc.defines << %w(MRB_USE_IV_SEGLIST) cc.defines << %w(MRB_IVHASH_INIT_SIZE=3) cc.defines << %w(KHASH_DEFAULT_SIZE=8) cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20) cc.defines << %w(MRB_GC_STRESS) #cc.defines << %w(DISABLE_STDIO) end conf.cxx do |cxx| cxx.command = conf.cc.command.dup cxx.include_paths = conf.cc.include_paths.dup cxx.flags = conf.cc.flags.dup cxx.defines = conf.cc.defines.dup cxx.compile_options = conf.cc.compile_options.dup end conf.archiver do |archiver| archiver.command = "#{XC32_PATH}/bin/xc32-ar" archiver.archive_options = 'rcs %{outfile} %{objs}' end #no executables conf.bins = [] #do not build test executable conf.build_mrbtest_lib_only end
mruby-1.0.0/examples/targetsフォルダの中のコードを参考にして、githubに
PICrouter.rbを作ってアップしておきました。
3.IncludeするGemの選択
2の記述を追加して、make clean & makeすれば、libmruby.aは出来上がります。
ただ、PIC32MX795F512HもRAMが128kしかないので、mruby本体にメモリを
圧迫され、自前のコードのためのスペースが少なくなってしまいます。なので、
PICrouterで使わないであろうGemのインクルードを止めることにします。
mruby-1.0.0/mrbgemsの中に「default.gembox」というのがあり、さきほどの
「build_config.rb」内で、「conf.gembox 'default'」としてあります。ここで、必要な
Gemのインクルードを記述をしているようです。なので、これを複製して、
picrouter.gemboxとファイル名を変更、mruby-timeなど不要なGemをコメント
アウトします。
MRuby::GemBox.new do |conf| # Use standard Kernel#sprintf method #conf.gem :core => "mruby-sprintf" # Use standard print/puts/p #conf.gem :core => "mruby-print" # Use standard Math module conf.gem :core => "mruby-math" # Use standard Time class #conf.gem :core => "mruby-time" # Use standard Struct class #conf.gem :core => "mruby-struct" # Use extensional Enumerable module conf.gem :core => "mruby-enum-ext" # Use extensional String class conf.gem :core => "mruby-string-ext" # Use extensional Numeric class conf.gem :core => "mruby-numeric-ext" # Use extensional Array class conf.gem :core => "mruby-array-ext" # Use extensional Hash class conf.gem :core => "mruby-hash-ext" # Use extensional Range class conf.gem :core => "mruby-range-ext" # Use extensional Proc class conf.gem :core => "mruby-proc-ext" # Use extensional Symbol class conf.gem :core => "mruby-symbol-ext" # Use Random class conf.gem :core => "mruby-random" # Use extensional Object class conf.gem :core => "mruby-object-ext" # Use ObjectSpace class #conf.gem :core => "mruby-objectspace" # Use Fiber class #conf.gem :core => "mruby-fiber" # Use extended toplevel object (main) methods conf.gem :core => "mruby-toplevel-ext" # Generate mirb command #conf.gem :core => "mruby-bin-mirb" # Generate mruby command #conf.gem :core => "mruby-bin-mruby" end
これもgithubに、picrouter.gemboxとしてアップしておきました。「build_config.rb」の
「conf.gembox 'default'」を「conf.gembox 'picrouter'」と書き換えて使用します。
4.メモリ節約のための記述
加えて、mruby-1.0.0/include/mruby/value.hの275行目付近
typedef struct mrb_value { union { mrb_float f; void *p; mrb_int i; mrb_sym sym; } value; enum mrb_vtype tt; } mrb_value;
となっている箇所を
typedef struct mrb_value { union { mrb_float f; void *p; mrb_int i; mrb_sym sym; } value; enum mrb_vtype tt:8; } mrb_value;
とします。以前は、ここをさらに「#pragma pack(1)」で詰めていましたが、これをすると
C側でmrb_funcallを呼び出したときに動作が停止してしまいました。pack()するときは
環境やコンパイラのバージョンなどに注意した方が良いかもしれません。
また、mruby-1.0.0/src/symbol.cの14行目付近
typedef struct symbol_name { mrb_bool lit; uint16_t len; const char *name; } symbol_name;
を
#pragma pack(1) typedef struct symbol_name { mrb_bool lit; unsigned char len; const char *name; } symbol_name; #pragma pack()
とします。これらは前回同様にkyabさんのブログを参考にさせて頂きました。
これで、「make clean & make」でmruby-1.0.0/build/PICrouter/libの中に
libmruby.aの出来上がりです。
これをMPLABX上でmruby用のプロジェクトの「Libraries」に加え、Project
PropertiesのCategories→「xc32-gcc」、Option categories→「Preprocessing
and messages」にある「Include directories」にmruby-1.0.0/includeを加えて
下準備は完了です。
Cのコードとmrubyのコードを用意して、ゴニョゴニョできるようになりました。
コメントをどうぞ