module.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #ifndef __MODULE_H__
  2. #define __MODULE_H__
  3. #include "user_modules.h"
  4. #include "lrotable.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, luaopen_myname);
  20. *
  21. * or perhaps
  22. *
  23. * NODEMCU_MODULE(MYNAME, "myname", myname, 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. luaR_entry MODULE_PASTE_(lua_lib_,cfgname) = { luaname, LRO_FUNCVAL(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. = {luaname, LRO_ROVAL(map ## _map)}
  70. #endif