diff --git a/CMakeLists.txt b/CMakeLists.txt
index fb6d6b5afa6..851d1488eca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -88,6 +88,7 @@ set(LIBRARY_SRCS
libraries/HTTPClient/src/HTTPClient.cpp
libraries/HTTPUpdate/src/HTTPUpdate.cpp
libraries/LittleFS/src/LittleFS.cpp
+ libraries/Insights/src/Insights.cpp
libraries/I2S/src/I2S.cpp
libraries/NetBIOS/src/NetBIOS.cpp
libraries/Preferences/src/Preferences.cpp
@@ -184,6 +185,7 @@ set(includedirs
libraries/HTTPClient/src
libraries/HTTPUpdate/src
libraries/LittleFS/src
+ libraries/Insights/src
libraries/I2S/src
libraries/NetBIOS/src
libraries/Preferences/src
diff --git a/boards.txt b/boards.txt
index 29ea4abb927..18ca70f534c 100644
--- a/boards.txt
+++ b/boards.txt
@@ -17110,7 +17110,7 @@ deneyapminiv2.menu.DebugLevel.verbose.build.code_debug=5
deneyapminiv2.menu.EraseFlash.none=Disabled
deneyapminiv2.menu.EraseFlash.none.upload.erase_cmd=
deneyapminiv2.menu.EraseFlash.all=Enabled
-deneyapminiv2.menu.EraseFlash.all.upload.erase_cmd=-e
+deneyapminiv2.menu.EraseFlash.all.upload.erase_cmd=-
##############################################################
diff --git a/docs/source/api/insights.rst b/docs/source/api/insights.rst
new file mode 100644
index 00000000000..5818a326f3d
--- /dev/null
+++ b/docs/source/api/insights.rst
@@ -0,0 +1,274 @@
+############
+ESP Insights
+############
+
+About
+-----
+
+ESP Insights is a remote diagnostics solution that allows users to remotely monitor the health of ESP devices in the field.
+
+Developers normally prefer debugging issues by physically probing them using gdb or observing the logs. This surely helps debug issues, but there are often cases wherein issues are seen only in specific environments under specific conditions. Even things like casings and placement of the product can affect the behaviour. A few examples are
+
+- Wi-Fi disconnections for a smart switch concealed in a wall.
+- Smart speakers crashing during some specific usage pattern.
+- Appliance frequently rebooting due to power supply issues.
+
+Additional information about ESP Insights can be found `here `__.
+
+ESP Insights Agent API
+----------------------
+
+Insights.begin
+**************
+
+This initializes the ESP Insights agent.
+
+.. code-block:: arduino
+
+ bool begin(const char *auth_key, const char *node_id = NULL, uint32_t log_type = 0xFFFFFFFF, bool alloc_ext_ram = false);
+
+* ``auth_key`` Auth key generated using Insights dashboard
+* ``log_type`` Type of logs to be captured (value can be a mask of ESP_DIAG_LOG_TYPE_ERROR, ESP_DIAG_LOG_TYPE_WARNING and ESP_DIAG_LOG_TYPE_EVENT)
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.send
+*************
+
+Read insights data from buffers and send it to the cloud. Call to this function is asynchronous, it may take some time to send the data.
+
+.. code-block:: arduino
+
+ bool sendData()
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.end
+************
+
+Deinitialize ESP Insights.
+
+.. code-block:: arduino
+
+ void end();
+
+Insights.disable
+****************
+
+Disable ESP Insights.
+
+.. code-block:: arduino
+
+ void disable();
+
+ESP Insights Metrics API
+------------------------
+
+`metrics` object of `Insights` class expose API's for using metrics.
+
+Insights.metrics.addX
+*********************
+
+Register a metric of type X, where X is one of: Bool, Int, Uint, Float, String, IPv4 or MAC
+
+.. code-block:: arduino
+
+ bool addX(const char *tag, const char *key, const char *label, const char *path);
+
+* ``tag`` : Tag of metrics
+* ``key`` : Unique key for the metrics
+* ``label`` : Label for the metrics
+* ``path`` : Hierarchical path for key, must be separated by '.' for more than one level
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.metrics.remove
+***********************
+
+Unregister a diagnostics metrics
+
+.. code-block:: arduino
+
+ bool remove(const char *key);
+
+* ``key`` : Key for the metrics
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.metrics.removeAll
+**************************
+
+Unregister all previously registered metrics
+
+.. code-block:: arduino
+
+ bool removeAll();
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.metrics.setX
+*********************
+
+Add metrics of type X to storage, where X is one of: Bool, Int, Uint, Float, String, IPv4 or MAC
+
+.. code-block:: arduino
+
+ bool setX(const char *key, const void val);
+
+* ``key`` : Key of metrics
+* ``val`` : Value of metrics
+
+This function will return
+
+1. `ESP_OK` : On success
+2. Error in case of failure
+
+Insights.metrics.dumpHeap
+*************************
+
+Dumps the heap metrics and prints them to the console.
+This API collects and reports metrics value at any give point in time.
+
+.. code-block:: arduino
+
+ bool dumpHeap();
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.metrics.dumpWiFi
+*************************
+
+Dumps the wifi metrics and prints them to the console.
+This API can be used to collect wifi metrics at any given point in time.
+
+.. code-block:: arduino
+
+ bool dumpWiFi();
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.metrics.setHeapPeriod
+******************************
+
+Reset the periodic interval
+By default, heap metrics are collected every 30 seconds, this function can be used to change the interval.
+If the interval is set to 0, heap metrics collection disabled.
+
+.. code-block:: arduino
+
+ void setHeapPeriod(uint32_t period);
+
+* ``period`` : Period interval in seconds
+
+Insights.metrics.setWiFiPeriod
+******************************
+
+Reset the periodic interval
+By default, wifi metrics are collected every 30 seconds, this function can be used to change the interval.
+If the interval is set to 0, wifi metrics collection disabled.
+
+.. code-block:: arduino
+
+ void setHeapPeriod(uint32_t period);
+
+* ``period`` : Period interval in seconds
+
+ESP Insights Variables API
+--------------------------
+
+`variables` object of `Insights` class expose API's for using variables.
+
+Insights.variables.addX
+***********************
+
+Register a variable of type X, where X is one of: Bool, Int, Uint, Float, String, IPv4 or MAC
+
+.. code-block:: arduino
+
+ bool addX(const char *tag, const char *key, const char *label, const char *path);
+
+* ``tag`` : Tag of variable
+* ``key`` : Unique key for the variable
+* ``label`` : Label for the variable
+* ``path`` : Hierarchical path for key, must be separated by '.' for more than one level
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.variables.remove
+*************************
+
+Unregister a diagnostics variable
+
+.. code-block:: arduino
+
+ bool remove(const char *key);
+
+* ``key`` : Key for the variable
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.variables.removeAll
+****************************
+
+Unregister all previously registered variables
+
+.. code-block:: arduino
+
+ bool unregisterAll();
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Insights.variables.setX
+***********************
+
+Add variable of type X to storage, where X is one of: Bool, Int, Uint, Float, String, IPv4 or MAC
+
+.. code-block:: arduino
+
+ bool setX(const char *key, const void val);
+
+* ``key`` : Key of metrics
+* ``val`` : Value of metrics
+
+This function will return
+
+1. true : On success
+2. false in case of failure
+
+Example
+-------
+
+To get started with Insights, you can try:
+
+.. literalinclude:: ../../../libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino
+ :language: arduino
diff --git a/libraries/Insights/examples/DiagnosticsSmokeTest/DiagnosticsSmokeTest.ino b/libraries/Insights/examples/DiagnosticsSmokeTest/DiagnosticsSmokeTest.ino
new file mode 100644
index 00000000000..7fa3eea79be
--- /dev/null
+++ b/libraries/Insights/examples/DiagnosticsSmokeTest/DiagnosticsSmokeTest.ino
@@ -0,0 +1,97 @@
+#include "Insights.h"
+#include "WiFi.h"
+#include "inttypes.h"
+#include "esp_err.h"
+
+const char insights_auth_key[] = "";
+
+#define WIFI_SSID ""
+#define WIFI_PASSPHRASE ""
+
+#define MAX_CRASHES 5
+#define MAX_PTRS 30
+#define TAG "sketch"
+
+RTC_NOINIT_ATTR static uint32_t s_reset_count;
+static void *s_ptrs[MAX_PTRS];
+
+static void smoke_test()
+{
+ int dice;
+ int count = 0;
+ bool allocating = false;
+
+ while (1) {
+ dice = esp_random() % 500;
+ log_i("dice=%d", dice);
+ if (dice > 0 && dice < 150) {
+ log_e("[count][%d]", count);
+ } else if (dice > 150 && dice < 300) {
+ log_w("[count][%d]", count);
+ } else if (dice > 300 && dice < 470) {
+ Insights.event(TAG, "[count][%d]", count);
+ } else {
+ /* 30 in 500 probability to crash */
+ if (s_reset_count > MAX_CRASHES) {
+ Insights.event(TAG, "[count][%d]", count);
+ } else {
+ log_e("[count][%d] [crash_count][%" PRIu32 "] [excvaddr][0x0f] Crashing...", count, s_reset_count);
+ *(int *)0x0F = 0x10;
+ }
+ }
+
+ Insights.metrics.dumpHeap();
+ if (count % MAX_PTRS == 0) {
+ allocating = !allocating;
+ log_i("Allocating:%s\n", allocating ? "true" : "false");
+ }
+ if (allocating) {
+ uint32_t size = 1024 * (esp_random() % 8);
+ void *p = malloc(size);
+ if (p) {
+ memset(p, size, 'A' + (esp_random() % 26));
+ log_i("Allocated %" PRIu32 " bytes", size);
+ }
+ s_ptrs[count % MAX_PTRS] = p;
+ } else {
+ free(s_ptrs[count % MAX_PTRS]);
+ s_ptrs[count % MAX_PTRS] = NULL;
+ log_i("Freeing some memory...");
+ }
+
+ count++;
+ delay(1000);
+ }
+}
+
+void setup()
+{
+ Serial.begin(115200);
+ WiFi.mode(WIFI_STA);
+ WiFi.begin(WIFI_SSID, WIFI_PASSPHRASE);
+ while (WiFi.status() != WL_CONNECTED) {
+ delay(500);
+ Serial.print(".");
+ }
+ Serial.println("");
+ Serial.println("WiFi connected");
+
+ if(!Insights.begin(insights_auth_key)){
+ return;
+ }
+ Serial.println("=========================================");
+ Serial.printf("ESP Insights enabled Node ID %s\n", Insights.nodeID());
+ Serial.println("=========================================");
+
+ if (esp_reset_reason() == ESP_RST_POWERON) {
+ s_reset_count = 1;
+ } else {
+ s_reset_count++;
+ }
+}
+
+void loop()
+{
+ smoke_test();
+ delay(100);
+}
diff --git a/libraries/Insights/examples/DiagnosticsSmokeTest/README.md b/libraries/Insights/examples/DiagnosticsSmokeTest/README.md
new file mode 100644
index 00000000000..9094eeca5d2
--- /dev/null
+++ b/libraries/Insights/examples/DiagnosticsSmokeTest/README.md
@@ -0,0 +1,45 @@
+# Smoke Test App
+
+## What to expect in this example?
+
+- This example is expected to exercise the various features of the ESP Insights framework
+- As a smoke test, this allows you to validate, by a quick perusal of the ESP Insights dashboard, the functioning of all the high-level features
+
+
+## End-to-End Tests
+
+### Lifecycle of the test (Hard reset resets the cycle)
+* Device boots up and logs errors/warnings/events in random order every 10 seconds
+* Every error/warning/event log with "diag_smoke" tag is associated with an incremental counter
+* There's a 30/500 probability that device will crash, this is done for verification of crash
+* Device will crash only five times and hard reset will reset the counter to 1
+* On sixth boot onwards device will not crash and logs errors/warnings/events and adds heap metrics
+
+### Facilitate the Auth Key
+In this example we will be using the auth key that we downloaded while [setting up ESP Insights account](https://github.com/espressif/esp-insights/tree/main/examples#set-up-esp-insights-account).
+
+Copy Auth Key to the example
+```
+const char insights_auth_key[] = "";
+```
+
+### Enter WiFi Credentials
+Inside the example sketch, enter your WiFi credentials in `WIFI_SSID` and `WIFI_PASSPHRASE` macros.
+
+### Setup
+* Build and flash the sketch and monitor the console
+* Device will eventually crash after some time
+* Before every crash you will see below log print
+```
+E (75826) diag_smoke: [count][7] [crash_count][1] [excvaddr][0x0f] Crashing...
+// [count][7]: count associated with the log
+// [crash_count][1]: This is the first crash since device boot up, this number will increment as the crash count increases
+// [excvaddr][0x0f]: Exception vaddr, will see this in crash verification part below
+```
+* You'll see five crashes([crash_count][5]) and after that device will not crash and will keep on logging and adding metrics
+* Onwards this point keep device running for more than 30 minutes
+* Now we are all set to visit the [dashboard](https://dashboard.insights.espressif.com)
+* Select the node-id printed on the console, look for the below log. It is printed early when device boots up
+```
+ESP Insights enabled for Node ID ----- wx3vEoGgJPk7Rn5JvRUFs9
+```
\ No newline at end of file
diff --git a/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino b/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino
new file mode 100644
index 00000000000..39cac0c13a5
--- /dev/null
+++ b/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino
@@ -0,0 +1,31 @@
+#include "Insights.h"
+#include "WiFi.h"
+
+const char insights_auth_key[] = "";
+
+#define WIFI_SSID ""
+#define WIFI_PASSPHRASE ""
+
+void setup()
+{
+ Serial.begin(115200);
+ WiFi.mode(WIFI_STA);
+ WiFi.begin(WIFI_SSID, WIFI_PASSPHRASE);
+ while (WiFi.status() != WL_CONNECTED) {
+ delay(500);
+ Serial.print(".");
+ }
+ Serial.println("");
+ Serial.println("WiFi connected");
+ if(!Insights.begin(insights_auth_key)){
+ return;
+ }
+ Serial.println("=========================================");
+ Serial.printf("ESP Insights enabled Node ID %s\n", Insights.nodeID());
+ Serial.println("=========================================");
+}
+
+void loop()
+{
+ delay(1000);
+}
diff --git a/libraries/Insights/examples/MinimalDiagnostics/README.md b/libraries/Insights/examples/MinimalDiagnostics/README.md
new file mode 100644
index 00000000000..35faa8d1788
--- /dev/null
+++ b/libraries/Insights/examples/MinimalDiagnostics/README.md
@@ -0,0 +1,43 @@
+# Minimal Diagnostics example
+- [What to expect in this example](#what-to-expect-in-this-example)
+- [Try out the example](#try-out-the-example)
+- [Insights Dashboard](#insights-dashboard)
+
+## What to expect in this example?
+- This example demonstrates the use of ESP Insights framework in minimal way
+- Device will try to connect with the configured WiFi network
+- ESP Insights is enabled in this example, so any error/warning logs, crashes will be reported to cloud
+- This example collects heap and wifi metrics every 10 minutes and network variables are collected when they change
+
+## Try out the example
+
+### Facilitate the Auth Key
+In this example we will be using the auth key that we downloaded while [setting up ESP Insights account](https://github.com/espressif/esp-insights/tree/main/examples#set-up-esp-insights-account).
+
+Copy Auth Key to the example
+```
+const char insights_auth_key[] = "";
+```
+
+### Enter WiFi Credentials
+Inside the example sketch, enter your WiFi credentials in `WIFI_SSID` and `WIFI_PASSPHRASE` macros.
+
+### Get the Node ID
+- Start the Serial monitor
+
+- Once the device boots, it will connect to the Wi-Fi network, look for logs similar to below and make a note of Node ID.
+```
+I (4161) esp_insights: =========================================
+I (4171) esp_insights: Insights enabled for Node ID 246F2880371C
+I (4181) esp_insights: =========================================
+```
+
+
+## Insights Dashboard
+Once everything is set up, any diagnostics information reported will show up on the [Insights Dashboard](https://dashboard.insights.espressif.com). Sign in using the your credentials.
+
+
+### Monitor the device diagnostics
+Visit [Nodes](https://dashboard.insights.espressif.com/home/nodes) section on the dashboard and click on the Node ID to monitor device diagnostics information.
+
+> Note: Diagnostics data is reported dynamically or when the buffers are filled to configured threshold. So, it can take some time for the logs to reflect on the dashboard. Moreover, if a large number of logs are generated then data will be sent to cloud but, if it fails(eg reasons: Wi-Fi failure, No internet) then any newer logs will be dropped.
diff --git a/libraries/Insights/library.properties b/libraries/Insights/library.properties
new file mode 100644
index 00000000000..489aa298618
--- /dev/null
+++ b/libraries/Insights/library.properties
@@ -0,0 +1,8 @@
+name=ESP Insights
+version=1.0.0
+author=Sanket Wadekar
+maintainer=Sanket Wadekar
+sentence=ESP Insights
+paragraph=With this library you can remotely monitor your device error logs, Network variables, WiFi/Heap Metrics, and also custom varibles / metrics.
+url=https://insights.espressif.com
+architectures=esp32
diff --git a/libraries/Insights/src/Insights.cpp b/libraries/Insights/src/Insights.cpp
new file mode 100644
index 00000000000..0ec65e86727
--- /dev/null
+++ b/libraries/Insights/src/Insights.cpp
@@ -0,0 +1,283 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#include "Insights.h"
+#ifdef CONFIG_ESP_INSIGHTS_ENABLED
+#include "esp_insights.h"
+#include "esp_diagnostics.h"
+#include "esp_diagnostics_metrics.h"
+#include "esp_diagnostics_system_metrics.h"
+#include "esp_diagnostics_variables.h"
+#include "esp_diagnostics_network_variables.h"
+
+const char * ERROR_INSIGHTS_NOT_INIT = "ESP Insights not initialized";
+
+#define BOOL_FN_OR_ERROR(f,e) \
+ if(!initialized){ \
+ log_e("%s",ERROR_INSIGHTS_NOT_INIT); \
+ return false; \
+ } \
+ esp_err_t err = f; \
+ if (err != ESP_OK) { \
+ log_e("ESP Insights " e ", err:0x%x", err); \
+ } \
+ return err == ESP_OK;
+
+#define BOOL_FN_OR_ERROR_ARG(f,e,a) \
+ if(!initialized){ \
+ log_e("%s",ERROR_INSIGHTS_NOT_INIT); \
+ return false; \
+ } \
+ esp_err_t err = f; \
+ if (err != ESP_OK) { \
+ log_e("ESP Insights " e ", err:0x%x", a, err); \
+ } \
+ return err == ESP_OK;
+
+#define VOID_FN_OR_ERROR(f) \
+ if(!initialized){ \
+ log_e("%s",ERROR_INSIGHTS_NOT_INIT); \
+ return; \
+ } \
+ f;
+
+ESPInsightsClass::ESPInsightsClass(): initialized(false){}
+
+ESPInsightsClass::~ESPInsightsClass(){
+ end();
+}
+
+bool ESPInsightsClass::begin(const char *auth_key, const char *node_id, uint32_t log_type, bool alloc_ext_ram){
+ if(!initialized){
+ if(log_type == 0xFFFFFFFF){
+ log_type = (ESP_DIAG_LOG_TYPE_ERROR | ESP_DIAG_LOG_TYPE_WARNING | ESP_DIAG_LOG_TYPE_EVENT);
+ }
+ esp_insights_config_t config = {.log_type = log_type, .node_id = node_id, .auth_key = auth_key, .alloc_ext_ram = alloc_ext_ram};
+ esp_err_t err = esp_insights_init(&config);
+ if (err != ESP_OK) {
+ log_e("Failed to initialize ESP Insights, err:0x%x", err);
+ }
+ initialized = err == ESP_OK;
+ metrics.setInitialized(initialized);
+ variables.setInitialized(initialized);
+ } else {
+ log_i("ESP Insights already initialized");
+ }
+ return initialized;
+}
+
+void ESPInsightsClass::end(){
+ if(initialized){
+ esp_insights_deinit();
+ initialized = false;
+ metrics.setInitialized(initialized);
+ variables.setInitialized(initialized);
+ }
+}
+
+const char * ESPInsightsClass::nodeID(){
+ if(!initialized){
+ log_e("%s",ERROR_INSIGHTS_NOT_INIT);
+ return "";
+ }
+ return esp_insights_get_node_id();
+}
+
+bool ESPInsightsClass::event(const char *tag, const char *format, ...){
+ if(!initialized){
+ log_e("%s",ERROR_INSIGHTS_NOT_INIT);
+ return false;
+ }
+
+ char loc_buf[64];
+ char * temp = loc_buf;
+ va_list arg;
+ va_list copy;
+ va_start(arg, format);
+ va_copy(copy, arg);
+ int len = vsnprintf(temp, sizeof(loc_buf), format, copy);
+ va_end(copy);
+ if(len < 0) {
+ va_end(arg);
+ return false;
+ };
+ if(len >= (int)sizeof(loc_buf)){ // comparation of same sign type for the compiler
+ temp = (char*) malloc(len+1);
+ if(temp == NULL) {
+ va_end(arg);
+ return false;
+ }
+ len = vsnprintf(temp, len+1, format, arg);
+ }
+ va_end(arg);
+ esp_err_t err = esp_diag_log_event(tag, "%s", temp);
+ if(temp != loc_buf){
+ free(temp);
+ }
+ if (err != ESP_OK) {
+ log_e("Failed to send ESP Insights event, err:0x%x", err);
+ }
+ return err == ESP_OK;
+}
+
+bool ESPInsightsClass::send(){
+ BOOL_FN_OR_ERROR(esp_insights_send_data(),"Failed to send");
+}
+
+void ESPInsightsClass::dumpTasksStatus(){
+ VOID_FN_OR_ERROR(esp_diag_task_snapshot_dump());
+}
+
+// ESPInsightsMetricsClass
+
+bool ESPInsightsMetricsClass::addBool(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_BOOL),"Failed to add metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::addInt(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_INT),"Failed to add metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::addUint(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_UINT),"Failed to add metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::addFloat(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_FLOAT),"Failed to add metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::addString(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_STR),"Failed to add metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::addIPv4(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_IPv4),"Failed to add metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::addMAC(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_MAC),"Failed to add metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::setBool(const char *key, bool b){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_add_bool(key, b),"Failed to set metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::setInt(const char *key, int32_t i){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_add_int(key, i),"Failed to set metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::setUint(const char *key, uint32_t u){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_add_uint(key, u),"Failed to set metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::setFloat(const char *key, float f){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_add_float(key, f),"Failed to set metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::setString(const char *key, const char *str){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_add_str(key, str),"Failed to set metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::setIPv4(const char *key, uint32_t ip){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_add_ipv4(key, ip),"Failed to set metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::setMAC(const char *key, uint8_t *mac){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_add_mac(key, mac),"Failed to set metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::remove(const char *key){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_metrics_unregister(key),"Failed to remove metric '%s'",key);
+}
+
+bool ESPInsightsMetricsClass::removeAll(){
+ BOOL_FN_OR_ERROR(esp_diag_metrics_unregister_all(),"Failed to remove metrics");
+}
+
+void ESPInsightsMetricsClass::setHeapPeriod(uint32_t seconds){
+ VOID_FN_OR_ERROR(esp_diag_heap_metrics_reset_interval(seconds));
+}
+
+bool ESPInsightsMetricsClass::dumpHeap(){
+ BOOL_FN_OR_ERROR(esp_diag_heap_metrics_dump(),"Failed to send heap metrics");
+}
+
+void ESPInsightsMetricsClass::setWiFiPeriod(uint32_t seconds){
+ VOID_FN_OR_ERROR(esp_diag_wifi_metrics_reset_interval(seconds));
+}
+
+bool ESPInsightsMetricsClass::dumpWiFi(){
+ BOOL_FN_OR_ERROR(esp_diag_wifi_metrics_dump(),"Failed to send wifi metrics");
+}
+
+// ESPInsightsVariablesClass
+
+bool ESPInsightsVariablesClass::addBool(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_BOOL),"Failed to add variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::addInt(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_INT),"Failed to add variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::addUint(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_UINT),"Failed to add variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::addFloat(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_FLOAT),"Failed to add variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::addString(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_STR),"Failed to add variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::addIPv4(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_IPv4),"Failed to add variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::addMAC(const char *tag, const char *key, const char *label, const char *path){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_register(tag, key, label, path, ESP_DIAG_DATA_TYPE_MAC),"Failed to add variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::setBool(const char *key, bool b){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_add_bool(key, b),"Failed to set variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::setInt(const char *key, int32_t i){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_add_int(key, i),"Failed to set variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::setUint(const char *key, uint32_t u){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_add_uint(key, u),"Failed to set variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::setFloat(const char *key, float f){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_add_float(key, f),"Failed to set variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::setString(const char *key, const char *str){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_add_str(key, str),"Failed to set variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::setIPv4(const char *key, uint32_t ip){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_add_ipv4(key, ip),"Failed to set variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::setMAC(const char *key, uint8_t *mac){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_add_mac(key, mac),"Failed to set variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::remove(const char *key){
+ BOOL_FN_OR_ERROR_ARG(esp_diag_variable_unregister(key),"Failed to remove variable '%s'",key);
+}
+
+bool ESPInsightsVariablesClass::removeAll(){
+ BOOL_FN_OR_ERROR(esp_diag_variable_unregister_all(),"Failed to remove variables");
+}
+
+ESPInsightsClass Insights;
+
+#endif
diff --git a/libraries/Insights/src/Insights.h b/libraries/Insights/src/Insights.h
new file mode 100644
index 00000000000..b950b937b14
--- /dev/null
+++ b/libraries/Insights/src/Insights.h
@@ -0,0 +1,118 @@
+/*
+ * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#pragma once
+#include "sdkconfig.h"
+#ifdef CONFIG_ESP_INSIGHTS_ENABLED
+#include "Arduino.h"
+
+#ifdef __cplusplus
+
+class ESPInsightsMetricsClass
+{
+ private:
+ bool initialized;
+
+ public:
+ ESPInsightsMetricsClass():initialized(false){}
+
+ bool addBool(const char *tag, const char *key, const char *label, const char *path);
+ bool addInt(const char *tag, const char *key, const char *label, const char *path);
+ bool addUint(const char *tag, const char *key, const char *label, const char *path);
+ bool addFloat(const char *tag, const char *key, const char *label, const char *path);
+ bool addString(const char *tag, const char *key, const char *label, const char *path);
+ bool addIPv4(const char *tag, const char *key, const char *label, const char *path);
+ bool addMAC(const char *tag, const char *key, const char *label, const char *path);
+
+ bool setBool(const char *key, bool b);
+ bool setInt(const char *key, int32_t i);
+ bool setUint(const char *key, uint32_t u);
+ bool setFloat(const char *key, float f);
+ bool setString(const char *key, const char *str);
+ bool setIPv4(const char *key, uint32_t ip);
+ bool setMAC(const char *key, uint8_t *mac);
+
+ bool remove(const char *key);
+ bool removeAll();
+
+ void setHeapPeriod(uint32_t seconds);
+ void setWiFiPeriod(uint32_t seconds);
+
+ bool dumpHeap();
+ bool dumpWiFi();
+
+ //internal use
+ void setInitialized(bool init){ initialized = init; }
+};
+
+class ESPInsightsVariablesClass
+{
+ private:
+ bool initialized;
+
+ public:
+ ESPInsightsVariablesClass():initialized(false){}
+
+ bool addBool(const char *tag, const char *key, const char *label, const char *path);
+ bool addInt(const char *tag, const char *key, const char *label, const char *path);
+ bool addUint(const char *tag, const char *key, const char *label, const char *path);
+ bool addFloat(const char *tag, const char *key, const char *label, const char *path);
+ bool addString(const char *tag, const char *key, const char *label, const char *path);
+ bool addIPv4(const char *tag, const char *key, const char *label, const char *path);
+ bool addMAC(const char *tag, const char *key, const char *label, const char *path);
+
+ bool setBool(const char *key, bool b);
+ bool setInt(const char *key, int32_t i);
+ bool setUint(const char *key, uint32_t u);
+ bool setFloat(const char *key, float f);
+ bool setString(const char *key, const char *str);
+ bool setIPv4(const char *key, uint32_t ip);
+ bool setMAC(const char *key, uint8_t *mac);
+
+ bool remove(const char *key);
+ bool removeAll();
+
+ //internal use
+ void setInitialized(bool init){ initialized = init; }
+};
+
+class ESPInsightsClass
+{
+ private:
+ bool initialized;
+
+ public:
+ ESPInsightsMetricsClass metrics;
+ ESPInsightsVariablesClass variables;
+
+ ESPInsightsClass();
+ ~ESPInsightsClass();
+
+ bool begin(const char *auth_key, const char *node_id = NULL, uint32_t log_type = 0xFFFFFFFF, bool alloc_ext_ram = false);
+ void end();
+ bool send();
+ const char * nodeID();
+
+ void dumpTasksStatus();
+
+ bool event(const char *tag, const char *format, ...);
+};
+
+extern ESPInsightsClass Insights;
+
+extern "C"
+{
+#endif
+
+#include "esp_err.h"
+#include "esp_log.h"
+esp_err_t esp_diag_log_event(const char *tag, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+#define insightsEvent(tag, format, ...) {esp_diag_log_event(tag, "EV (%" PRIu32 ") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__);}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform.txt b/platform.txt
index f8100935bad..5b22ba87d73 100644
--- a/platform.txt
+++ b/platform.txt
@@ -24,6 +24,9 @@ tools.esp_ota.cmd.windows="{runtime.platform.path}/tools/espota.exe" -r
tools.gen_esp32part.cmd=python3 "{runtime.platform.path}/tools/gen_esp32part.py"
tools.gen_esp32part.cmd.windows="{runtime.platform.path}/tools/gen_esp32part.exe"
+tools.gen_insights_pkg.cmd=python3 "{runtime.platform.path}"/tools/gen_insights_package.py
+tools.gen_insights_pkg.cmd.windows="{runtime.platform.path}/tools/gen_insights_package.exe"
+
compiler.path={runtime.tools.{build.tarch}-{build.target}-elf-gcc.path}/bin/
compiler.sdk.path={runtime.platform.path}/tools/sdk/{build.mcu}
compiler.prefix={build.tarch}-{build.target}-elf-
@@ -211,10 +214,15 @@ recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-Wl,--Map={build
recipe.objcopy.partitions.bin.pattern={tools.gen_esp32part.cmd} -q "{build.path}/partitions.csv" "{build.path}/{build.project_name}.partitions.bin"
## Create bin
-recipe.objcopy.bin.pattern_args=--chip {build.mcu} elf2image --flash_mode "{build.flash_mode}" --flash_freq "{build.flash_freq}" --flash_size "{build.flash_size}" -o "{build.path}/{build.project_name}.bin" "{build.path}/{build.project_name}.elf"
+recipe.objcopy.bin.pattern_args=--chip {build.mcu} elf2image --flash_mode "{build.flash_mode}" --flash_freq "{build.flash_freq}" --flash_size "{build.flash_size}" --elf-sha256-offset 0xb0 -o "{build.path}/{build.project_name}.bin" "{build.path}/{build.project_name}.elf"
recipe.objcopy.bin.pattern="{tools.esptool_py.path}/{tools.esptool_py.cmd}" {recipe.objcopy.bin.pattern_args}
recipe.objcopy.bin.pattern.linux=python3 "{tools.esptool_py.path}/{tools.esptool_py.cmd}" {recipe.objcopy.bin.pattern_args}
+## Create Insights Firmware Package
+recipe.hooks.objcopy.postobjcopy.1.pattern_args={build.path} {build.project_name} "{build.source.path}"
+recipe.hooks.objcopy.postobjcopy.1.pattern=bash -c "[ ! -d "{build.path}"/libraries/Insights ] || {tools.gen_insights_pkg.cmd} {recipe.hooks.objcopy.postobjcopy.1.pattern_args}"
+recipe.hooks.objcopy.postobjcopy.1.pattern.windows=cmd /c if exist "{build.path}\libraries\Insights" {tools.gen_insights_pkg.cmd} {recipe.hooks.objcopy.postobjcopy.1.pattern_args}
+
## Save bin
recipe.output.tmp_file={build.project_name}.bin
recipe.output.save_file={build.project_name}.{build.variant}.bin
diff --git a/tools/gen_insights_package.exe b/tools/gen_insights_package.exe
new file mode 100755
index 00000000000..e8e0c9640a1
Binary files /dev/null and b/tools/gen_insights_package.exe differ
diff --git a/tools/gen_insights_package.py b/tools/gen_insights_package.py
new file mode 100644
index 00000000000..c2b5047d5d6
--- /dev/null
+++ b/tools/gen_insights_package.py
@@ -0,0 +1,56 @@
+import os
+import sys
+import shutil
+import json
+
+APP_HEADER_SIZE = 32
+VERSION_NAME_OFFSET = APP_HEADER_SIZE + 16
+VERSION_NAME_SIZE = 32
+PROJECT_NAME_OFFSET = VERSION_NAME_OFFSET + VERSION_NAME_SIZE
+PROJECT_NAME_SIZE = 32
+
+# Input path of temporary build directory created by Arduino
+BUILD_DIR=sys.argv[1]
+# Input project name
+PROJ_NAME=sys.argv[2]
+# Input path to create output package
+TARGET_PATH=sys.argv[3]
+
+def main():
+ print("Creating ESP Insights Firmware Package.")
+ archive_path = os.path.join(BUILD_DIR, PROJ_NAME)
+ out_path = os.path.join(TARGET_PATH, PROJ_NAME)
+
+ # Create target archive directories
+ os.makedirs(archive_path, exist_ok = True)
+ os.makedirs(os.path.join(archive_path, "partition_table"), exist_ok = True)
+ os.makedirs(os.path.join(archive_path, "bootloader"), exist_ok = True)
+
+ # Copy files from build directory to archive directory
+ shutil.copy2(os.path.join(BUILD_DIR, PROJ_NAME + ".bin"), archive_path)
+ shutil.copy2(os.path.join(BUILD_DIR, PROJ_NAME + ".elf"), archive_path)
+ shutil.copy2(os.path.join(BUILD_DIR, PROJ_NAME + ".map"), archive_path)
+ shutil.copy2(os.path.join(BUILD_DIR, "partitions.csv"), archive_path)
+ shutil.copy2(os.path.join(BUILD_DIR, PROJ_NAME + ".bootloader.bin"), os.path.join(archive_path, "bootloader"))
+ shutil.copy2(os.path.join(BUILD_DIR, PROJ_NAME + ".partitions.bin"), os.path.join(archive_path, "partition_table"))
+
+ with open(os.path.join(BUILD_DIR, PROJ_NAME + ".bin"), 'rb') as bin_file:
+ bin_file.seek(VERSION_NAME_OFFSET)
+ version_name = (bin_file.read(VERSION_NAME_SIZE).decode('utf-8')).split('\x00', 1)[0]
+ bin_file.seek(PROJECT_NAME_OFFSET)
+ project_name = (bin_file.read(PROJECT_NAME_SIZE).decode('utf-8')).split('\x00', 1)[0]
+ project_build_config_obj = {
+ "project" : {
+ "name" : project_name,
+ "version": version_name
+ }
+ }
+ with open(os.path.join(archive_path, "project_build_config.json"), "w") as json_file:
+ json_file.write(json.dumps(project_build_config_obj))
+
+ shutil.make_archive(out_path, "zip", BUILD_DIR, PROJ_NAME)
+ print("Archive created at {}".format(out_path + ".zip"))
+ return
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/tools/partitions/app3M_fat9M_16MB.csv b/tools/partitions/app3M_fat9M_16MB.csv
index 0f67e69fbfe..1f8f04531ed 100644
--- a/tools/partitions/app3M_fat9M_16MB.csv
+++ b/tools/partitions/app3M_fat9M_16MB.csv
@@ -3,5 +3,6 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x300000,
app1, app, ota_1, 0x310000,0x300000,
-ffat, data, fat, 0x610000,0x9F0000,
-# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage
+ffat, data, fat, 0x610000,0x9E0000,
+coredump, data, coredump,0xFF0000,0x10000,
+# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage
\ No newline at end of file
diff --git a/tools/partitions/bare_minimum_2MB.csv b/tools/partitions/bare_minimum_2MB.csv
index e688a47cfa2..290745e72e4 100644
--- a/tools/partitions/bare_minimum_2MB.csv
+++ b/tools/partitions/bare_minimum_2MB.csv
@@ -1,3 +1,3 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 36K, 20K,
-factory, app, factory, 64K, 1900K,
+factory, app, factory, 64K, 1900K,
\ No newline at end of file
diff --git a/tools/partitions/default.csv b/tools/partitions/default.csv
index e9772b6f891..6f68ce16fec 100644
--- a/tools/partitions/default.csv
+++ b/tools/partitions/default.csv
@@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
-spiffs, data, spiffs, 0x290000,0x170000,
+spiffs, data, spiffs, 0x290000,0x160000,
+coredump, data, coredump,0x3F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/default_16MB.csv b/tools/partitions/default_16MB.csv
index 7b89daee9f0..28511d0af9a 100644
--- a/tools/partitions/default_16MB.csv
+++ b/tools/partitions/default_16MB.csv
@@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x640000,
app1, app, ota_1, 0x650000,0x640000,
-spiffs, data, spiffs, 0xc90000,0x370000,
+spiffs, data, spiffs, 0xc90000,0x360000,
+coredump, data, coredump,0xFF0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/default_8MB.csv b/tools/partitions/default_8MB.csv
index d21c7f6b177..0310ac62977 100644
--- a/tools/partitions/default_8MB.csv
+++ b/tools/partitions/default_8MB.csv
@@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x330000,
app1, app, ota_1, 0x340000,0x330000,
-spiffs, data, spiffs, 0x670000,0x190000,
+spiffs, data, spiffs, 0x670000,0x180000,
+coredump, data, coredump,0x7F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/default_ffat.csv b/tools/partitions/default_ffat.csv
index d921c9fe3d9..a7278a577ca 100644
--- a/tools/partitions/default_ffat.csv
+++ b/tools/partitions/default_ffat.csv
@@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
-ffat, data, fat, 0x290000,0x170000,
+ffat, data, fat, 0x290000,0x160000,
+coredump, data, coredump,0x3F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/ffat.csv b/tools/partitions/ffat.csv
index b98bf0c3034..189f70c1513 100644
--- a/tools/partitions/ffat.csv
+++ b/tools/partitions/ffat.csv
@@ -3,5 +3,6 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x200000,
app1, app, ota_1, 0x210000,0x200000,
-ffat, data, fat, 0x410000,0xBF0000,
+ffat, data, fat, 0x410000,0xBE0000,
+coredump, data, coredump,0xFF0000,0x10000,
# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage
diff --git a/tools/partitions/huge_app.csv b/tools/partitions/huge_app.csv
index 290a7cc738b..61254fcab25 100644
--- a/tools/partitions/huge_app.csv
+++ b/tools/partitions/huge_app.csv
@@ -2,4 +2,5 @@
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x300000,
-spiffs, data, spiffs, 0x310000,0xF0000,
+spiffs, data, spiffs, 0x310000,0xE0000,
+coredump, data, coredump,0x3F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/large_spiffs_16MB.csv b/tools/partitions/large_spiffs_16MB.csv
index 7974c9eb140..2fd720504d7 100644
--- a/tools/partitions/large_spiffs_16MB.csv
+++ b/tools/partitions/large_spiffs_16MB.csv
@@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x480000,
app1, app, ota_1, 0x490000,0x480000,
-spiffs, data, spiffs, 0x910000,0x6F0000,
+spiffs, data, spiffs, 0x910000,0x6E0000,
+coredump, data, coredump,0xFF0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/max_app_8MB.csv b/tools/partitions/max_app_8MB.csv
index c33a3846799..6aa8e8ec485 100644
--- a/tools/partitions/max_app_8MB.csv
+++ b/tools/partitions/max_app_8MB.csv
@@ -1,4 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
-app0, app, factory, 0x10000, 0x7F0000,
+app0, app, factory, 0x10000, 0x7E0000,
+coredump, data, coredump,0x7F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/min_spiffs.csv b/tools/partitions/min_spiffs.csv
index 0b6a9ffd01e..080f491d1dd 100644
--- a/tools/partitions/min_spiffs.csv
+++ b/tools/partitions/min_spiffs.csv
@@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x1E0000,
app1, app, ota_1, 0x1F0000,0x1E0000,
-spiffs, data, spiffs, 0x3D0000,0x30000,
+spiffs, data, spiffs, 0x3D0000,0x20000,
+coredump, data, coredump,0x3F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/minimal.csv b/tools/partitions/minimal.csv
index 6ebeeb32dc2..90280fbfaba 100644
--- a/tools/partitions/minimal.csv
+++ b/tools/partitions/minimal.csv
@@ -2,4 +2,5 @@
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
-spiffs, data, spiffs, 0x150000, 0xB0000,
+spiffs, data, spiffs, 0x150000, 0xA0000,
+coredump, data, coredump,0x1F0000, 0x10000,
\ No newline at end of file
diff --git a/tools/partitions/no_ota.csv b/tools/partitions/no_ota.csv
index 3314273b884..47ceb607797 100644
--- a/tools/partitions/no_ota.csv
+++ b/tools/partitions/no_ota.csv
@@ -2,4 +2,5 @@
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x200000,
-spiffs, data, spiffs, 0x210000,0x1F0000,
+spiffs, data, spiffs, 0x210000,0x1E0000,
+coredump, data, coredump,0x3F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/noota_3g.csv b/tools/partitions/noota_3g.csv
index a684385bdc8..233cfb28258 100644
--- a/tools/partitions/noota_3g.csv
+++ b/tools/partitions/noota_3g.csv
@@ -2,4 +2,5 @@
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x100000,
-spiffs, data, spiffs, 0x110000,0x2F0000,
+spiffs, data, spiffs, 0x110000,0x2E0000,
+coredump, data, coredump,0x3F0000,0x10000,
\ No newline at end of file
diff --git a/tools/partitions/noota_3gffat.csv b/tools/partitions/noota_3gffat.csv
index f008c277897..4712dd1ac96 100644
--- a/tools/partitions/noota_3gffat.csv
+++ b/tools/partitions/noota_3gffat.csv
@@ -2,5 +2,6 @@
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x100000,
-ffat, data, fat, 0x110000,0x2F0000,
+ffat, data, fat, 0x110000,0x2E0000,
+coredump, data, coredump,0x3F0000,0x10000,
# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage
diff --git a/tools/partitions/noota_ffat.csv b/tools/partitions/noota_ffat.csv
index 69d702f80b2..86c3067dfcb 100644
--- a/tools/partitions/noota_ffat.csv
+++ b/tools/partitions/noota_ffat.csv
@@ -2,5 +2,6 @@
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x200000,
-ffat, data, fat, 0x210000,0x1F0000,
+ffat, data, fat, 0x210000,0x1E0000,
+coredump, data, coredump,0x3F0000,0x10000,
# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage
diff --git a/tools/partitions/rainmaker.csv b/tools/partitions/rainmaker.csv
index 0760b99b871..6038dafa1a0 100644
--- a/tools/partitions/rainmaker.csv
+++ b/tools/partitions/rainmaker.csv
@@ -4,3 +4,4 @@ otadata, data, ota, 0xe000, 0x2000,
ota_0, app, ota_0, 0x10000, 0x1E0000,
ota_1, app, ota_1, 0x1F0000, 0x1E0000,
fctry, data, nvs, 0x3D0000, 0x6000,
+coredump, data, coredump, 0x3F0000, 0x10000,
\ No newline at end of file
diff --git a/tools/platformio-build.py b/tools/platformio-build.py
index 5f3086e0810..b3fa396a489 100644
--- a/tools/platformio-build.py
+++ b/tools/platformio-build.py
@@ -25,7 +25,7 @@
# Extends: https://github.com/platformio/platform-espressif32/blob/develop/builder/main.py
from os.path import abspath, basename, isdir, isfile, join
-
+from copy import deepcopy
from SCons.Script import DefaultEnvironment, SConscript
env = DefaultEnvironment()
@@ -237,3 +237,13 @@ def add_tinyuf2_extra_image():
),
)
env.Depends("$BUILD_DIR/$PROGNAME$PROGSUFFIX", partition_table)
+
+#
+# Adjust the `esptoolpy` command in the `ElfToBin` builder with firmware checksum offset
+#
+
+action = deepcopy(env["BUILDERS"]["ElfToBin"].action)
+action.cmd_list = env["BUILDERS"]["ElfToBin"].action.cmd_list.replace(
+ "-o", "--elf-sha256-offset 0xb0 -o"
+)
+env["BUILDERS"]["ElfToBin"].action = action
diff --git a/tools/sdk/esp32/include/esp_diagnostics/include/esp_diagnostics.h b/tools/sdk/esp32/include/esp_diagnostics/include/esp_diagnostics.h
index 682f316db7b..0e0fb50da36 100644
--- a/tools/sdk/esp32/include/esp_diagnostics/include/esp_diagnostics.h
+++ b/tools/sdk/esp32/include/esp_diagnostics/include/esp_diagnostics.h
@@ -238,7 +238,7 @@ esp_err_t esp_diag_log_event(const char *tag, const char *format, ...) __attribu
*/
#define ESP_DIAG_EVENT(tag, format, ...) \
{ \
- esp_diag_log_event(tag, "EV (%"PRIu32") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
+ esp_diag_log_event(tag, "EV (%" PRIu32 ") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
ESP_LOGI(tag, format, ##__VA_ARGS__); \
}
diff --git a/tools/sdk/esp32c3/include/esp_diagnostics/include/esp_diagnostics.h b/tools/sdk/esp32c3/include/esp_diagnostics/include/esp_diagnostics.h
index 682f316db7b..0e0fb50da36 100644
--- a/tools/sdk/esp32c3/include/esp_diagnostics/include/esp_diagnostics.h
+++ b/tools/sdk/esp32c3/include/esp_diagnostics/include/esp_diagnostics.h
@@ -238,7 +238,7 @@ esp_err_t esp_diag_log_event(const char *tag, const char *format, ...) __attribu
*/
#define ESP_DIAG_EVENT(tag, format, ...) \
{ \
- esp_diag_log_event(tag, "EV (%"PRIu32") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
+ esp_diag_log_event(tag, "EV (%" PRIu32 ") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
ESP_LOGI(tag, format, ##__VA_ARGS__); \
}
diff --git a/tools/sdk/esp32s2/include/esp_diagnostics/include/esp_diagnostics.h b/tools/sdk/esp32s2/include/esp_diagnostics/include/esp_diagnostics.h
index 682f316db7b..0e0fb50da36 100644
--- a/tools/sdk/esp32s2/include/esp_diagnostics/include/esp_diagnostics.h
+++ b/tools/sdk/esp32s2/include/esp_diagnostics/include/esp_diagnostics.h
@@ -238,7 +238,7 @@ esp_err_t esp_diag_log_event(const char *tag, const char *format, ...) __attribu
*/
#define ESP_DIAG_EVENT(tag, format, ...) \
{ \
- esp_diag_log_event(tag, "EV (%"PRIu32") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
+ esp_diag_log_event(tag, "EV (%" PRIu32 ") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
ESP_LOGI(tag, format, ##__VA_ARGS__); \
}
diff --git a/tools/sdk/esp32s3/include/esp_diagnostics/include/esp_diagnostics.h b/tools/sdk/esp32s3/include/esp_diagnostics/include/esp_diagnostics.h
index 682f316db7b..0e0fb50da36 100644
--- a/tools/sdk/esp32s3/include/esp_diagnostics/include/esp_diagnostics.h
+++ b/tools/sdk/esp32s3/include/esp_diagnostics/include/esp_diagnostics.h
@@ -238,7 +238,7 @@ esp_err_t esp_diag_log_event(const char *tag, const char *format, ...) __attribu
*/
#define ESP_DIAG_EVENT(tag, format, ...) \
{ \
- esp_diag_log_event(tag, "EV (%"PRIu32") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
+ esp_diag_log_event(tag, "EV (%" PRIu32 ") %s: " format, esp_log_timestamp(), tag, ##__VA_ARGS__); \
ESP_LOGI(tag, format, ##__VA_ARGS__); \
}