]> hydra-www.ietfng.org Git - acmetensortoys-esp-lua_core/commitdiff
Rework in light of LFS
authorNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sat, 11 Aug 2018 22:52:22 +0000 (23:52 +0100)
committerNathaniel Wesley Filardo <nwfilardo@gmail.com>
Sun, 12 Aug 2018 10:37:29 +0000 (11:37 +0100)
README.rst
init.lua
net/fifosock.lua
net/nwfnet-go.lua
telnetd/telnetd-file.lua
telnetd/telnetd.lua
test/fifosocktest.lua [new file with mode: 0644]
test/morse.lua [new file with mode: 0644]
tq/tq-diag.lua
util/diag.lua
util/lfs-strings.lua [new file with mode: 0644]

index 19619d5112d58c8243ba6f524b58ab92a9a36799..fe89dedb5ceff592ee3ee4fcfbe3ba009ece4f67 100644 (file)
@@ -6,9 +6,9 @@ Introduction
 ############
 
 This is a collection of Lua modules I've used in various nodemcu/ESP8266
-projects.  It's largely an overlay-style approach to code residency; many
-things are intended to be ``dofile()``'d or ``loadfile()``'d and kept around
-only while being used.
+projects.  It's largely an overlay-style approach to code residency: most
+things are fetched through the ``OVL`` table created by ``init.lua`` rather
+than ``require``.
 
 The files here are available under the GNU Affero General Public License,
 version 3 or later.  See ``COPYING`` for details.
@@ -27,7 +27,7 @@ Generic Utilities
 
 * ``util/diag.lua`` -- a simple set of diagnostic calls intended for general
   calling from the command line.  A quick overview of the device.  Use as
-  ``dofile("diag.lc")``.
+  ``OVL.diag()``.
 
 * ``host/pushinit.sh`` -- a host-side utility to push a minimum set of files
   up to the device, either via `luatool
@@ -45,15 +45,15 @@ Networking Utilities
 Networking Framework
 --------------------
 
-* ``net/nwfnet.lua`` -- an event dispatch module; intended to be resident at
-  all times.
+* ``net/nwfnet.lua`` -- an event dispatch module; load with require so that
+  there is a singleton instance.
 
 * ``nwfnet-diag.lua`` -- generic event reporting using the above; intended
-  as diagnostics from console.  Use as ``dofile("nwfnet-diag.lc")(true)`` to
-  enable or ``...(false)`` to disable and unload.
+  as diagnostics from console.  Use as ``OVL["nwfnet-diag"]()(true)`` to
+  enable or ``...(false)`` to disable.
 
 * ``net/nwfnet-go.lua`` -- bring up the network and dispatch events via
-  ``nwfnet`` above.  Use via ``dofile``.
+  ``nwfnet`` above.  Use via ``OVL``.
 
 * ``net/netnet-sntp.lua`` -- utilities for invoking SNTP time
   synchronization once or repeatedly (using ``tq``, below).  Reads server
@@ -103,9 +103,9 @@ Timer Queue
   Enqueue events with ``:queue(time,function,args...)``; ``:queue`` returns
   a handle suitable for use with ``:dequeue()`` to unregister a pending
   future event.  All ESP-specific behavior is overridable by replacing
-  ``:now`` and ``:arm``.  Use as ``tq = dofile("tq.lc")(timer)``.
+  ``:now`` and ``:arm``.  Use as ``tq = OVL.tq()(timer)``.
 
 * ``tq/tq-diag.lua`` -- knows how to traverse a ``tq`` for diagnostic
-  utility.  Use as ``dofile("tq-diag.lc")(tq,print,print)``, e.g.
+  utility.  Use as ``OVL["tq-diag"]()(tq,print,print)``, e.g.
 
 
index 389b45831331d07930f255b72e676f6d4a06e75c..59576019839d670d21149d987350118cf6291a24 100644 (file)
--- a/init.lua
+++ b/init.lua
@@ -1,16 +1,54 @@
--- DEPEND: file?, gpio, node, rtctime?, tmr ; nwfnet, nwfnet-diag, nwfnet-go, telnetd
+-- DEPEND: gpio, node, rtctime?, tmr ; nwfnet, nwfnet-diag, nwfnet-go, telnetd
+
+-- An "overlay" table: load files or flash components in a way
+-- that, unlike require, doesn't cause them to "stick" in RAM.
+--
+-- Based on lua_examples/lfs/_init.lua
+local G=getfenv()
+local flashindex = node.flashindex
+local ovl_t = {
+  __index = function(_, name)
+      local f = loadfile(name..".lua")
+      if f then return f end
+      local f = loadfile(name..".lc")
+      if f then return f end
+      if flashindex then
+        local fn_ut, ba, ma, size, modules = flashindex(name)
+        if not ba then return fn_ut end
+      end
+      return nil
+    end,
+  __newindex = function(_, name, value)
+      error("Overlay is a synthetic view! " .. name, 2)
+    end,
+  }
+G.OVL = setmetatable(ovl_t,ovl_t)
+
+-- Install LFS as a package loader, as suggested by lua_examples/lfs/_init.lua
+if flashindex then
+  table.insert(package.loaders,function(module)
+    local fn, ba = flashindex(module)
+    return ba and "Module not in LFS" or fn
+  end)
+end
+
+-- Save some bytes, as suggested by lua_examples/lfs/_init.lua
+G.module       = nil
+package.seeall = nil
+
 if rtctime then rtctime.set(0) end -- set time to 0 until someone corrects us
 
 -- See if there's any early startup to do.
-if file and file.exists("init-early.lua") then dofile("init-early.lua") end
+local ie = OVL["init-early"]
+if ie then ie() end
 
 local function goab()
-    dofile("nwfnet-diag.lc")(true)
-    dofile("diag.lc")
-    dofile("nwfnet-go.lc")
+    OVL["nwfnet-diag"]()(true)
+    OVL["diag"]()
+    OVL["nwfnet-go"]()
     tcpserv = net.createServer(net.TCP, 180)
     tcpserv:listen(23,function(k)
-          local telnetd = dofile "telnetd.lc"
+          local telnetd = OVL["telnetd"]()
           telnetd.on["conn"] = function(s)
               tmr.unregister(6)
               s(string.format("NODE-%06X RECOVERY (auto reboot cancelled)",node.chipid()))
@@ -18,11 +56,10 @@ local function goab()
           telnetd.server(k)
         end)
 end
-local function gof(fn)
-    local f, e = loadfile(fn)
-    if f == nil then print("Error:",fn,e); goab() else node.task.post(f) end
+local function goi2()
+  local i2 = OVL.init2
+  if not i2 then goab() else node.task.post(i2) end
 end
-local function goi2() gof("init2.lc") end
 local function waitFLASH()
     local function stop_()
       gpio.mode(3,gpio.INPUT); gpio.trig(3); tmr.unregister(6)
index 87cf26c7f3a7e5dd64daaa3d5c413a4b4b281b35..2dfe7d4f5af9050d1d3545136b7330bf38cf17ea 100644 (file)
@@ -8,7 +8,7 @@ local FSMALLLIM = 32    -- maximum number of small strings held
 local concat = table.concat
 local insert = table.insert
 
-local fifo = (require "fifo")()
+local fifo = OVL.fifo()
 
 return function(sock)
   local ssend  = function(s) sock:send(s) end
index d89d2b7ed6f9c71875c9ab5eb70e2911fdca301d..4579caebbce6acae7897e804cce29c39545086cc 100644 (file)
@@ -2,7 +2,7 @@
 wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function(t)
   (require "nwfnet"):runnet("wstagoip",t)
   if mdns then mdns.register(wifi.sta.gethostname()) end
-  dofile("nwfnet-sntp.lc").dosntp(nil)
+  OVL["nwfnet-sntp"]().dosntp(nil)
 end)
 wifi.eventmon.register(wifi.eventmon.STA_DHCP_TIMEOUT, function(_) (require "nwfnet"):runnet("wstadtmo") end)
 wifi.eventmon.register(wifi.eventmon.STA_CONNECTED, function(t) (require "nwfnet"):runnet("wstaconn",t) end)
index 4578d6b6bd43ba8541d64c662d85463673e82186..f7d4716cc0de60a258207bd51be3a7269d162d3c 100644 (file)
@@ -12,6 +12,9 @@ return {
 , ["compile"] = function(ll,s) local fn = string.match(ll,"^%s*([^%s]+)%s*$");
     local r,err = pcall(node.compile,fn); if not r then s("ERR: "..err) end
   end
+, ["flashreload"] = function(ll,s) local fn = string.match(ll,"^%s*([^%s]+)%s*$");
+    local r,err = pcall(node.flashreload,fn); if not r then s("ERR: "..err) end
+  end
 , ["sha256"] = function(ll,s) -- compute the hash of a file in flash
     local fn = string.match(ll,"^%s*([^%s]+)%s*$")
     s(crypto.toBase64(crypto.fhash('sha256',fn)))
index e9fa5998fcd9f33a094ca593578b96261384bb4b..9b0d4a65168246044e5aaa01e762668386ce7643 100644 (file)
@@ -15,8 +15,8 @@ function self.rx(tx,input,k)
   self.tryin(input, self.commands,
     function(c,r)
       if c == "quit" then k(false) else
-       local rt = loadfile(string.format("telnetd-%s.lc",c))
-       if rt ~= nil
+       local rt = OVL["telnetd-"..c]
+       if type(rt) == 'function'
         then self.tryin(r,rt(),function(c2) tx(c.." "..c2.."?") end, function() tx(c.." ??") end,tx)
         else tx(c.."?")
        end
@@ -26,7 +26,7 @@ function self.rx(tx,input,k)
     function(_) tx("?") k(true) end,tx)
 end
 function self.server(sock_)
-  local fsend = (dofile("fifosock.lc"))((require "fifo")(), sock_)
+  local fsend = OVL.fifosock()(sock_)
   local function teardown(rawsock)
     rawsock:on("sent", nil)
     rawsock:on("receive", nil)
diff --git a/test/fifosocktest.lua b/test/fifosocktest.lua
new file mode 100644 (file)
index 0000000..2efdc3f
--- /dev/null
@@ -0,0 +1,67 @@
+OVL={}
+OVL.fifo = function() return dofile("./fifo/fifo.lua") end
+package.loaded["fifosock"] = dofile("./net/fifosock.lua")
+
+-- vprint = print
+vprint = function() end
+outs = {}
+
+fakesock = {
+  cb = nil,
+  on = function(this, _, cb) vprint("CBSET") this.cb = cb end,
+  send = function(this, s) vprint("SEND", verbose and s) table.insert(outs, s) end,
+}
+function sent() vprint("CB") fakesock.cb() end
+
+fsend = require "fifosock" (fakesock)
+function fcheck(x)
+  vprint ("CHECK", verbose and x)
+  assert (#outs > 0)
+  assert (x == outs[1])
+  table.remove(outs, 1)
+end
+function fsendc(x) fsend(x) fcheck(x) end
+function fchecke() vprint("CHECKE") assert (#outs == 0) end
+
+fsendc("abracadabra none")
+sent() ; fchecke()
+
+fsendc("abracadabra three")
+fsend("short")
+fsend("string")
+fsend("build")
+sent() ; fcheck("shortstringbuild")
+sent() ; fchecke()
+
+-- Hit default FSMALLLIM while building up
+fsendc("abracadabra lots small")
+for i = 1, 34 do fsend("a") end
+sent() ; fcheck(string.rep("a", 32))
+sent() ; fcheck("aa")
+sent() ; fchecke()
+
+-- Hit string length while building up
+fsendc("abracadabra overlong")
+for i = 1, 10 do fsend(string.rep("a",32)) end
+sent() ; fcheck(string.rep("a", 256))
+sent() ; fcheck(string.rep("a", 64))
+sent() ; fchecke()
+
+-- Hit neither before sending a big string
+fsendc("abracadabra mid long")
+for i = 1, 6 do fsend(string.rep("a",32)) end
+fsend(string.rep("b", 256))
+for i = 1, 6 do fsend(string.rep("c",32)) end
+sent() ; fcheck(string.rep("a", 192))
+sent() ; fcheck(string.rep("b", 256))
+sent() ; fcheck(string.rep("c", 192))
+sent() ; fchecke()
+
+-- send a huge string
+fsend(string.rep("a",256) .. string.rep("b", 256) .. string.rep("c", 260))
+fcheck(string.rep("a",256))
+sent() ; fcheck(string.rep("b",256))
+sent() ; fcheck(string.rep("c",260))
+sent() ; fchecke()
+
+print("All tests OK")
diff --git a/test/morse.lua b/test/morse.lua
new file mode 100644 (file)
index 0000000..18e2f8c
--- /dev/null
@@ -0,0 +1,6 @@
+morse = dofile("morse/morse.lua")
+
+function tm(str)
+  local m = morse(str)
+  while m(print) do end
+end
index 129cced6901ed7aeb76e5cde69afb015024590b3..5dbe3570c0eee9d8d726f52e02dfc1d774f21d4e 100644 (file)
@@ -1,3 +1,3 @@
 -- call directly or wrap in tq immediately to get updated leader time value:
--- tq:queue(1,function() dofile("tq-diag.lc")(tq,print,print) end)
+-- tq:queue(1,function() OVL["tq-diag"]()(tq,print,print) end)
 return function (self,kt,ke) local i,t; for i,t in ipairs(self._q) do kt(i,t["t"],#t) for k,v in ipairs(t) do ke(i,k,v) end end end
index 32d81afa868b376060a09c701580996221e843df..7c312582bc7cbcc3a148c513261c98ad76558a2c 100644 (file)
@@ -1,4 +1,5 @@
 -- SOFT DEPENDS: file, rtcfifo, node, wifi
+local k,v
 if node then
   print('INFO:',string.format("major=%d minor=%d dev=%d chip=%d flash=%d fs=%d fm=%d fs=%d",node.info()))
   print('HEAP:', node.heap())
@@ -17,5 +18,14 @@ end
 if file then
   print('FS:', file.fsinfo()); for k,v in pairs(file.list()) do print("",k,v) end
 end
+if node.flashindex then
+ local ut, fa, ma, sz, t = node.flashindex()
+ if ut then
+   print('LFS:', ut, fa, ma, sz)
+   for k,v in ipairs(t) do print("", v) end
+ else
+   print('LFS:', fa, ma)
+ end
+end
 print('PACKAGES:'); for k,v in pairs(package.loaded) do print("",k,v) end
 print('GLOBAL:'); for k,v in pairs(_G) do print("",k,v) end
diff --git a/util/lfs-strings.lua b/util/lfs-strings.lua
new file mode 100644 (file)
index 0000000..764c44c
--- /dev/null
@@ -0,0 +1,16 @@
+-- from lua_examples/lfs/dummy_strings.lua
+local preload = "?.lc;?.lua", "/\n;\n?\n!\n-", "@init.lua", "_G", "_LOADED",
+"_LOADLIB", "__add", "__call", "__concat", "__div", "__eq", "__gc", "__index",
+"__le", "__len", "__lt", "__mod", "__mode", "__mul", "__newindex", "__pow",
+"__sub", "__tostring", "__unm", "collectgarbage", "cpath", "debug", "file",
+"file.obj", "file.vol", "flash", "getstrings", "index", "ipairs", "list", "loaded",
+"loader", "loaders", "loadlib", "module", "net.tcpserver", "net.tcpsocket",
+"net.udpsocket", "newproxy", "package", "pairs", "path", "preload", "reload",
+"require", "seeall", "wdclr", "not enough memory", "sjson.decoder","sjson.encoder", 
+"tmr.timer"
+
+local initload =
+  ".lc", ".lua", "loadfile",
+  "Module not in LFS", 
+  "NODE-%06X RECOVERY (auto reboot cancelled)", 
+  "Overlay is a synthetic view! "