mirror of
https://github.com/espressif/openthread.git
synced 2026-07-30 15:47:46 +00:00
[spinel] improve RCP crash dump request logic (#13150)
This commit updates the RCP crash dump request logic to provide better debug information while ensuring the recovery process is not interrupted: - `RadioSpinel::HandleRcpUnexpectedReset` now explicitly clears `mWaitingTid` and requests a crash dump if RCP restoration is disabled before proceeding with the abort / exit logic. If RCP restoration is enabled, request for crash dump will be deferred to `RecoverFromRcpFailure`, before resetting the coprocessor. - Updates crash dump requests to use `IgnoreReturnValue` instead. Failing to retrieve a crash dump is not a fatal error and should not halt the initialization or recovery process.
This commit is contained in:
@@ -157,7 +157,7 @@ void RadioSpinel::Init(bool aSkipRcpVersionCheck,
|
||||
if (sSupportsLogCrashDump)
|
||||
{
|
||||
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
|
||||
SuccessOrExit(error = Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
|
||||
IgnoreReturnValue(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
|
||||
}
|
||||
|
||||
if (!aSkipRcpVersionCheck)
|
||||
@@ -1328,14 +1328,17 @@ otError RadioSpinel::Set(spinel_prop_key_t aKey, const char *aFormat, ...)
|
||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
||||
do
|
||||
{
|
||||
RecoverFromRcpFailure();
|
||||
if (aKey != SPINEL_PROP_RCP_LOG_CRASH_DUMP)
|
||||
{
|
||||
RecoverFromRcpFailure();
|
||||
}
|
||||
#endif
|
||||
va_start(mPropertyArgs, aFormat);
|
||||
error = RequestWithExpectedCommandV(SPINEL_CMD_PROP_VALUE_IS, SPINEL_CMD_PROP_VALUE_SET, aKey, aFormat,
|
||||
mPropertyArgs);
|
||||
va_end(mPropertyArgs);
|
||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
||||
} while (mRcpFailure != kRcpFailureNone);
|
||||
} while (aKey != SPINEL_PROP_RCP_LOG_CRASH_DUMP && mRcpFailure != kRcpFailureNone);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
@@ -1399,12 +1402,19 @@ otError RadioSpinel::WaitResponse(bool aHandleRcpTimeout)
|
||||
if ((end <= now) || (GetSpinelDriver().GetSpinelInterface()->WaitForFrame(end - now) != OT_ERROR_NONE))
|
||||
{
|
||||
LogWarn("Wait for response timeout");
|
||||
if (aHandleRcpTimeout)
|
||||
// Skip RCP timeout handling for the non-essential crash dump property
|
||||
if (aHandleRcpTimeout && mWaitingKey != SPINEL_PROP_RCP_LOG_CRASH_DUMP)
|
||||
{
|
||||
HandleRcpTimeout();
|
||||
}
|
||||
ExitNow(mError = OT_ERROR_RESPONSE_TIMEOUT);
|
||||
}
|
||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
||||
if (mRcpFailure != kRcpFailureNone)
|
||||
{
|
||||
ExitNow(mError = OT_ERROR_RESPONSE_TIMEOUT);
|
||||
}
|
||||
#endif
|
||||
} while (mWaitingTid);
|
||||
|
||||
LogIfFail("Error waiting response", mError);
|
||||
@@ -1412,6 +1422,11 @@ otError RadioSpinel::WaitResponse(bool aHandleRcpTimeout)
|
||||
mWaitingKey = SPINEL_PROP_LAST_STATUS;
|
||||
|
||||
exit:
|
||||
if (mError != OT_ERROR_NONE && mWaitingTid != 0)
|
||||
{
|
||||
FreeTid(mWaitingTid);
|
||||
mWaitingTid = 0;
|
||||
}
|
||||
return mError;
|
||||
}
|
||||
|
||||
@@ -1991,11 +2006,20 @@ void RadioSpinel::HandleRcpUnexpectedReset(spinel_status_t aStatus)
|
||||
|
||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
||||
mRcpFailure = kRcpFailureUnexpectedReset;
|
||||
#elif OPENTHREAD_SPINEL_CONFIG_ABORT_ON_UNEXPECTED_RCP_RESET_ENABLE
|
||||
#else
|
||||
if (sSupportsLogCrashDump)
|
||||
{
|
||||
mWaitingTid = 0;
|
||||
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
|
||||
IgnoreReturnValue(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
|
||||
}
|
||||
|
||||
#if OPENTHREAD_SPINEL_CONFIG_ABORT_ON_UNEXPECTED_RCP_RESET_ENABLE
|
||||
abort();
|
||||
#else
|
||||
DieNow(OT_EXIT_RADIO_SPINEL_RESET);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void RadioSpinel::HandleRcpTimeout(void)
|
||||
@@ -2044,6 +2068,14 @@ void RadioSpinel::RecoverFromRcpFailure(void)
|
||||
DieNow(OT_EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (sSupportsLogCrashDump)
|
||||
{
|
||||
mWaitingTid = 0;
|
||||
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
|
||||
IgnoreReturnValue(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
|
||||
mRcpFailure = kRcpFailureNone;
|
||||
}
|
||||
|
||||
LogWarn("Trying to recover (%d/%d)", mRcpFailureCount, kMaxFailureCount);
|
||||
|
||||
mState = kStateDisabled;
|
||||
@@ -2106,12 +2138,6 @@ void RadioSpinel::RecoverFromRcpFailure(void)
|
||||
|
||||
--mRcpFailureCount;
|
||||
|
||||
if (sSupportsLogCrashDump)
|
||||
{
|
||||
LogDebg("RCP supports crash dump logging. Requesting crash dump.");
|
||||
SuccessOrDie(Set(SPINEL_PROP_RCP_LOG_CRASH_DUMP, nullptr));
|
||||
}
|
||||
|
||||
LogNote("RCP recovery is done");
|
||||
|
||||
exit:
|
||||
|
||||
Reference in New Issue
Block a user