mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[spinel] add support for logging crash dumps (#10061)
This commit adds a new feature that allows platforms to log crash logs.
### Additions
- `void otPlatLogCrashDump(void)` - API that logs a crash dump using
OpenThread Logging APIs
- `SPINEL_PROP_RCP_LOG_CRASH_DUMP` - spinel prop that calls
`otPlatLogCrashDump()` when `Set`
- `SPINEL_CAP_RCP_LOG_CRASH_DUMP` - spinel capability denoting that a
RCP supports logging crash dumps
### Usage
- For `ot-cli-ftd|mtd`, `otPlatLogCrashDump()` is called at the end of
app initialization, before the main loop. See [main.c]
- For Host/RCP setups, during initialization, the Host gets the RCP
capabilities. If the RCP has the `SPINEL_CAP_RCP_LOG_CRASH_DUMP`
capability, the Host will `Set` the `SPINEL_PROP_RCP_LOG_CRASH_DUMP`
property, triggering the RCP to call `otPlatLogCrashDump()`.
- If RCP Recovery is enabled, the this will also happen once the RCP
has been restored
This commit is contained in:
@@ -233,6 +233,7 @@ ot_option(OT_OTNS OPENTHREAD_CONFIG_OTNS_ENABLE "OTNS")
|
||||
ot_option(OT_PING_SENDER OPENTHREAD_CONFIG_PING_SENDER_ENABLE "ping sender" ${OT_APP_CLI})
|
||||
ot_option(OT_PLATFORM_BOOTLOADER_MODE OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE "platform bootloader mode")
|
||||
ot_option(OT_PLATFORM_KEY_REF OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE "platform key reference secure storage")
|
||||
ot_option(OT_PLATFORM_LOG_CRASH_DUMP OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE "platform log crash dump")
|
||||
ot_option(OT_PLATFORM_NETIF OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE "platform netif")
|
||||
ot_option(OT_PLATFORM_POWER_CALIBRATION OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE "power calibration")
|
||||
ot_option(OT_PLATFORM_UDP OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE "platform UDP")
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <openthread/diag.h>
|
||||
#include <openthread/tasklet.h>
|
||||
#include <openthread/platform/logging.h>
|
||||
#include <openthread/platform/misc.h>
|
||||
|
||||
#include "openthread-system.h"
|
||||
#include "cli/cli_config.h"
|
||||
@@ -140,6 +141,10 @@ pseudo_reset:
|
||||
IgnoreError(otCliSetUserCommands(kCommands, OT_ARRAY_LENGTH(kCommands), instance));
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
otPlatLogCrashDump();
|
||||
#endif
|
||||
|
||||
while (!otSysPseudoResetWasRequested())
|
||||
{
|
||||
otTaskletsProcess(instance);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <setjmp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openthread/logging.h>
|
||||
#include <openthread/platform/misc.h>
|
||||
|
||||
#include "openthread-system.h"
|
||||
@@ -108,3 +109,13 @@ otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance)
|
||||
|
||||
return gPlatMcuPowerState;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
otError otPlatLogCrashDump(void)
|
||||
{
|
||||
otLogCritPlat("LOGGING SIMULATED CRASH DUMP");
|
||||
otLogCritPlat("Reset Reason: %d", sPlatResetReason);
|
||||
|
||||
return OT_ERROR_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -207,6 +207,16 @@ otError otPlatSetMcuPowerState(otInstance *aInstance, otPlatMcuPowerState aState
|
||||
*/
|
||||
otPlatMcuPowerState otPlatGetMcuPowerState(otInstance *aInstance);
|
||||
|
||||
/**
|
||||
* Logs a crash dump using OpenThread logging APIs
|
||||
*
|
||||
* @note This API is an optional logging platform API. It's up to the platform layer to implement it.
|
||||
*
|
||||
* @retval OT_ERROR_NONE Crash dump was logged successfully
|
||||
* @retval OT_ERROR_NOT_CAPABLE Platform is not capable of logging a crash dump
|
||||
*/
|
||||
otError otPlatLogCrashDump(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -104,6 +104,7 @@ build_simulation()
|
||||
"-DOT_MESSAGE_USE_HEAP=OFF"
|
||||
"-DOT_NETDATA_PUBLISHER=ON"
|
||||
"-DOT_PING_SENDER=ON"
|
||||
"-DOT_PLATFORM_LOG_CRASH_DUMP=ON"
|
||||
"-DOT_REFERENCE_DEVICE=ON"
|
||||
"-DOT_SERVICE=ON"
|
||||
"-DOT_SRP_CLIENT=ON"
|
||||
@@ -173,6 +174,7 @@ build_posix()
|
||||
"-DBUILD_TESTING=ON"
|
||||
"-DOT_MESSAGE_USE_HEAP=ON"
|
||||
"-DOT_PLATFORM_BOOTLOADER_MODE=ON"
|
||||
"-DOT_PLATFORM_LOG_CRASH_DUMP=ON"
|
||||
"-DOT_THREAD_VERSION=${version}"
|
||||
)
|
||||
|
||||
|
||||
@@ -609,6 +609,20 @@
|
||||
#define OPENTHREAD_CONFIG_BLE_TCAT_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
*
|
||||
* Define to 1 to enable crash dump logging.
|
||||
*
|
||||
* On platforms that support crash dump logging, this feature will log a crash dump using the OT Debug Log service.
|
||||
*
|
||||
* Logging a crash dump requires the platform to implement the `otPlatLogCrashDump()` function.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
#define OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -340,6 +340,15 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
|
||||
}
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_RCP_LOG_CRASH_DUMP:
|
||||
{
|
||||
const char *name;
|
||||
name = "log-crash-dump";
|
||||
|
||||
start += Snprintf(start, static_cast<uint32_t>(end - start), ", %s", name);
|
||||
}
|
||||
break;
|
||||
|
||||
case SPINEL_PROP_MAC_ENERGY_SCAN_RESULT:
|
||||
case SPINEL_PROP_PHY_CHAN_MAX_POWER:
|
||||
{
|
||||
|
||||
@@ -64,6 +64,8 @@ bool RadioSpinel::sSupportsLogStream =
|
||||
|
||||
bool RadioSpinel::sSupportsResetToBootloader = false; ///< RCP supports resetting into bootloader mode.
|
||||
|
||||
bool RadioSpinel::sSupportsLogCrashDump = false; ///< RCP supports logging a crash dump.
|
||||
|
||||
otRadioCaps RadioSpinel::sRadioCaps = OT_RADIO_CAPS_NONE;
|
||||
|
||||
RadioSpinel::RadioSpinel(void)
|
||||
@@ -147,6 +149,12 @@ void RadioSpinel::Init(SpinelInterface &aSpinelInterface,
|
||||
SuccessOrExit(error = Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_EUI64_S, sIeeeEui64.m8));
|
||||
InitializeCaps(supportsRcpApiVersion, supportsRcpMinHostApiVersion);
|
||||
|
||||
if (sSupportsLogCrashDump)
|
||||
{
|
||||
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
|
||||
SuccessOrExit(error = Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
|
||||
}
|
||||
|
||||
if (!aSkipRcpCompatibilityCheck)
|
||||
{
|
||||
SuccessOrDie(CheckRcpApiVersion(supportsRcpApiVersion, supportsRcpMinHostApiVersion));
|
||||
@@ -212,8 +220,9 @@ void RadioSpinel::InitializeCaps(bool &aSupportsRcpApiVersion, bool &aSupportsRc
|
||||
|
||||
sSupportsLogStream = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_OPENTHREAD_LOG_METADATA);
|
||||
aSupportsRcpApiVersion = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_API_VERSION);
|
||||
sSupportsResetToBootloader = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_RESET_TO_BOOTLOADER);
|
||||
aSupportsRcpMinHostApiVersion = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_MIN_HOST_API_VERSION);
|
||||
sSupportsResetToBootloader = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_RESET_TO_BOOTLOADER);
|
||||
sSupportsLogCrashDump = mSpinelDriver.CoprocessorHasCap(SPINEL_CAP_RCP_LOG_CRASH_DUMP);
|
||||
}
|
||||
|
||||
otError RadioSpinel::CheckRadioCapabilities(void)
|
||||
@@ -2001,6 +2010,9 @@ void RadioSpinel::RecoverFromRcpFailure(void)
|
||||
}
|
||||
|
||||
--mRcpFailureCount;
|
||||
|
||||
SuccessOrDie(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
|
||||
|
||||
LogNote("RCP recovery is done");
|
||||
|
||||
exit:
|
||||
|
||||
@@ -1247,6 +1247,7 @@ private:
|
||||
static bool sIsReady; ///< NCP ready.
|
||||
static bool sSupportsLogStream; ///< RCP supports `LOG_STREAM` property with OpenThread log meta-data format.
|
||||
static bool sSupportsResetToBootloader; ///< RCP supports resetting into bootloader mode.
|
||||
static bool sSupportsLogCrashDump; ///< RCP supports logging a crash dump.
|
||||
|
||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
||||
|
||||
|
||||
@@ -1427,6 +1427,7 @@ const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
|
||||
{SPINEL_PROP_SERVER_LEADER_SERVICES, "SERVER_LEADER_SERVICES"},
|
||||
{SPINEL_PROP_RCP_API_VERSION, "RCP_API_VERSION"},
|
||||
{SPINEL_PROP_RCP_MIN_HOST_API_VERSION, "RCP_MIN_HOST_API_VERSION"},
|
||||
{SPINEL_PROP_RCP_LOG_CRASH_DUMP, "RCP_LOG_CRASH_DUMP"},
|
||||
{SPINEL_PROP_UART_BITRATE, "UART_BITRATE"},
|
||||
{SPINEL_PROP_UART_XON_XOFF, "UART_XON_XOFF"},
|
||||
{SPINEL_PROP_15_4_PIB_PHY_CHANNELS_SUPPORTED, "15_4_PIB_PHY_CHANNELS_SUPPORTED"},
|
||||
@@ -1608,6 +1609,7 @@ const char *spinel_capability_to_cstr(spinel_capability_t capability)
|
||||
{SPINEL_CAP_RCP_API_VERSION, "RCP_API_VERSION"},
|
||||
{SPINEL_CAP_RCP_MIN_HOST_API_VERSION, "RCP_MIN_HOST_API_VERSION"},
|
||||
{SPINEL_CAP_RCP_RESET_TO_BOOTLOADER, "RCP_RESET_TO_BOOTLOADER"},
|
||||
{SPINEL_CAP_RCP_LOG_CRASH_DUMP, "RCP_LOG_CRASH_DUMP"},
|
||||
{SPINEL_CAP_MAC_ALLOWLIST, "MAC_ALLOWLIST"},
|
||||
{SPINEL_CAP_MAC_RAW, "MAC_RAW"},
|
||||
{SPINEL_CAP_OOB_STEERING_DATA, "OOB_STEERING_DATA"},
|
||||
|
||||
@@ -1296,6 +1296,7 @@ enum
|
||||
SPINEL_CAP_RCP_API_VERSION = (SPINEL_CAP_RCP__BEGIN + 0),
|
||||
SPINEL_CAP_RCP_MIN_HOST_API_VERSION = (SPINEL_CAP_RCP__BEGIN + 1),
|
||||
SPINEL_CAP_RCP_RESET_TO_BOOTLOADER = (SPINEL_CAP_RCP__BEGIN + 2),
|
||||
SPINEL_CAP_RCP_LOG_CRASH_DUMP = (SPINEL_CAP_RCP__BEGIN + 3),
|
||||
SPINEL_CAP_RCP__END = 80,
|
||||
|
||||
SPINEL_CAP_OPENTHREAD__BEGIN = 512,
|
||||
@@ -4399,6 +4400,16 @@ enum
|
||||
*/
|
||||
SPINEL_PROP_RCP_MIN_HOST_API_VERSION = SPINEL_PROP_RCP__BEGIN + 1,
|
||||
|
||||
/// Crash Dump
|
||||
/** Format: Empty : Write only
|
||||
*
|
||||
* Required capability: SPINEL_CAP_RADIO and SPINEL_CAP_RCP_LOG_CRASH_DUMP.
|
||||
*
|
||||
* Writing to this property instructs the RCP to log a crash dump if available.
|
||||
*
|
||||
*/
|
||||
SPINEL_PROP_RCP_LOG_CRASH_DUMP = SPINEL_PROP_RCP__BEGIN + 2,
|
||||
|
||||
SPINEL_PROP_RCP__END = 0xFF,
|
||||
|
||||
SPINEL_PROP_INTERFACE__BEGIN = 0x100,
|
||||
|
||||
@@ -1947,6 +1947,10 @@ template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_CAPS>(void)
|
||||
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_RCP_RESET_TO_BOOTLOADER));
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_RCP_LOG_CRASH_DUMP));
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_PLATFORM_POSIX
|
||||
SuccessOrExit(error = mEncoder.WriteUintPacked(SPINEL_CAP_POSIX));
|
||||
#endif
|
||||
|
||||
@@ -479,6 +479,13 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
#if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE),
|
||||
#endif
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE && OPENTHREAD_RADIO
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_LOG_CRASH_DUMP),
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RESET),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_ALL_MAC_COUNTERS),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MLE_COUNTERS),
|
||||
@@ -487,6 +494,7 @@ NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM),
|
||||
#endif
|
||||
#endif // OPENTHREAD_MTD || OPENTHREAD_FTD
|
||||
|
||||
#if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_KEY),
|
||||
OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_FRAME_COUNTER),
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <openthread/link.h>
|
||||
#include <openthread/link_raw.h>
|
||||
#include <openthread/ncp.h>
|
||||
#include <openthread/platform/misc.h>
|
||||
#include <openthread/platform/multipan.h>
|
||||
#include <openthread/platform/radio.h>
|
||||
#include <openthread/platform/time.h>
|
||||
@@ -614,6 +615,10 @@ exit:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
template <> otError NcpBase::HandlePropertySet<SPINEL_PROP_RCP_LOG_CRASH_DUMP>(void) { return otPlatLogCrashDump(); }
|
||||
#endif
|
||||
|
||||
} // namespace Ncp
|
||||
} // namespace ot
|
||||
|
||||
|
||||
@@ -844,4 +844,8 @@ OT_TOOL_WEAK void otPlatDnssdUnregisterKey(otInstance *aInstance
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
|
||||
OT_TOOL_WEAK otError otPlatLogCrashDump(void) { return OT_ERROR_NONE; }
|
||||
#endif
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Reference in New Issue
Block a user