mirror of
https://github.com/espressif/openthread.git
synced 2026-09-13 12:40:05 +00:00
[posix] unify the RCP reset sequence (#8858)
This commit unifies the RCP reset sequence on the HDLC and SPI interfaces. The host will try the software reset first, and then try the hardware reset if the software reset fails or allowed. Reasons for unifying the RCP reset sequence: - The parameters of the Thread stack are fixed on Android. Developers can't use different parameters to specify SPI or HDLC interfaces to use different methods to reset RCP. - If the Thread stack and the BLE stack are running on the same radio chip, the hardware reset chip will cause the BLE stack to crash. The host needs to software reset RCP first, and try the hardware reset if the software reset fails. This can reduce the impact on the BLE stack.
This commit is contained in:
@@ -962,6 +962,7 @@ private:
|
|||||||
|
|
||||||
static void HandleReceivedFrame(void *aContext);
|
static void HandleReceivedFrame(void *aContext);
|
||||||
|
|
||||||
|
void ResetRcp(bool aResetRadio);
|
||||||
otError CheckSpinelVersion(void);
|
otError CheckSpinelVersion(void);
|
||||||
otError CheckRadioCapabilities(void);
|
otError CheckRadioCapabilities(void);
|
||||||
otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsMinHostRcpApiVersion);
|
otError CheckRcpApiVersion(bool aSupportsRcpApiVersion, bool aSupportsMinHostRcpApiVersion);
|
||||||
@@ -998,7 +999,7 @@ private:
|
|||||||
spinel_prop_key_t aKey,
|
spinel_prop_key_t aKey,
|
||||||
const char *aFormat,
|
const char *aFormat,
|
||||||
va_list aArgs);
|
va_list aArgs);
|
||||||
otError WaitResponse(void);
|
otError WaitResponse(bool aHandleRcpTimeout = true);
|
||||||
otError SendCommand(uint32_t aCommand,
|
otError SendCommand(uint32_t aCommand,
|
||||||
spinel_prop_key_t aKey,
|
spinel_prop_key_t aKey,
|
||||||
spinel_tid_t aTid,
|
spinel_tid_t aTid,
|
||||||
|
|||||||
@@ -230,23 +230,7 @@ void RadioSpinel<InterfaceType, ProcessContextType>::Init(bool aResetRadio,
|
|||||||
mResetRadioOnStartup = aResetRadio;
|
mResetRadioOnStartup = aResetRadio;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (aResetRadio)
|
ResetRcp(aResetRadio);
|
||||||
{
|
|
||||||
SuccessOrExit(error = SendReset(SPINEL_RESET_STACK));
|
|
||||||
SuccessOrDie(mSpinelInterface.ResetConnection());
|
|
||||||
}
|
|
||||||
|
|
||||||
SuccessOrExit(error = WaitResponse());
|
|
||||||
|
|
||||||
#if OPENTHREAD_SPINEL_CONFIG_RCP_RESTORATION_MAX_COUNT > 0
|
|
||||||
while (mRcpFailed)
|
|
||||||
{
|
|
||||||
RecoverFromRcpFailure();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VerifyOrExit(mIsReady, error = OT_ERROR_FAILED);
|
|
||||||
|
|
||||||
SuccessOrExit(error = CheckSpinelVersion());
|
SuccessOrExit(error = CheckSpinelVersion());
|
||||||
SuccessOrExit(error = Get(SPINEL_PROP_NCP_VERSION, SPINEL_DATATYPE_UTF8_S, mVersion, sizeof(mVersion)));
|
SuccessOrExit(error = Get(SPINEL_PROP_NCP_VERSION, SPINEL_DATATYPE_UTF8_S, mVersion, sizeof(mVersion)));
|
||||||
SuccessOrExit(error = Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_EUI64_S, mIeeeEui64.m8));
|
SuccessOrExit(error = Get(SPINEL_PROP_HWADDR, SPINEL_DATATYPE_EUI64_S, mIeeeEui64.m8));
|
||||||
@@ -279,6 +263,43 @@ exit:
|
|||||||
SuccessOrDie(error);
|
SuccessOrDie(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename InterfaceType, typename ProcessContextType>
|
||||||
|
void RadioSpinel<InterfaceType, ProcessContextType>::ResetRcp(bool aResetRadio)
|
||||||
|
{
|
||||||
|
bool hardwareReset;
|
||||||
|
bool resetDone = false;
|
||||||
|
|
||||||
|
mIsReady = false;
|
||||||
|
mWaitingKey = SPINEL_PROP_LAST_STATUS;
|
||||||
|
|
||||||
|
if (aResetRadio && (SendReset(SPINEL_RESET_STACK) == OT_ERROR_NONE) && (WaitResponse(false) == OT_ERROR_NONE))
|
||||||
|
{
|
||||||
|
otLogInfoPlat("Software reset RCP successfully");
|
||||||
|
ExitNow(resetDone = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
hardwareReset = (mSpinelInterface.HardwareReset() == OT_ERROR_NONE);
|
||||||
|
SuccessOrExit(WaitResponse(false));
|
||||||
|
|
||||||
|
resetDone = true;
|
||||||
|
|
||||||
|
if (hardwareReset)
|
||||||
|
{
|
||||||
|
otLogInfoPlat("Hardware reset RCP successfully");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
otLogInfoPlat("RCP self reset successfully");
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!resetDone)
|
||||||
|
{
|
||||||
|
otLogCritPlat("Failed to reset RCP!");
|
||||||
|
DieNow(OT_EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename InterfaceType, typename ProcessContextType>
|
template <typename InterfaceType, typename ProcessContextType>
|
||||||
otError RadioSpinel<InterfaceType, ProcessContextType>::CheckSpinelVersion(void)
|
otError RadioSpinel<InterfaceType, ProcessContextType>::CheckSpinelVersion(void)
|
||||||
{
|
{
|
||||||
@@ -1699,7 +1720,7 @@ otError RadioSpinel<InterfaceType, ProcessContextType>::Remove(spinel_prop_key_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename InterfaceType, typename ProcessContextType>
|
template <typename InterfaceType, typename ProcessContextType>
|
||||||
otError RadioSpinel<InterfaceType, ProcessContextType>::WaitResponse(void)
|
otError RadioSpinel<InterfaceType, ProcessContextType>::WaitResponse(bool aHandleRcpTimeout)
|
||||||
{
|
{
|
||||||
uint64_t end = otPlatTimeGet() + kMaxWaitTime * US_PER_MS;
|
uint64_t end = otPlatTimeGet() + kMaxWaitTime * US_PER_MS;
|
||||||
|
|
||||||
@@ -1713,7 +1734,10 @@ otError RadioSpinel<InterfaceType, ProcessContextType>::WaitResponse(void)
|
|||||||
if ((end <= now) || (mSpinelInterface.WaitForFrame(end - now) != OT_ERROR_NONE))
|
if ((end <= now) || (mSpinelInterface.WaitForFrame(end - now) != OT_ERROR_NONE))
|
||||||
{
|
{
|
||||||
otLogWarnPlat("Wait for response timeout");
|
otLogWarnPlat("Wait for response timeout");
|
||||||
HandleRcpTimeout();
|
if (aHandleRcpTimeout)
|
||||||
|
{
|
||||||
|
HandleRcpTimeout();
|
||||||
|
}
|
||||||
ExitNow(mError = OT_ERROR_NONE);
|
ExitNow(mError = OT_ERROR_NONE);
|
||||||
}
|
}
|
||||||
} while (mWaitingTid || !mIsReady);
|
} while (mWaitingTid || !mIsReady);
|
||||||
@@ -2305,24 +2329,14 @@ void RadioSpinel<InterfaceType, ProcessContextType>::RecoverFromRcpFailure(void)
|
|||||||
|
|
||||||
mState = kStateDisabled;
|
mState = kStateDisabled;
|
||||||
mRxFrameBuffer.Clear();
|
mRxFrameBuffer.Clear();
|
||||||
mSpinelInterface.OnRcpReset();
|
|
||||||
mCmdTidsInUse = 0;
|
mCmdTidsInUse = 0;
|
||||||
mCmdNextTid = 1;
|
mCmdNextTid = 1;
|
||||||
mTxRadioTid = 0;
|
mTxRadioTid = 0;
|
||||||
mWaitingTid = 0;
|
mWaitingTid = 0;
|
||||||
mWaitingKey = SPINEL_PROP_LAST_STATUS;
|
|
||||||
mError = OT_ERROR_NONE;
|
mError = OT_ERROR_NONE;
|
||||||
mIsReady = false;
|
|
||||||
mIsTimeSynced = false;
|
mIsTimeSynced = false;
|
||||||
|
|
||||||
if (mResetRadioOnStartup)
|
ResetRcp(mResetRadioOnStartup);
|
||||||
{
|
|
||||||
SuccessOrDie(SendReset(SPINEL_RESET_STACK));
|
|
||||||
SuccessOrDie(mSpinelInterface.ResetConnection());
|
|
||||||
}
|
|
||||||
|
|
||||||
SuccessOrDie(WaitResponse());
|
|
||||||
|
|
||||||
SuccessOrDie(Set(SPINEL_PROP_PHY_ENABLED, SPINEL_DATATYPE_BOOL_S, true));
|
SuccessOrDie(Set(SPINEL_PROP_PHY_ENABLED, SPINEL_DATATYPE_BOOL_S, true));
|
||||||
mState = kStateSleep;
|
mState = kStateSleep;
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#define POSIX_APP_SPINEL_INTERFACE_HPP_
|
#define POSIX_APP_SPINEL_INTERFACE_HPP_
|
||||||
|
|
||||||
#include "lib/hdlc/hdlc.hpp"
|
#include "lib/hdlc/hdlc.hpp"
|
||||||
|
#include "lib/spinel/spinel.h"
|
||||||
|
|
||||||
namespace ot {
|
namespace ot {
|
||||||
namespace Spinel {
|
namespace Spinel {
|
||||||
@@ -58,6 +59,23 @@ public:
|
|||||||
typedef Hdlc::MultiFrameBuffer<kMaxFrameSize> RxFrameBuffer;
|
typedef Hdlc::MultiFrameBuffer<kMaxFrameSize> RxFrameBuffer;
|
||||||
|
|
||||||
typedef void (*ReceiveFrameCallback)(void *aContext);
|
typedef void (*ReceiveFrameCallback)(void *aContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method indicates whether or not the frame is the Spinel SPINEL_CMD_RESET frame.
|
||||||
|
*
|
||||||
|
* @param[in] aFrame A pointer to buffer containing the spinel frame.
|
||||||
|
* @param[in] aLength The length (number of bytes) in the frame.
|
||||||
|
*
|
||||||
|
* @retval true If the frame is a Spinel SPINEL_CMD_RESET frame.
|
||||||
|
* @retval false If the frame is not a Spinel SPINEL_CMD_RESET frame.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static bool IsSpinelResetCommand(const uint8_t *aFrame, uint16_t aLength)
|
||||||
|
{
|
||||||
|
static constexpr uint8_t kSpinelResetCommand[] = {SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_CMD_RESET};
|
||||||
|
return (aLength >= sizeof(kSpinelResetCommand)) &&
|
||||||
|
(memcmp(aFrame, kSpinelResetCommand, sizeof(kSpinelResetCommand)) == 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace Spinel
|
} // namespace Spinel
|
||||||
} // namespace ot
|
} // namespace ot
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
#include <openthread/logging.h>
|
#include <openthread/logging.h>
|
||||||
|
|
||||||
#include "common/code_utils.hpp"
|
#include "common/code_utils.hpp"
|
||||||
|
#include "lib/spinel/spinel.h"
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
@@ -139,8 +140,6 @@ HdlcInterface::HdlcInterface(SpinelInterface::ReceiveFrameCallback aCallback,
|
|||||||
mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_UART;
|
mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_UART;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HdlcInterface::OnRcpReset(void) { mHdlcDecoder.Reset(); }
|
|
||||||
|
|
||||||
otError HdlcInterface::Init(const Url::Url &aRadioUrl)
|
otError HdlcInterface::Init(const Url::Url &aRadioUrl)
|
||||||
{
|
{
|
||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
@@ -210,6 +209,12 @@ otError HdlcInterface::SendFrame(const uint8_t *aFrame, uint16_t aLength)
|
|||||||
error = Write(encoderBuffer.GetFrame(), encoderBuffer.GetLength());
|
error = Write(encoderBuffer.GetFrame(), encoderBuffer.GetLength());
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
if ((error == OT_ERROR_NONE) && ot::Spinel::SpinelInterface::IsSpinelResetCommand(aFrame, aLength))
|
||||||
|
{
|
||||||
|
mHdlcDecoder.Reset();
|
||||||
|
error = ResetConnection();
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,16 +158,13 @@ public:
|
|||||||
uint32_t GetBusSpeed(void) const { return mBaudRate; }
|
uint32_t GetBusSpeed(void) const { return mBaudRate; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when RCP failure detected and resets internal states of the interface.
|
* This method hardware resets the RCP.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully reset the RCP.
|
||||||
|
* @retval OT_ERROR_NOT_IMPLEMENT The hardware reset is not implemented.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void OnRcpReset(void);
|
otError HardwareReset(void) { return OT_ERROR_NOT_IMPLEMENTED; }
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called when RCP is reset to recreate the connection with it.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
otError ResetConnection(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the RCP interface metrics.
|
* This method returns the RCP interface metrics.
|
||||||
@@ -178,6 +175,12 @@ public:
|
|||||||
const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
|
const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* This method is called when RCP is reset to recreate the connection with it.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
otError ResetConnection(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method instructs `HdlcInterface` to read and decode data from radio over the socket.
|
* This method instructs `HdlcInterface` to read and decode data from radio over the socket.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ SpiInterface::SpiInterface(SpinelInterface::ReceiveFrameCallback aCallback,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiInterface::OnRcpReset(void)
|
void SpiInterface::ResetStates(void)
|
||||||
{
|
{
|
||||||
mSpiTxIsReady = false;
|
mSpiTxIsReady = false;
|
||||||
mSpiTxRefusedCount = 0;
|
mSpiTxRefusedCount = 0;
|
||||||
@@ -95,9 +95,20 @@ void SpiInterface::OnRcpReset(void)
|
|||||||
memset(mSpiTxFrameBuffer, 0, sizeof(mSpiTxFrameBuffer));
|
memset(mSpiTxFrameBuffer, 0, sizeof(mSpiTxFrameBuffer));
|
||||||
memset(&mInterfaceMetrics, 0, sizeof(mInterfaceMetrics));
|
memset(&mInterfaceMetrics, 0, sizeof(mInterfaceMetrics));
|
||||||
mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_SPI;
|
mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_SPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
otError SpiInterface::HardwareReset(void)
|
||||||
|
{
|
||||||
|
ResetStates();
|
||||||
TriggerReset();
|
TriggerReset();
|
||||||
|
|
||||||
|
// If the `INT` pin is set to low during the restart of the RCP chip, which triggers continuous invalid SPI
|
||||||
|
// transactions by the host, it will cause the function `PushPullSpi()` to output lots of invalid warn log
|
||||||
|
// messages. Adding the delay here is used to wait for the RCP chip starts up to avoid outputing invalid
|
||||||
|
// log messages.
|
||||||
usleep(static_cast<useconds_t>(mSpiResetDelay) * kUsecPerMsec);
|
usleep(static_cast<useconds_t>(mSpiResetDelay) * kUsecPerMsec);
|
||||||
|
|
||||||
|
return OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
otError SpiInterface::Init(const Url::Url &aRadioUrl)
|
otError SpiInterface::Init(const Url::Url &aRadioUrl)
|
||||||
@@ -182,12 +193,6 @@ otError SpiInterface::Init(const Url::Url &aRadioUrl)
|
|||||||
InitResetPin(spiGpioResetDevice, spiGpioResetLine);
|
InitResetPin(spiGpioResetDevice, spiGpioResetLine);
|
||||||
InitSpiDev(aRadioUrl.GetPath(), spiMode, spiSpeed);
|
InitSpiDev(aRadioUrl.GetPath(), spiMode, spiSpeed);
|
||||||
|
|
||||||
// Reset RCP chip.
|
|
||||||
TriggerReset();
|
|
||||||
|
|
||||||
// Waiting for the RCP chip starts up.
|
|
||||||
usleep(static_cast<useconds_t>(spiResetDelay) * kUsecPerMsec);
|
|
||||||
|
|
||||||
return OT_ERROR_NONE;
|
return OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,6 +805,12 @@ otError SpiInterface::SendFrame(const uint8_t *aFrame, uint16_t aLength)
|
|||||||
otError error = OT_ERROR_NONE;
|
otError error = OT_ERROR_NONE;
|
||||||
|
|
||||||
VerifyOrExit(aLength < (kMaxFrameSize - kSpiFrameHeaderSize), error = OT_ERROR_NO_BUFS);
|
VerifyOrExit(aLength < (kMaxFrameSize - kSpiFrameHeaderSize), error = OT_ERROR_NO_BUFS);
|
||||||
|
|
||||||
|
if (ot::Spinel::SpinelInterface::IsSpinelResetCommand(aFrame, aLength))
|
||||||
|
{
|
||||||
|
ResetStates();
|
||||||
|
}
|
||||||
|
|
||||||
VerifyOrExit(!mSpiTxIsReady, error = OT_ERROR_BUSY);
|
VerifyOrExit(!mSpiTxIsReady, error = OT_ERROR_BUSY);
|
||||||
|
|
||||||
memcpy(&mSpiTxFrameBuffer[kSpiFrameHeaderSize], aFrame, aLength);
|
memcpy(&mSpiTxFrameBuffer[kSpiFrameHeaderSize], aFrame, aLength);
|
||||||
|
|||||||
@@ -147,17 +147,13 @@ public:
|
|||||||
uint32_t GetBusSpeed(void) const { return ((mSpiDevFd >= 0) ? mSpiSpeedHz : 0); }
|
uint32_t GetBusSpeed(void) const { return ((mSpiDevFd >= 0) ? mSpiSpeedHz : 0); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when RCP failure detected and resets internal states of the interface.
|
* This method hardware resets the RCP.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully reset the RCP.
|
||||||
|
* @retval OT_ERROR_NOT_IMPLEMENT The hardware reset is not implemented.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void OnRcpReset(void);
|
otError HardwareReset(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called when RCP is reset to recreate the connection with it.
|
|
||||||
* Intentionally empty.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
otError ResetConnection(void) { return OT_ERROR_NONE; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the RCP interface metrics.
|
* This method returns the RCP interface metrics.
|
||||||
@@ -168,6 +164,7 @@ public:
|
|||||||
const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
|
const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ResetStates(void);
|
||||||
int SetupGpioHandle(int aFd, uint8_t aLine, uint32_t aHandleFlags, const char *aLabel);
|
int SetupGpioHandle(int aFd, uint8_t aLine, uint32_t aHandleFlags, const char *aLabel);
|
||||||
int SetupGpioEvent(int aFd, uint8_t aLine, uint32_t aHandleFlags, uint32_t aEventFlags, const char *aLabel);
|
int SetupGpioEvent(int aFd, uint8_t aLine, uint32_t aHandleFlags, uint32_t aEventFlags, const char *aLabel);
|
||||||
void SetGpioValue(int aFd, uint8_t aValue);
|
void SetGpioValue(int aFd, uint8_t aValue);
|
||||||
|
|||||||
@@ -144,19 +144,13 @@ public:
|
|||||||
uint32_t GetBusSpeed(void) const;
|
uint32_t GetBusSpeed(void) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called when RCP failure detected and resets internal states of the interface.
|
* This method hardware resets the RCP.
|
||||||
|
*
|
||||||
|
* @retval OT_ERROR_NONE Successfully reset the RCP.
|
||||||
|
* @retval OT_ERROR_NOT_IMPLEMENT The hardware reset is not implemented.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void OnRcpReset(void);
|
otError HardwareReset(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called when RCP is reset to recreate the connection with it.
|
|
||||||
*
|
|
||||||
* @retval OT_ERROR_NONE Reset the connection successfully.
|
|
||||||
* @retval OT_ERROR_FAILED Failed to reset the connection.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
otError ResetConnection(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the RCP interface metrics.
|
* This method returns the RCP interface metrics.
|
||||||
|
|||||||
@@ -101,9 +101,11 @@ void VendorInterface::Deinit(void)
|
|||||||
|
|
||||||
uint32_t VendorInterface::GetBusSpeed(void) const { return 1000000; }
|
uint32_t VendorInterface::GetBusSpeed(void) const { return 1000000; }
|
||||||
|
|
||||||
void VendorInterface::OnRcpReset(void)
|
otError VendorInterface::HardwareReset(void)
|
||||||
{
|
{
|
||||||
// TODO: Implement vendor code here.
|
// TODO: Implement vendor code here.
|
||||||
|
|
||||||
|
return OT_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VendorInterface::UpdateFdSet(fd_set &aReadFdSet, fd_set &aWriteFdSet, int &aMaxFd, struct timeval &aTimeout)
|
void VendorInterface::UpdateFdSet(fd_set &aReadFdSet, fd_set &aWriteFdSet, int &aMaxFd, struct timeval &aTimeout)
|
||||||
@@ -142,13 +144,6 @@ otError VendorInterface::SendFrame(const uint8_t *aFrame, uint16_t aLength)
|
|||||||
return OT_ERROR_NONE;
|
return OT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
otError VendorInterface::ResetConnection(void)
|
|
||||||
{
|
|
||||||
// TODO: Implement vendor code here.
|
|
||||||
|
|
||||||
return OT_ERROR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
const otRcpInterfaceMetrics *VendorInterface::GetRcpInterfaceMetrics(void)
|
const otRcpInterfaceMetrics *VendorInterface::GetRcpInterfaceMetrics(void)
|
||||||
{
|
{
|
||||||
// TODO: Implement vendor code here.
|
// TODO: Implement vendor code here.
|
||||||
|
|||||||
Reference in New Issue
Block a user