stack / heap collisions; NodeMCU also complains that there isn't enough
memory to run the code, which isn't particularly long. There's a useful
C SDK function system_print_meminfo(), but that won't work when being
called from NodeMCU. I wrote the C module below to get the same information,
which might come in handy for others. Ideally it would be part of the
node module, but compiling your own build is pretty straightforward,
at leas on Linux.
#include "module.h"
#include "lauxlib.h"
#include "platform.h"
/*
** demo.meminfo()
**
** Show system memory usage.
*/
extern unsigned int _data_start;
extern unsigned int _data_end;
extern unsigned int _rodata_start;
extern unsigned int _rodata_end;
extern unsigned int _bss_start;
extern unsigned int _bss_end;
extern unsigned int _heap_start;
static int demo_meminfo( lua_State * L )
{
unsigned int u, v;
lua_newtable(L);
/* Push an integer onto the stack,
** and then write the stacktop value
** into the table at -2 at the table
** index 1 and pop the stack.
*/
lua_pushinteger(L, (unsigned int) &_data_start);
lua_rawseti(L, -2, 1);
/* Same again, table index 2 */
lua_pushinteger(L, (unsigned int) &_data_end);
lua_rawseti(L, -2, 2);
lua_pushinteger(L, (unsigned int) &_rodata_start);
lua_rawseti(L, -2, 3);
lua_pushinteger(L, (unsigned int) &_rodata_end);
lua_rawseti(L, -2, 4);
lua_pushinteger(L, (unsigned int) &_bss_start);
lua_rawseti(L, -2, 5);
lua_pushinteger(L, (unsigned int) &_bss_end);
lua_rawseti(L, -2, 6);
lua_pushinteger(L, (unsigned int) &_heap_start);
lua_rawseti(L, -2, 7);
lua_pushinteger(L, 0x3fffc000);
lua_rawseti(L, -2, 8);
return 1;
}
/*
** Define an empty module initialisation function.
** (Not used at the moment.)
*/
int luaopen_demo( lua_State * L ) {
return 0;
}
/*
** Module function map.
*/
static const LUA_REG_TYPE demo_map[] = {
{ LSTRKEY( "meminfo" ), LFUNCVAL( demo_meminfo ) },
{ LSTRKEY( "__metatable" ), LROVAL( demo_map ) },
{ LNILKEY, LNILVAL }
};
/*
** Register the module
*/
NODEMCU_MODULE(DEMO, "demo", demo_map, NULL);
The demo module needs to be added to user_modules.h, as well.
A typical use would be:
function meminfo()
local w
local hdr = { "data :", "rodata:", "bss :", "heap :" }
for k, v in ipairs(demo.meminfo())
do
if (k % 2) == 0
then
uart.write(0, string.format("%s 0x%x - 0x%x, len: %d\r\n",
hdr[k / 2], w, v, v - w))
end
w = v
end
end
meminfo()
which gives:
> dofile("main.lua")
data : 0x3ffe8000 - 0x3ffe88c4, len: 2244
rodata: 0x3ffe88c4 - 0x3ffe88cc, len: 8
bss : 0x3ffe88d0 - 0x3ffef4d0, len: 27648
heap : 0x3ffef4d0 - 0x3fffc000, len: 52016
>
The next problem is to work out what on earth the stack is doing.
The combination of lua, C, and the underlying SDK code is pretty confusing.
C W Rose