Merge branch 'feat/diagnostics' into 'main'

Add Diagnostic Logs Support in All Device Type App

See merge request app-frameworks/esp-matter!1172
This commit is contained in:
Hrishikesh Dhayagude
2025-08-28 13:07:27 +08:00
5 changed files with 124 additions and 4 deletions
+55 -2
View File
@@ -14,7 +14,60 @@ No additional setup is required.
## 2. Usage
- To build the app with a specific PROJECT_VER and PROJECT_VER_NUMBER for OTA firmware, use the following command from the command line:
#### To use diagnostic tracing
Enable Diagnostics trace and BDX protocol for diagnostic logs transfer from menuconfig
```
idf.py menuconfig
CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
CONFIG_CHIP_ENABLE_BDX_LOG_TRANSFER
```
Set diagnostic storage buffer size from `Platform Diagnostics` menu
- End user buffer default size 4096
- Retrieval buffer default size 4096
#### To retrieve the diagnostic via diagnostic logs cluster
```
# Commission the app
chip-tool pairing ble-wifi 1 SSID PASSPHRASE 20202021 3840
# Read end user support logs using response payload protocol
chip-tool diagnosticlogs retrieve-logs-request 0 0 1 0
# Read end user diagnostic using BDX protocol
chip-tool interactive start
> diagnosticlogs retrieve-logs-request 0 1 1 0 --TransferFileDesignator enduser-diag.log
# Retrieve crash summary over BDX
> diagnosticlogs retrieve-logs-request 2 1 1 0 --TransferFileDesignator crash-summary.bin
```
esp-idf supports storing and retrieving
[core dump in flash](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/core_dump.html#core-dump-to-flash).
To support that, application needs to add core dump partition's entry in
[partitions.csv](partitions.csv#7) and we need to enable few extra menuconfig options along with above diagnostic tracing options.
```
CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y
CONFIG_ESP32_COREDUMP_DATA_FORMAT_ELF=y
```
This example's partition table and sdkconfig.default are already modified
- Retrieve the core dump using diagnostic logs cluster
```
# Read crash summary over BDX
chip-tool interactive start
> diagnosticlogs retrieve-logs-request 2 1 1 0 --TransferFileDesignator crash-summary.bin
```
#### To build the app with a specific PROJECT_VER and PROJECT_VER_NUMBER for OTA firmware, use the following command from the command line:
For e.g.:
@@ -29,7 +82,7 @@ On boot-up esp-idf console starts. In order to create a device user have to use
Setup OTBR for a device
- Please use the [OTBR board](https://github.com/espressif/esp-thread-br#hardware-platforms) as the harware platform running this example.
- Please use the [OTBR board](https://github.com/espressif/esp-thread-br#hardware-platforms) as the hardware platform running this example.
- The sdkconfig file `sdkconfig.defaults.otbr` is provided to enable the OTBR feature on the device. Build and flash the example with the sdkconfig file 'sdkconfig.defaults.otbr'
```
idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults.otbr" set-target esp32s3 build
@@ -12,8 +12,13 @@ if(CONFIG_IDF_TARGET_ESP32 OR CONFIG_IDF_TARGET_ESP32S3)
list(APPEND INCLUDE_DIRS_LIST "driver/fan/include")
endif()
if (CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE)
list(APPEND PRIV_INCLUDE_DIRS_LIST "${MATTER_SDK_PATH}/examples/platform/esp32/diagnostics")
list(APPEND SRC_DIRS_LIST "${MATTER_SDK_PATH}/examples/platform/esp32/diagnostics")
endif (CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE)
idf_component_register(SRC_DIRS ${SRC_DIRS_LIST}
PRIV_INCLUDE_DIRS "." "${ESP_MATTER_PATH}/examples/common/utils"
PRIV_INCLUDE_DIRS "." "${ESP_MATTER_PATH}/examples/common/utils" ${PRIV_INCLUDE_DIRS_LIST}
# PRIV_REQUIRES ${PRIV_REQUIRES_LIST}
INCLUDE_DIRS ${INCLUDE_DIRS_LIST}
LDFRAGMENTS "${ldfragments}")
@@ -95,3 +95,21 @@ menu "Example Configuration"
This will allow you to monitor memory usage during runtime.
endmenu
menu "Platform Diagnostics"
config END_USER_BUFFER_SIZE
int "Set buffer size for end user diagnostic data"
depends on ENABLE_ESP_DIAGNOSTICS_TRACE
default 4096
help
Defines the buffer size (in bytes) for storing diagnostic data related to end user activity.
This buffer will hold logs and traces relevant to user interactions with the Matter protocol.
config RETRIEVAL_BUFFER_SIZE
int "Set buffer size for retrieval of diagnostics from diagnostic storage"
depends on ENABLE_ESP_DIAGNOSTICS_TRACE
default 4096
help
Defines the buffer size (in bytes) for retrieval of diagnostic data.
endmenu
@@ -44,6 +44,22 @@
// External variables for electrical sensor initialization
extern bool g_electrical_sensor_created;
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
#include <app/clusters/diagnostic-logs-server/diagnostic-logs-server.h>
#include <diagnostic-logs-provider-delegate-impl.h>
#include <tracing/esp32_diagnostic_trace/DiagnosticTracing.h>
static uint8_t endUserBuffer[CONFIG_END_USER_BUFFER_SIZE]; // Global static buffer used to store diagnostics
static uint8_t retrievalBuffer[CONFIG_RETRIEVAL_BUFFER_SIZE]; // Global static buffer used to retrieve diagnostics
using namespace chip;
using namespace chip::Tracing;
using namespace chip::Tracing::Diagnostics;
using namespace chip::app::Clusters::DiagnosticLogs;
CircularDiagnosticBuffer diagnosticStorage(endUserBuffer, CONFIG_END_USER_BUFFER_SIZE);
auto & logProvider = LogProvider::GetInstance();
constexpr uint16_t kRootNodeEndpointId = 0;
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
static const char *TAG = "app_main";
uint16_t app_endpoint_id = 0;
@@ -188,6 +204,23 @@ static void ElectricalMeasurementWorkHandler(intptr_t context)
}
}
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
void diagnostic_init()
{
lock::status_t lock_status = lock::chip_stack_lock(portMAX_DELAY);
LogProvider::LogProviderInit providerInit = {
.endUserBuffer = endUserBuffer,
.endUserBufferSize = CONFIG_END_USER_BUFFER_SIZE,
.retrievalBuffer = retrievalBuffer,
.retrievalBufferSize = CONFIG_RETRIEVAL_BUFFER_SIZE,
};
logProvider.Init(providerInit);
if (lock_status == lock::SUCCESS) {
lock::chip_stack_unlock();
}
}
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
extern "C" void app_main()
{
esp_err_t err = ESP_OK;
@@ -202,7 +235,13 @@ extern "C" void app_main()
// node handle can be used to add/modify other endpoints.
node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb);
ABORT_APP_ON_FAILURE(node != nullptr, ESP_LOGE(TAG, "Failed to create Matter node"));
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
endpoint_t *root_node_endpoint = endpoint::get(node, kRootNodeEndpointId);
esp_matter::cluster::diagnostic_logs::config_t diagnostic_logs_config;
diagnostic_logs_config.delegate = &logProvider;
diagnostic_logs::create(root_node_endpoint, &diagnostic_logs_config, CLUSTER_FLAG_SERVER);
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
MEMORY_PROFILER_DUMP_HEAP_STAT("node created");
uint8_t device_type_index;
@@ -243,6 +282,10 @@ extern "C" void app_main()
ESP_LOGE(TAG, "Matter start failed: %d", err);
}
#ifdef CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
diagnostic_init();
#endif // CONFIG_ENABLE_ESP_DIAGNOSTICS_TRACE
MEMORY_PROFILER_DUMP_HEAP_STAT("matter started");
// Initialize electrical measurement clusters if electrical sensor was created
if (g_electrical_sensor_created) {
@@ -8,3 +8,4 @@ phy_init, data, phy, , 0x1000,
ota_0, app, ota_0, 0x20000, 0x1E0000,
ota_1, app, ota_1, 0x200000, 0x1E0000,
fctry, data, nvs, 0x3E0000, 0x6000
coredump, data, coredump,0x3F0000, 0x10000
1 # Name, Type, SubType, Offset, Size, Flags
8 ota_0, app, ota_0, 0x20000, 0x1E0000,
9 ota_1, app, ota_1, 0x200000, 0x1E0000,
10 fctry, data, nvs, 0x3E0000, 0x6000
11 coredump, data, coredump,0x3F0000, 0x10000