From f67792e0d336c69ff547fbf242d01d506d939988 Mon Sep 17 00:00:00 2001 From: Philip Gladstone Date: Sat, 7 Nov 2020 16:38:40 -0500 Subject: [PATCH] Add support for using doubles in the LUA53 build. (#3225) --- app/include/lwip/app/espconn_tcp.h | 3 +++ app/include/lwip/mem.h | 8 +++++++ app/include/mbedtls/platform.h | 3 +++ app/include/sys/socket.h | 7 ++++++ app/include/user_config.h | 37 ++++++++++++++++++++---------- app/lua/luaconf.h | 4 ++++ app/lua53/ldump.c | 2 +- app/lua53/lobject.h | 7 +++++- app/lua53/luaconf.h | 12 ++++++++-- app/mbedtls/app/Makefile | 1 + app/mbedtls/app/espconn_mbedtls.c | 2 ++ app/mbedtls/app/lwIPSocket.c | 4 ++++ app/net/nodemcu_mdns.c | 2 +- docs/build.md | 24 ++++++++++++++++--- docs/compiling.md | 25 +++++++++++++++++--- tools/update_buildinfo.sh | 4 ++++ 16 files changed, 122 insertions(+), 23 deletions(-) diff --git a/app/include/lwip/app/espconn_tcp.h b/app/include/lwip/app/espconn_tcp.h index 76aa4b8c..3da9dabd 100644 --- a/app/include/lwip/app/espconn_tcp.h +++ b/app/include/lwip/app/espconn_tcp.h @@ -16,6 +16,9 @@ #define espconn_manual_recv_disabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_MANUALRECV) != 0) #define espconn_manual_recv_enabled(espconn) (((espconn)->pcommon.espconn_opt & ESPCONN_MANUALRECV) == 0) +extern int ets_task(); +extern int ets_post(); + /****************************************************************************** * FunctionName : espconn_kill_oldest_pcb * Description : A oldest incoming connection has been killed. diff --git a/app/include/lwip/mem.h b/app/include/lwip/mem.h index 825d2226..52362f3a 100644 --- a/app/include/lwip/mem.h +++ b/app/include/lwip/mem.h @@ -45,6 +45,14 @@ extern "C" { typedef size_t mem_size_t; +void *pvPortMalloc (size_t sz, const char *, unsigned, bool); +void vPortFree (void *p, const char *, unsigned); +void *pvPortZalloc (size_t sz, const char *, unsigned); +void *pvPortRealloc (void *p, size_t n, const char *, unsigned); +void* pvPortCalloc(size_t count,size_t size,const char *,unsigned); +void* pvPortCallocIram(size_t count,size_t size,const char *,unsigned); +void *pvPortZallocIram (size_t sz, const char *, unsigned); + /* aliases for C library malloc() */ #define mem_init() /* in case C library malloc() needs extra protection, diff --git a/app/include/mbedtls/platform.h b/app/include/mbedtls/platform.h index 1f907d6f..3a164897 100644 --- a/app/include/mbedtls/platform.h +++ b/app/include/mbedtls/platform.h @@ -58,6 +58,9 @@ extern "C" { * \{ */ +void *pvPortCalloc(unsigned int count, unsigned int size, const char*, unsigned); +void vPortFree (void *p, const char *, unsigned); + #if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) #include #include diff --git a/app/include/sys/socket.h b/app/include/sys/socket.h index a57378dc..937cacc0 100644 --- a/app/include/sys/socket.h +++ b/app/include/sys/socket.h @@ -63,6 +63,9 @@ typedef enum{ NETCONN_STATE_SUMNUM }netconn_state; +extern int __attribute__((weak)) espconn_mbedtls_parse_internal(int socket, sint8 error); +extern int __attribute__((weak)) espconn_mbedtls_parse_thread(int socket, int event, int error); + #if (!defined(lwIP_unlikely)) #define lwIP_unlikely(Expression) !!(Expression) #endif @@ -330,4 +333,8 @@ uint32_t lwip_getul(char *str); #define close(s) lwip_close(s) #define getul(s) lwip_getul(s) +extern int system_overclock(void); +extern int system_restoreclock(void); +extern char *sys_itoa(int n); + #endif /* ESPCONN_SOCKT_H_ */ diff --git a/app/include/user_config.h b/app/include/user_config.h index 084910e0..4ba65786 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -42,21 +42,34 @@ //#define DISABLE_STARTUP_BANNER -// Three separate build variants are now supported. The main difference is in the -// processing of numeric data types. If LUA_NUMBER_INTEGRAL is defined, then +// When using Lua 5.1, two different builds are now supported. +// The main difference is in the // processing of numeric data types. +// If LUA_NUMBER_INTEGRAL is defined, then // all numeric calculations are done in integer, with divide being an integer -// operations, and decimal fraction constants are illegal. Otherwise all -// numeric operations use floating point, though they are exact for integer -// expressions < 2^53. - -// The main advantage of INTEGRAL builds is that the basic internal storage unit, -// the TValue, is 8 bytes long. We have now reduced the size of FP TValues to -// 12 bytes rather than the previous 16 as this gives a material RAM saving with -// no performance loss. However, you can define LUA_DWORD_ALIGNED_TVALUES and -// this will force 16 byte TValues on FP builds. +// operation, and decimal fraction constants are illegal. +// Otherwise all floating point operations use doubles. All integer values +// can be represented exactly in floating point. //#define LUA_NUMBER_INTEGRAL -//#define LUA_DWORD_ALIGNED_TVALUES + +// When using Lua 5.3, two different builds are now supported. +// The main difference is in the processing of numeric data types. +// If LUA_NUMBER_64BITS is defined, then doubles are used to hold floating +// point numbers. Integers under 2^53 are representable exactly in doubles. +// Integers are held in 64-bit variables. +// Otherwise all floating point operations use floats. Only integers under 2^24 +// can be represented exactly in floating point. Integers are represented in 32 bit variables. +// Note that Lua 5.3 also supports Integers natively, but you have to be careful +// not to promote an integer to a floating point variable if you are using a float build +// as you can lose precision. + +//#define LUA_NUMBER_64BITS + +// The main advantage of INTEGRAL builds and non 64BITS builds is that the basic internal +// storage unit, the TValue, is 8 bytes long. For 64BITS builds, we have now reduced +// the size of FP TValues to 12 bytes rather than the previous 16 as this gives a +// material RAM saving with no performance loss. +// // The Lua Flash Store (LFS) allows you to store Lua code in Flash memory and diff --git a/app/lua/luaconf.h b/app/lua/luaconf.h index 0a21d0be..4d261ceb 100644 --- a/app/lua/luaconf.h +++ b/app/lua/luaconf.h @@ -181,6 +181,10 @@ #endif // #if !defined LUA_INTEGRAL_LONGLONG #endif // #if !defined LUA_NUMBER_INTEGRAL +#ifdef LUA_NUMBER_64BITS +#error Lua 5.1 does not support 64 bit inetegers. +#endif + /* @@ LUA_API is a mark for all core API functions. @@ LUALIB_API is a mark for all standard library functions. diff --git a/app/lua53/ldump.c b/app/lua53/ldump.c index 394cdd84..90bbdfaa 100644 --- a/app/lua53/ldump.c +++ b/app/lua53/ldump.c @@ -102,7 +102,7 @@ static void DumpNumber (lua_Number x, DumpState *D) { ** 0TTTNNNN or 1TTTNNNN (1NNNNNNN)* 0NNNNNNN */ static void DumpIntTT (lu_byte tt, lua_Integer y, DumpState *D) { - int x = y < 0 ? -(y + 1) : y; + lua_Integer x = y < 0 ? -(y + 1) : y; lu_byte buf[sizeof(lua_Integer) + 3]; lu_byte *b = buf + sizeof(buf) - 1; *b-- = x & 0x7f; x >>= 7; diff --git a/app/lua53/lobject.h b/app/lua53/lobject.h index c83efb23..5441f81a 100644 --- a/app/lua53/lobject.h +++ b/app/lua53/lobject.h @@ -134,12 +134,17 @@ typedef union Value { #define TValuefields Value value_; int tt_ +#ifdef LUA_USE_ESP +# pragma pack(4) +#endif typedef struct lua_TValue { TValuefields; } TValue; - +#ifdef LUA_USE_ESP +# pragma pack() +#endif /* macro defining a nil value */ #define NILCONSTANT {NULL}, LUA_TNIL diff --git a/app/lua53/luaconf.h b/app/lua53/luaconf.h index 0bb4bef8..c4b91d0d 100644 --- a/app/lua53/luaconf.h +++ b/app/lua53/luaconf.h @@ -85,9 +85,17 @@ # define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE #endif #endif -# define LUA_INT_TYPE LUA_INT_INT +#ifdef LUA_NUMBER_64BITS +# define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE +# define LUA_INT_TYPE LUA_INT_LONGLONG +#else # define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT -//# define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE +# define LUA_INT_TYPE LUA_INT_INT +#endif + +#ifdef LUA_NUMBER_INTEGRAL +#error LUA_NUMBER_INTEGRAL is not supported in LUA5.3 builds +#endif /* ** Configuration for Paths. diff --git a/app/mbedtls/app/Makefile b/app/mbedtls/app/Makefile index fa5dc92f..55c0baa5 100644 --- a/app/mbedtls/app/Makefile +++ b/app/mbedtls/app/Makefile @@ -17,6 +17,7 @@ GEN_LIBS = libapp.a endif +STD_CFLAGS=-std=gnu11 ############################################################# # Configuration i.e. compile options etc. diff --git a/app/mbedtls/app/espconn_mbedtls.c b/app/mbedtls/app/espconn_mbedtls.c index 82beaec9..15282b7b 100644 --- a/app/mbedtls/app/espconn_mbedtls.c +++ b/app/mbedtls/app/espconn_mbedtls.c @@ -42,6 +42,8 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #include "sys/socket.h" #include "sys/espconn_mbedtls.h" +#include "lwip/app/espconn_tcp.h" + static os_event_t lwIPThreadQueue[lwIPThreadQueueLen]; static bool lwIPThreadFlag = false; diff --git a/app/mbedtls/app/lwIPSocket.c b/app/mbedtls/app/lwIPSocket.c index 8c798f1c..4b351413 100644 --- a/app/mbedtls/app/lwIPSocket.c +++ b/app/mbedtls/app/lwIPSocket.c @@ -34,6 +34,7 @@ #include "ets_sys.h" #include "os_type.h" +#include #include "lwip/mem.h" #include "sys/socket.h" @@ -42,6 +43,9 @@ static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__; #endif +void *pvPortZalloc (size_t sz, const char *, unsigned); +void vPortFree (void *p, const char *, unsigned); + /** The global array of available sockets */ static lwIP_sock sockets[NUM_SOCKETS]; diff --git a/app/net/nodemcu_mdns.c b/app/net/nodemcu_mdns.c index 5750a9b7..119d7a38 100644 --- a/app/net/nodemcu_mdns.c +++ b/app/net/nodemcu_mdns.c @@ -1001,7 +1001,7 @@ mdns_set_servicename(const char *name) { char tmpBuf[128]; os_sprintf(tmpBuf, "_%s._tcp.local", name); if (service_name_with_suffix) { - os_free(service_name_with_suffix); + os_free((void *) service_name_with_suffix); } service_name_with_suffix = strdup(tmpBuf); } diff --git a/docs/build.md b/docs/build.md index e9f04e5f..18c94892 100644 --- a/docs/build.md +++ b/docs/build.md @@ -76,13 +76,31 @@ editing `BIT_RATE_DEFAULT` in `app/include/user_config.h`: Note that, by default, the firmware runs an auto-baudrate detection algorithm so that typing a few characters at boot time will cause the firmware to lock onto that baud rate (between 1200 and 230400). -### Integer build -By default a build will be generated supporting floating-point variables. +### Double build (Lua 5.3 only) +By default a build will be generated supporting floating point variables (floats) and integers. +To increase the precision of the floating point variables, a double build can be created. This +is also the default in the Lua 5.1 builds. The downside is that more memory is consumed when +storing variables. +You can change this +either by uncommenting `LUA_NUMBER_64BITS` in `app/include/user_config.h`: + +```c +//#define LUA_NUMBER_64BITS +``` + +OR by overriding this with the `make` command + +``` +make EXTRA_CCFLAGS="-DLUA_NUMBER_64BITS .... +``` + +### Integer build (Lua 5.1 only) +By default a build will be generated supporting floating-point variables (doubles). To reduce memory size an integer build can be created. You can change this either by uncommenting `LUA_NUMBER_INTEGRAL` in `app/include/user_config.h`: ```c -#define LUA_NUMBER_INTEGRAL +//#define LUA_NUMBER_INTEGRAL ``` OR by overriding this with the `make` command as it's [done during the CI diff --git a/docs/compiling.md b/docs/compiling.md index 731ee547..700a44f7 100644 --- a/docs/compiling.md +++ b/docs/compiling.md @@ -57,11 +57,30 @@ facilitates simple OTA updates to an LFS based Lua application; the absolute for facilitates factory installation of LFS based applications. Also note that the `app/lua/luac_cross` make and Makefile can be executed to build -just the `luac.cross` image. You must first ensure that the following option in -`app/include/user_config.h` is matched to your target configuration: +just the `luac.cross` image. You must first ensure that the following options in +`app/include/user_config.h` are matched to your target configuration: ```c -//#define LUA_NUMBER_INTEGRAL // uncomment if you want an integer build +// When using Lua 5.1, two different builds are now supported. +// The main difference is in the // processing of numeric data types. +// If LUA_NUMBER_INTEGRAL is defined, then +// all numeric calculations are done in integer, with divide being an integer +// operation, and decimal fraction constants are illegal. +// Otherwise all floating point operations use doubles. All integer values +// can be represented exactly in floating point. + +//#define LUA_NUMBER_INTEGRAL + +// When using Lua 5.3, two different builds are now supported. +// If LUA_NUMBER_64BITS is defined, then doubles are used to hold floating +// point numbers and integers are 64 bits long. Integers smaller than 2^53 can be i +// converted to doubles and back without any loss of precision. +// Otherwise all floating point operations use floats, and integers are 32-bit. +// Only integers under 2^24 can be represented exactly in floating point. +// Note that Lua 5.3 also supports Integers natively, but you have to be careful +// not to promote an integer to a floating point variable as you can lose precision. + +//#define LUA_NUMBER_64BITS ``` Note that the use of LFS and the LFS region size is now configured through the partition table. diff --git a/tools/update_buildinfo.sh b/tools/update_buildinfo.sh index 7caa09e5..747caee9 100755 --- a/tools/update_buildinfo.sh +++ b/tools/update_buildinfo.sh @@ -38,8 +38,12 @@ cat > $TEMPFILE << EndOfMessage #ifdef LUA_NUMBER_INTEGRAL #define BUILDINFO_BUILD_TYPE "integer" #else +#ifdef LUA_NUMBER_64BITS +#define BUILDINFO_BUILD_TYPE "double" +#else #define BUILDINFO_BUILD_TYPE "float" #endif +#endif #define USER_PROLOG "$USER_PROLOG" #define BUILDINFO_BRANCH "$BRANCH"