まずソースファイルをすべて追加する。
環境によってはコレだけで動くと思う。
追記:2017/09/11
僕の環境でmallocが使えるようになりました。ってことでLuaのソースコードそのままで動くようになりました。あとprintfの浮動小数点出力も正常になりました。
いちおう、mallocじゃなく、FreeRTOSのpvPortMallocを使った方法も残しておきます↓。
僕の環境だとmallocが使えないので、FreeRTOSのpvPortMallocを使うように書き換える。ただ、LuaはReallocを使ってるので、単純に置き換えることはできない。
まず、lua_mallocという関数を用意する。
void *lua_malloc(void *ptr, size_t size) { if (ptr && size == 0) { vPortFree(ptr); return (0); } void *newptr = pvPortMalloc(size); if (!newptr) { vPortFree(ptr); return (0); } if (ptr) { memcpy(newptr, ptr, size); vPortFree(ptr); } return (newptr); }
これはmallocやrealloc、freeを1つの関数で処理するためのもの。
拡張前のメモリから値を引き継ぐのに、memcpyで新しいサイズの全域をコピーしている。かなり無駄の多い処理だが、拡張前の大きさを調べるのが面倒だったので、今回はこういう感じにした。
mallocで確保したメモリの初期値は不定でいいので、範囲外からコピーされた値が入っていても問題ない。ただ、バッファオーバーランによる他スレッドのデータを読まれたりとか、そういうことは気にしてない。あと、MMUとかついてると問題かも。でもSTM32F4には無いのでキニシナイ。そもそもMMUがある環境ならこんな面倒なことは(以下略。
次に、lauxlib.cのl_allocを書き換える。
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { (void)ud; (void)osize; /* not used */ return lua_malloc(ptr, nsize); }
freeとかの処理はlua_mallocでラッパーできてるから、単純に呼び出すだけ。
あとは、コンソールのコマンドがstrという文字列バッファに入ってるとすれば、以下のような処理になる。
if (!strncmp(str, "lua ", 4)) { osDelay(50); lua_State *L = luaL_newstate(); luaL_openlibs(L); do { const char *code = str + 4; if (luaL_loadbuffer(L, code, strlen(code), "code")) { fprintf(stderr, "lua couldn't parse '%s': %s.\n", code, lua_tostring(L, -1)); lua_pop(L, 1); break; } if (lua_pcall(L, 0, 1, 0)) { fprintf(stderr, "lua couldn't execute '%s': %s.\n", code, lua_tostring(L, -1)); lua_pop(L, 1); break; } } while (0); lua_pop(L, lua_gettop(L)); lua_close(L); }
この例では、コマンドを受けるたびにLuaインタラプタを初期化してコードを実行する。
"lua print 'hello'"のような文字列が入力されれば、ちゃんとhelloと表示される。"lua print(1+2)"とすれば、3と表示される。"lua print(math.sqrt(2))"とすれば平方根の計算もできるはずだが、ウチの環境だと浮動小数点のprintfが正常に動かないので、動作確認できていない。
ウチの環境、不具合多いなぁ。
とりあえず、Luaは動いているようだが、かなり大量のメモリが必用。
"lua print 'hello world' print(3*5)"という簡単なコードでも、20KiBほどのメモリを使っている。凄まじい。
ま、まずはLuaの動作確認ができたので良しとする。
コンパイルやフラッシュへの書き込み無しにコードが動くのは結構楽しい。
ありがとうございます、記事は私を手伝いました!私もLuaとFreeRTOSとSTM32-F7を使ってみるでしたが「メモリが十分ではない」と言った。その上、「#define LUA_32BITS」とluaconf.hに書かなくてはなりませんでした。カナダからこんにちは!
返信削除