@TerryE Sorry, I had the repo set to private in case I published my password, which is still a good precaution, so I made a public one... https://github.com/poorandunlucky/lfs-public
sorry about that 😕
.gitexclude
to prevent this file from being added to the repo. However, remember that this will still leave these secrets in a form that can still be read from flash. There are ways to mitigate this but things can get quite complicated to do this properly.
log.lua
is pretty verbose for what it does uses RAM where there is little to be gained from doing so:module()
and package.seeall
are Lua 5.0 constructs which are deprecated in 5.1 and run inefficiently on NodeMCU. I am not even sure they work in Lua 5.3.error()
statement.log(message,facility, level )
function and the ability to configure the level from 'DEBUG' to NONE
with an option filename, but this IoT functionality doesn't need RAM arrays or this quite verbose logic.strtolvl2()
logic could be coded in a dozen lines, run faster and use no RAM arrays:level = level:upper()
if ( level == 'DEBUG' ) then return 7
-- ...
elseif level == 'EMERG' or level == 'EMERGENCY' then return 0
else error( 'Invalid error level specified: '..level)
end
BTW, you could also code the str2lvl
function something like the following. Perhaps, not the clearest code, but only a 26 instruction function that is fast and has low RAM use in an ESP8266 LFS context. OK, it will miscode error levels like "NOTE", but IMO it does the job. (Note that string.find(s,p,i,true)
does a simple fast memory scan.)
local function str2lvl(s)
local vals = 'DEB\07INF\6NOT\5WAR\4ERR\3CRI\2ALE\1EME\0'
local i = vals:find(s:sub(1,3):upper(),1,true) or error('Invalid error level '..s)
return vals:sub(i+3,i+3):byte()
end
Of course there are many ways of implementing this, but some take far less ESP8266 resources than others. All you need is a little lateral thinking in your approach.
Hello; just wanted to say thankyou to the hard-work put into this project; I've come back to use the esp8266 that have been lying around not being used for too long.
Very much enjoying using them. As a professional software engineer by day, I can see the effort that's gone into it :clap:
Hi, got a weird one.. Suddenly my device fails to boot my LFS image. My init.lua fails node.LFS.get('_init')
(nil), so it triggers LFs.reload from the image. which seems to work:Erasing LFS from flash addr 0x08a000................................ to 0x0a9fff
LFS image loaded
and then boot continues, aaand.. LFS.get still fails. node.LFS.list reveals no files at all.
Now, if I remove some (random) code from the built image, it works just fine!
lfs.img failing is 68056 bytes, working right now is 67815 bytes.. File content is correct on SPIFFS (md5 ok).
LFS: 0x20000 bytes total capacity
firmware is dev (+ some stuff of my own but just other modules)
Am I hitting some kind of size limitation?
Yup, with 0x30000 it boots fine on the image previously "broken". And back to 0x20000, not working.
Noticed that for the failed ones, it logsLoading lfs.img...
init.lua:8: system restarting
stack traceback:
[C]: in field 'reload'
� init.lua:8: in function <init.lua:3>
(i.e. the lua_error from LFS.reload(..) is actually showed. but I guess it could be race between restart/printing that)
Yeah, perhaps.. Easy to reproduce here at least, so I can assist with debugging if needed.
I'm using it for all sorts of stuff. Started a few years back with just one node for tinkering, and found NodeMCU appealing with the fast development cycles possible with LUA. So started out with some bme280 integrations sending measurements over mqtt.. then my lua "firmware" have kind of grown into modularized code, all modules are in the LFS image, but I enable different ones with different config, depending on the node usage. And OTA for the lfs image.
So, now I have a bunch of them, in addition of having multiple nodes with bme280's, I also have some 1-wire buses on a few of them (temp sensors, and custom AVR slaves with MoaT fw), some mcp28003 IO muxers, mcp2438 A/Ds for some battery monitoring in one of my battery+sun-powered nodes,..what else.. my house power meter has a Mbus-interface, which I'm reading logging with one node.. and some other powermeters with modbus will be read by another...
Oh, and for xmas I'm also running some LED lights in the garden, one set via some basic PWM driver.. and two other nodes with 350 RGB-pixels each, receiving streamed "scene data" via E1.31 protocol ("DMX over ethernet"), outputting to the RGB pixels with DMA-backed i2s code . Those last two are done with C modules, not pushed upstream (yet?).
So yeah.. a bit of this and a bit of that.. :) Dunno what other esp8266 firmwares there are out there these days, but this has worked nice for me. And although the 8266 is a bit overruled by the 32, for alooot of stuff the esp8266 has plenty of power. And with LFS, just have to sprinkle alot of garbagecollect() calls at appropriate places ;)
@DennisMart
Decoding stack results
0x4008e49e: _vfprintf_r at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32s2-elf/src/newlib/newlib/libc/stdio/vfprintf.c line 1410
0x4008d1c9: _vfprintf_r at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32s2-elf/src/newlib/newlib/libc/stdio/vfprintf.c line 1056
0x4008d144: _vfprintf_r at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32s2-elf/src/newlib/newlib/libc/stdio/vfprintf.c line 1017
0x4008a654: (anonymous namespace)::pool::free(void*) at /builds/idf/crosstool-NG/.build/HOST-i686-w64-mingw32/xtensa-esp32s2-elf/src/gcc/libstdc++-v3/libsupc++/eh_alloc.cc line 23
line 235
Hi, any good suggestions on how to figure out the address reported in epc1? I'm working on some low-level i2s stuff in the esp8266 code base (i2s-based IR receiver / blaster). Works pretty good, but every now and then something causes a reboot with
Reset cause: 2
Fatal exception (28)
epc1=0x40100ee6, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
Everytime it's the same address.. But looking in the .map file, I'm not sure what to identify.. This is the closest in address:
.text.free 0x0000000040100eb8 0x1b /opt/nodemcu-firmware/sdk/esp_iot_sdk_v3.0-e4434aa/lib/libmain.a(mem_manager.o)
0x1f (size before relaxing)
0x0000000040100ebc free
fill 0x0000000040100ed3 0x1
.text.xPortGetFreeHeapSize
0x0000000040100ed4 0x7 /opt/nodemcu-firmware/sdk/esp_iot_sdk_v3.0-e4434aa/lib/libmain.a(mem_manager.o)
0xb (size before relaxing)
0x0000000040100ed4 xPortGetFreeHeapSize
fill 0x0000000040100edb 0x1
.text.prvInsertBlockIntoFreeList
0x0000000040100edc 0x43 /opt/nodemcu-firmware/sdk/esp_iot_sdk_v3.0-e4434aa/lib/libmain.a(mem_manager.o)
0x4b (size before relaxing)
fill 0x0000000040100f1f 0x1
Not sure how to interpret the mapfile, but my guess is that it might be something in prvInsertBlockIntoFreeList?
Any hints or suggestions welcome, thanks :)