まずソースファイルをすべて追加する。
環境によってはコレだけで動くと思う。
追記: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に書かなくてはなりませんでした。カナダからこんにちは!
返信削除