Skip to content

Commit

Permalink
samples: matter: Refactored diagnostic crash logs module
Browse files Browse the repository at this point in the history
Refactored and enhanced diagnostic crash logs module:
* Extracted crash logs specific methods from generic diagnostic
logs provider to the diagnostic logs crash module.
* Removed usage of persistent storage as a back-up for the
retention RAM memory
* Added saving intent implementation object as a part of
mIntentMap what allows to perform several independent log
collection sessions at the same time.

Signed-off-by: Kamil Kasperczyk <[email protected]>
  • Loading branch information
kkasperczyk-no committed May 24, 2024
1 parent 14ecdd9 commit e7787ff
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 217 deletions.
1 change: 0 additions & 1 deletion applications/matter_weather_station/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ CONFIG_MINIMAL_LIBC=y
# Enable Diagnostic Logs feature
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_CRASH_LOGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_SAVE_CRASH_TO_SETTINGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ=y

# Enable test event triggers for diagnostic logs testing purposes.
Expand Down
1 change: 0 additions & 1 deletion applications/matter_weather_station/prj_release.conf
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ CONFIG_NCS_SAMPLE_MATTER_WATCHDOG=y
# Enable Diagnostic Logs feature
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_CRASH_LOGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_SAVE_CRASH_TO_SETTINGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ=y

# Enable test event triggers for diagnostic logs testing purposes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,6 @@ Only the latest crash data will be stored in the device's memory, meaning that i
After receiving the read request from the Matter controller, the device reads the crash data and creates human readable logs at runtime.
The device sends converted logs to the Matter controller as a response.

By default, the :ref:`ug_matter_diagnostic_logs_snippet` enables copying the crash data to Zephyr's settings storage at the first boot after a crash.
This operation allows the device to keep crash data even if a power breakdown occurs, but it will use some space within the settings storage partition and you need to take it into account while setting the partition size.
If the new crash data is the same as the previous one, the entry will not be updated.
You can disable saving crash data to the settings storage by setting the :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_SAVE_CRASH_TO_SETTINGS` Kconfig option to ``n``.

After the crash data is successfully read, it will be removed and further read attempts will notify the user that there is no available data to read.
To keep the crash log in the memory after reading it, set the :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ` Kconfig option to ``n``.

Expand All @@ -272,7 +267,6 @@ The snippet sets the following kconfig options:

* :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS` to ``y``.
* :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_CRASH_LOGS` to ``y``.
* :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_SAVE_CRASH_TO_SETTINGS` to ``y``.
* :kconfig:option:`CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ` to ``y``.

To use the snippet when building a sample, add ``-S diagnostic-logs`` to the west arguments list.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_CRASH_LOGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_SAVE_CRASH_TO_SETTINGS=y
CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ=y

# Enable test event triggers for diagnostic logs testing purposes.
Expand Down
10 changes: 1 addition & 9 deletions samples/matter/common/src/diagnostic/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

menuconfig NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS
bool "Enable diagnostics logs support"
select CHIP_ENABLE_BDX_LOG_TRANSFER
imply CHIP_ENABLE_BDX_LOG_TRANSFER
help
Provides support for diagnostics logs. Diagnostics logs allow the Matter controller to read end-user,
network and crash logs from the Matter device.
Expand Down Expand Up @@ -40,14 +40,6 @@ config NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ
Removes the last crash data after reading it by Matter controller.
Disable this option to read the last crash multiple times.

config NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_SAVE_CRASH_TO_SETTINGS
bool "Save crash logs to settings storage"
select NCS_SAMPLE_MATTER_PERSISTENT_STORAGE
help
Saves crash logs to settings storage at the boot time if there is an entry in the retention memory.
If this option is disabled crash logs will be saved only in the retention memory and can be lost
during physical power down.

endif # NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_CRASH_LOGS

config NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_TEST
Expand Down
73 changes: 73 additions & 0 deletions samples/matter/common/src/diagnostic/diagnostic_logs_crash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@
#include <zephyr/kernel.h>
#include <zephyr/retention/retention.h>

#include <lib/support/CodeUtils.h>
#include <system/SystemError.h>

using namespace Nrf;
using namespace chip;

namespace
{
const struct device *kCrashDataMem = DEVICE_DT_GET(DT_NODELABEL(crash_retention));
} // namespace

#define Verify(expr, value) \
do { \
Expand Down Expand Up @@ -127,6 +136,70 @@ bool CrashData::Collect(const char *format, ...)
return true;
}

void CrashData::ClearState()
{
mLastLine = 0;
}

CHIP_ERROR CrashData::LoadCrashData()
{
int ret = retention_is_valid(kCrashDataMem);
VerifyOrReturnError(ret == 1, CHIP_ERROR_NOT_FOUND);
ret = retention_read(kCrashDataMem, 0, reinterpret_cast<uint8_t *>(GetDescription()),
sizeof(*GetDescription()));
VerifyOrReturnError(0 == ret, System::MapErrorZephyr(ret));

return CHIP_NO_ERROR;
}

size_t CrashData::GetLogsSize()
{
size_t outSize = 0;

VerifyOrExit(CHIP_NO_ERROR == LoadCrashData(), );
outSize = CalculateSize();

exit:
/* Size calculation requires collecting all logs to get the summarized size. Clear state after that to start
* exact log collection from the beginning when requested. */
ClearState();

return outSize;
}

CHIP_ERROR CrashData::GetLogs(chip::MutableByteSpan &outBuffer, bool &outIsEndOfLog)
{
size_t convertedSize = 0;
CHIP_ERROR err = LoadCrashData();
VerifyOrExit(CHIP_NO_ERROR == err, );

convertedSize =
ProcessConversionToLog(reinterpret_cast<char *>(outBuffer.data()), outBuffer.size(), outIsEndOfLog);
outBuffer.reduce_size(convertedSize);

ChipLogDetail(Zcl, "Getting log with size %zu. Is end of log: %s", convertedSize,
outIsEndOfLog ? "true" : "false");

exit:
/* If it is the end of the log message we can clear the state, otherwise, we need to keep Esf data for
* the following bunch */
if (outIsEndOfLog || convertedSize == 0 || err != CHIP_NO_ERROR) {
ClearState();
}

return err;
}

CHIP_ERROR CrashData::FinishLogs()
{
#ifdef CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ
int ret = retention_clear(kCrashDataMem);
VerifyOrReturnError(0 == ret, System::MapErrorZephyr(ret));
#endif /* CONFIG_NCS_SAMPLE_MATTER_DIAGNOSTIC_LOGS_REMOVE_CRASH_AFTER_READ */

return CHIP_NO_ERROR;
}

extern "C" {

/* The actual code of the z_fatal_error function assigned as __real_ for linker wrapping purpose.
Expand Down
38 changes: 26 additions & 12 deletions samples/matter/common/src/diagnostic/diagnostic_logs_crash.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@

#pragma once

#include <lib/core/CHIPError.h>
#include <lib/support/Span.h>

#include "diagnostic_logs_provider.h"

#include <zephyr/device.h>
#include <zephyr/kernel.h>

using namespace chip;

namespace Nrf
{
struct CrashDescription {
Expand Down Expand Up @@ -46,10 +53,25 @@ static_assert(DT_REG_SIZE(DT_NODELABEL(crash_retention)) - 4 > sizeof(CrashDescr
* MultithreadDump converts the information about the the thread from which the error occurred.
Can be disabled using CONFIG_MULTITHREADING.
*/
class CrashData {
class CrashData : public Nrf::Matter::DiagnosticLogsIntentImpl {
public:
constexpr static size_t MaxSingleDumpSize = 100;

CHIP_ERROR GetLogs(chip::MutableByteSpan &outBuffer, bool &outIsEndOfLog) override;
CHIP_ERROR FinishLogs() override;
size_t GetLogsSize() override;

private:
/* The source is obtained based on values from ARM Cortex vector table set in the ICSR register. */
enum FaultSource {
HardFault = 3,
MemManageFault = 4,
BusFault = 5,
UsageFault = 6,
SecureFault = 7,
DebugMonitor = 12
};

/**
* @brief Convert CrashDat to output string buffer that will contain a crash message.
*
Expand Down Expand Up @@ -81,24 +103,16 @@ class CrashData {
*/
size_t CalculateSize();

private:
/* The source is obtained based on values from ARM Cortex vector table set in the ICSR register. */
enum FaultSource {
HardFault = 3,
MemManageFault = 4,
BusFault = 5,
UsageFault = 6,
SecureFault = 7,
DebugMonitor = 12
};

const char *FaultSourceToStr(uint32_t source);

bool Collect(const char *format, ...);

bool BasicDump();
bool ReasonDump();

CHIP_ERROR LoadCrashData();
void ClearState();

/* Actual crash data to be filled */
CrashDescription mDescription = {};

Expand Down
Loading

0 comments on commit e7787ff

Please sign in to comment.