我使用Keil,MDK-ARM Pro 4.71获取Cortex-M3目标(STM32F107)。
我已经编译了Lua解释器和一个Lua“定时器”模块,它接口芯片的定时器。我想在计时器结束时调用lua函数。
以下是使用示例:
t = timer.open()
t.event = function() print("Bing !") end
t:start()
直到这里,一切正常:-)!我看到了“Bing!”每次计时器结束时都会打印消息。
现在如果我使用闭包:
t = timer.open()
i = 0
t.event = function() i = i + 1; print(i); end
t:start()
经过一些计时器的更新后,我在GC中的内存访问不正确。由于它是一个内存非常少的嵌入式上下文,如果发生泄漏,我的内存可能会很快耗尽。
这是“t.event”setter(ELIB_TIMER是代表我的计时器的C结构):
static int ElibTimerSetEvent(lua_State* L)
{
ELIB_TIMER* pTimer_X = ElibCheckTimer(L, 1, TRUE);
if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
{
luaL_unref(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
pTimer_X->LuaFuncKey_i = LUA_REFNIL;
}
if (!lua_isnil(L, 2))
{
pTimer_X->LuaFuncKey_i = luaL_ref(L, LUA_REGISTRYINDEX);
}
return 0;
}
这是本机回调实现:
static void ElibTimerEventHandler(SYSEVT_HANDLE Event_H)
{
ELIB_TIMER* pTimer_X = (ELIB_TIMER*)SWLIB_SYSEVT_GetSideData(Event_H);
lua_State* L = pTimer_X->L;
int i = lua_gettop(L);
if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
lua_call(L, 0, 0);
lua_settop(L, i);
}
}
这是外部同步的,因此这不是同步问题。
我做错了吗?
修改
这是callstack(使用lua_pcall而不是lua_call,但它是相同的)。第一行是我的硬故障处理程序。
答案 0 :(得分:2)
我发现了问题!我用尽了堆栈(本机堆栈,而不是Lua)空间:p。 我想这个特定的脚本导致了一个特别长的调用堆栈。增加为我的本机堆栈分配的内存后,问题就消失了。相反,如果我减少它,我甚至无法初始化解释器。
非常感谢那些试图在这里提供帮助的人。
答案 1 :(得分:1)
在您的C代码中发现了一个错误。你打破了static int ElibTimerSetEvent(lua_State* L)
luaL_ref
会弹出Lua堆栈顶部的值:http://www.lua.org/manual/5.2/manual.html#luaL_ref
因此,在调用luaL_ref
:
lua_pushvalue(L, 2); // push the callback to stack top, and then it will be consumed by luaL_ref()
请解决此问题,然后重试。