ひとしれずひっそり

主にソフトに関することをメモしていきます。過程をそのまま書いていたりするので間違いが含まれます。鵜呑みしない様に。

M5でmruby/c (4)

いつもmrubyとかmruby/c動いたで終わってしまうのでもうちょっと突っ込んでみる。
Peripheralをmrubyで動かしてこそmrubyを使った感があると思う。

  • M5StackのLCD用に mruby-lcd-m5stack がある。
    github.com
  • mrubyだと build_config.rb で組込む様だがPlatformIOでやっている分には build_config.rb が見当たらない。
  • platformio.iniのlib_depsに追加してみるか。
  • M5Stack.hをインクルードしているので、試しにM5Unifiedを入れてみる。
  • mruby.hもインクルードしている。
    • mruby/cはmrubyc.hになるから mruby-lcd-m5stack はmruby用かとここで気付く

振り出しに戻る

るびまに記事があった。

magazine.rubyist.net

仕様としてはLcdのフォントサイズを指定し、printで表示させることを目指す。
クラスとしてDisplayでクラスメソッドとしていset_text_sizeとprintを使用する。

  • Display.set_text_size
  • Display.print

様々な機種に対応できる様にM5Unifiedを使用する。

platformio.ini

lib_deps =
  https://github.com/mrubyc/mrubyc
  M5Unified

クラス定義用としてdefine_classes.[h|cpp]を作成。

define_classes.h

void define_display_class();

define_classes.cpp

#include <M5Unified.h>
#include <mrubyc.h>
#include "define_classes.h"

static void
class_display_set_text_size(mrb_vm *vm, mrb_value *v, int argc)
{
}

static void
class_display_print(mrb_vm *vm, mrb_value *v, int argc)
{
}

void define_display_class()
{
    mrb_class *class_display;
    class_display = mrbc_define_class(0, "Display", mrbc_class_object);
    mrbc_define_method(0, class_display, "set_text_size", class_display_set_text_size);
    mrbc_define_method(0, class_display, "print", class_display_print);
}
  • mrbc_define_classでクラス定義をする。
    • 最初は0でいいということなのでこのままですすめる。
    • 次はクラス名
    • 次は親クラスを指定ということだが今はこのままで進める。
  • mrbc_define_methodでメソッドを定義する。
    • 上と同様に0のままで。
    • 次はクラスのポインターでmrbc_define_class の戻りを与える。
    • 次がメソッド名
    • 次がメソッドのポインター

メソッドはまだうまくいっていないのでここでは中身は空で表現した。

main.c から呼び出す。

int main(void) {
.
.

  mrbc_init(memory_pool, MRBC_MEMORY_SIZE);

  define_display_class();
.
.

ここで暫くハマってしまった。
define_display_classが見つからないとエラーがでてしまう。

mrubycはC言語のみだったが、M5UnifiedはC++も使っている。

  • main.cファイルはmain.cppにしなければならない。
  • C++では外部ファイルからC関数を使用するにはextern "C" {}で囲まないといけない。

define_classes.h

extern "C" {
void define_display_class();
}

main.cpp

extern "C" {
void app_main() {
  main();
}
}

これでコンパイルが通る様になった。

まだ中身はないので次で動くといいな。