Post your best Lua script examples here

User avatar
By cwr
#59642 I've been writing some NodeMCU code which has all the appearance of
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.

Code: Select all#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:
Code: Select allfunction 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:
Code: Select all> 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