Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LFS support for ESP32 NodeMCU #2801

Merged
merged 32 commits into from
Jul 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0ed464a
Port LFS from ESP8266 to ESP32
jasaw May 21, 2019
2d560af
lfs: fix linking problem
jasaw May 21, 2019
81c7930
Add luac.cross to build
jasaw Jun 6, 2019
f271895
lfs: fix writing to esp32 flash
jasaw Jun 6, 2019
216780b
luac_cross: add -a option
jasaw Jun 6, 2019
5f4c802
luac_cross: fix makefile
jasaw Jun 6, 2019
c1cf68d
Remove old tools
jasaw Jun 6, 2019
27941d8
lfs: link in luac.out
jasaw Jun 11, 2019
43c7a65
lfs: add flashindex and flashreload functions
jasaw Jun 11, 2019
35172b4
lfs: convenient script to cross compile lua
jasaw Jun 11, 2019
404eac5
lfs embed: fix dependency
jasaw Jun 13, 2019
bac2e31
luac_cross: fix missing define causing LFS code execution error
jasaw Jun 14, 2019
3fd75e3
lfs luac.cross: fix cross compile struct size mismatch
jasaw Jun 18, 2019
83ac7e8
lfs examples
jasaw Jun 18, 2019
6ee61ac
lfs: automatically load _init from LFS after boot
jasaw Jun 19, 2019
1896e30
lfs: renamed _init to init for consistency
jasaw Jun 19, 2019
cd28d9f
lfs: disable writing to LFS secttion on the device
jasaw Jun 19, 2019
1c9015b
lfs: remove deprecated lrodefs.h
jasaw Jun 19, 2019
6fb8802
pulsecnt: use new rotable style registration
jasaw Jun 20, 2019
28f4fe2
Make LFS in partition work, plus tidy-ups.
jmattsson Jun 20, 2019
e074a64
Fixed overgrown 2MB partition table.
jmattsson Jun 20, 2019
603fb25
Bash, not dash...
jmattsson Jun 20, 2019
1657ca1
Throw packages at Travis until it builds...
jmattsson Jun 20, 2019
4c48d34
Merge remote-tracking branch 'upstream/dev-esp32' into lfs
jmattsson Jun 24, 2019
2dd203a
Fix alignment issue of our link-time arrays.
jmattsson Jun 24, 2019
7963060
Handle integer-only builds with align/size checks.
jmattsson Jun 24, 2019
ac644e7
...and tidy up linker fragments to match.
jmattsson Jun 24, 2019
642836e
Undo line break behaviour change.
jmattsson Jun 27, 2019
6b2f185
Fix broken system event callbacks.
jmattsson Jun 27, 2019
cb07a90
Merge remote-tracking branch 'upstream/dev-esp32' into lfs
jmattsson Jul 11, 2019
6e8dea3
Remove requirement of 32bit build luac.cross
jmattsson Jul 11, 2019
2337b80
Merge remote-tracking branch 'upstream/dev-esp32' into lfs
jmattsson Jul 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion components/base_nodemcu/Makefile.projbuild
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
BASE_NODEMCU_DIR:=$(dir $(lastword $(MAKEFILE_LIST)))
BASE_NODEMCU_BUILD_DIR:=$(BUILD_DIR_BASE)/base_nodemcu

ifeq ($(CONFIG_LUA_EMBED_LFS),y)
NODEMCU_LD_SCRIPT:= nodemcu_rodata_lfs.ld
else
NODEMCU_LD_SCRIPT:= nodemcu_rodata.ld
endif

$(BUILD_DIR_BASE)/$(PROJECT_NAME).elf: $(BASE_NODEMCU_BUILD_DIR)/ld_patched

$(BASE_NODEMCU_BUILD_DIR)/ld_patched: $(BUILD_DIR_BASE)/esp32/esp32.project.ld
"$(BASE_NODEMCU_DIR)/add_rodata_ld.sh" "$<" "$(BASE_NODEMCU_DIR)/ld/nodemcu_rodata.ld"
"$(BASE_NODEMCU_DIR)/add_rodata_ld.sh" "$<" "$(BASE_NODEMCU_DIR)/ld/$(NODEMCU_LD_SCRIPT)"
touch $@
26 changes: 0 additions & 26 deletions components/base_nodemcu/c_stdlib.c

This file was deleted.

6 changes: 0 additions & 6 deletions components/base_nodemcu/include/c_stdlib.h

This file was deleted.

48 changes: 24 additions & 24 deletions components/base_nodemcu/include/module.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef __MODULE_H__
#define __MODULE_H__

#include "lrodefs.h"
#include "sdkconfig.h"
#include "lrotable.h"

/* Registering a module within NodeMCU is really easy these days!
*
Expand Down Expand Up @@ -36,37 +36,37 @@
#define MODULE_PASTE_(x,y) x##y
#define MODULE_EXPAND_PASTE_(x,y) MODULE_PASTE_(x,y)

#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(s)))

#ifdef LUA_CROSS_COMPILER
#ifdef _MSC_VER
//on msvc it is necessary to go through more pre-processor hoops to get the
//section name built; string merging does not happen in the _declspecs.
//NOTE: linker magic is invoked via the magical '$' character. Caveat editor.
#define __TOKIFY(s) .rodata1$##s
#define __TOTOK(s) __TOKIFY(s)
#define __STRINGIFY(x) #x
#define __TOSTRING(x) __STRINGIFY(x)
#define __ROSECNAME(s) __TOSTRING(__TOTOK(s))
#define LOCK_IN_SECTION(s) __declspec ( allocate( __ROSECNAME(s) ) )
#else
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".rodata1." #s)))
#endif
#else
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
#endif
/* For the ROM table, we name the variable according to ( | denotes concat):
* cfgname | _module_selected | CONFIG_LUA_MODULE_##cfgname
* where the CONFIG_LUA_MODULE_XYZ macro is first expanded to yield either
* an empty string (or 1) if the module has been enabled, or the literal
* CONFIG_LUA_MODULE_XYZ in the case it hasn't. Thus, the name of the variable
* ends up looking either like XYZ_module_enabled, or if not enabled,
* XYZ_module_enabledLUA_USE_MODULES_XYZ. This forms the basis for
* XYZ_module_enabledCONFIG_LUA_MODULE_XYZ. This forms the basis for
* letting the build system detect automatically (via nm) which modules need
* to be linked in.
*/
#define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \
const LOCK_IN_SECTION(".lua_libs") \
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
const LOCK_IN_SECTION(".lua_rotable") \
luaR_table MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(CONFIG_LUA_MODULE_,cfgname))) \
= { luaname, map }


/* System module registration support, not using CONFIG_LUA_MODULE_XYZ. */
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
const LOCK_IN_SECTION(".lua_libs") \
luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }

#define BUILTIN_LIB(name, luaname, map) \
const LOCK_IN_SECTION(".lua_rotable") \
luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }

#if !defined(LUA_CROSS_COMPILER) && !(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

const LOCK_IN_SECTION(libs) \
luaR_entry MODULE_PASTE_(lua_lib_,cfgname) = { luaname, LRO_FUNCVAL(initfunc) }; \
const LOCK_IN_SECTION(rotable) \
luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(CONFIG_LUA_MODULE_,cfgname))) \
= {luaname, LRO_ROVAL(map ## _map)}
#endif
9 changes: 7 additions & 2 deletions components/base_nodemcu/include/nodemcu_esp_event.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
* Copyright 2016-2019 Dius Computing Pty Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -36,6 +36,8 @@

#include "esp_event.h"
#include "module.h"
#include <assert.h>
#include <stdalign.h>

/**
* Similarly to how a NodeMCU module is registered, a module can register
Expand Down Expand Up @@ -66,7 +68,10 @@ typedef struct {
extern nodemcu_esp_event_reg_t esp_event_cb_table;

#define NODEMCU_ESP_EVENT(evcode, func) \
static const LOCK_IN_SECTION(".esp_event_cb_table") \
static const LOCK_IN_SECTION(esp_event_cb_table) \
nodemcu_esp_event_reg_t MODULE_PASTE_(func,evcode) = { evcode, func };

_Static_assert(_Alignof(nodemcu_esp_event_reg_t) == 4, "Unexpected alignment of event registration - update linker script snippets to match!");
_Static_assert(sizeof(nodemcu_esp_event_reg_t) == 8, "Unexpected size of array member - update the linker script snippets to match!");

#endif
26 changes: 19 additions & 7 deletions components/base_nodemcu/ld/nodemcu_rodata.ld
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@

/* ----- Begin NodeMCU link-time arrays ------- */

. = ALIGN(4);
/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
/* Link-time arrays containing the defs for the included modules */
lua_libs = ABSOLUTE(.);
lua_libs_map = ABSOLUTE(.);
KEEP(*(.lua_libs))
LONG(0) LONG(0) /* Null-terminate the array */
lua_rotable = ABSOLUTE(.);
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)

/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
lua_rotables_map = ABSOLUTE(.);
KEEP(*(.lua_rotable))
LONG(0) LONG(0) /* Null-terminate the array */
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)

/* Don't change the alignment here without also updating the _Static_assert
* over in nodemcu_esp_event.h! */
. = ALIGN(4);
esp_event_cb_table = ABSOLUTE(.);
KEEP(*(.esp_event_cb_table))
LONG(0) LONG(0) /* Null-terminate the array */
KEEP(*(.lua_esp_event_cb_table))
LONG(0) LONG(0) /* Null-terminate the array, 8 bytes */

/* ----- End NodeMCU link-time arrays ------- */

37 changes: 37 additions & 0 deletions components/base_nodemcu/ld/nodemcu_rodata_lfs.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

/* ----- Begin NodeMCU link-time arrays ------- */

/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
/* Link-time arrays containing the defs for the included modules */
lua_libs_map = ABSOLUTE(.);
KEEP(*(.lua_libs))
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)

/* Don't change the alignment here without also updating the _Static_assert
* over in linit.c! */
. = ALIGN(8);
lua_rotables_map = ABSOLUTE(.);
KEEP(*(.lua_rotable))
/* Null-terminate the array, 24 bytes */
LONG(0) LONG(0) LONG(0) LONG(0) LONG(0) LONG(0)

/* Don't change the alignment here without also updating the _Static_assert
* over in nodemcu_esp_event.h! */
. = ALIGN(4);
esp_event_cb_table = ABSOLUTE(.);
KEEP(*(.lua_esp_event_cb_table))
LONG(0) LONG(0) /* Null-terminate the array, 8 bytes */

/* ----- End NodeMCU link-time arrays ------- */

/* ----- NodeMCU embedded LFS reserved area --------- */

. = ALIGN(4096); /* flash page alignment needed */
lua_flash_store_reserved = ABSOLUTE(.);
KEEP(*(.lfs.reserved))

/* ----- End NodeMCU embedded LFS reserved area ----- */

135 changes: 91 additions & 44 deletions components/base_nodemcu/linit.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,64 +15,111 @@
#include "lauxlib.h"
#include "luaconf.h"
#include "module.h"
#include "sdkconfig.h"
#include "lstate.h"
#include <assert.h>
#include <stdalign.h>

BUILTIN_LIB_INIT( BASE, "", luaopen_base);
BUILTIN_LIB_INIT( LOADLIB, LUA_LOADLIBNAME, luaopen_package);

#if defined(LUA_USE_BUILTIN_IO)
BUILTIN_LIB_INIT( IO, LUA_IOLIBNAME, luaopen_io);
#endif

#if defined (CONFIG_LUA_BUILTIN_STRING)
extern const luaR_entry strlib[];
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);
BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
LROT_EXTERN(strlib);
LROT_EXTERN(tab_funcs);
LROT_EXTERN(dblib);
LROT_EXTERN(co_funcs);
LROT_EXTERN(math);
#if defined(LUA_CROSS_COMPILER)
LROT_EXTERN(oslib);
//LROT_EXTERN(iolib);
#endif
/*
* The NodeMCU Lua initalisation has been adapted to use linker-based module
* registration. This uses a PSECT naming convention to allow the ROTable and
* initialisation function entries to be collected by the linker into two
* consoliated ROTables. This significantly simplifies adding new modules and
* configuring builds with a small subset of the total modules.
*
* This linker-based approach is not practical for cross compiler builds which
* must link on a range of platforms, and where we don't have control of PSECT
* placement. However unlike the target builds, the luac.cross builds only
* used a small and fixed list of libraries and so in this case the table can
* be defined in this source file, so in this case all library ROTables are
* defined here, avoiding the need for linker magic is avoided on host builds.
*
* Note that a separate ROTable is defined in lbaselib.c for the base functions
* and there is a metatable index cascade from _G to this base function table to
* the master rotables table. In the target build, the linker marshals the
* table, hence the LROT_BREAK() macros which don't 0 terminate the lists.
*/

#if defined(CONFIG_LUA_BUILTIN_TABLE)
extern const luaR_entry tab_funcs[];
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
#ifdef _MSC_VER
//MSVC requires us to declare these sections before we refer to them
#pragma section(__ROSECNAME(A), read)
#pragma section(__ROSECNAME(zzzzzzzz), read)
#pragma section(__ROSECNAME(libs), read)
#pragma section(__ROSECNAME(rotable), read)
//These help us to find the beginning and ending of the RO data. NOTE: linker
//magic is used; the section names are lexically sorted, so 'a' and 'z' are
//important to keep the other sections lexically between these two dummy
//variables. Check your mapfile output if you need to fiddle with this stuff.
const LOCK_IN_SECTION(A) char _ro_start[1] = {0};
const LOCK_IN_SECTION(zzzzzzzz) char _ro_end[1] = {0};
#endif

#if defined(CONFIG_LUA_BUILTIN_DEBUG)
extern const luaR_entry dblib[];
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(rotable) lua_rotables)
LROT_TABENTRY( string, strlib )
LROT_TABENTRY( table, tab_funcs )
LROT_TABENTRY( debug, dblib)
LROT_TABENTRY( coroutine, co_funcs )
LROT_TABENTRY( math, math )
LROT_TABENTRY( ROM, lua_rotables )
#ifdef LUA_CROSS_COMPILER
LROT_TABENTRY( os, oslib )
//LROT_TABENTRY( io, iolib )
LROT_END(lua_rotables, NULL, 0)
#else
LROT_BREAK(lua_rotables)
#endif

#if defined(LUA_USE_BUILTIN_OS)
extern const luaR_entry syslib[];
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(libs) lua_libs)
LROT_FUNCENTRY( _, luaopen_base )
LROT_FUNCENTRY( package, luaopen_package )
LROT_FUNCENTRY( string, luaopen_string )
LROT_FUNCENTRY( table, luaopen_table )
LROT_FUNCENTRY( debug, luaopen_debug )
#ifndef LUA_CROSS_COMPILER
LROT_BREAK(lua_rotables)
#else
LROT_FUNCENTRY( io, luaopen_io )
LROT_END( lua_libs, NULL, 0)
#endif

#if defined(CONFIG_LUA_BUILTIN_COROUTINE)
extern const luaR_entry co_funcs[];
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);
#ifndef LUA_CROSS_COMPILER
extern void luaL_dbgbreak(void);
#endif

#if defined(CONFIG_LUA_BUILTIN_MATH)
extern const luaR_entry math_map[];
BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);
#endif
void luaL_openlibs (lua_State *L) {

#ifdef LUA_CROSS_COMPILER
const luaL_Reg lua_libs[] = {{NULL, NULL}};
const luaR_table lua_rotable[] = {{NULL, NULL}};
#else
extern const luaL_Reg lua_libs[];
lua_pushrotable(L, LROT_TABLEREF(lua_libs));
lua_pushnil(L); /* first key */
/* loop round and open libraries */
#ifndef LUA_CROSS_COMPILER
// luaL_dbgbreak(); // This is a test point for debugging library start ups
#endif

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);
while (lua_next(L, -2) != 0) {
if (lua_islightfunction(L,-1) &&
fvalue(L->top-1)) { // only process function entries
lua_pushvalue(L, -2);
lua_call(L, 1, 0); // call luaopen_XXX(libname)
} else {
lua_pop(L, 1);
}
}
lua_pop(L, 1); //cleanup stack
}

#ifndef LUA_CROSS_COMPILER
# ifdef LUA_NUMBER_INTEGRAL
# define COMPARE <=
# else
# define COMPARE ==
# endif
_Static_assert(_Alignof(luaR_entry) COMPARE 8, "Unexpected alignment of module registration - update the linker script snippets to match!");
_Static_assert(sizeof(luaR_entry) COMPARE 24, "Unexpect size of array member - update the linker script snippets to match!");
#endif
Loading