module.h 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #ifndef __MODULE_H__
  2. #define __MODULE_H__
  3. #include "user_modules.h"
  4. #include "lrodefs.h"
  5. /* Registering a module within NodeMCU is really easy these days!
  6. *
  7. * Most of the work is done by a combination of pre-processor, compiler
  8. * and linker "magic". Gone are the days of needing to update 4+ separate
  9. * files just to register a module!
  10. *
  11. * You will need:
  12. * - to include this header
  13. * - a name for the module
  14. * - a LUA_REG_TYPE module map
  15. * - optionally, an init function
  16. *
  17. * Then simply put a line like this at the bottom of your module file:
  18. *
  19. * NODEMCU_MODULE(MYNAME, "myname", myname_map, luaopen_myname);
  20. *
  21. * or perhaps
  22. *
  23. * NODEMCU_MODULE(MYNAME, "myname", myname_map, NULL);
  24. *
  25. * if you don't need an init function.
  26. *
  27. * When you've done this, the module can be enabled in user_modules.h with:
  28. *
  29. * #define LUA_USE_MODULES_MYNAME
  30. *
  31. * and within NodeMCU you access it with myname.foo(), assuming you have
  32. * a foo function in your module.
  33. */
  34. #define MODULE_EXPAND_(x) x
  35. #define MODULE_PASTE_(x,y) x##y
  36. #define MODULE_EXPAND_PASTE_(x,y) MODULE_PASTE_(x,y)
  37. #ifdef LUA_CROSS_COMPILER
  38. #ifdef _MSC_VER
  39. //on msvc it is necessary to go through more pre-processor hoops to get the
  40. //section name built; string merging does not happen in the _declspecs.
  41. //NOTE: linker magic is invoked via the magical '$' character. Caveat editor.
  42. #define __TOKIFY(s) .rodata1$##s
  43. #define __TOTOK(s) __TOKIFY(s)
  44. #define __STRINGIFY(x) #x
  45. #define __TOSTRING(x) __STRINGIFY(x)
  46. #define __ROSECNAME(s) __TOSTRING(__TOTOK(s))
  47. #define LOCK_IN_SECTION(s) __declspec ( allocate( __ROSECNAME(s) ) )
  48. #else
  49. #define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".rodata1." #s)))
  50. #endif
  51. #else
  52. #define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
  53. #endif
  54. /* For the ROM table, we name the variable according to ( | denotes concat):
  55. * cfgname | _module_selected | LUA_USE_MODULES_##cfgname
  56. * where the LUA_USE_MODULES_XYZ macro is first expanded to yield either
  57. * an empty string (or 1) if the module has been enabled, or the literal
  58. * LUA_USE_MOUDLE_XYZ in the case it hasn't. Thus, the name of the variable
  59. * ends up looking either like XYZ_module_enabled, or if not enabled,
  60. * XYZ_module_enabledLUA_USE_MODULES_XYZ. This forms the basis for
  61. * letting the build system detect automatically (via nm) which modules need
  62. * to be linked in.
  63. */
  64. #define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \
  65. const LOCK_IN_SECTION(libs) \
  66. luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
  67. const LOCK_IN_SECTION(rotable) \
  68. luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
  69. = {LSTRKEY(luaname), LROVAL(map)}
  70. #if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
  71. # error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
  72. #endif
  73. #endif