[platform] add RCP interface metrics (#7860)

This commit is contained in:
Zhanglong Xia
2022-07-07 08:47:58 -07:00
committed by GitHub
parent 7e7da0e211
commit eb3ca48042
6 changed files with 91 additions and 34 deletions
+21
View File
@@ -135,6 +135,8 @@ HdlcInterface::HdlcInterface(SpinelInterface::ReceiveFrameCallback aCallback,
, mHdlcDecoder(aFrameBuffer, HandleHdlcFrame, this)
, mRadioUrl(nullptr)
{
memset(&mInterfaceMetrics, 0, sizeof(mInterfaceMetrics));
mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_UART;
}
void HdlcInterface::OnRcpReset(void)
@@ -252,6 +254,19 @@ otError HdlcInterface::Write(const uint8_t *aFrame, uint16_t aLength)
exit:
#endif // OPENTHREAD_POSIX_VIRTUAL_TIME
mInterfaceMetrics.mTransferredFrameCount++;
if (error == OT_ERROR_NONE)
{
mInterfaceMetrics.mTxFrameCount++;
mInterfaceMetrics.mTxFrameByteCount += aLength;
mInterfaceMetrics.mTransferredValidFrameCount++;
}
else
{
mInterfaceMetrics.mTransferredGarbageFrameCount++;
}
return error;
}
@@ -654,12 +669,18 @@ void HdlcInterface::HandleHdlcFrame(void *aContext, otError aError)
void HdlcInterface::HandleHdlcFrame(otError aError)
{
mInterfaceMetrics.mTransferredFrameCount++;
if (aError == OT_ERROR_NONE)
{
mInterfaceMetrics.mRxFrameCount++;
mInterfaceMetrics.mRxFrameByteCount += mReceiveFrameBuffer.GetLength();
mInterfaceMetrics.mTransferredValidFrameCount++;
mReceiveFrameCallback(mReceiveFrameContext);
}
else
{
mInterfaceMetrics.mTransferredGarbageFrameCount++;
mReceiveFrameBuffer.DiscardFrame();
otLogWarnPlat("Error decoding hdlc frame: %s", otThreadErrorToString(aError));
}
+10
View File
@@ -169,6 +169,14 @@ public:
*/
otError ResetConnection(void);
/**
* This method returns the RCP interface metrics.
*
* @returns The RCP interface metrics.
*
*/
const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
private:
/**
* This method instructs `HdlcInterface` to read and decode data from radio over the socket.
@@ -258,6 +266,8 @@ private:
Hdlc::Decoder mHdlcDecoder;
const Url::Url *mRadioUrl;
otRcpInterfaceMetrics mInterfaceMetrics;
// Non-copyable, intentionally not implemented.
HdlcInterface(const HdlcInterface &);
HdlcInterface &operator=(const HdlcInterface &);
@@ -84,6 +84,22 @@ typedef struct otPlatformConfig
///< directly after initialization.
} otPlatformConfig;
/**
* This structure represents RCP interface metrics.
*
*/
typedef struct otRcpInterfaceMetrics
{
uint8_t mRcpInterfaceType; ///< The RCP interface type.
uint64_t mTransferredFrameCount; ///< The number of transferred frames.
uint64_t mTransferredValidFrameCount; ///< The number of transferred valid frames.
uint64_t mTransferredGarbageFrameCount; ///< The number of transferred garbage frames.
uint64_t mRxFrameCount; ///< The number of received frames.
uint64_t mRxFrameByteCount; ///< The number of received bytes.
uint64_t mTxFrameCount; ///< The number of transmitted frames.
uint64_t mTxFrameByteCount; ///< The number of transmitted bytes.
} otRcpInterfaceMetrics;
/**
* This function performs all platform-specific initialization of OpenThread's drivers and initializes the OpenThread
* instance.
@@ -194,6 +210,14 @@ const char *otSysGetInfraNetifName(void);
*/
const otRadioSpinelMetrics *otSysGetRadioSpinelMetrics(void);
/**
* This method returns the RCP interface metrics.
*
* @returns The RCP interface metrics.
*
*/
const otRcpInterfaceMetrics *otSysGetRcpInterfaceMetrics(void);
#ifdef __cplusplus
} // end of extern "C"
#endif
+5
View File
@@ -665,3 +665,8 @@ const otRadioSpinelMetrics *otSysGetRadioSpinelMetrics(void)
{
return sRadioSpinel.GetRadioSpinelMetrics();
}
const otRcpInterfaceMetrics *otSysGetRcpInterfaceMetrics(void)
{
return sRadioSpinel.GetSpinelInterface().GetRcpInterfaceMetrics();
}
+21 -27
View File
@@ -74,15 +74,8 @@ SpiInterface::SpiInterface(SpinelInterface::ReceiveFrameCallback aCallback,
, mResetGpioValueFd(-1)
, mIntGpioValueFd(-1)
, mSlaveResetCount(0)
, mSpiFrameCount(0)
, mSpiValidFrameCount(0)
, mSpiGarbageFrameCount(0)
, mSpiDuplexFrameCount(0)
, mSpiUnresponsiveFrameCount(0)
, mSpiRxFrameCount(0)
, mSpiRxFrameByteCount(0)
, mSpiTxFrameCount(0)
, mSpiTxFrameByteCount(0)
, mSpiTxIsReady(false)
, mSpiTxRefusedCount(0)
, mSpiTxPayloadSize(0)
@@ -94,13 +87,14 @@ SpiInterface::SpiInterface(SpinelInterface::ReceiveFrameCallback aCallback,
void SpiInterface::OnRcpReset(void)
{
mSpiValidFrameCount = 0;
mSpiTxIsReady = false;
mSpiTxRefusedCount = 0;
mSpiTxPayloadSize = 0;
mDidPrintRateLimitLog = false;
mSpiSlaveDataLen = 0;
memset(mSpiTxFrameBuffer, 0, sizeof(mSpiTxFrameBuffer));
memset(&mInterfaceMetrics, 0, sizeof(mInterfaceMetrics));
mInterfaceMetrics.mRcpInterfaceType = OT_POSIX_RCP_BUS_SPI;
TriggerReset();
usleep(static_cast<useconds_t>(mSpiResetDelay) * kUsecPerMsec);
@@ -402,7 +396,7 @@ otError SpiInterface::DoSpiTransfer(uint8_t *aSpiRxFrameBuffer, uint32_t aTransf
otDumpDebgPlat("SPI-TX", mSpiTxFrameBuffer, static_cast<uint16_t>(transfer[1].len));
otDumpDebgPlat("SPI-RX", aSpiRxFrameBuffer, static_cast<uint16_t>(transfer[1].len));
mSpiFrameCount++;
mInterfaceMetrics.mTransferredFrameCount++;
}
return (ret < 0) ? OT_ERROR_FAILED : OT_ERROR_NONE;
@@ -421,7 +415,7 @@ otError SpiInterface::PushPullSpi(void)
Ncp::SpiFrame txFrame(mSpiTxFrameBuffer);
uint16_t skipAlignAllowanceLength;
if (mSpiValidFrameCount == 0)
if (mInterfaceMetrics.mTransferredValidFrameCount == 0)
{
// Set the reset flag to indicate to our slave that we are coming up from scratch.
txFrame.SetHeaderFlagByte(true);
@@ -525,7 +519,7 @@ otError SpiInterface::PushPullSpi(void)
else
{
// Header is full of garbage
mSpiGarbageFrameCount++;
mInterfaceMetrics.mTransferredGarbageFrameCount++;
otLogWarnPlat("Garbage in header : %02X %02X %02X %02X %02X", spiRxFrame[0], spiRxFrame[1],
spiRxFrame[2], spiRxFrame[3], spiRxFrame[4]);
@@ -542,7 +536,7 @@ otError SpiInterface::PushPullSpi(void)
if (!rxFrame.IsValid() || (slaveAcceptLen > kMaxFrameSize) || (mSpiSlaveDataLen > kMaxFrameSize))
{
mSpiGarbageFrameCount++;
mInterfaceMetrics.mTransferredGarbageFrameCount++;
mSpiTxRefusedCount++;
mSpiSlaveDataLen = 0;
@@ -554,7 +548,7 @@ otError SpiInterface::PushPullSpi(void)
ExitNow();
}
mSpiValidFrameCount++;
mInterfaceMetrics.mTransferredValidFrameCount++;
if (rxFrame.IsResetFlagSet())
{
@@ -567,9 +561,9 @@ otError SpiInterface::PushPullSpi(void)
// Handle received packet, if any.
if ((mSpiSlaveDataLen != 0) && (mSpiSlaveDataLen <= txFrame.GetHeaderAcceptLen()))
{
mSpiRxFrameByteCount += mSpiSlaveDataLen;
mInterfaceMetrics.mRxFrameByteCount += mSpiSlaveDataLen;
mSpiSlaveDataLen = 0;
mSpiRxFrameCount++;
mInterfaceMetrics.mRxFrameCount++;
successfulExchanges++;
// Set the skip length to skip align bytes and SPI frame header.
@@ -594,8 +588,8 @@ otError SpiInterface::PushPullSpi(void)
// that uplayer can pull another packet for us to send.
successfulExchanges++;
mSpiTxFrameCount++;
mSpiTxFrameByteCount += mSpiTxPayloadSize;
mInterfaceMetrics.mTxFrameCount++;
mInterfaceMetrics.mTxFrameByteCount += mSpiTxPayloadSize;
mSpiTxIsReady = false;
mSpiTxPayloadSize = 0;
@@ -833,16 +827,16 @@ void SpiInterface::LogError(const char *aString)
void SpiInterface::LogStats(void)
{
otLogInfoPlat("INFO: mSlaveResetCount=%" PRIu64, mSlaveResetCount);
otLogInfoPlat("INFO: mSpiFrameCount=%" PRIu64, mSpiFrameCount);
otLogInfoPlat("INFO: mSpiValidFrameCount=%" PRIu64, mSpiValidFrameCount);
otLogInfoPlat("INFO: mSpiDuplexFrameCount=%" PRIu64, mSpiDuplexFrameCount);
otLogInfoPlat("INFO: mSpiUnresponsiveFrameCount=%" PRIu64, mSpiUnresponsiveFrameCount);
otLogInfoPlat("INFO: mSpiGarbageFrameCount=%" PRIu64, mSpiGarbageFrameCount);
otLogInfoPlat("INFO: mSpiRxFrameCount=%" PRIu64, mSpiRxFrameCount);
otLogInfoPlat("INFO: mSpiRxFrameByteCount=%" PRIu64, mSpiRxFrameByteCount);
otLogInfoPlat("INFO: mSpiTxFrameCount=%" PRIu64, mSpiTxFrameCount);
otLogInfoPlat("INFO: mSpiTxFrameByteCount=%" PRIu64, mSpiTxFrameByteCount);
otLogInfoPlat("INFO: SlaveResetCount=%" PRIu64, mSlaveResetCount);
otLogInfoPlat("INFO: SpiDuplexFrameCount=%" PRIu64, mSpiDuplexFrameCount);
otLogInfoPlat("INFO: SpiUnresponsiveFrameCount=%" PRIu64, mSpiUnresponsiveFrameCount);
otLogInfoPlat("INFO: TransferredFrameCount=%" PRIu64, mInterfaceMetrics.mTransferredFrameCount);
otLogInfoPlat("INFO: TransferredValidFrameCount=%" PRIu64, mInterfaceMetrics.mTransferredValidFrameCount);
otLogInfoPlat("INFO: TransferredGarbageFrameCount=%" PRIu64, mInterfaceMetrics.mTransferredGarbageFrameCount);
otLogInfoPlat("INFO: RxFrameCount=%" PRIu64, mInterfaceMetrics.mRxFrameCount);
otLogInfoPlat("INFO: RxFrameByteCount=%" PRIu64, mInterfaceMetrics.mRxFrameByteCount);
otLogInfoPlat("INFO: TxFrameCount=%" PRIu64, mInterfaceMetrics.mTxFrameCount);
otLogInfoPlat("INFO: TxFrameByteCount=%" PRIu64, mInterfaceMetrics.mTxFrameByteCount);
}
} // namespace Posix
} // namespace ot
+10 -7
View File
@@ -159,6 +159,14 @@ public:
*/
otError ResetConnection(void) { return OT_ERROR_NONE; }
/**
* This method returns the RCP interface metrics.
*
* @returns The RCP interface metrics.
*
*/
const otRcpInterfaceMetrics *GetRcpInterfaceMetrics(void) const { return &mInterfaceMetrics; }
private:
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);
@@ -228,15 +236,8 @@ private:
uint32_t mSpiSpeedHz;
uint64_t mSlaveResetCount;
uint64_t mSpiFrameCount;
uint64_t mSpiValidFrameCount;
uint64_t mSpiGarbageFrameCount;
uint64_t mSpiDuplexFrameCount;
uint64_t mSpiUnresponsiveFrameCount;
uint64_t mSpiRxFrameCount;
uint64_t mSpiRxFrameByteCount;
uint64_t mSpiTxFrameCount;
uint64_t mSpiTxFrameByteCount;
bool mSpiTxIsReady;
uint16_t mSpiTxRefusedCount;
@@ -248,6 +249,8 @@ private:
bool mDidRxFrame;
otRcpInterfaceMetrics mInterfaceMetrics;
// Non-copyable, intentionally not implemented.
SpiInterface(const SpiInterface &);
SpiInterface &operator=(const SpiInterface &);