2

我为 Cortex-M3 目标(STM32F107)使用 Keil、MDK-ARM Pro 4.71。

我已经编译了 Lua 解释器和一个 Lua“定时器”模块,它与芯片的定时器接口。我想在计时器结束时调用一个 lua 函数。

这是一个示例使用:

t = timer.open()
t.event = function() print("Bing !") end
t:start()

直到这里,一切正常:-)!我看到了“必应!” 每次计时器经过时都会打印消息。

现在,如果我使用闭包:

t = timer.open()
i = 0
t.event = function() i = i + 1; print(i); end
t:start()

经过一定数量的计时器更新后,我在 GC 中的内存访问不正确。由于它是一个内存很少的嵌入式上下文,因此如果发生泄漏,我可能会很快耗尽内存。

这是“t.event”设置器(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);
   }
}

这是在外部同步的,所以这不是同步问题。

难道我做错了什么 ?

编辑

这是调用堆栈(使用 lua_pcall 而不是 lua_call,但它是相同的)。第一行是我的硬故障处理程序。

Lua 调用栈

4

2 回答 2

2

我发现了问题!我用完了堆栈(本机堆栈,而不是 Lua)空间:p。我猜这个特定的脚本导致了一个特别长的调用堆栈。在为我的本机堆栈增加分配的内存后,问题就消失了。相反,如果我减少它,我什至无法初始化解释器。

非常感谢那些试图在这里提供帮助的人。

于 2013-08-20T06:59:15.140 回答
1

在您的 C 代码中发现了一个错误。你破坏了 lua 堆栈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()

请解决此问题并重试。

于 2013-08-20T03:25:22.883 回答