Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
11592951
Unverified
Commit
11592951
authored
Dec 07, 2018
by
Arnim Läuger
Committed by
GitHub
Dec 07, 2018
Browse files
Merge pull request #2582 from nodemcu/dev
Next master drop
parents
4095c408
61433c44
Changes
125
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
11592951
.gdb_history
sdk/
cache/
.ccache/
local/
luac.cross
user_config.h
server-ca.crt
luac.cross
uz_unzip
uz_zip
tools/toolchains/
#ignore Eclipse project files
.cproject
...
...
.gitmodules
View file @
11592951
[submodule "app/u8g2lib/u8g2"]
path = app/u8g2lib/u8g2
url = https://github.com/olikraus/U8g2_Arduino.git
[submodule "app/ucglib/ucg"]
path = app/ucglib/ucg
url = https://github.com/olikraus/Ucglib_Arduino.git
.travis.yml
View file @
11592951
sudo
:
false
language
:
cpp
addons
:
apt
:
...
...
@@ -8,9 +7,6 @@ addons:
cache
:
-
directories
:
-
cache
install
:
-
tar -Jxvf tools/esp-open-sdk.tar.xz
-
export PATH=$PATH:$PWD/esp-open-sdk/xtensa-lx106-elf/bin
script
:
-
export BUILD_DATE=$(date +%Y%m%d)
-
make EXTRA_CCFLAGS="-DBUILD_DATE='\"'$BUILD_DATE'\"'" all
...
...
Makefile
View file @
11592951
...
...
@@ -2,6 +2,8 @@
#
.NOTPARALLEL
:
TOOLCHAIN_VERSION
:=
20181106.0
# SDK base version, as released by Espressif
SDK_BASE_VER
:=
2.2.1
...
...
@@ -47,7 +49,7 @@ ifeq ($(OS),Windows_NT)
OBJCOPY
=
xt-objcopy
#MAKE = xt-make
CCFLAGS
+=
--rename-section
.text
=
.irom0.text
--rename-section
.literal
=
.irom0.literal
else
else
# It is gcc, may be cygwin
# Can we use -fdata-sections?
CCFLAGS
+=
-ffunction-sections
-fno-jump-tables
-fdata-sections
...
...
@@ -73,11 +75,13 @@ ifeq ($(OS),Windows_NT)
else
# We are under other system, may be Linux. Assume using gcc.
# Can we use -fdata-sections?
PLATFORM
:=
linux-x86_64
ifndef
COMPORT
ESPPORT
=
/dev/ttyUSB0
else
ESPPORT
=
$(COMPORT)
endif
export
PATH
:=
$(PATH)
:
$(TOP_DIR)
/tools/toolchains/esp8266-
$(PLATFORM)
-
$(TOOLCHAIN_VERSION)
/bin/
CCFLAGS
+=
-ffunction-sections
-fno-jump-tables
-fdata-sections
AR
=
xtensa-lx106-elf-ar
CC
=
$(WRAPCC)
xtensa-lx106-elf-gcc
...
...
@@ -145,9 +149,9 @@ endif
endif
#
# Note:
# Note:
# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
# If you add global optimize options like "-O2" here
# If you add global optimize options like "-O2" here
# they will override "-Os" defined above.
# "-Os" should be used to reduce code size
#
...
...
@@ -161,7 +165,7 @@ CCFLAGS += \
-nostdlib
\
-mlongcalls
\
-mtext-section-literals
# -Wall
# -Wall
CFLAGS
=
$(CCFLAGS)
$(DEFINES)
$(EXTRA_CCFLAGS)
$(STD_CFLAGS)
$(INCLUDES)
DFLAGS
=
$(CCFLAGS)
$(DDEFINES)
$(EXTRA_CCFLAGS)
$(STD_CFLAGS)
$(INCLUDES)
...
...
@@ -191,7 +195,7 @@ DEP_LIBS_$(1) = $$(foreach lib,$$(filter %.a,$$(COMPONENTS_$(1))),$$(dir $$(lib)
DEP_OBJS_$(1)
=
$
$(
foreach
obj,
$
$(
filter
%.o,
$$
(
COMPONENTS_
$(1)
))
,
$
$(
dir
$
$(obj)
)
$
$(OBJODIR)
/
$
$(
notdir
$
$(obj)
))
$$(IMAGEODIR)/$(1).out
:
$$(OBJS) $$(DEP_OBJS_$(1)) $$(DEP_LIBS_$(1)) $$(DEPENDS_$(1))
@
mkdir
-p
$
$(IMAGEODIR)
$
$(CC)
$
$(LDFLAGS)
$
$(
if
$$
(
LINKFLAGS_
$(1)
)
,
$$
(
LINKFLAGS_
$(1)
)
,
$
$(LINKFLAGS_DEFAULT)
$
$(OBJS)
$$
(
DEP_OBJS_
$(1)
)
$$
(
DEP_LIBS_
$(1)
))
-o
$$
@
$
$(CC)
$
$(LDFLAGS)
$
$(
if
$$
(
LINKFLAGS_
$(1)
)
,
$$
(
LINKFLAGS_
$(1)
)
,
$
$(LINKFLAGS_DEFAULT)
$
$(OBJS)
$$
(
DEP_OBJS_
$(1)
)
$$
(
DEP_LIBS_
$(1)
))
-o
$$
@
endef
$(BINODIR)/%.bin
:
$(IMAGEODIR)/%.out
...
...
@@ -204,16 +208,32 @@ $(BINODIR)/%.bin: $(IMAGEODIR)/%.out
# Should be done in top-level makefile only
#
all
:
sdk_pruned pre_build .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
all
:
toolchain
sdk_pruned pre_build .subdirs $(OBJS) $(OLIBS) $(OIMAGES) $(OBINS) $(SPECIAL_MKTARGETS)
.PHONY
:
sdk_extracted
.PHONY
:
sdk_patched
.PHONY
:
sdk_pruned
.PHONY
:
toolchain
sdk_extracted
:
$(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER)
sdk_patched
:
sdk_extracted $(TOP_DIR)/sdk/.patched-$(SDK_VER)
sdk_pruned
:
$(SDK_DIR_DEPENDS) $(TOP_DIR)/sdk/.pruned-$(SDK_VER)
ifeq
($(OS),Windows_NT)
toolchain
:
else
toolchain
:
$(TOP_DIR)/tools/toolchains/esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION)/bin/xtensa-lx106-elf-gcc
$(TOP_DIR)/tools/toolchains/esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION)/bin/xtensa-lx106-elf-gcc
:
$(TOP_DIR)/cache/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz
mkdir
-p
$(TOP_DIR)
/tools/toolchains/
tar
-xJf
$<
-C
$(TOP_DIR)
/tools/toolchains/
touch
$@
$(TOP_DIR)/cache/toolchain-esp8266-$(PLATFORM)-$(TOOLCHAIN_VERSION).tar.xz
:
mkdir
-p
$(TOP_DIR)
/cache
wget
--tries
=
10
--timeout
=
15
--waitretry
=
30
--read-timeout
=
20
--retry-connrefused
https://github.com/jmattsson/esp-toolchains/releases/download/
$(PLATFORM)
-
$(TOOLCHAIN_VERSION)
/toolchain-esp8266-
$(PLATFORM)
-
$(TOOLCHAIN_VERSION)
.tar.xz
-O
$@
||
{
rm
-f
"
$@
"
;
exit
1
;
}
endif
$(TOP_DIR)/sdk/.extracted-$(SDK_BASE_VER)
:
$(TOP_DIR)/cache/v$(SDK_FILE_VER).zip
mkdir
-p
"
$(
dir
$@
)
"
(
cd
"
$(
dir
$@
)
"
&&
rm
-fr
esp_iot_sdk_v
$(SDK_VER)
ESP8266_NONOS_SDK-
$(SDK_BASE_VER)
&&
unzip
$(TOP_DIR)
/cache/v
$(SDK_FILE_VER)
.zip ESP8266_NONOS_SDK-
$(SDK_BASE_VER)
/lib/
*
ESP8266_NONOS_SDK-
$(SDK_BASE_VER)
/ld/eagle.rom.addr.v6.ld ESP8266_NONOS_SDK-
$(SDK_BASE_VER)
/include/
*
ESP8266_NONOS_SDK-
$(SDK_BASE_VER)
/bin/esp_init_data_default_v05.bin
)
...
...
app/Makefile
View file @
11592951
...
...
@@ -20,7 +20,7 @@ FLAVOR = debug
ifndef
PDIR
# {
GEN_IMAGES
=
eagle.app.v6.out
GEN_BINS
=
eagle.app.v6.bin
OPT_MKTARGETS
:=
coap
crypto
dht http mqtt pcm sjson sqlite3 tsl2561 websocket
OPT_MKTARGETS
:=
coap dht http mqtt pcm sjson sqlite3 tsl2561 websocket
OPT_MKLIBTARGETS
:=
u8g2 ucg
SEL_MKTARGETS
:=
$(
shell
$(CC)
-E
-dM
include/user_modules.h |
sed
-n
'/^\#define LUA_USE_MODULES_/{s/.\{24\}\(.*\)/\L\1/; p
}
'
)
OPT_SEL_MKLIBTARGETS
:=
$(
foreach
tgt,
$(OPT_MKLIBTARGETS)
,
$(
findstring
$(tgt)
,
$(SEL_MKTARGETS)
))
...
...
@@ -31,6 +31,7 @@ SPECIAL_MKTARGETS :=$(APP_MKTARGETS)
SUBDIRS
=
\
user
\
crypto
\
driver
\
mbedtls
\
platform
\
...
...
@@ -45,6 +46,7 @@ SUBDIRS= \
fatfs
\
esp-gdbstub
\
pm
\
uzlib
\
$(OPT_SEL_MKTARGETS)
endif
# } PDIR
...
...
@@ -62,6 +64,7 @@ LD_FILE = $(LDDIR)/nodemcu.ld
COMPONENTS_eagle.app.v6
=
\
user/libuser.a
\
crypto/libcrypto.a
\
driver/libdriver.a
\
platform/libplatform.a
\
task/libtask.a
\
...
...
@@ -76,6 +79,8 @@ COMPONENTS_eagle.app.v6 = \
net/libnodemcu_net.a
\
mbedtls/libmbedtls.a
\
modules/libmodules.a
\
smart/smart.a
\
uzlib/libuzlib.a
\
$(OPT_SEL_COMPONENTS)
...
...
app/http/httpclient.c
View file @
11592951
...
...
@@ -210,7 +210,7 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg )
char
ua_header
[
32
]
=
""
;
int
ua_len
=
0
;
if
(
os_strstr
(
req
->
headers
,
"User-Agent:"
)
==
NULL
&&
os_str
str
(
req
->
headers
,
"
u
ser-
a
gent:"
)
==
NULL
)
if
(
strcase
str
(
req
->
headers
,
"
U
ser-
A
gent:"
)
==
NULL
)
{
os_sprintf
(
ua_header
,
"User-Agent: %s
\r\n
"
,
"ESP8266"
);
ua_len
=
strlen
(
ua_header
);
...
...
@@ -218,7 +218,7 @@ static void ICACHE_FLASH_ATTR http_connect_callback( void * arg )
char
*
host_header
=
""
;
int
host_len
=
0
;
if
(
os_strstr
(
req
->
headers
,
"Host:"
)
==
NULL
&&
os_str
str
(
req
->
headers
,
"
h
ost:"
)
==
NULL
)
if
(
strcase
str
(
req
->
headers
,
"
H
ost:"
)
==
NULL
)
{
int
max_header_len
=
9
+
strlen
(
req
->
hostname
);
// 9 is fixed size of "Host:[space][cr][lf]\0"
if
((
req
->
port
==
80
)
...
...
@@ -328,10 +328,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg )
{
http_status
=
atoi
(
req
->
buffer
+
strlen
(
version_1_0
)
);
char
*
locationOffset
=
(
char
*
)
os_strstr
(
req
->
buffer
,
"Location:"
);
if
(
locationOffset
==
NULL
)
{
locationOffset
=
(
char
*
)
os_strstr
(
req
->
buffer
,
"location:"
);
}
char
*
locationOffset
=
(
char
*
)
strcasestr
(
req
->
buffer
,
"Location:"
);
if
(
locationOffset
!=
NULL
&&
http_status
>=
300
&&
http_status
<=
308
)
{
if
(
req
->
redirect_follow_count
<
REDIRECTION_FOLLOW_MAX
)
{
...
...
@@ -414,7 +411,7 @@ static void ICACHE_FLASH_ATTR http_disconnect_callback( void * arg )
body
=
body
+
4
;
}
if
(
os_strstr
(
req
->
buffer
,
"Transfer-Encoding: chunked"
)
||
os_str
str
(
req
->
buffer
,
"
t
ransfer-
e
ncoding: chunked"
)
)
if
(
strcase
str
(
req
->
buffer
,
"
T
ransfer-
E
ncoding: chunked"
)
)
{
int
body_size
=
req
->
buffer_size
-
(
body
-
req
->
buffer
);
char
chunked_decode_buffer
[
body_size
];
...
...
app/include/module.h
View file @
11592951
...
...
@@ -57,18 +57,8 @@
const LOCK_IN_SECTION(libs) \
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
const LOCK_IN_SECTION(rotable) \
luaR_table MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= { luaname, map }
/* System module registration support, not using LUA_USE_MODULES_XYZ. */
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
const LOCK_IN_SECTION(libs) \
luaL_Reg MODULE_PASTE_(lua_lib_,name) = { luaname, initfunc }
#define BUILTIN_LIB(name, luaname, map) \
const LOCK_IN_SECTION(rotable) \
luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= {LSTRKEY(luaname), LROVAL(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)"
...
...
app/include/u8g2_displays.h
View file @
11592951
...
...
@@ -31,11 +31,26 @@
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_i2c_128x64_vcomh0_f, sh1106_i2c_128x64_vcomh0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_96x16_er_f, ssd1306_i2c_96x16_er) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_i2c_128x64_noname_f, sh1106_i2c_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_i2c_64x128_f, sh1107_i2c_64x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_i2c_seeed_96x96_f, sh1107_i2c_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_i2c_128x128_f, sh1107_i2c_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1108_i2c_160x160_f, sh1108_i2c_160x160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1122_i2c_256x64_f, sh1122_i2c_256x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_vcomh0_f, ssd1306_i2c_128x64_vcomh0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_noname_f, ssd1306_i2c_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1309_i2c_128x64_noname2_f, ssd1309_i2c_128x64_noname2) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_alt0_f, ssd1306_i2c_128x64_alt0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_i2c_ea_dogm240_f, uc1611_i2c_ea_dogm240) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1326_i2c_er_256x32_f, ssd1326_i2c_er_256x32 )\
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_i2c_seeed_96x96_f, ssd1327_i2c_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_i2c_ea_w128128_f, ssd1327_i2c_ea_w128128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_i2c_midas_128x128_f, ssd1327_i2c_midas_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_i2c_64x32_f, st7567_i2c_64x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx256128_f, st75256_i2c_jlx256128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx256160_f, st75256_i2c_jlx256160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx240160_f, st75256_i2c_jlx240160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx25664_f, st75256_i2c_jlx25664) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_i2c_jlx172104_f, st75256_i2c_jlx172104) \
#define U8G2_DISPLAY_TABLE_I2C \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_i2c_128x64_noname_f, ssd1306_i2c_128x64_noname) \
...
...
@@ -72,18 +87,25 @@
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7920_s_192x32_f, st7920_s_192x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1325_nhd_128x64_f, ssd1325_nhd_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_noname_f, ssd1306_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_alt0_f, ssd1306_128x64_alt0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sed1520_122x32_f, sed1520_122x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_ea_dogm128_f, st7565_ea_dogm128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ld7032_60x32_f, ld7032_60x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1607_200x200_f, ssd1607_200x200) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1309_128x64_noname2_f, ssd1309_128x64_noname2) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_128x64_noname_f, sh1106_128x64_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_64x128_f, sh1107_64x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_seeed_96x96_f, sh1107_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1107_128x128_f, sh1107_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1108_160x160_f, sh1108_160x160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1122_256x64_f, sh1122_256x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x32_univision_f, ssd1306_128x32_univision) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7920_s_128x64_f, st7920_s_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_64128n_f, st7565_64128n) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1701_ea_dogs102_f, uc1701_ea_dogs102) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1611_ew50850_f, uc1611_ew50850) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1322_nhd_256x64_f, ssd1322_nhd_256x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1322_nhd_128x64_f, ssd1322_nhd_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_ea_dogm132_f, st7565_ea_dogm132) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1329_128x96_noname_f, ssd1329_128x96_noname) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_zolen_128x64_f, st7565_zolen_128x64) \
...
...
@@ -91,17 +113,37 @@
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_96x16_er_f, ssd1306_96x16_er) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ist3020_erc19264_f, ist3020_erc19264) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7588_jlx12864_f, st7588_jlx12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1326_er_256x32_f, ssd1326_er_256x32 )\
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_seeed_96x96_f, ssd1327_seeed_96x96) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_ea_w128128_f, ssd1327_ea_w128128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1327_midas_128x128_f, ssd1327_midas_128x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx172104_f, st75256_jlx172104) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7565_nhd_c12832_f, st7565_nhd_c12832) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx256160_f, st75256_jlx256160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx240160_f, st75256_jlx240160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st75256_jlx25664_f, st75256_jlx25664) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_64x48_er_f, ssd1306_64x48_er) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_pcf8812_96x65_f, pcf8812_96x65) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_pi_132x64_f, st7567_pi_132x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_jlx12864_f, st7567_jlx12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_enh_dg128064i_f, st7567_enh_dg128064i) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7567_64x32_f, st7567_64x32) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7586s_s028hn118a_f, st7586s_s028hn118a) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_st7586s_erc240160_f, st7586s_erc240160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_pcd8544_84x48_f, pcd8544_84x48) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_sh1106_128x64_vcomh0_f, sh1106_128x64_vcomh0) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_nt7534_tg12864r_f, nt7534_tg12864r) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_uc1701_mini12864_f, uc1701_mini12864) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_240x128_f, t6963_240x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_240x64_f, t6963_240x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_256x64_f, t6963_256x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_128x64_f, t6963_128x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_t6963_160x80_f, t6963_160x80) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_160x80_f, lc7981_160x80) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_160x160_f, lc7981_160x160) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_240x128_f, lc7981_240x128) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_lc7981_240x64_f, lc7981_240x64) \
// U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_hx1230_96x68_f, hx1230_96x68) \
#define U8G2_DISPLAY_TABLE_SPI \
U8G2_DISPLAY_TABLE_ENTRY(u8g2_Setup_ssd1306_128x64_noname_f, ssd1306_128x64_noname) \
...
...
app/include/ucg_config.h
View file @
11592951
...
...
@@ -27,8 +27,10 @@
// Uncomment the UCG_DISPLAY_TABLE_ENTRY for the device(s) you want to
// compile into the firmware.
//
// UCG_DISPLAY_TABLE_ENTRY(hx8352c_18x240x400_hw_spi, ucg_dev_hx8352c_18x240x400, ucg_ext_hx8352c_18) \
// UCG_DISPLAY_TABLE_ENTRY(ili9163_18x128x128_hw_spi, ucg_dev_ili9163_18x128x128, ucg_ext_ili9163_18) \
// UCG_DISPLAY_TABLE_ENTRY(ili9341_18x240x320_hw_spi, ucg_dev_ili9341_18x240x320, ucg_ext_ili9341_18) \
// UCG_DISPLAY_TABLE_ENTRY(ili9486_18x320x480_hw_spi, ucg_dev_ili9486_18x320x480, ucg_ext_ili9486_18) \
// UCG_DISPLAY_TABLE_ENTRY(pcf8833_16x132x132_hw_spi, ucg_dev_pcf8833_16x132x132, ucg_ext_pcf8833_16) \
// UCG_DISPLAY_TABLE_ENTRY(seps225_16x128x128_uvis_hw_spi, ucg_dev_seps225_16x128x128_univision, ucg_ext_seps225_16) \
// UCG_DISPLAY_TABLE_ENTRY(ssd1351_18x128x128_hw_spi, ucg_dev_ssd1351_18x128x128_ilsoft, ucg_ext_ssd1351_18) \
...
...
app/include/user_config.h
View file @
11592951
...
...
@@ -110,7 +110,7 @@
// firmware to manage timer rescheduling over sleeps (the CPU clock is
// suspended so timers get out of sync) then enable the following options
//#define
ENABLE_
TIMER_SUSPEND
//#define TIMER_SUSPEND
_ENABLE
//#define PMSLEEP_ENABLE
...
...
app/lua/Makefile
View file @
11592951
...
...
@@ -46,6 +46,7 @@ INCLUDES += -I ../spiffs
INCLUDES
+=
-I
../libc
INCLUDES
+=
-I
../modules
INCLUDES
+=
-I
../platform
INCLUDES
+=
-I
../uzlib
PDIR
:=
../
$(PDIR)
sinclude
$(PDIR)Makefile
app/lua/lauxlib.c
View file @
11592951
...
...
@@ -25,8 +25,6 @@
#define lauxlib_c
#define LUA_LIB
#include "lrotable.h"
#include "lauxlib.h"
#include "lgc.h"
#include "ldo.h"
...
...
@@ -555,14 +553,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
if
(
e
==
NULL
)
e
=
fname
+
c_strlen
(
fname
);
lua_pushlstring
(
L
,
fname
,
e
-
fname
);
lua_rawget
(
L
,
-
2
);
if
(
lua_isnil
(
L
,
-
1
))
{
/* If looking for a global variable, check the rotables too */
void
*
ptable
=
luaR_findglobal
(
fname
,
e
-
fname
);
if
(
ptable
)
{
lua_pop
(
L
,
1
);
lua_pushrotable
(
L
,
ptable
);
}
}
if
(
lua_isnil
(
L
,
-
1
))
{
/* no such field? */
lua_pop
(
L
,
1
);
/* remove this nil */
lua_createtable
(
L
,
0
,
(
*
e
==
'.'
?
1
:
szhint
));
/* new table for field */
...
...
@@ -967,12 +958,12 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
#endif
}
#ifdef
DEVELOPMENT_USE_GDB
#if
def
ined(
DEVELOPMENT_USE_GDB
) && !defined(LUA_CROSS_COMPILER)
/*
* This is a simple stub used by lua_assert() if DEVELOPMENT_USE_GDB is defined.
* Instead of crashing out with an assert error, this hook starts the GDB remote
* stub if not already running and then issues a break. The rationale here is
* that when testing the developer mig
g
ht be using screen/PuTTY to work ineractively
* that when testing the developer might be using screen/PuTTY to work in
t
eractively
* with the Lua Interpreter via UART0. However if an assert triggers, then there
* is the option to exit the interactive session and start the Xtensa remote GDB
* which will then sync up with the remote GDB client to allow forensics of the error.
...
...
app/lua/lbaselib.c
View file @
11592951
...
...
@@ -16,7 +16,7 @@
#include C_HEADER_STDLIB
#include "lauxlib.h"
#include "lualib.h"
#include "lro
table
.h"
#include "lro
defs
.h"
...
...
@@ -462,71 +462,62 @@ static int luaB_newproxy (lua_State *L) {
return
1
;
}
#define LUA_BASELIB_FUNCLIST\
{LSTRKEY("assert"), LFUNCVAL(luaB_assert)},\
{LSTRKEY("collectgarbage"), LFUNCVAL(luaB_collectgarbage)},\
{LSTRKEY("dofile"), LFUNCVAL(luaB_dofile)},\
{LSTRKEY("error"), LFUNCVAL(luaB_error)},\
{LSTRKEY("gcinfo"), LFUNCVAL(luaB_gcinfo)},\
{LSTRKEY("getfenv"), LFUNCVAL(luaB_getfenv)},\
{LSTRKEY("getmetatable"), LFUNCVAL(luaB_getmetatable)},\
{LSTRKEY("loadfile"), LFUNCVAL(luaB_loadfile)},\
{LSTRKEY("load"), LFUNCVAL(luaB_load)},\
{LSTRKEY("loadstring"), LFUNCVAL(luaB_loadstring)},\
{LSTRKEY("next"), LFUNCVAL(luaB_next)},\
{LSTRKEY("pcall"), LFUNCVAL(luaB_pcall)},\
{LSTRKEY("print"), LFUNCVAL(luaB_print)},\
{LSTRKEY("rawequal"), LFUNCVAL(luaB_rawequal)},\
{LSTRKEY("rawget"), LFUNCVAL(luaB_rawget)},\
{LSTRKEY("rawset"), LFUNCVAL(luaB_rawset)},\
{LSTRKEY("select"), LFUNCVAL(luaB_select)},\
{LSTRKEY("setfenv"), LFUNCVAL(luaB_setfenv)},\
{LSTRKEY("setmetatable"), LFUNCVAL(luaB_setmetatable)},\
{LSTRKEY("tonumber"), LFUNCVAL(luaB_tonumber)},\
{LSTRKEY("tostring"), LFUNCVAL(luaB_tostring)},\
{LSTRKEY("type"), LFUNCVAL(luaB_type)},\
{LSTRKEY("unpack"), LFUNCVAL(luaB_unpack)},\
{LSTRKEY("xpcall"), LFUNCVAL(luaB_xpcall)}
#if LUA_OPTIMIZE_MEMORY == 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const
LUA_REG_TYPE
base_funcs_list
[]
=
{
LUA_BASELIB_FUNCLIST
,
{
LNILKEY
,
LNILVAL
}
};
#endif
extern
const
luaR_entry
lua_rotable_base
[];
static
int
luaB_index
(
lua_State
*
L
)
{
#if LUA_OPTIMIZE_MEMORY == 2
int
fres
;
if
((
fres
=
luaR_findfunction
(
L
,
base_funcs_list
))
!=
0
)
return
fres
;
#endif
const
char
*
keyname
=
luaL_checkstring
(
L
,
2
);
if
(
!
c_strcmp
(
keyname
,
"_VERSION"
))
{
lua_pushliteral
(
L
,
LUA_VERSION
);
return
1
;
}
void
*
res
=
luaR_findglobal
(
keyname
,
c_strlen
(
keyname
));
if
(
!
res
)
return
0
;
else
{
lua_pushrotable
(
L
,
res
);
return
1
;
}
}
/*
* ESP builds use specific linker directives to marshal all ROTable declarations
*
int
o a single ROTable in the PSECT ".lua_rotable".
*
* This is not practical on Posix builds using a standard link so for cross
* compiler builds, separate ROTables are used for the base functions and library
* ROTables, with the latter chained from the former using its __index meta-method.
* In this case all library ROTables are defined in linit.c.
*/
#ifdef LUA_CROSS_COMPILER
#define BASE_ROTABLE base_func_map
#define LOCK_IN_ROTABLE
static
const
LUA_REG_TYPE
base_func_meta
[]
=
{
LROT_TABENTRY
(
__index
,
lua_rotable_base
),
LROT_END
};
#else
#define BASE_ROTABLE lua_rotable_base
#define LOCK_IN_ROTABLE __attribute__((used,unused,section(".lua_rotable")))
#endif
static
const
luaL_Reg
base_funcs
[]
=
{
#if LUA_OPTIMIZE_MEMORY != 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 0
#include "lrodefs.h"
LUA_BASELIB_FUNCLIST
,
static
const
LUA_REG_TYPE
LOCK_IN_ROTABLE
base_func_map
[]
=
{
LROT_FUNCENTRY
(
assert
,
luaB_assert
),
LROT_FUNCENTRY
(
collectgarbage
,
luaB_collectgarbage
),
LROT_FUNCENTRY
(
dofile
,
luaB_dofile
),
LROT_FUNCENTRY
(
error
,
luaB_error
),
LROT_FUNCENTRY
(
gcinfo
,
luaB_gcinfo
),
LROT_FUNCENTRY
(
getfenv
,
luaB_getfenv
),
LROT_FUNCENTRY
(
getmetatable
,
luaB_getmetatable
),
LROT_FUNCENTRY
(
loadfile
,
luaB_loadfile
),
LROT_FUNCENTRY
(
load
,
luaB_load
),
LROT_FUNCENTRY
(
loadstring
,
luaB_loadstring
),
LROT_FUNCENTRY
(
next
,
luaB_next
),
LROT_FUNCENTRY
(
pcall
,
luaB_pcall
),
LROT_FUNCENTRY
(
print
,
luaB_print
),
LROT_FUNCENTRY
(
rawequal
,
luaB_rawequal
),
LROT_FUNCENTRY
(
rawget
,
luaB_rawget
),
LROT_FUNCENTRY
(
rawset
,
luaB_rawset
),
LROT_FUNCENTRY
(
select
,
luaB_select
),
LROT_FUNCENTRY
(
setfenv
,
luaB_setfenv
),
LROT_FUNCENTRY
(
setmetatable
,
luaB_setmetatable
),
LROT_FUNCENTRY
(
tonumber
,
luaB_tonumber
),
LROT_FUNCENTRY
(
tostring
,
luaB_tostring
),
LROT_FUNCENTRY
(
type
,
luaB_type
),
LROT_FUNCENTRY
(
unpack
,
luaB_unpack
),
LROT_FUNCENTRY
(
xpcall
,
luaB_xpcall
)
#ifdef LUA_CROSS_COMPILER
,
LROT_TABENTRY
(
__metatable
,
base_func_meta
),
LROT_END
#endif
{
"__index"
,
luaB_index
},
};
static
const
luaL_Reg
base_funcs
[]
=
{
{
NULL
,
NULL
}
};
...
...
@@ -661,7 +652,6 @@ static int luaB_corunning (lua_State *L) {
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const
LUA_REG_TYPE
co_funcs
[]
=
{
{
LSTRKEY
(
"create"
),
LFUNCVAL
(
luaB_cocreate
)},
{
LSTRKEY
(
"resume"
),
LFUNCVAL
(
luaB_coresume
)},
...
...
@@ -682,7 +672,6 @@ static void auxopen (lua_State *L, const char *name,
lua_setfield
(
L
,
-
2
,
name
);
}
static
void
base_open
(
lua_State
*
L
)
{
/* set global _G */
lua_pushvalue
(
L
,
LUA_GLOBALSINDEX
);
...
...
@@ -691,11 +680,12 @@ static void base_open (lua_State *L) {
luaL_register_light
(
L
,
"_G"
,
base_funcs
);
#if LUA_OPTIMIZE_MEMORY > 0
lua_pushvalue
(
L
,
-
1
);
lua_setmetatable
(
L
,
-
2
);
#else
lua_setmetatable
(
L
,
-
2
);
lua_pushrotable
(
L
,
(
void
*
)
BASE_ROTABLE
);
lua_setglobal
(
L
,
"__index"
);
#endif
lua_pushliteral
(
L
,
LUA_VERSION
);
lua_setglobal
(
L
,
"_VERSION"
);
/* set global _VERSION */
#endif
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
auxopen
(
L
,
"ipairs"
,
luaB_ipairs
,
ipairsaux
);
auxopen
(
L
,
"pairs"
,
luaB_pairs
,
luaB_next
);
...
...
app/lua/ldblib.c
View file @
11592951
...
...
@@ -16,7 +16,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lstring.h"
#include "lflash.h"
#include "user_modules.h"
...
...
app/lua/ldump.c
View file @
11592951
...
...
@@ -47,7 +47,7 @@ static void DumpChar(int y, DumpState* D)
static
void
Align4
(
DumpState
*
D
)
{
while
(
D
->
wrote
&
3
)
while
(
D
->
wrote
&
3
&&
D
->
status
==
0
)
DumpChar
(
0
,
D
);
}
...
...
app/lua/lflash.c
View file @
11592951
...
...
@@ -16,6 +16,7 @@
#include "lflash.h"
#include "platform.h"
#include "vfs.h"
#include "uzlib.h"
#include "c_fcntl.h"
#include "c_stdio.h"
...
...
@@ -34,15 +35,52 @@ static uint32_t flashAddrPhys;
static
uint32_t
flashSector
;
static
uint32_t
curOffset
;
#define ALIGN(s) (((s)+sizeof(size_t)-1) & ((size_t) (- (signed) sizeof(size_t))))
#define ALIGN(s)
(((s)+sizeof(size_t)-1) & ((size_t) (- (signed) sizeof(size_t))))
#define ALIGN_BITS(s) (((uint32_t)s) & (sizeof(size_t)-1))
#define ALL_SET
cast(uint32_t, -1
)
#define FLASH_SIZE LUA_FLASH_STORE
#define ALL_SET
(~0
)
#define FLASH_SIZE
LUA_FLASH_STORE
#define FLASH_PAGE_SIZE INTERNAL_FLASH_SECTOR_SIZE
#define FLASH_PAGES (FLASH_SIZE/FLASH_PAGE_SIZE)
#define FLASH_PAGES (FLASH_SIZE/FLASH_PAGE_SIZE)
#define READ_BLOCKSIZE 1024
#define WRITE_BLOCKSIZE 2048
#define DICTIONARY_WINDOW 16384
#define WORDSIZE (sizeof(int))
#define BITS_PER_WORD 32
#define WRITE_BLOCKS ((DICTIONARY_WINDOW/WRITE_BLOCKSIZE)+1)
#define WRITE_BLOCK_WORDS (WRITE_BLOCKSIZE/WORDSIZE)
char
flash_region_base
[
FLASH_SIZE
]
ICACHE_FLASH_RESERVED_ATTR
;
struct
INPUT
{
int
fd
;
int
len
;
uint8_t
block
[
READ_BLOCKSIZE
];
uint8_t
*
inPtr
;
int
bytesRead
;
int
left
;
void
*
inflate_state
;
}
*
in
;
typedef
struct
{
uint8_t
byte
[
WRITE_BLOCKSIZE
];
}
outBlock
;
struct
OUTPUT
{
lua_State
*
L
;
lu_int32
flash_sig
;
int
len
;
outBlock
*
block
[
WRITE_BLOCKS
];
outBlock
buffer
;
int
ndx
;
uint32_t
crc
;
int
(
*
fullBlkCB
)
(
void
);
int
flashLen
;
int
flagsLen
;
int
flagsNdx
;
uint32_t
*
flags
;
const
char
*
error
;
}
*
out
;
#ifdef NODE_DEBUG
extern
void
dbg_printf
(
const
char
*
fmt
,
...)
__attribute__
((
format
(
printf
,
1
,
2
)));
void
dumpStrt
(
stringtable
*
tb
,
const
char
*
type
)
{
...
...
@@ -54,11 +92,11 @@ void dumpStrt(stringtable *tb, const char *type) {
for
(
i
=
0
;
i
<
tb
->
size
;
i
++
)
for
(
o
=
tb
->
hash
[
i
],
j
=
0
;
o
;
(
o
=
o
->
gch
.
next
),
j
++
)
{
TString
*
ts
=
cast
(
TString
*
,
o
);
NODE_DBG
(
"%5d %5d %08x %08x %5d %1s %s
\n
"
,
NODE_DBG
(
"%5d %5d %08x %08x %5d %1s %s
\n
"
,
i
,
j
,
(
size_t
)
ts
,
ts
->
tsv
.
hash
,
ts
->
tsv
.
len
,
ts_isreadonly
(
ts
)
?
"R"
:
" "
,
getstr
(
ts
));
}
}
}
LUA_API
void
dumpStrings
(
lua_State
*
L
)
{
dumpStrt
(
&
G
(
L
)
->
strt
,
"RAM"
);
...
...
@@ -70,7 +108,7 @@ LUA_API void dumpStrings(lua_State *L) {
/* =====================================================================================
* The next 4 functions: flashPosition, flashSetPosition, flashBlock and flashErase
* wrap writing to flash. The last two are platform dependent. Also note that any
* writes are suppressed if the global writeToFlash is false. This is used in
* writes are suppressed if the global writeToFlash is false. This is used in
* phase I where the pass is used to size the structures in flash.
*/
static
char
*
flashPosition
(
void
){
...
...
@@ -104,28 +142,37 @@ static void flashErase(uint32_t start, uint32_t end){
platform_flash_erase_sector
(
flashSector
+
i
);
}
/* =====================================================================================
* luaN_init(), luaN_reload_reboot() and luaN_index() are exported via lflash.h.
* The first is the startup hook used in lstate.c and the last two are
* implementations of the node.flash API calls.
*/
/*
* Hook in lstate.c:f_luaopen() to set up ROstrt and ROpvmain if needed
*/
*/
LUAI_FUNC
void
luaN_init
(
lua_State
*
L
)
{
// luaL_dbgbreak();
curOffset
=
0
;
flashAddr
=
flash_region_base
;
flashAddrPhys
=
platform_flash_mapped2phys
((
uint32_t
)
flashAddr
);
flashSector
=
platform_flash_get_sector_of_address
(
flashAddrPhys
);
curOffset
=
0
;
flashAddr
=
flash_region_base
;
flashAddrPhys
=
platform_flash_mapped2phys
((
uint32_t
)
flashAddr
);
flashSector
=
platform_flash_get_sector_of_address
(
flashAddrPhys
);
FlashHeader
*
fh
=
cast
(
FlashHeader
*
,
flashAddr
);
/*
* For the LFS to be valid, its signature has to be correct for this build
variant,
* th
r
ROhash and main proto fields must be defined and the main proto
address
* be within the LFS address bounds. (This last check is primarily to
detect the
* direct imaging of an absolute LFS with the wrong base address.
* For the LFS to be valid, its signature has to be correct for this build
*
variant,
th
e
ROhash and main proto fields must be defined and the main proto
*
address
be within the LFS address bounds. (This last check is primarily to
*
detect the
direct imaging of an absolute LFS with the wrong base address.
*/
if
(
fh
->
flash_sig
==
0
||
fh
->
flash_sig
==
~
0
)
{
NODE_ERR
(
"No LFS image loaded
\n
"
);
return
;
}
if
((
fh
->
flash_sig
&
(
~
FLASH_SIG_ABSOLUTE
))
!=
FLASH_SIG
)
{
NODE_ERR
(
"Flash sig not correct: %p vs %p
\n
"
,
fh
->
flash_sig
&
(
~
FLASH_SIG_ABSOLUTE
),
FLASH_SIG
);
fh
->
flash_sig
&
(
~
FLASH_SIG_ABSOLUTE
),
FLASH_SIG
);
return
;
}
...
...
@@ -135,107 +182,89 @@ LUAI_FUNC void luaN_init (lua_State *L) {
fh
->
mainProto
-
cast
(
FlashAddr
,
fh
),
fh
->
flash_size
);
return
;
}
G
(
L
)
->
ROstrt
.
hash
=
cast
(
GCObject
**
,
fh
->
pROhash
);
G
(
L
)
->
ROstrt
.
nuse
=
fh
->
nROuse
;
G
(
L
)
->
ROstrt
.
size
=
fh
->
nROsize
;
G
(
L
)
->
ROpvmain
=
cast
(
Proto
*
,
fh
->
mainProto
);
}
#define BYTE_OFFSET(t,f) cast(size_t, &(cast(t *, NULL)->f))
/*
* Rehook address chain to correct Flash byte addressed within the mapped adress space
* Note that on input each 32-bit address field is split into 2×16-bit subfields
* - the lu_int16 offset of the target address being referenced
* - the lu_int16 offset of the next address pointer.
*/
static
int
rebuild_core
(
int
fd
,
uint32_t
size
,
lu_int32
*
buf
,
int
is_absolute
)
{
int
bi
;
/* byte offset into memory mapped LFS of current buffer */
int
wNextOffset
=
BYTE_OFFSET
(
FlashHeader
,
mainProto
)
/
sizeof
(
lu_int32
);
int
wj
;
/* word offset into current input buffer */
for
(
bi
=
0
;
bi
<
size
;
bi
+=
FLASH_PAGE_SIZE
)
{
int
wi
=
bi
/
sizeof
(
lu_int32
);
int
blen
=
((
bi
+
FLASH_PAGE_SIZE
)
<
size
)
?
FLASH_PAGE_SIZE
:
size
-
bi
;
int
wlen
=
blen
/
sizeof
(
lu_int32
);
if
(
vfs_read
(
fd
,
buf
,
blen
)
!=
blen
)
return
0
;
if
(
!
is_absolute
)
{
for
(
wj
=
0
;
wj
<
wlen
;
wj
++
)
{
if
((
wi
+
wj
)
==
wNextOffset
)
{
/* this word is the next linked address */
int
wTargetOffset
=
buf
[
wj
]
&
0xFFFF
;
wNextOffset
=
buf
[
wj
]
>>
16
;
lua_assert
(
!
wNextOffset
||
(
wNextOffset
>
(
wi
+
wj
)
&&
wNextOffset
<
size
/
sizeof
(
lu_int32
)));
buf
[
wj
]
=
cast
(
lu_int32
,
flashAddr
+
wTargetOffset
*
sizeof
(
lu_int32
));
}
}
}
flashBlock
(
buf
,
blen
);
}
return
size
;
}
//extern void software_reset(void);
static
int
loadLFS
(
lua_State
*
L
);
static
int
loadLFSgc
(
lua_State
*
L
);
static
int
procFirstPass
(
void
);
/*
* Library function called by node.flash
.
load(filename).
* Library function called by node.flash
re
load(filename).
*/
LUALIB_API
int
luaN_reload_reboot
(
lua_State
*
L
)
{
int
fd
,
status
,
is_absolute
;
FlashHeader
fh
;
const
char
*
fn
=
lua_tostring
(
L
,
1
);
if
(
!
fn
||
!
(
fd
=
vfs_open
(
fn
,
"r"
)))
return
0
;
if
(
vfs_read
(
fd
,
&
fh
,
sizeof
(
fh
))
!=
sizeof
(
fh
)
||
(
fh
.
flash_sig
&
(
~
FLASH_SIG_ABSOLUTE
))
!=
FLASH_SIG
)
return
0
;
if
(
vfs_lseek
(
fd
,
-
1
,
VFS_SEEK_END
)
!=
fh
.
flash_size
-
1
||
vfs_lseek
(
fd
,
0
,
VFS_SEEK_SET
)
!=
0
)
return
0
;
is_absolute
=
fh
.
flash_sig
&
FLASH_SIG_ABSOLUTE
;
lu_int32
*
buffer
=
luaM_newvector
(
L
,
FLASH_PAGE_SIZE
/
sizeof
(
lu_int32
),
lu_int32
);
/*
* This is the point of no return. We attempt to rebuild the flash. If there
* are any problems them the Flash is going to be corrupt, so the only fallback
* is to erase it and reboot with a clean but blank flash. Otherwise the reboot
* will load the new LFS.
*
* Note that the Lua state is not passed into the lua core because from this
* point on, we make no calls on the Lua RTS.
*/
flashErase
(
0
,
-
1
);
if
(
rebuild_core
(
fd
,
fh
.
flash_size
,
buffer
,
is_absolute
)
!=
fh
.
flash_size
)
flashErase
(
0
,
-
1
);
/*
* Issue a break 0,0. This will either enter the debugger or force a restart if
* not installed. Follow this by a H/W timeout is a robust way to insure that
* other interrupts / callbacks don't fire and reference THE old LFS context.
*/
asm
(
"break 0,0"
::
);
while
(
1
)
{}
// luaL_dbgbreak();
const
char
*
fn
=
lua_tostring
(
L
,
1
),
*
msg
=
""
;
int
status
;
/*
* Do a protected call of loadLFS.
*
* - This will normally rewrite the LFS and reboot, with no return.
* - If an error occurs then it is sent to the UART.
* - If this occured in the 1st pass, the previous LFS is unchanged so it is
* safe to return to the calling Lua.
* - If in the 1st pass, then the ESP is rebooted.
*/
status
=
lua_cpcall
(
L
,
&
loadLFS
,
cast
(
void
*
,
fn
));
if
(
!
out
||
out
->
fullBlkCB
==
procFirstPass
)
{
/*
* Never entered the 2nd pass, so it is safe to return the error. Note
* that I've gone to some trouble to ensure that all dynamically allocated
* working areas have been freed, so that we have no memory leaks.
*/
if
(
status
==
LUA_ERRMEM
)
msg
=
"Memory allocation error"
;
else
if
(
out
&&
out
->
error
)
msg
=
out
->
error
;
else
msg
=
"Unknown Error"
;
/* We can clean up and return error */
lua_cpcall
(
L
,
&
loadLFSgc
,
NULL
);
lua_settop
(
L
,
0
);
lua_pushstring
(
L
,
msg
);
return
1
;
}
if
(
status
==
0
)
{
/* Successful LFS rewrite */
msg
=
"LFS region updated. Restarting."
;
}
else
{
/* We have errored during the second pass so clear the LFS and reboot */
if
(
status
==
LUA_ERRMEM
)
msg
=
"Memory allocation error"
;
else
if
(
out
->
error
)
msg
=
out
->
error
;
else
msg
=
"Unknown Error"
;
flashErase
(
0
,
-
1
);
}
NODE_ERR
(
msg
);
while
(
1
)
{}
// Force WDT as the ROM software_reset() doesn't seem to work
return
0
;
}
/*
* I
n
the arg is a valid LFS module name then return the LClosure
pointing to it.
* Otherwise return:
* I
f
the arg is a valid LFS module name then return the LClosure
*
pointing to it.
Otherwise return:
* - The Unix time that the LFS was built
* - The base address and length of the LFS
* - An array of the module names in the
the
LFS
* - An array of the module names in the LFS
*/
LUAI_FUNC
int
luaN_index
(
lua_State
*
L
)
{
int
i
;
int
n
=
lua_gettop
(
L
);
/* Return nil + the LFS base address if the LFS isn't loaded */
/* Return nil + the LFS base address if the LFS isn't loaded */
if
(
!
(
G
(
L
)
->
ROpvmain
))
{
lua_settop
(
L
,
0
);
lua_pushnil
(
L
);
...
...
@@ -270,5 +299,262 @@ LUAI_FUNC int luaN_index (lua_State *L) {
lua_insert
(
L
,
4
);
return
5
;
}
/* =====================================================================================
* The following routines use my uzlib which was based on pfalcon's inflate and
* deflate routines. The standard NodeMCU make also makes two host tools uz_zip
* and uz_unzip which also use these and luac.cross uses the deflate. As discussed
* below, The main action routine loadLFS() calls uzlib_inflate() to do the actual
* stream inflation but uses three supplied CBs to abstract input and output
* stream handling.
*
* ESP8266 RAM limitations and heap fragmentation are a key implementation
* constraint and hence these routines use a number of ~2K buffers (11) as
* working storage.
*
* The inflate is done twice, in order to limit storage use and avoid forward /
* backward reference issues. However this has a major advantage that the LFS
* is scanned with the headers, CRC, etc. validated BEFORE the write to flash
* is started, so the only real chance of failure during the second pass
* write is if a power fail occurs during the pass.
*/
static
void
flash_error
(
const
char
*
err
)
{
if
(
out
)
out
->
error
=
err
;
if
(
in
&&
in
->
inflate_state
)
uz_free
(
in
->
inflate_state
);
lua_pushnil
(
out
->
L
);
/* can't use it on a cpcall anyway */
lua_error
(
out
->
L
);
}
/*
* uzlib_inflate does a stream inflate on an RFC 1951 encoded data stream.
* It uses three application-specific CBs passed in the call to do the work:
*
* - get_byte() CB to return next byte in input stream
* - put_byte() CB to output byte to output buffer
* - recall_byte() CB to output byte to retrieve a historic byte from
* the output buffer.
*
* Note that put_byte() also triggers secondary CBs to do further processing.
*/
static
uint8_t
get_byte
(
void
)
{
if
(
--
in
->
left
<
0
)
{
/* Read next input block */
int
remaining
=
in
->
len
-
in
->
bytesRead
;
int
wanted
=
remaining
>=
READ_BLOCKSIZE
?
READ_BLOCKSIZE
:
remaining
;
if
(
vfs_read
(
in
->
fd
,
in
->
block
,
wanted
)
!=
wanted
)
flash_error
(
"read error on LFS image file"
);
system_soft_wdt_feed
();
in
->
bytesRead
+=
wanted
;
in
->
inPtr
=
in
->
block
;
in
->
left
=
wanted
-
1
;
}
return
*
in
->
inPtr
++
;
}
static
void
put_byte
(
uint8_t
value
)
{
int
offset
=
out
->
ndx
%
WRITE_BLOCKSIZE
;
/* counts from 0 */
out
->
block
[
0
]
->
byte
[
offset
++
]
=
value
;
out
->
ndx
++
;
if
(
offset
==
WRITE_BLOCKSIZE
||
out
->
ndx
==
out
->
len
)
{
if
(
out
->
fullBlkCB
)
out
->
fullBlkCB
();
/* circular shift the block pointers (redundant on last block, but so what) */
outBlock
*
nextBlock
=
out
->
block
[
WRITE_BLOCKS
-
1
];
memmove
(
out
->
block
+
1
,
out
->
block
,
(
WRITE_BLOCKS
-
1
)
*
sizeof
(
void
*
));
out
->
block
[
0
]
=
nextBlock
;
}
}
static
uint8_t
recall_byte
(
uint
offset
)
{
if
(
offset
>
DICTIONARY_WINDOW
||
offset
>=
out
->
ndx
)
flash_error
(
"invalid dictionary offset on inflate"
);
/* ndx starts at 1. Need relative to 0 */
uint
n
=
out
->
ndx
-
offset
;
uint
pos
=
n
%
WRITE_BLOCKSIZE
;
uint
blockNo
=
out
->
ndx
/
WRITE_BLOCKSIZE
-
n
/
WRITE_BLOCKSIZE
;
return
out
->
block
[
blockNo
]
->
byte
[
pos
];
}
/*
* On the first pass the break index is set to call this process at the end
* of each completed output buffer.
* - On the first call, the Flash Header is checked.
* - On each call the CRC is rolled up for that buffer.
* - Once the flags array is in-buffer this is also captured.
* This logic is slightly complicated by the last buffer is typically short.
*/
int
procFirstPass
(
void
)
{
int
len
=
(
out
->
ndx
%
WRITE_BLOCKSIZE
)
?
out
->
ndx
%
WRITE_BLOCKSIZE
:
WRITE_BLOCKSIZE
;
if
(
out
->
ndx
<=
WRITE_BLOCKSIZE
)
{
uint32_t
fl
;
/* Process the flash header and cache the FlashHeader fields we need */
FlashHeader
*
fh
=
cast
(
FlashHeader
*
,
out
->
block
[
0
]);
out
->
flashLen
=
fh
->
flash_size
;
/* in bytes */
out
->
flagsLen
=
(
out
->
len
-
fh
->
flash_size
)
/
WORDSIZE
;
/* in words */
out
->
flash_sig
=
fh
->
flash_sig
;
if
((
fh
->
flash_sig
&
FLASH_FORMAT_MASK
)
!=
FLASH_FORMAT_VERSION
)
flash_error
(
"Incorrect LFS header version"
);
if
((
fh
->
flash_sig
&
FLASH_SIG_B2_MASK
)
!=
FLASH_SIG_B2
)
flash_error
(
"Incorrect LFS build type"
);
if
((
fh
->
flash_sig
&
~
FLASH_SIG_ABSOLUTE
)
!=
FLASH_SIG
)
flash_error
(
"incorrect LFS header signature"
);
if
(
fh
->
flash_size
>
FLASH_SIZE
)
flash_error
(
"LFS Image too big for configured LFS region"
);
if
((
fh
->
flash_size
&
0x3
)
||
fh
->
flash_size
>
FLASH_SIZE
||
out
->
flagsLen
!=
1
+
(
out
->
flashLen
/
WORDSIZE
-
1
)
/
BITS_PER_WORD
)
flash_error
(
"LFS length mismatch"
);
out
->
flags
=
luaM_newvector
(
out
->
L
,
out
->
flagsLen
,
uint
);
}
/* update running CRC */
out
->
crc
=
uzlib_crc32
(
out
->
block
[
0
],
len
,
out
->
crc
);
/* copy out any flag vector */
if
(
out
->
ndx
>
out
->
flashLen
)
{
int
start
=
out
->
flashLen
-
(
out
->
ndx
-
len
);
if
(
start
<
0
)
start
=
0
;
memcpy
(
out
->
flags
+
out
->
flagsNdx
,
out
->
block
[
0
]
->
byte
+
start
,
len
-
start
);
out
->
flagsNdx
+=
(
len
-
start
)
/
WORDSIZE
;
/* flashLen and len are word aligned */
}
return
1
;
}
int
procSecondPass
(
void
)
{
/*
* The length rules are different for the second pass since this only processes
* upto the flashLen and not the full image. This also works in word units.
* (We've already validated these are word multiples.)
*/
int
i
,
len
=
(
out
->
ndx
>
out
->
flashLen
)
?
(
out
->
flashLen
%
WRITE_BLOCKSIZE
)
/
WORDSIZE
:
WRITE_BLOCKSIZE
/
WORDSIZE
;
uint32_t
*
buf
=
(
uint32_t
*
)
out
->
buffer
.
byte
,
flags
;
/*
* Relocate all the addresses tagged in out->flags. This can't be done in
* place because the out->blocks are still in use as dictionary content so
* first copy the block to a working buffer and do the relocation in this.
*/
memcpy
(
out
->
buffer
.
byte
,
out
->
block
[
0
]
->
byte
,
WRITE_BLOCKSIZE
);
for
(
i
=
0
;
i
<
len
;
i
++
,
flags
>>=
1
)
{
if
((
i
&
31
)
==
0
)
flags
=
out
->
flags
[
out
->
flagsNdx
++
];
if
(
flags
&
1
)
buf
[
i
]
=
WORDSIZE
*
buf
[
i
]
+
cast
(
uint32_t
,
flashAddr
);
}
/*
* On first block, set the flash_sig has the in progress bit set and this
* is not cleared until end.
*/
if
(
out
->
ndx
<=
WRITE_BLOCKSIZE
)
buf
[
0
]
=
out
->
flash_sig
|
FLASH_SIG_IN_PROGRESS
;
flashBlock
(
buf
,
len
*
WORDSIZE
);
if
(
out
->
ndx
>=
out
->
flashLen
)
{
/* we're done so disable CB and rewrite flash sig to complete flash */
flashSetPosition
(
0
);
flashBlock
(
&
out
->
flash_sig
,
WORDSIZE
);
out
->
fullBlkCB
=
NULL
;
}
}
/*
* loadLFS)() is protected called from luaN_reload_reboot so that it can recover
* from out of memory and other thrown errors. loadLFSgc() GCs any resources.
*/
static
int
loadLFS
(
lua_State
*
L
)
{
const
char
*
fn
=
cast
(
const
char
*
,
lua_touserdata
(
L
,
1
));
int
i
,
n
,
res
;
uint32_t
crc
;
/* Allocate and zero in and out structures */
in
=
NULL
;
out
=
NULL
;
in
=
luaM_new
(
L
,
struct
INPUT
);
memset
(
in
,
0
,
sizeof
(
*
in
));
out
=
luaM_new
(
L
,
struct
OUTPUT
);
memset
(
out
,
0
,
sizeof
(
*
out
));
out
->
L
=
L
;
out
->
fullBlkCB
=
procFirstPass
;
out
->
crc
=
~
0
;
/* Open LFS image/ file, read unpacked length from last 4 byte and rewind */
if
(
!
(
in
->
fd
=
vfs_open
(
fn
,
"r"
)))
flash_error
(
"LFS image file not found"
);
in
->
len
=
vfs_size
(
in
->
fd
);
if
(
in
->
len
<=
200
||
/* size of an empty luac output */
vfs_lseek
(
in
->
fd
,
in
->
len
-
4
,
VFS_SEEK_SET
)
!=
in
->
len
-
4
||
vfs_read
(
in
->
fd
,
&
out
->
len
,
sizeof
(
uint
))
!=
sizeof
(
uint
))
flash_error
(
"read error on LFS image file"
);
vfs_lseek
(
in
->
fd
,
0
,
VFS_SEEK_SET
);
/* Allocate the out buffers */
for
(
i
=
0
;
i
<=
WRITE_BLOCKS
;
i
++
)
out
->
block
[
i
]
=
luaM_new
(
L
,
outBlock
);
/* first inflate pass */
if
(
uzlib_inflate
(
get_byte
,
put_byte
,
recall_byte
,
in
->
len
,
&
crc
,
&
in
->
inflate_state
)
<
0
)
flash_error
(
"read error on LFS image file"
);
if
(
crc
!=
~
out
->
crc
)
flash_error
(
"checksum error on LFS image file"
);
out
->
fullBlkCB
=
procSecondPass
;
out
->
flagsNdx
=
0
;
out
->
ndx
=
0
;
in
->
bytesRead
=
in
->
left
=
0
;
/*
* Once we have completed the 1st pass then the LFS image has passed the
* basic signature, crc and length checks, so now we can reset the counts
* to do the actual write to flash on the second pass.
*/
vfs_lseek
(
in
->
fd
,
0
,
VFS_SEEK_SET
);
flashErase
(
0
,(
out
->
flashLen
-
1
)
/
FLASH_PAGE_SIZE
);
flashSetPosition
(
0
);
if
(
uzlib_inflate
(
get_byte
,
put_byte
,
recall_byte
,
in
->
len
,
&
crc
,
&
in
->
inflate_state
)
!=
UZLIB_OK
)
if
(
res
<
0
)
{
const
char
*
err
[]
=
{
"Data_error during decompression"
,
"Chksum_error during decompression"
,
"Dictionary error during decompression"
"Memory_error during decompression"
};
flash_error
(
err
[
UZLIB_DATA_ERROR
-
res
]);
}
return
0
;
}
static
int
loadLFSgc
(
lua_State
*
L
)
{
int
i
;
if
(
out
)
{
for
(
i
=
0
;
i
<
WRITE_BLOCKS
;
i
++
)
if
(
out
->
block
[
i
])
luaM_free
(
L
,
out
->
block
[
i
]);
if
(
out
->
flags
)
luaM_freearray
(
L
,
out
->
flags
,
out
->
flagsLen
,
uint32_t
);
luaM_free
(
L
,
out
);
}
if
(
in
)
{
if
(
in
->
fd
)
vfs_close
(
in
->
fd
);
luaM_free
(
L
,
in
);
}
return
0
;
}
#endif
app/lua/lflash.h
View file @
11592951
...
...
@@ -15,7 +15,8 @@
#else
# define FLASH_SIG_B1 0x00
#endif
#define FLASH_FORMAT_VERSION (1 << 8)
#define FLASH_FORMAT_MASK 0xF00
#ifdef LUA_PACK_TVALUES
#ifdef LUA_NUMBER_INTEGRAL
#error "LUA_PACK_TVALUES is only valid for Floating point builds"
...
...
@@ -24,9 +25,10 @@
#else
# define FLASH_SIG_B2 0x00
#endif
# define FLASH_SIG_B2_MASK 0x04
#define FLASH_SIG_ABSOLUTE 0x01
#define FLASH_SIG_IN_PROGRESS 0x08
#define FLASH_SIG (0xfafaa
f
50 | FLASH_SIG_B2 | FLASH_SIG_B1)
#define FLASH_SIG (0xfafaa
0
50 |
FLASH_FORMAT_VERSION |
FLASH_SIG_B2 | FLASH_SIG_B1)
typedef
lu_int32
FlashAddr
;
typedef
struct
{
...
...
app/lua/lgc.c
View file @
11592951
...
...
@@ -43,7 +43,7 @@
#define stringmark(s) if (!isLFSobject(&(s)->tsv)) {reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT);}
#define isfinalized(u) testbit(
(u)->
marked, FINALIZEDBIT)
#define isfinalized(u) testbit(
get
marked
(u)
, FINALIZEDBIT)
#define markfinalized(u) l_setbit((u)->marked, FINALIZEDBIT)
...
...
@@ -73,12 +73,12 @@ static void removeentry (Node *n) {
static
void
reallymarkobject
(
global_State
*
g
,
GCObject
*
o
)
{
/* don't mark LFS Protos (or strings) */
if
(
o
->
gch
.
tt
==
LUA_TPROTO
&&
isLFSobject
(
&
(
o
->
gch
)))
if
(
gettt
(
&
o
->
gch
)
==
LUA_TPROTO
&&
isLFSobject
(
&
(
o
->
gch
)))
return
;
lua_assert
(
iswhite
(
o
)
&&
!
isdead
(
g
,
o
));
white2gray
(
o
);
switch
(
o
->
gch
.
tt
)
{
switch
(
gettt
(
&
o
->
gch
)
)
{
case
LUA_TSTRING
:
{
return
;
}
...
...
@@ -168,10 +168,14 @@ static int traversetable (global_State *g, Table *h) {
int
i
;
int
weakkey
=
0
;
int
weakvalue
=
0
;
const
TValue
*
mode
;
if
(
h
->
metatable
&&
!
luaR_isrotable
(
h
->
metatable
))
markobject
(
g
,
h
->
metatable
);
mode
=
gfasttm
(
g
,
h
->
metatable
,
TM_MODE
);
const
TValue
*
mode
=
luaO_nilobject
;
if
(
h
->
metatable
)
{
if
(
!
luaR_isrotable
(
h
->
metatable
))
markobject
(
g
,
h
->
metatable
);
mode
=
gfasttm
(
g
,
h
->
metatable
,
TM_MODE
);
}
if
(
mode
&&
ttisstring
(
mode
))
{
/* is there a weak mode? */
weakkey
=
(
c_strchr
(
svalue
(
mode
),
'k'
)
!=
NULL
);
weakvalue
=
(
c_strchr
(
svalue
(
mode
),
'v'
)
!=
NULL
);
...
...
@@ -295,7 +299,7 @@ static l_mem propagatemark (global_State *g) {
GCObject
*
o
=
g
->
gray
;
lua_assert
(
isgray
(
o
));
gray2black
(
o
);
switch
(
o
->
gch
.
tt
)
{
switch
(
gettt
(
&
o
->
gch
)
)
{
case
LUA_TTABLE
:
{
Table
*
h
=
gco2h
(
o
);
g
->
gray
=
h
->
gclist
;
...
...
@@ -400,7 +404,7 @@ static void cleartable (GCObject *l) {
static
void
freeobj
(
lua_State
*
L
,
GCObject
*
o
)
{
switch
(
o
->
gch
.
tt
)
{
switch
(
gettt
(
&
o
->
gch
)
)
{
case
LUA_TPROTO
:
lua_assert
(
!
isLFSobject
(
&
(
o
->
gch
)));
luaF_freeproto
(
L
,
gco2p
(
o
));
...
...
app/lua/lgc.h
View file @
11592951
...
...
@@ -102,8 +102,8 @@
#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT)
#define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT)
#ifdef LUA_FLASH_STORE
#define isLFSobject(x) testbit(
(x)->
marked, LFSBIT)
#define stringfix(s) if (!test2bits((s)->tsv
.marked
, FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);}
#define isLFSobject(x) testbit(
get
marked
(x)
, LFSBIT)
#define stringfix(s) if (!test2bits(
getmarked(&
(s)->tsv
)
, FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);}
#else
#define isLFSobject(x) (0)
#define stringfix(s) {l_setbit((s)->tsv.marked, FIXEDBIT);}
...
...
app/lua/linit.c
View file @
11592951
...
...
@@ -15,60 +15,71 @@
#include "lauxlib.h"
#include "luaconf.h"
#include "module.h"
#if defined(LUA_CROSS_COMPILER)
BUILTIN_LIB
(
start_list
,
NULL
,
NULL
);
BUILTIN_LIB_INIT
(
start_list
,
NULL
,
NULL
);
#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
extern
const
luaR_entry
strlib
[],
tab_funcs
[],
dblib
[],
co_funcs
[],
math_map
[],
syslib
[];
extern
const
luaR_entry
syslib
[],
io_funcs
[];
// Only used on cross-compile builds
BUILTIN_LIB_INIT
(
BASE
,
""
,
luaopen_base
);
BUILTIN_LIB_INIT
(
LOADLIB
,
LUA_LOADLIBNAME
,
luaopen_package
);
BUILTIN_LIB
(
STRING
,
LUA_STRLIBNAME
,
strlib
);
BUILTIN_LIB_INIT
(
STRING
,
LUA_STRLIBNAME
,
luaopen_string
);
BUILTIN_LIB
(
TABLE
,
LUA_TABLIBNAME
,
tab_funcs
);
BUILTIN_LIB_INIT
(
TABLE
,
LUA_TABLIBNAME
,
luaopen_table
);
BUILTIN_LIB
(
DBG
,
LUA_DBLIBNAME
,
dblib
);
BUILTIN_LIB_INIT
(
DBG
,
LUA_DBLIBNAME
,
luaopen_debug
);
BUILTIN_LIB
(
CO
,
LUA_COLIBNAME
,
co_funcs
);
BUILTIN_LIB
(
MATH
,
LUA_MATHLIBNAME
,
math_map
);
#if defined(LUA_CROSS_COMPILER)
extern
const
luaR_entry
syslib
[],
iolib
[];
BUILTIN_LIB
(
OS
,
LUA_OSLIBNAME
,
syslib
);
BUILTIN_LIB_INIT
(
IO
,
LUA_IOLIBNAME
,
luaopen_io
);
BUILTIN_LIB
(
end_list
,
NULL
,
NULL
);
BUILTIN_LIB_INIT
(
end_list
,
NULL
,
NULL
);
/*
* These base addresses are internal to this module for cross compile builds
* This also exploits feature of the GCC code generator that the variables are
* emitted in either normal OR reverse order within PSECT.
* The NodeMCU Lua initalisation has been adapted to use linker-based module
* registration. This uses a PSECT naming convention to allow the lib and rotab
* entries to be collected by the linker into consoliated tables. The linker
* defines lua_libs_base and lua_rotable_base.
*
* This is not practical on Posix builds which use a standard loader declaration
* so for cross compiler builds, separate ROTables are used for the base functions
* and library ROTables, with the latter chained from the former using its __index
* meta-method. In this case all library ROTables are defined here, avoiding the
* need for linker magic is avoided on host builds.
*/
#define isascending(n) ((&(n ## _end_list)-&(n ## _start_list))>0)
static
const
luaL_Reg
*
lua_libs
;
const
luaR_table
*
lua_rotable
;
#
el
se
/* These base addresses
are Xtensa toolchain linker constant
s for Firmware build
s */
#if defined(LUA_CROSS_COMPILER)
#define LUA_ROTABLES
lua_rotable
_base
#
define LUA_LIBS lua_libs_ba
se
#else
/* decl
are Xtensa toolchain linker
defined
constants */
extern
const
luaL_Reg
lua_libs_base
[];
extern
const
luaR_
table
lua_rotable_base
[];
static
const
luaL_Reg
*
lua_libs
=
lua_libs_base
;
const
luaR_table
*
lua_rotable
=
lua_rotable_base
;
extern
const
luaR_
entry
lua_rotable_base
[];
#define LUA_ROTABLES lua_rotable_core
#define LUA_LIBS lua_libs_core
#endif
static
const
LOCK_IN_SECTION
(
libs
)
luaL_reg
LUA_LIBS
[]
=
{
{
""
,
luaopen_base
},
{
LUA_LOADLIBNAME
,
luaopen_package
},
{
LUA_STRLIBNAME
,
luaopen_string
},
{
LUA_TABLIBNAME
,
luaopen_table
},
{
LUA_DBLIBNAME
,
luaopen_debug
}
#if defined(LUA_CROSS_COMPILER)
,{
LUA_IOLIBNAME
,
luaopen_io
},
{
NULL
,
NULL
}
#endif
};
void
luaL_openlibs
(
lua_State
*
L
)
{
#define ENTRY(n,t) {LSTRKEY(n), LRO_ROVAL(t)}
const
LOCK_IN_SECTION
(
rotable
)
ROTable
LUA_ROTABLES
[]
=
{
ENTRY
(
"ROM"
,
LUA_ROTABLES
),
ENTRY
(
LUA_STRLIBNAME
,
strlib
),
ENTRY
(
LUA_TABLIBNAME
,
tab_funcs
),
ENTRY
(
LUA_DBLIBNAME
,
dblib
),
ENTRY
(
LUA_COLIBNAME
,
co_funcs
),
ENTRY
(
LUA_MATHLIBNAME
,
math_map
)
#if defined(LUA_CROSS_COMPILER)
lua_libs
=
(
isascending
(
lua_lib
)
?
&
lua_lib_start_list
:
&
lua_lib_end_list
)
+
1
;
lua_rotable
=
(
isascending
(
lua_rotable
)
?
&
lua_rotable_start_list
:
&
lua_rotable_end_list
)
+
1
;
,
ENTRY
(
LUA_OSLIBNAME
,
syslib
),
LROT_END
#endif
const
luaL_Reg
*
lib
=
lua_libs
;
};
void
luaL_openlibs
(
lua_State
*
L
)
{
const
luaL_Reg
*
lib
=
lua_libs_base
;
/* loop round and open libraries */
for
(;
lib
->
name
;
lib
++
)
{
if
(
lib
->
func
)
{
if
(
lib
->
func
)
{
lua_pushcfunction
(
L
,
lib
->
func
);
lua_pushstring
(
L
,
lib
->
name
);
lua_call
(
L
,
1
,
0
);
...
...
Prev
1
2
3
4
5
…
7
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment