diff --git a/.gitignore b/.gitignore index e161118d..c0cc7b1e 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ dependencies.lock # ignore IDEA files .idea *.iml + +#ignore temp file for build infos +buildinfo.h diff --git a/components/modules/CMakeLists.txt b/components/modules/CMakeLists.txt index dd755908..a1525569 100644 --- a/components/modules/CMakeLists.txt +++ b/components/modules/CMakeLists.txt @@ -122,6 +122,7 @@ idf_component_register( # "-u _module_selected1" option to force the linker to include # the module. See components/core/include/module.h for further details on # how this works. +set(buildinfo_modules) set(modules_enabled) foreach(module_src ${module_srcs}) string(REPLACE ".c" "" module_name ${module_src}) @@ -129,9 +130,11 @@ foreach(module_src ${module_srcs}) set(mod_opt "CONFIG_NODEMCU_CMODULE_${module_ucase}") if (${${mod_opt}}) list(APPEND modules_enabled ${module_ucase}) + list(APPEND buildinfo_modules ${module_name}) endif() endforeach() message("Including the following modules: ${modules_enabled}") +string(REPLACE ";" "," buildinfo_modules "${buildinfo_modules}") foreach(mod ${modules_enabled}) target_link_libraries(${COMPONENT_LIB} "-u ${mod}_module_selected1") @@ -182,3 +185,77 @@ set_property( PROPERTY ADDITIONAL_MAKE_CLEAN_FILES eromfs.bin ) + +set(buildinfo_h +"#ifndef __BUILDINFO_H__ +#define __BUILDINFO_H__ + +#ifdef CONFIG_LUA_NUMBER_INT64 +#define BUILDINFO_BUILD_TYPE \"integer\" +#else +#ifdef CONFIG_LUA_NUMBER_DOUBLE +#define BUILDINFO_BUILD_TYPE \"double\" +#else +#define BUILDINFO_BUILD_TYPE \"float\" +#endif +#endif + +#define USER_PROLOG \"@user_prolog@\" +#define BUILDINFO_BRANCH \"@branch@\" +#define BUILDINFO_COMMIT_ID \"@commit_id@\" +#define BUILDINFO_RELEASE \"@release@\" +#define BUILDINFO_RELEASE_DTS \"@release_dts@\" +#define BUILDINFO_BUILD_DATE \"@build_date@\" +#define BUILDINFO_MODULES \"@buildinfo_modules@\" +#define BUILDINFO_LFS_SIZE \@buildinfo_lfs_size@\ + +#endif /* __BUILDINFO_H__ */ +" +) + +execute_process( + COMMAND date "+%Y-%m-%d %H:%M" + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE build_date +) + +execute_process( + COMMAND git rev-parse HEAD + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE commit_id +) + +execute_process( + COMMAND git rev-parse --abbrev-ref HEAD + COMMAND sed -E "s/[\/\\]+/_/g" + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE branch +) + +execute_process( + COMMAND git describe --tags --long + COMMAND sed -E "s/(.*)-(.*)-.*/\\1 +\\2/g" + COMMAND sed "s/ +0$//" + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE release +) + +execute_process( + COMMAND ${CMAKE_COMMAND} -E env TZ=UTC0 -- git show --quiet --date=format-local:%Y%m%d%H%M --format=%cd HEAD + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE release_dts +) + +execute_process( +COMMAND grep "^lfs,.*" ${PROJECT_DIR}/components/platform/partitions.csv +COMMAND cut -d, -f5 +COMMAND tr -d " " +COMMAND awk "{print strtonum( $1 )}" +OUTPUT_STRIP_TRAILING_WHITESPACE +OUTPUT_VARIABLE buildinfo_lfs_size +) + +file(CONFIGURE OUTPUT ${PROJECT_DIR}/components/platform/include/buildinfo.h + CONTENT "${buildinfo_h}" + @ONLY +) diff --git a/components/modules/node.c b/components/modules/node.c index 3a1a3c5d..9979a399 100644 --- a/components/modules/node.c +++ b/components/modules/node.c @@ -17,6 +17,9 @@ #include "rom/rtc.h" #include "freertos/FreeRTOS.h" #include "freertos/timers.h" +#include "esp_chip_info.h" +#include "esp_flash.h" +#include "user_version.h" static void restart_callback(TimerHandle_t timer) { (void)timer; @@ -409,6 +412,85 @@ static int node_dsleep (lua_State *L) } +static void add_int_field( lua_State* L, lua_Integer i, const char *name){ + lua_pushinteger(L, i); + lua_setfield(L, -2, name); +} + +static void add_string_field( lua_State* L, const char *s, const char *name) { + lua_pushstring(L, s); + lua_setfield(L, -2, name); +} + +static void get_lfs_config ( lua_State* ); + +static int node_info( lua_State* L ){ + const char* options[] = {"lfs", "hw", "sw_version", "build_config", "default", NULL}; + int option = luaL_checkoption (L, 1, options[4], options); + + switch (option) { + case 0: { // lfs + get_lfs_config(L); + return 1; + } + case 1: { // hw + uint32_t flash_size, flash_id; + esp_chip_info_t chip_info; + esp_chip_info(&chip_info); + if(esp_flash_get_size(NULL, &flash_size) != ESP_OK) { + ESP_LOGW("node", "Get flash size failed"); + flash_size = 0; + } + if(esp_flash_read_id(NULL, &flash_id) != ESP_OK) { + ESP_LOGW("node", "Get flash ID failed"); + flash_id = 0; + } + lua_createtable(L, 0, 7); + add_string_field(L, CONFIG_IDF_TARGET, "chip_model"); + add_int_field(L, chip_info.features, "chip_features"); + add_int_field(L, chip_info.revision / 100, "chip_major_rev"); + add_int_field(L, chip_info.revision % 100, "chip_minor_rev"); + add_int_field(L, chip_info.cores, "cpu_cores"); + add_int_field(L, flash_size / 1024, "flash_size"); // flash size in KB + add_int_field(L, flash_id, "flash_id"); + return 1; + } + // based on PR https://github.com/nodemcu/nodemcu-firmware/pull/3289 + case 2: { // sw_version + lua_createtable(L, 0, 8); + add_string_field(L, NODE_VERSION, "node_version"); + add_int_field(L, NODE_VERSION_MAJOR, "node_version_major"); + add_int_field(L, NODE_VERSION_MINOR, "node_version_minor"); + add_int_field(L, NODE_VERSION_REVISION, "node_version_revision"); + add_string_field(L, BUILDINFO_BRANCH, "git_branch"); + add_string_field(L, BUILDINFO_COMMIT_ID, "git_commit_id"); + add_string_field(L, BUILDINFO_RELEASE, "git_release"); + add_string_field(L, BUILDINFO_RELEASE_DTS, "git_commit_dts"); + return 1; + } + case 3: { // build_config + lua_createtable(L, 0, 5); + lua_pushboolean(L, CONFIG_MBEDTLS_TLS_ENABLED); + lua_setfield(L, -2, "ssl"); + add_int_field(L, BUILDINFO_LFS_SIZE, "lfs_size"); + add_string_field(L, BUILDINFO_BUILD_TYPE, "number_type"); + add_string_field(L, BUILDINFO_MODULES, "modules"); + #if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM + add_string_field(L, "uart", "esp_console"); + #elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + add_string_field(L, "usb_serial_jtag", "esp_console"); + #elif CONFIG_ESP_CONSOLE_USB_CDC + add_string_field(L, "usb_cdc", "esp_console"); + #endif + return 1; + } + default: { // default + lua_newtable(L); + return 1; + } + } +} + // Lua: input("string") static int node_input( lua_State* L ) { @@ -796,12 +878,6 @@ static int node_lfslist (lua_State *L) { //== node.LFS Table emulator ==============================================// - -static void add_int_field( lua_State* L, lua_Integer i, const char *name){ - lua_pushinteger(L, i); - lua_setfield(L, -2, name); -} - static void get_lfs_config ( lua_State* L ){ int config[5]; lua_getlfsconfig(L, config); @@ -885,6 +961,7 @@ LROT_BEGIN(node, NULL, 0) LROT_FUNCENTRY( flashindex, node_lfsindex ) LROT_TABENTRY( LFS, node_lfs ) LROT_FUNCENTRY( heap, node_heap ) + LROT_FUNCENTRY( info, node_info ) LROT_FUNCENTRY( input, node_input ) LROT_FUNCENTRY( output, node_output ) LROT_FUNCENTRY( osprint, node_osprint ) diff --git a/components/platform/include/user_version.h b/components/platform/include/user_version.h index 82d47f4f..1cea59a1 100644 --- a/components/platform/include/user_version.h +++ b/components/platform/include/user_version.h @@ -1,6 +1,8 @@ #ifndef __USER_VERSION_H__ #define __USER_VERSION_H__ +#include + #define NODE_VERSION_MAJOR 0U #define NODE_VERSION_MINOR 0U #define NODE_VERSION_REVISION 0U @@ -8,7 +10,7 @@ #define NODE_VERSION "NodeMCU ESP32" #ifndef BUILD_DATE -#define BUILD_DATE "unspecified" +#define BUILD_DATE BUILDINFO_BUILD_DATE #endif #define SDK_VERSION IDF_VER diff --git a/docs/modules/node.md b/docs/modules/node.md index a86b814d..66772ee7 100644 --- a/docs/modules/node.md +++ b/docs/modules/node.md @@ -191,6 +191,74 @@ none system heap size left in bytes (number) +## node.info() + +Returns information about hardware, software version and build configuration. + +#### Syntax +`node.info([group])` + +#### Parameters +`group` A designator for a group of properties. May be one of `"hw"`, `"sw_version"`, `"build_config"`, `"lfs"`. If omitted the empty table is returned. + +#### Returns +If a `group` is given the return value will be a table containing the following elements: + +- for `group` = `"hw"` + - `chip_model` (string) one of "ESP32", "ESP32S2", "ESP32S3", "ESP32C3", "ESP32C2", "ESP32C6", "ESP32H2" + - `chip_features` (number) bit mask of chip feature flags + - BIT(0), Chip has embedded flash memory + - BIT(1), Chip has 2.4GHz WiFi + - BIT(4), Chip has Bluetooth LE + - BIT(5), Chip has Bluetooth Classic + - BIT(6), Chip has IEEE 802.15.4 + - BIT(7), Chip has embedded psram + - `chip_major_rev` (number) chip revision; wafer major version + - `chip_minor_rev` (number) chip revision; wafer minor version + - `cpu_cores` (number) number of CPU cores + - `flash_size` (number) flash size in KB + - `flash_id` (number) flash ID + +- for `group` = `"sw_version"` + - `git_branch` (string) + - `git_commit_id` (string) + - `git_release` (string) release name +additional commits e.g. "2.0.0-master_20170202 +403" + - `git_commit_dts` (string) commit timestamp in an ordering format. e.g. "201908111200" + - `node_version_major` (number) + - `node_version_minor` (number) + - `node_version_revision` (number) + - `node_version` (string) + +- for `group` = `"build_config"` + - `esp_console` (string) one of `uart`, `usb_serial_jtag` or `usb_cdc` + - `lfs_size` (number) as defined at build time + - `modules` (string) comma separated list + - `number_type` (string) `integer`, `float` or `double` + - `ssl` (boolean) + +- for `group` = `"lfs"` + - `lfs_base` (number) Flash offset of selected LFS region + - `lfs_mapped` (number) Mapped memory address of selected LFS region + - `lfs_size` (number) size of selected LFS region + - `lfs_used` (number) actual size used by current LFS image + +!!! attention + + Not providing a `group` will result in the empty table being returned. + +#### Example + +```lua +for k,v in pairs(node.info("build_config")) do + print (k,v) +end +``` + +```lua +print(node.info("sw_version").git_release) +``` + + ## node.input() Submits a string to the Lua interpreter. Similar to `pcall(loadstring(str))`, but without the single-line limitation.