Bladeren bron

Reworked module registration, removed modules.h

Module creation & registration now made a lot simpler. In essence,
each module file is now self-contained and only needs a

  NODEMCU_MODULE(MYNAME, "myname", myname_map, luaopen_myname);

line to both be automatically recognised by the Lua initialization
as well as honor the LUA_USE_MODULES_MYNAME #define.
Johny Mattsson 8 jaren geleden
bovenliggende
commit
4e8ef87d03

+ 74 - 0
app/include/module.h

@@ -0,0 +1,74 @@
+#ifndef __MODULE_H__
+#define __MODULE_H__
+
+#include "user_modules.h"
+#include "lrodefs.h"
+
+/* Registering a module within NodeMCU is really easy these days!
+ *
+ * Most of the work is done by a combination of pre-processor, compiler
+ * and linker "magic". Gone are the days of needing to update 4+ separate
+ * files just to register a module!
+ *
+ * You will need:
+ *   - to include this header
+ *   - a name for the module
+ *   - a LUA_REG_TYPE module map
+ *   - optionally, an init function
+ *
+ * Then simply put a line like this at the bottom of your module file:
+ *
+ *   NODEMCU_MODULE(MYNAME, "myname", myname_map, luaopen_myname);
+ *
+ * or perhaps
+ *
+ *   NODEMCU_MODULE(MYNAME, "myname", myname_map, NULL);
+ *
+ * if you don't need an init function.
+ *
+ * When you've done this, the module can be enabled in user_modules.h with:
+ *
+ *   #define LUA_USE_MODULES_MYNAME
+ *
+ * and within NodeMCU you access it with myname.foo(), assuming you have
+ * a foo function in your module.
+ */
+
+#define MODULE_STRIFY__(x) #x
+#define MODULE_STRIFY_(x) MODULE_STRIFY__(x)
+#define MODULE_EXPAND_(x) x
+#define MODULE_PASTE_(x,y) x##y
+
+/* Given an uppercase name XYZ, look at the corresponding LUA_USE_MODULES_XYZ
+ * and append that to the section name prefix (e.g. "lua_libs"). For an
+ * included module, this will yield either ".lua_libs" (for an empty #define)
+ * or ".lua_libs1" (if #defined to 1). The linker script will then
+ * pick up all items in those sections and construct an array for us.
+ * A non-included module ZZZ ends up in a section named
+ * ".lua_libsLUA_USE_MODULES_ZZZ" which gets discarded by the linker (together
+ * with the associated module code).
+ */
+#define PICK_SECTION_(pfx, name) \
+   pfx MODULE_STRIFY_(MODULE_EXPAND_(LUA_USE_MODULES_ ## name))
+
+#define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \
+  static const __attribute__((used,unused,section(PICK_SECTION_(".lua_libs",cfgname)))) \
+    luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
+  static const __attribute__((used,unused,section(PICK_SECTION_(".lua_rotable",cfgname)))) \
+    luaR_table MODULE_PASTE_(lua_rotable_,cfgname) = { luaname, map }
+
+
+/* System module registration support, not using LUA_USE_MODULES_XYZ. */
+#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
+  static const __attribute__((used,unused,section(".lua_libs"))) \
+    luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }
+
+#define BUILTIN_LIB(name, luaname, map) \
+  static const __attribute__((used,unused,section(".lua_rotable"))) \
+    luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
+
+#if !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
+# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
+#endif
+
+#endif

+ 1 - 4
app/include/user_modules.h

@@ -12,9 +12,7 @@
 #define LUA_USE_BUILTIN_DEBUG_MINIMAL // for debug.getregistry() and debug.traceback()
 
 #ifndef LUA_CROSS_COMPILER
-#define LUA_USE_MODULES
 
-#ifdef LUA_USE_MODULES
 #define LUA_USE_MODULES_ADC
 #define LUA_USE_MODULES_BIT
 //#define LUA_USE_MODULES_BMP085
@@ -47,7 +45,6 @@
 //#define LUA_USE_MODULES_WS2801
 #define LUA_USE_MODULES_WS2812
 
-#endif /* LUA_USE_MODULES */
-#endif
 
+#endif  /* LUA_CROSS_COMPILER */
 #endif	/* __USER_MODULES_H__ */

+ 1 - 1
app/lua/lrodefs.h

@@ -16,7 +16,7 @@
 #undef LREGISTER
 
 #if (MIN_OPT_LEVEL > 0) && (LUA_OPTIMIZE_MEMORY >= MIN_OPT_LEVEL)
-#define LUA_REG_TYPE                luaR_entry ICACHE_RODATA_ATTR
+#define LUA_REG_TYPE                luaR_entry
 #define LSTRKEY                     LRO_STRKEY
 #define LNUMKEY                     LRO_NUMKEY
 #define LNILKEY                     LRO_NILKEY

+ 3 - 9
app/modules/adc.c

@@ -1,8 +1,8 @@
 // Module for interfacing with adc
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_types.h"
 #include "user_interface.h"
@@ -25,16 +25,10 @@ static int adc_readvdd33( lua_State* L )
 }
 
 // Module function map
-const LUA_REG_TYPE adc_map[] = {
+static const LUA_REG_TYPE adc_map[] = {
   { LSTRKEY( "read" ),      LFUNCVAL( adc_sample ) },
   { LSTRKEY( "readvdd33" ), LFUNCVAL( adc_readvdd33) },
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_adc( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-# error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(ADC, "adc", adc_map, NULL);

+ 3 - 9
app/modules/bit.c

@@ -5,10 +5,10 @@
 // Modified by BogdanM for eLua
 
 
+#include "module.h"
 #include "c_limits.h"
 
 #include "lauxlib.h"
-#include "lrodefs.h"
 
 /* FIXME: Assume size_t is an unsigned lua_Integer */
 typedef size_t lua_UInteger;
@@ -119,7 +119,7 @@ static int bit_clear( lua_State* L )
   return 1; 
 }
 
-const LUA_REG_TYPE bit_map[] = {
+static const LUA_REG_TYPE bit_map[] = {
   { LSTRKEY( "bnot" ),    LFUNCVAL( bit_bnot ) },
   { LSTRKEY( "band" ),    LFUNCVAL( bit_band ) },
   { LSTRKEY( "bor" ),     LFUNCVAL( bit_bor ) },
@@ -135,10 +135,4 @@ const LUA_REG_TYPE bit_map[] = {
   { LNILKEY, LNILVAL}
 };
 
-LUALIB_API int luaopen_bit (lua_State *L) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-# error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(BIT, "bit", bit_map, NULL);

+ 3 - 9
app/modules/bmp085.c

@@ -1,6 +1,6 @@
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "c_stdlib.h"
 #include "c_string.h"
 
@@ -183,7 +183,7 @@ static int ICACHE_FLASH_ATTR bmp085_lua_pressure(lua_State* L) {
     return 1;
 }
 
-const LUA_REG_TYPE bmp085_map[] = {
+static const LUA_REG_TYPE bmp085_map[] = {
     { LSTRKEY( "temperature" ),  LFUNCVAL( bmp085_lua_temperature )},
     { LSTRKEY( "pressure" ),     LFUNCVAL( bmp085_lua_pressure )},
     { LSTRKEY( "pressure_raw" ), LFUNCVAL( bmp085_lua_pressure_raw )},
@@ -191,10 +191,4 @@ const LUA_REG_TYPE bmp085_map[] = {
     { LNILKEY, LNILVAL}
 };
 
-LUALIB_API int luaopen_bmp085(lua_State *L) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(BMP085, "bmp085", bmp085_map, NULL);

+ 5 - 7
app/modules/cjson.c

@@ -37,11 +37,11 @@
  */
 
 // #include <assert.h>
+#include "module.h"
 #include "c_string.h"
 #include "c_math.h"
 #include "c_limits.h"
 #include "lauxlib.h"
-#include "lrodefs.h"
 #include "flash_api.h"
 
 #include "strbuf.h"
@@ -1600,7 +1600,7 @@ int luaopen_cjson_safe(lua_State *l)
 #endif
 
 // Module function map
-const LUA_REG_TYPE cjson_map[] = {
+static const LUA_REG_TYPE cjson_map[] = {
   { LSTRKEY( "encode" ),                  LFUNCVAL( json_encode ) },
   { LSTRKEY( "decode" ),                  LFUNCVAL( json_decode ) },
 //{ LSTRKEY( "encode_sparse_array" ),     LFUNCVAL( json_cfg_encode_sparse_array ) },
@@ -1614,7 +1614,7 @@ const LUA_REG_TYPE cjson_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_cjson( lua_State *L )
+int luaopen_cjson( lua_State *L )
 {
   cjson_mem_setlua (L);
 
@@ -1623,11 +1623,9 @@ LUALIB_API int luaopen_cjson( lua_State *L )
   if(-1==cfg_init(&_cfg)){
     return luaL_error(L, "BUG: Unable to init config for cjson");;
   }
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(CJSON, "cjson", cjson_map, luaopen_cjson);
 /* vi:ai et sw=4 ts=4:
  */

+ 5 - 7
app/modules/coap.c

@@ -1,8 +1,8 @@
 // Module for coapwork
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_string.h"
 #include "c_stdlib.h"
@@ -578,7 +578,7 @@ static const LUA_REG_TYPE coap_client_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-const LUA_REG_TYPE coap_map[] = 
+static const LUA_REG_TYPE coap_map[] = 
 {
   { LSTRKEY( "Server" ),      LFUNCVAL( coap_createServer ) },
   { LSTRKEY( "Client" ),      LFUNCVAL( coap_createClient ) },
@@ -594,14 +594,12 @@ const LUA_REG_TYPE coap_map[] =
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_coap( lua_State *L )
+int luaopen_coap( lua_State *L )
 {
   endpoint_setup();
   luaL_rometatable(L, "coap_server", (void *)coap_server_map);  // create metatable for coap_server 
   luaL_rometatable(L, "coap_client", (void *)coap_client_map);  // create metatable for coap_client  
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(COAP, "coap", coap_map, luaopen_coap);

+ 3 - 9
app/modules/crypto.c

@@ -1,8 +1,8 @@
 // Module for cryptography
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "c_types.h"
 #include "c_stdlib.h"
 #include "../crypto/digests.h"
@@ -150,7 +150,7 @@ static int crypto_lhmac (lua_State *L)
 
 
 // Module function map
-const LUA_REG_TYPE crypto_map[] = {
+static const LUA_REG_TYPE crypto_map[] = {
   { LSTRKEY( "sha1" ),     LFUNCVAL( crypto_sha1 ) },
   { LSTRKEY( "toBase64" ), LFUNCVAL( crypto_base64_encode ) },
   { LSTRKEY( "toHex" ),    LFUNCVAL( crypto_hex_encode ) },
@@ -160,10 +160,4 @@ const LUA_REG_TYPE crypto_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_crypto( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(CRYPTO, "crypto", crypto_map, NULL);

+ 3 - 9
app/modules/dht.c

@@ -1,7 +1,7 @@
 // Module for interfacing with the DHTxx sensors (xx = 11-21-22-33-44).
 
+#include "module.h"
 #include "lauxlib.h"
-#include "lrodefs.h"
 #include "platform.h"
 #include "cpu_esp8266.h"
 #include "dht.h"
@@ -99,7 +99,7 @@ static int dht_lapi_readxx( lua_State *L )
 // }
 
 // Module function map
-const LUA_REG_TYPE dht_map[] = {
+static const LUA_REG_TYPE dht_map[] = {
   { LSTRKEY( "read" ),           LFUNCVAL( dht_lapi_read ) },
   { LSTRKEY( "read11" ),         LFUNCVAL( dht_lapi_read11 ) },
   { LSTRKEY( "readxx" ),         LFUNCVAL( dht_lapi_readxx ) },
@@ -109,10 +109,4 @@ const LUA_REG_TYPE dht_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_dht( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(DHT, "dht", dht_map, NULL);

+ 3 - 11
app/modules/enduser_setup.c

@@ -31,10 +31,9 @@
  * @author Robert Foss <dev@robertfoss.se>
  */
 
-
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "c_stdlib.h"
 #include "c_string.h"
 #include "user_interface.h"
@@ -927,17 +926,10 @@ static int enduser_setup_stop(lua_State* L)
 }
 
 
-const LUA_REG_TYPE enduser_setup_map[] = {
+static const LUA_REG_TYPE enduser_setup_map[] = {
   { LSTRKEY( "start" ), LFUNCVAL( enduser_setup_start )},
   { LSTRKEY( "stop" ),  LFUNCVAL( enduser_setup_stop  )},
   { LNILKEY, LNILVAL}
 };
 
-LUALIB_API int luaopen_enduser_setup(lua_State *L) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
-
+NODEMCU_MODULE(ENDUSER_SETUP, "enduser_setup", enduser_setup_map, NULL);

+ 3 - 9
app/modules/file.c

@@ -1,8 +1,8 @@
 // Module for interfacing with file system
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_types.h"
 #include "flash_fs.h"
@@ -296,7 +296,7 @@ static int file_writeline( lua_State* L )
 }
 
 // Module function map
-const LUA_REG_TYPE file_map[] = {
+static const LUA_REG_TYPE file_map[] = {
   { LSTRKEY( "list" ),      LFUNCVAL( file_list ) },
   { LSTRKEY( "open" ),      LFUNCVAL( file_open ) },
   { LSTRKEY( "close" ),     LFUNCVAL( file_close ) },
@@ -316,10 +316,4 @@ const LUA_REG_TYPE file_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_file( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(FILE, "file", file_map, NULL);

+ 5 - 8
app/modules/gpio.c

@@ -1,8 +1,8 @@
 // Module for interfacing with GPIO
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_types.h"
 #include "c_string.h"
@@ -220,7 +220,7 @@ static int lgpio_serout( lua_State* L )
 #undef DELAY_TABLE_MAX_LEN
 
 // Module function map
-const LUA_REG_TYPE gpio_map[] = {
+static const LUA_REG_TYPE gpio_map[] = {
   { LSTRKEY( "mode" ),   LFUNCVAL( lgpio_mode ) },
   { LSTRKEY( "read" ),   LFUNCVAL( lgpio_read ) },
   { LSTRKEY( "write" ),  LFUNCVAL( lgpio_write ) },
@@ -238,7 +238,7 @@ const LUA_REG_TYPE gpio_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_gpio( lua_State *L ) {
+int luaopen_gpio( lua_State *L ) {
 #ifdef GPIO_INTERRUPT_ENABLE
   int i;
   for(i=0;i<GPIO_PIN_NUM;i++){
@@ -246,10 +246,7 @@ LUALIB_API int luaopen_gpio( lua_State *L ) {
   }
   platform_gpio_init(gpio_intr_callback);
 #endif
-
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(GPIO, "gpio", gpio_map, luaopen_gpio);

+ 5 - 7
app/modules/hx711.c

@@ -1,9 +1,9 @@
 // Module for HX711 load cell amplifier
 // https://learn.sparkfun.com/tutorials/load-cell-amplifier-hx711-breakout-hookup-guide
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "c_stdlib.h"
 #include "c_string.h"
 #include "user_interface.h"
@@ -66,17 +66,15 @@ static int ICACHE_FLASH_ATTR hx711_read(lua_State* L) {
 }
 
 // Module function map
-const LUA_REG_TYPE hx711_map[] = {
+static const LUA_REG_TYPE hx711_map[] = {
   { LSTRKEY( "init" ), LFUNCVAL( hx711_init )},
   { LSTRKEY( "read" ), LFUNCVAL( hx711_read )},
   { LNILKEY, LNILVAL}
 };
 
-LUALIB_API int luaopen_hx711(lua_State *L) {
+int luaopen_hx711(lua_State *L) {
   // TODO: Make sure that the GPIO system is initialized
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(HX711, "hx711", hx711_map, luaopen_hx711);

+ 3 - 10
app/modules/i2c.c

@@ -1,8 +1,8 @@
 // Module for interfacing with the I2C interface
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 // Lua: speed = i2c.setup( id, sda, scl, speed )
 static int i2c_setup( lua_State *L )
@@ -140,7 +140,7 @@ static int i2c_read( lua_State *L )
 }
 
 // Module function map
-const LUA_REG_TYPE i2c_map[] = {
+static const LUA_REG_TYPE i2c_map[] = {
   { LSTRKEY( "setup" ),       LFUNCVAL( i2c_setup ) },
   { LSTRKEY( "start" ),       LFUNCVAL( i2c_start ) },
   { LSTRKEY( "stop" ),        LFUNCVAL( i2c_stop ) },
@@ -154,11 +154,4 @@ const LUA_REG_TYPE i2c_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_i2c( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
-
+NODEMCU_MODULE(I2C, "i2c", i2c_map, NULL);

+ 29 - 92
app/modules/linit.c

@@ -13,124 +13,61 @@
 
 #include "lualib.h"
 #include "lauxlib.h"
-#include "lrotable.h"
 #include "luaconf.h"
+#include "module.h"
 
-#include "user_modules.h"
 
-#if defined(LUA_USE_MODULES)
-#include "modules.h"
-#endif
-
-#if defined(LUA_MODULES_ROM)
-#undef _ROM
-#define _ROM( name, openf, table ) extern int openf(lua_State *);
-LUA_MODULES_ROM
-#endif
+BUILTIN_LIB_INIT( BASE,      "",                 luaopen_base);
+BUILTIN_LIB_INIT( LOADLIB,   LUA_LOADLIBNAME,    luaopen_package);
 
-static const luaL_Reg lualibs[] = {
-  {"", luaopen_base},
-  {LUA_LOADLIBNAME, luaopen_package},
 #if defined(LUA_USE_BUILTIN_IO)
-  {LUA_IOLIBNAME, luaopen_io},
+BUILTIN_LIB_INIT( IO,        LUA_IOLIBNAME,      luaopen_io);
 #endif
 
-#if defined(LUA_USE_BUILTIN_STRING)
-  {LUA_STRLIBNAME, luaopen_string},
-#endif
-
-#if LUA_OPTIMIZE_MEMORY == 0
-  #if defined(LUA_USE_BUILTIN_MATH)
-  {LUA_MATHLIBNAME, luaopen_math},
-  #endif
-
-  #if defined(LUA_USE_BUILTIN_TABLE)
-  {LUA_TABLIBNAME, luaopen_table},  
-  #endif
-
-  #if defined(LUA_USE_BUILTIN_DEBUG) || defined(LUA_USE_BUILTIN_DEBUG_MINIMAL)
-  {LUA_DBLIBNAME, luaopen_debug},
-  #endif 
-#endif
-#if defined(LUA_MODULES_ROM)
-#undef _ROM
-#define _ROM( name, openf, table ) { name, openf },
-  LUA_MODULES_ROM
-#endif
-  {NULL, NULL}
-};
-
-#if defined(LUA_USE_BUILTIN_STRING)
+#if defined (LUA_USE_BUILTIN_STRING)
 extern const luaR_entry strlib[];
-#endif
-
-#if defined(LUA_USE_BUILTIN_OS)
-extern const luaR_entry syslib[];
+BUILTIN_LIB_INIT( STRING,    LUA_STRLIBNAME,     luaopen_string);
+BUILTIN_LIB(      STRING,    LUA_STRLIBNAME,     strlib);
 #endif
 
 #if defined(LUA_USE_BUILTIN_TABLE)
 extern const luaR_entry tab_funcs[];
+BUILTIN_LIB_INIT( TABLE,     LUA_TABLIBNAME,     luaopen_table);
+BUILTIN_LIB(      TABLE,     LUA_TABLIBNAME,     tab_funcs);
 #endif
 
 #if defined(LUA_USE_BUILTIN_DEBUG) || defined(LUA_USE_BUILTIN_DEBUG_MINIMAL)
 extern const luaR_entry dblib[];
+BUILTIN_LIB_INIT( DBG,       LUA_DBLIBNAME,      luaopen_debug);
+BUILTIN_LIB(      DBG,       LUA_DBLIBNAME,      dblib);
+#endif
+
+#if defined(LUA_USE_BUILTIN_OS)
+extern const luaR_entry syslib[];
+BUILTIN_LIB(      OS,        LUA_OSLIBNAME,     syslib);
 #endif
 
 #if defined(LUA_USE_BUILTIN_COROUTINE)
 extern const luaR_entry co_funcs[];
+BUILTIN_LIB(      CO,        LUA_COLIBNAME,     co_funcs);
 #endif
 
 #if defined(LUA_USE_BUILTIN_MATH)
 extern const luaR_entry math_map[];
+BUILTIN_LIB(      MATH,      LUA_MATHLIBNAME,   math_map);
 #endif
 
-#if defined(LUA_MODULES_ROM) && LUA_OPTIMIZE_MEMORY == 2
-#undef _ROM
-#define _ROM( name, openf, table ) extern const luaR_entry table[];
-LUA_MODULES_ROM
-#endif
-const luaR_table lua_rotable[] = 
-{
-#if LUA_OPTIMIZE_MEMORY > 0
-  #if defined(LUA_USE_BUILTIN_STRING)
-  {LUA_STRLIBNAME, strlib},
-  #endif
-
-  #if defined(LUA_USE_BUILTIN_TABLE)
-  {LUA_TABLIBNAME, tab_funcs},
-  #endif
-
-  #if defined(LUA_USE_BUILTIN_DEBUG) || defined(LUA_USE_BUILTIN_DEBUG_MINIMAL)
-  {LUA_DBLIBNAME, dblib},
-  #endif
-
-  #if defined(LUA_USE_BUILTIN_COROUTINE)
-  {LUA_COLIBNAME, co_funcs},
-  #endif
-
-  #if defined(LUA_USE_BUILTIN_MATH)
-  {LUA_MATHLIBNAME, math_map},
-  #endif
-
-  #if defined(LUA_USE_BUILTIN_OS)
-  {LUA_OSLIBNAME, syslib},
-  #endif
-
-#if defined(LUA_MODULES_ROM) && LUA_OPTIMIZE_MEMORY == 2
-#undef _ROM
-#define _ROM( name, openf, table ) { name, table },
-  LUA_MODULES_ROM
-#endif
-#endif
-  {NULL, NULL}
-};
-
-LUALIB_API void luaL_openlibs (lua_State *L) {
-  const luaL_Reg *lib = lualibs;
-  for (; lib->func; lib++) {
-    lua_pushcfunction(L, lib->func);
-    lua_pushstring(L, lib->name);
-    lua_call(L, 1, 0);
+extern const luaL_Reg lua_libs[];
+
+void luaL_openlibs (lua_State *L) {
+  const luaL_Reg *lib = lua_libs;
+  for (; lib->name; lib++) {
+    if (lib->func)
+    {
+      lua_pushcfunction(L, lib->func);
+      lua_pushstring(L, lib->name);
+      lua_call(L, 1, 0);
+    }
   }
 }
 

+ 0 - 289
app/modules/modules.h

@@ -1,289 +0,0 @@
-/**
- * External modules library
- */
-
-#ifndef __MODULES_H__
-#define __MODULES_H__
-
-#if defined(LUA_USE_MODULES_GPIO)
-#define MODULES_GPIO        "gpio"
-#define ROM_MODULES_GPIO    \
-    _ROM(MODULES_GPIO, luaopen_gpio, gpio_map)
-#else
-#define ROM_MODULES_GPIO
-#endif
-
-#if defined(LUA_USE_MODULES_PWM)
-#define MODULES_PWM         "pwm"
-#define ROM_MODULES_PWM     \
-    _ROM(MODULES_PWM, luaopen_pwm, pwm_map)
-#else
-#define ROM_MODULES_PWM
-#endif
-
-#if defined(LUA_USE_MODULES_WIFI)
-#define MODULES_WIFI        "wifi"
-#define ROM_MODULES_WIFI    \
-    _ROM(MODULES_WIFI, luaopen_wifi, wifi_map)
-#else
-#define ROM_MODULES_WIFI
-#endif
-
-#if defined(LUA_USE_MODULES_NET)
-#define MODULES_NET         "net"
-#define ROM_MODULES_NET     \
-    _ROM(MODULES_NET, luaopen_net, net_map)
-#else
-#define ROM_MODULES_NET
-#endif
-
-#if defined(LUA_USE_MODULES_COAP)
-#define MODULES_COAP        "coap"
-#define ROM_MODULES_COAP    \
-    _ROM(MODULES_COAP, luaopen_coap, coap_map)
-#else
-#define ROM_MODULES_COAP
-#endif
-
-#if defined(LUA_USE_MODULES_MQTT)
-#define MODULES_MQTT        "mqtt"
-#define ROM_MODULES_MQTT    \
-    _ROM(MODULES_MQTT, luaopen_mqtt, mqtt_map)
-#else
-#define ROM_MODULES_MQTT
-#endif
-
-#if defined(LUA_USE_MODULES_U8G)
-#define MODULES_U8G         "u8g"
-#define ROM_MODULES_U8G     \
-    _ROM(MODULES_U8G, luaopen_u8g, lu8g_map)
-#else
-#define ROM_MODULES_U8G
-#endif
-
-#if defined(LUA_USE_MODULES_UCG)
-#define MODULES_UCG         "ucg"
-#define ROM_MODULES_UCG     \
-    _ROM(MODULES_UCG, luaopen_ucg, lucg_map)
-#else
-#define ROM_MODULES_UCG
-#endif
-
-#if defined(LUA_USE_MODULES_I2C)
-#define MODULES_I2C         "i2c"
-#define ROM_MODULES_I2C     \
-    _ROM(MODULES_I2C, luaopen_i2c, i2c_map)
-#else
-#define ROM_MODULES_I2C
-#endif
-
-#if defined(LUA_USE_MODULES_SPI)
-#define MODULES_SPI         "spi"
-#define ROM_MODULES_SPI     \
-    _ROM(MODULES_SPI, luaopen_spi, spi_map)
-#else
-#define ROM_MODULES_SPI
-#endif
-
-#if defined(LUA_USE_MODULES_TMR)
-#define MODULES_TMR         "tmr"
-#define ROM_MODULES_TMR     \
-    _ROM(MODULES_TMR, luaopen_tmr, tmr_map)
-#else
-#define ROM_MODULES_TMR
-#endif
-
-#if defined(LUA_USE_MODULES_NODE)
-#define MODULES_NODE        "node"
-#define ROM_MODULES_NODE    \
-    _ROM(MODULES_NODE, luaopen_node, node_map)
-#else
-#define ROM_MODULES_NODE
-#endif
-
-#if defined(LUA_USE_MODULES_FILE)
-#define MODULES_FILE        "file"
-#define ROM_MODULES_FILE    \
-    _ROM(MODULES_FILE, luaopen_file, file_map)
-#else
-#define ROM_MODULES_FILE
-#endif
-
-#if defined(LUA_USE_MODULES_ADC)
-#define MODULES_ADC         "adc"
-#define ROM_MODULES_ADC     \
-    _ROM(MODULES_ADC, luaopen_adc, adc_map)
-#else
-#define ROM_MODULES_ADC
-#endif
-
-#if defined(LUA_USE_MODULES_UART)
-#define MODULES_UART        "uart"
-#define ROM_MODULES_UART    \
-    _ROM(MODULES_UART, luaopen_uart, uart_map)
-#else
-#define ROM_MODULES_UART
-#endif
-
-#if defined(LUA_USE_MODULES_OW)
-#define MODULES_OW          "ow"
-#define ROM_MODULES_OW      \
-    _ROM(MODULES_OW, luaopen_ow, ow_map)
-#else
-#define ROM_MODULES_OW
-#endif
-
-#if defined(LUA_USE_MODULES_BIT)
-#define MODULES_BIT         "bit"
-#define ROM_MODULES_BIT     \
-    _ROM(MODULES_BIT, luaopen_bit, bit_map)
-#else
-#define ROM_MODULES_BIT
-#endif
-
-#if defined(LUA_USE_MODULES_WS2801)
-#define MODULES_WS2801      "ws2801"
-#define ROM_MODULES_WS2801  \
-    _ROM(MODULES_WS2801, luaopen_ws2801, ws2801_map)
-#else
-#define ROM_MODULES_WS2801
-#endif
-
-#if defined(LUA_USE_MODULES_WS2812)
-#define MODULES_WS2812      "ws2812"
-#define ROM_MODULES_WS2812  \
-    _ROM(MODULES_WS2812, luaopen_ws2812, ws2812_map)
-#else
-#define ROM_MODULES_WS2812
-#endif
-
-#if defined(LUA_USE_MODULES_ENDUSER_SETUP)
-#define MODULES_ENDUSER_SETUP      "enduser_setup"
-#define ROM_MODULES_ENDUSER_SETUP  \
-    _ROM(MODULES_ENDUSER_SETUP, luaopen_enduser_setup, enduser_setup_map)
-#else
-#define ROM_MODULES_ENDUSER_SETUP
-#endif
-
-#if defined(LUA_USE_MODULES_CJSON)
-#define MODULES_CJSON       "cjson"
-#define ROM_MODULES_CJSON   \
-    _ROM(MODULES_CJSON, luaopen_cjson, cjson_map)
-#else
-#define ROM_MODULES_CJSON
-#endif
-
-#if defined(LUA_USE_MODULES_CRYPTO)
-#define MODULES_CRYPTO      "crypto"
-#define ROM_MODULES_CRYPTO  \
-    _ROM(MODULES_CRYPTO, luaopen_crypto, crypto_map)
-#else
-#define ROM_MODULES_CRYPTO
-#endif
-
-#if defined(LUA_USE_MODULES_RC)
-#define MODULES_RC          "rc"
-#define ROM_MODULES_RC      \
-    _ROM(MODULES_RC, luaopen_rc, rc_map)
-#else
-#define ROM_MODULES_RC
-#endif
-
-#if defined(LUA_USE_MODULES_DHT)
-#define MODULES_DHT         "dht"
-#define ROM_MODULES_DHT     \
-    _ROM(MODULES_DHT, luaopen_dht, dht_map)
-#else
-#define ROM_MODULES_DHT
-#endif
-
-#if defined(LUA_USE_MODULES_RTCMEM)
-#define MODULES_RTCMEM      "rtcmem"
-#define ROM_MODULES_RTCMEM  \
-    _ROM(MODULES_RTCMEM, luaopen_rtcmem, rtcmem_map)
-#else
-#define ROM_MODULES_RTCMEM
-#endif
-
-#if defined(LUA_USE_MODULES_RTCTIME)
-#define MODULES_RTCTIME      "rtctime"
-#define ROM_MODULES_RTCTIME  \
-    _ROM(MODULES_RTCTIME, luaopen_rtctime, rtctime_map)
-#else
-#define ROM_MODULES_RTCTIME
-#endif
-
-#if defined(LUA_USE_MODULES_RTCFIFO)
-#define MODULES_RTCFIFO      "rtcfifo"
-#define ROM_MODULES_RTCFIFO  \
-    _ROM(MODULES_RTCFIFO, luaopen_rtcfifo, rtcfifo_map)
-#else
-#define ROM_MODULES_RTCFIFO
-#endif
-
-#if defined(LUA_USE_MODULES_SNTP)
-#define MODULES_SNTP      "sntp"
-#define ROM_MODULES_SNTP  \
-    _ROM(MODULES_SNTP, luaopen_sntp, sntp_map)
-#else
-#define ROM_MODULES_SNTP
-#endif
-
-#if defined(LUA_USE_MODULES_BMP085)
-#define MODULES_BMP085      "bmp085"
-#define ROM_MODULES_BMP085  \
-    _ROM(MODULES_BMP085, luaopen_bmp085, bmp085_map)
-#else
-#define ROM_MODULES_BMP085
-#endif
-
-#if defined(LUA_USE_MODULES_TSL2561)
-#define MODULES_TSL2561      "tsl2561"
-#define ROM_MODULES_TSL2561  \
-    _ROM(MODULES_TSL2561, luaopen_tsl2561, tsl2561_map)
-#else
-#define ROM_MODULES_TSL2561
-#endif
-
-#if defined(LUA_USE_MODULES_HX711)
-#define MODULES_HX711      "hx711"
-#define ROM_MODULES_HX711  \
-    _ROM(MODULES_HX711, luaopen_hx711, hx711_map)
-#else
-#define ROM_MODULES_HX711
-#endif
-
-#define LUA_MODULES_ROM     \
-        ROM_MODULES_GPIO    \
-        ROM_MODULES_PWM		\
-        ROM_MODULES_WIFI	\
-        ROM_MODULES_COAP	\
-        ROM_MODULES_MQTT    \
-        ROM_MODULES_U8G     \
-        ROM_MODULES_UCG     \
-        ROM_MODULES_I2C     \
-        ROM_MODULES_SPI     \
-        ROM_MODULES_TMR     \
-        ROM_MODULES_NODE    \
-        ROM_MODULES_FILE    \
-        ROM_MODULES_NET     \
-        ROM_MODULES_ADC     \
-        ROM_MODULES_UART    \
-        ROM_MODULES_OW      \
-        ROM_MODULES_BIT     \
-        ROM_MODULES_ENDUSER_SETUP \
-        ROM_MODULES_WS2801  \
-        ROM_MODULES_WS2812  \
-        ROM_MODULES_CJSON   \
-        ROM_MODULES_CRYPTO  \
-        ROM_MODULES_RC      \
-        ROM_MODULES_DHT     \
-        ROM_MODULES_RTCMEM  \
-        ROM_MODULES_RTCTIME \
-        ROM_MODULES_RTCFIFO \
-        ROM_MODULES_SNTP    \
-        ROM_MODULES_BMP085  \
-        ROM_MODULES_TSL2561 \
-        ROM_MODULES_HX711  
-
-#endif

+ 5 - 7
app/modules/mqtt.c

@@ -1,8 +1,8 @@
 // Module for mqtt
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_string.h"
 #include "c_stdlib.h"
@@ -1401,18 +1401,16 @@ static const LUA_REG_TYPE mqtt_socket_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-const LUA_REG_TYPE mqtt_map[] = {
+static const LUA_REG_TYPE mqtt_map[] = {
   { LSTRKEY( "Client" ),      LFUNCVAL( mqtt_socket_client ) },
   { LSTRKEY( "__metatable" ), LROVAL( mqtt_map ) },
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_mqtt( lua_State *L )
+int luaopen_mqtt( lua_State *L )
 {
   luaL_rometatable(L, "mqtt.socket", (void *)mqtt_socket_map);  // create metatable for mqtt.socket
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(MQTT, "mqtt", mqtt_map, luaopen_mqtt);

+ 5 - 7
app/modules/net.c

@@ -1,8 +1,8 @@
 // Module for network
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_string.h"
 #include "c_stdlib.h"
@@ -1545,7 +1545,7 @@ static const LUA_REG_TYPE net_dns_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-const LUA_REG_TYPE net_map[] = {
+static const LUA_REG_TYPE net_map[] = {
   { LSTRKEY( "createServer" ),     LFUNCVAL( net_createServer ) },
   { LSTRKEY( "createConnection" ), LFUNCVAL( net_createConnection ) },
   { LSTRKEY( "multicastJoin"),     LFUNCVAL( net_multicastJoin ) },
@@ -1557,7 +1557,7 @@ const LUA_REG_TYPE net_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_net( lua_State *L ) {
+int luaopen_net( lua_State *L ) {
   int i;
   for(i=0;i<MAX_SOCKET;i++)
   {
@@ -1570,9 +1570,7 @@ LUALIB_API int luaopen_net( lua_State *L ) {
   luaL_rometatable(L, "net.array", (void *)net_array_map);    // create metatable for net.array
   #endif
 
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(NET, "net", net_map, luaopen_net);

+ 3 - 5
app/modules/node.c

@@ -1,5 +1,6 @@
 // Module for interfacing with system
 
+#include "module.h"
 #include "lauxlib.h"
 
 #include "ldebug.h"
@@ -547,7 +548,7 @@ static int node_stripdebug (lua_State *L) {
 #endif
 
 // Module function map
-const LUA_REG_TYPE node_map[] =
+static const LUA_REG_TYPE node_map[] =
 {
   { LSTRKEY( "restart" ), LFUNCVAL( node_restart ) },
   { LSTRKEY( "dsleep" ), LFUNCVAL( node_deepsleep ) },
@@ -579,7 +580,4 @@ const LUA_REG_TYPE node_map[] =
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_node( lua_State *L )
-{
-  return 0;
-}
+NODEMCU_MODULE(NODE, "node", node_map, NULL);

+ 3 - 9
app/modules/ow.c

@@ -1,7 +1,7 @@
 // Module for interfacing with the OneWire interface
 
+#include "module.h"
 #include "lauxlib.h"
-#include "lrodefs.h"
 #include "platform.h"
 #include "driver/onewire.h"
 
@@ -280,7 +280,7 @@ static int ow_crc16( lua_State *L )
 #endif
 
 // Module function map
-const LUA_REG_TYPE ow_map[] = {
+static const LUA_REG_TYPE ow_map[] = {
   { LSTRKEY( "setup" ),         LFUNCVAL( ow_setup ) },
   { LSTRKEY( "reset" ),         LFUNCVAL( ow_reset ) },
   { LSTRKEY( "skip" ),          LFUNCVAL( ow_skip ) },
@@ -305,10 +305,4 @@ const LUA_REG_TYPE ow_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_ow( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(OW, "ow", ow_map, NULL);

+ 3 - 10
app/modules/pwm.c

@@ -1,9 +1,8 @@
 // Module for interfacing with PWM
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
-
 #include "c_types.h"
 
 // Lua: realfrequency = setup( id, frequency, duty )
@@ -122,7 +121,7 @@ static int lpwm_getduty( lua_State* L )
 }
 
 // Module function map
-const LUA_REG_TYPE pwm_map[] = {
+static const LUA_REG_TYPE pwm_map[] = {
   { LSTRKEY( "setup" ),    LFUNCVAL( lpwm_setup ) },
   { LSTRKEY( "close" ),    LFUNCVAL( lpwm_close ) },
   { LSTRKEY( "start" ),    LFUNCVAL( lpwm_start ) },
@@ -134,10 +133,4 @@ const LUA_REG_TYPE pwm_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_pwm( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(PWM, "pwm", pwm_map, NULL);

+ 5 - 8
app/modules/rc.c

@@ -1,6 +1,6 @@
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 //#include "driver/easygpio.h"
 //static Ping_Data pingA;
 #define defPulseLen 185
@@ -80,17 +80,14 @@ static int ICACHE_FLASH_ATTR rc_send(lua_State* L) {
 }
 
 // Module function map
-const LUA_REG_TYPE rc_map[] = {
+static const LUA_REG_TYPE rc_map[] = {
   { LSTRKEY( "send" ), LFUNCVAL( rc_send )},
   { LNILKEY, LNILVAL}
 };
 
-//LUALIB_API int luaopen_ultra(lua_State *L) {
-LUALIB_API int luaopen_rc(lua_State *L) {
+int luaopen_rc(lua_State *L) {
   // TODO: Make sure that the GPIO system is initialized
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(RC, "rc", rc_map, luaopen_rc);

+ 3 - 10
app/modules/rtcfifo.c

@@ -1,7 +1,7 @@
 // Module for RTC sample FIFO storage
 
+#include "module.h"
 #include "lauxlib.h"
-#include "lrodefs.h"
 #include "user_modules.h"
 #include "rtc/rtctime.h"
 #define RTCTIME_SLEEP_ALIGNED rtctime_deep_sleep_until_aligned_us
@@ -165,7 +165,7 @@ static int rtcfifo_dsleep_until_sample (lua_State *L)
 #endif
 
 // Module function map
-const LUA_REG_TYPE rtcfifo_map[] = {
+static const LUA_REG_TYPE rtcfifo_map[] = {
   { LSTRKEY("prepare"),             LFUNCVAL(rtcfifo_prepare) },
   { LSTRKEY("ready"),               LFUNCVAL(rtcfifo_ready) },
   { LSTRKEY("put"),                 LFUNCVAL(rtcfifo_put) },
@@ -179,11 +179,4 @@ const LUA_REG_TYPE rtcfifo_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_rtcfifo (lua_State *L)
-{
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(RTCFIFO, "rtcfifo", rtcfifo_map, NULL);

+ 3 - 9
app/modules/rtcmem.c

@@ -1,7 +1,7 @@
 // Module for RTC user memory access
 
+#include "module.h"
 #include "lauxlib.h"
-#include "lrodefs.h"
 #include "rtc/rtcaccess.h"
 
 static int rtcmem_read32 (lua_State *L)
@@ -41,16 +41,10 @@ static int rtcmem_write32 (lua_State *L)
 
 
 // Module function map
-const LUA_REG_TYPE rtcmem_map[] = {
+static const LUA_REG_TYPE rtcmem_map[] = {
   { LSTRKEY("read32"),  LFUNCVAL(rtcmem_read32)  },
   { LSTRKEY("write32"), LFUNCVAL(rtcmem_write32) },
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_rtcmem (lua_State *L) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(RTCMEM, "rtcmem", rtcmem_map, NULL);

+ 3 - 9
app/modules/rtctime.c

@@ -1,7 +1,7 @@
 // Module for RTC time keeping
 
+#include "module.h"
 #include "lauxlib.h"
-#include "lrodefs.h"
 
 #include "rtc/rtctime_internal.h"
 #include "rtc/rtctime.h"
@@ -116,7 +116,7 @@ static int rtctime_dsleep_aligned (lua_State *L)
 
 
 // Module function map
-const LUA_REG_TYPE rtctime_map[] = {
+static const LUA_REG_TYPE rtctime_map[] = {
   { LSTRKEY("set"),            LFUNCVAL(rtctime_set) },
   { LSTRKEY("get"),            LFUNCVAL(rtctime_get) },
   { LSTRKEY("dsleep"),         LFUNCVAL(rtctime_dsleep)  },
@@ -124,10 +124,4 @@ const LUA_REG_TYPE rtctime_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_rtctime (lua_State *L) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(RTCTIME, "rtctime", rtctime_map, NULL);

+ 3 - 9
app/modules/sntp.c

@@ -33,8 +33,8 @@
 
 // Module for Simple Network Time Protocol (SNTP)
 
+#include "module.h"
 #include "lauxlib.h"
-#include "lrodefs.h"
 #include "os_type.h"
 #include "osapi.h"
 #include "lwip/udp.h"
@@ -376,15 +376,9 @@ error:
 
 
 // Module function map
-const LUA_REG_TYPE sntp_map[] = {
+static const LUA_REG_TYPE sntp_map[] = {
   { LSTRKEY("sync"),  LFUNCVAL(sntp_sync)  },
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_sntp (lua_State *L) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(SNTP, "sntp", sntp_map, NULL);

+ 3 - 9
app/modules/spi.c

@@ -1,8 +1,8 @@
 // Module for interfacing with the SPI interface
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #define SPI_HALFDUPLEX 0
 #define SPI_FULLDUPLEX 1
@@ -306,7 +306,7 @@ static int spi_transaction( lua_State *L )
 
 
 // Module function map
-const LUA_REG_TYPE spi_map[] = {
+static const LUA_REG_TYPE spi_map[] = {
   { LSTRKEY( "setup" ),       LFUNCVAL( spi_setup ) },
   { LSTRKEY( "send" ),        LFUNCVAL( spi_send_recv ) },
   { LSTRKEY( "recv" ),        LFUNCVAL( spi_recv ) },
@@ -325,10 +325,4 @@ const LUA_REG_TYPE spi_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_spi( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(SPI, "spi", spi_map, NULL);

+ 5 - 8
app/modules/tmr.c

@@ -48,9 +48,9 @@ tmr.softwd(int)
 	the timer units are seconds
 */
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "c_types.h"
 
 #define TIMER_MODE_OFF 3
@@ -306,7 +306,7 @@ static int tmr_softwd( lua_State* L ){
 
 // Module function map
 
-const LUA_REG_TYPE tmr_map[] = {
+static const LUA_REG_TYPE tmr_map[] = {
 	{ LSTRKEY( "delay" ),        LFUNCVAL( tmr_delay ) },
 	{ LSTRKEY( "now" ),          LFUNCVAL( tmr_now ) },
 	{ LSTRKEY( "wdclr" ),        LFUNCVAL( tmr_wdclr ) },
@@ -325,7 +325,7 @@ const LUA_REG_TYPE tmr_map[] = {
 	{ LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_tmr( lua_State *L ){
+int luaopen_tmr( lua_State *L ){
 	int i;	
 	for(i=0; i<NUM_TMR; i++){
 		alarm_timers[i].lua_ref = LUA_NOREF;
@@ -336,10 +336,7 @@ LUALIB_API int luaopen_tmr( lua_State *L ){
 	ets_timer_disarm(&rtc_timer);
 	ets_timer_setfn(&rtc_timer, rtc_callback, NULL);
 	ets_timer_arm_new(&rtc_timer, 1000, 1, 1);
-
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(TMR, "tmr", tmr_map, luaopen_tmr);

+ 3 - 9
app/modules/tsl2561.c

@@ -4,9 +4,9 @@
  *  Created on: Aug 21, 2015
  *  Author: Michael Lucas (Aeprox @github)
  */
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "../tsl2561/tsl2561.h"
 
 static uint16_t ch0;
@@ -101,7 +101,7 @@ static int ICACHE_FLASH_ATTR tsl2561_lua_getchannels(lua_State* L) {
 }
 
 // Module function map
-const LUA_REG_TYPE tsl2561_map[] = {
+static const LUA_REG_TYPE tsl2561_map[] = {
 	{	LSTRKEY( "settiming" ),             LFUNCVAL( tsl2561_lua_settiming)},
 	{	LSTRKEY( "getlux" ),                LFUNCVAL( tsl2561_lua_calclux )},
 	{	LSTRKEY( "getrawchannels" ),        LFUNCVAL( tsl2561_lua_getchannels )},
@@ -124,10 +124,4 @@ const LUA_REG_TYPE tsl2561_map[] = {
 	{	LNILKEY, LNILVAL}
 };
 
-LUALIB_API int luaopen_tsl2561(lua_State *L) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(TSL2561, "tsl2561", tsl2561_map, NULL);

+ 5 - 7
app/modules/u8g.c

@@ -1,8 +1,8 @@
 // Module for U8glib
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_stdlib.h"
 
@@ -1084,7 +1084,7 @@ static const LUA_REG_TYPE lu8g_display_map[] = {
 #undef U8G_DISPLAY_TABLE_ENTRY
 #undef U8G_FONT_TABLE_ENTRY
 
-const LUA_REG_TYPE lu8g_map[] = {
+static const LUA_REG_TYPE lu8g_map[] = {
 #define U8G_DISPLAY_TABLE_ENTRY(device) \
   { LSTRKEY( #device ),            LFUNCVAL ( lu8g_ ##device ) },
   U8G_DISPLAY_TABLE_I2C
@@ -1106,11 +1106,9 @@ const LUA_REG_TYPE lu8g_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_u8g( lua_State *L ) {
+int luaopen_u8g( lua_State *L ) {
   luaL_rometatable(L, "u8g.display", (void *)lu8g_display_map);  // create metatable
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
   return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
 }
+
+NODEMCU_MODULE(U8G, "u8g", lu8g_map, luaopen_u8g);

+ 3 - 9
app/modules/uart.c

@@ -1,8 +1,8 @@
 // Module for interfacing with serial
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_types.h"
 #include "c_string.h"
@@ -155,7 +155,7 @@ static int uart_write( lua_State* L )
 }
 
 // Module function map
-const LUA_REG_TYPE uart_map[] =  {
+static const LUA_REG_TYPE uart_map[] =  {
   { LSTRKEY( "setup" ),  LFUNCVAL( uart_setup ) },
   { LSTRKEY( "write" ),  LFUNCVAL( uart_write ) },
   { LSTRKEY( "on" ),     LFUNCVAL( uart_on ) },
@@ -163,10 +163,4 @@ const LUA_REG_TYPE uart_map[] =  {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_uart( lua_State *L ) {
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(UART, "uart", uart_map, NULL);

+ 5 - 3
app/modules/ucg.c

@@ -1,8 +1,8 @@
 // Module for Ucglib
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_stdlib.h"
 
@@ -925,7 +925,7 @@ static const LUA_REG_TYPE lucg_display_map[] =
     { LNILKEY, LNILVAL }
 };
 
-const LUA_REG_TYPE lucg_map[] = 
+static const LUA_REG_TYPE lucg_map[] = 
 {
 #undef UCG_DISPLAY_TABLE_ENTRY
 #define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension) { LSTRKEY( #binding ), LFUNCVAL ( lucg_ ##binding ) },
@@ -951,8 +951,10 @@ const LUA_REG_TYPE lucg_map[] =
     { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_ucg( lua_State *L )
+int luaopen_ucg( lua_State *L )
 {
     luaL_rometatable(L, "ucg.display", (void *)lucg_display_map);  // create metatable
     return 0;
 }
+
+NODEMCU_MODULE(UCG, "ucg", lucg_map, luaopen_ucg);

+ 3 - 10
app/modules/wifi.c

@@ -1,8 +1,8 @@
 // Module for interfacing with WIFI
 
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 
 #include "c_string.h"
 #include "c_stdlib.h"
@@ -1377,7 +1377,7 @@ static const LUA_REG_TYPE wifi_ap_map[] = {
   { LNILKEY, LNILVAL }
 };
 
-const LUA_REG_TYPE wifi_map[] =  {
+static const LUA_REG_TYPE wifi_map[] =  {
   { LSTRKEY( "setmode" ),        LFUNCVAL( wifi_setmode ) },
   { LSTRKEY( "getmode" ),        LFUNCVAL( wifi_getmode ) },
   { LSTRKEY( "getchannel" ),     LFUNCVAL( wifi_getchannel ) },
@@ -1421,11 +1421,4 @@ const LUA_REG_TYPE wifi_map[] =  {
   { LNILKEY, LNILVAL }
 };
 
-LUALIB_API int luaopen_wifi( lua_State *L )
-{
-#if MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2
-  return 0;
-#else
-#  error "NodeMCU modules must be build with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)" 
-#endif
-}
+NODEMCU_MODULE(WIFI, "wifi", wifi_map, NULL);

+ 3 - 6
app/modules/ws2801.c

@@ -1,6 +1,6 @@
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "c_stdlib.h"
 #include "c_string.h"
 
@@ -122,14 +122,11 @@ static int ICACHE_FLASH_ATTR ws2801_writergb(lua_State* L) {
     return 0;
 }
 
-const LUA_REG_TYPE ws2801_map[] =
+static const LUA_REG_TYPE ws2801_map[] =
 {
     { LSTRKEY( "write" ), LFUNCVAL( ws2801_writergb )},
     { LSTRKEY( "init" ), LFUNCVAL( ws2801_init_lua )},
     { LNILKEY, LNILVAL}
 };
 
-LUALIB_API int luaopen_ws2801(lua_State *L) {
-    return 0;
-}
-
+NODEMCU_MODULE(WS2801, "ws2801", ws2801_map, NULL);

+ 5 - 3
app/modules/ws2812.c

@@ -1,6 +1,6 @@
+#include "module.h"
 #include "lauxlib.h"
 #include "platform.h"
-#include "lrodefs.h"
 #include "c_stdlib.h"
 #include "c_string.h"
 #include "user_interface.h"
@@ -125,14 +125,16 @@ static int ICACHE_FLASH_ATTR ws2812_writegrb(lua_State* L) {
   return 0;
 }
 
-const LUA_REG_TYPE ws2812_map[] =
+static const LUA_REG_TYPE ws2812_map[] =
 {
   { LSTRKEY( "writergb" ), LFUNCVAL( ws2812_writergb )},
   { LSTRKEY( "write" ), LFUNCVAL( ws2812_writegrb )},
   { LNILKEY, LNILVAL}
 };
 
-LUALIB_API int luaopen_ws2812(lua_State *L) {
+int luaopen_ws2812(lua_State *L) {
   // TODO: Make sure that the GPIO system is initialized
   return 0;
 }
+
+NODEMCU_MODULE(WS2812, "ws2812", ws2812_map, luaopen_ws2812);

+ 10 - 0
ld/nodemcu.ld

@@ -79,6 +79,16 @@ SECTIONS
     *(.rodata*)
     *(.sdk.version)
 
+    /* Link-time arrays containing the defs for the included modules */
+    . = ALIGN(4);
+    lua_libs = ABSOLUTE(.);
+    /* Allow either empty define or defined-to-1 to include the module */
+    KEEP(*(.lua_libs .lua_libs1))
+    LONG(0) LONG(0) /* Null-terminate the array */
+    lua_rotable = ABSOLUTE(.);
+    KEEP(*(.lua_rotable .lua_rotable1))
+    LONG(0) LONG(0) /* Null-terminate the array */
+
     /* These are *only* pulled in by Lua, and therefore safe to put in flash */
     */libc.a:lib_a-isalnum.o(.text* .literal*)
     */libc.a:lib_a-isalpha.o(.text* .literal*)