From f5248b9e3ecc07587b397ee6b64c771d8e9b2c70 Mon Sep 17 00:00:00 2001 From: Zhanglong Xia Date: Fri, 2 Aug 2024 09:49:42 +0800 Subject: [PATCH] [spinel] stop Spinel time sync when Thread satck is not running The radio_spinel periodically send Spinel command SPINEL_PROP_RCP_TIMESTAMP to RCP to synchronize time between host and RCP. Even if Thread stack is not running, it will periodically wake up the Thread host. This commit stops the time sync when the Thread stack is not running to save host power. --- src/lib/spinel/radio_spinel.cpp | 10 ++++++---- src/lib/spinel/radio_spinel.hpp | 11 ++++++++++- src/posix/platform/openthread-core-posix-config.h | 7 +++++++ src/posix/platform/platform-posix.h | 9 +++++++++ src/posix/platform/radio.cpp | 8 ++++++++ src/posix/platform/system.cpp | 6 ++---- 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/lib/spinel/radio_spinel.cpp b/src/lib/spinel/radio_spinel.cpp index 5244bcefc112..0ae89a237364 100644 --- a/src/lib/spinel/radio_spinel.cpp +++ b/src/lib/spinel/radio_spinel.cpp @@ -111,7 +111,8 @@ RadioSpinel::RadioSpinel(void) , mVendorRestorePropertiesCallback(nullptr) , mVendorRestorePropertiesContext(nullptr) #endif - , mEnableRcpTimeSync(false) + , mTimeSyncFeatureEnabled(false) + , mTimeSyncEnabled(false) , mSpinelDriver(nullptr) { memset(&mRadioSpinelMetrics, 0, sizeof(mRadioSpinelMetrics)); @@ -134,7 +135,7 @@ void RadioSpinel::Init(bool aSkipRcpCompatibilityCheck, mResetRadioOnStartup = aSoftwareReset; #endif - mEnableRcpTimeSync = aEnableRcpTimeSync; + mTimeSyncFeatureEnabled = aEnableRcpTimeSync; mSpinelDriver = aSpinelDriver; mSpinelDriver->SetFrameHandler(&HandleReceivedFrame, &HandleSavedFrame, this); @@ -798,7 +799,7 @@ void RadioSpinel::Process(const void *aContext) ProcessRadioStateMachine(); RecoverFromRcpFailure(); - if (mEnableRcpTimeSync) + if (mTimeSyncFeatureEnabled) { CalcRcpTimeOffset(); } @@ -1919,6 +1920,7 @@ void RadioSpinel::CalcRcpTimeOffset(void) * D = T1' - ((T0 + T2)/ 2) */ + EXPECT(mTimeSyncEnabled, NO_ACTION); EXPECT(!mIsTimeSynced || (otPlatTimeGet() >= GetNextRadioTimeRecalcStart()), NO_ACTION); LogDebg("Trying to get RCP time offset"); @@ -2231,7 +2233,7 @@ void RadioSpinel::RestoreProperties(void) } #endif - if (mEnableRcpTimeSync) + if (mTimeSyncFeatureEnabled) { CalcRcpTimeOffset(); } diff --git a/src/lib/spinel/radio_spinel.hpp b/src/lib/spinel/radio_spinel.hpp index 0eb49108b900..cc1fb1eed812 100644 --- a/src/lib/spinel/radio_spinel.hpp +++ b/src/lib/spinel/radio_spinel.hpp @@ -1106,6 +1106,14 @@ class RadioSpinel : private Logger void SetVendorRestorePropertiesCallback(otRadioSpinelVendorRestorePropertiesCallback aCallback, void *aContext); #endif // OPENTHREAD_SPINEL_CONFIG_VENDOR_HOOK_ENABLE + /** + * Enables or disables the time synchronization between the host and RCP. + * + * @param[in] aEnabled TRUE to enable time synchronization, FALSE otherwise. + * + */ + void SetTimeSyncEnabled(bool aEnabled) { mTimeSyncEnabled = aEnabled; } + private: enum { @@ -1342,7 +1350,8 @@ class RadioSpinel : private Logger void *mVendorRestorePropertiesContext; #endif - bool mEnableRcpTimeSync; + bool mTimeSyncFeatureEnabled : 1; + bool mTimeSyncEnabled : 1; SpinelDriver *mSpinelDriver; }; diff --git a/src/posix/platform/openthread-core-posix-config.h b/src/posix/platform/openthread-core-posix-config.h index ebe784f45636..a837ddc960ef 100644 --- a/src/posix/platform/openthread-core-posix-config.h +++ b/src/posix/platform/openthread-core-posix-config.h @@ -156,4 +156,11 @@ #define OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE 1 #endif +#ifndef OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS +/** + * The `system.cpp` has registered a state-changed callback handler. Another state-changed callback handler + * is reserved for application use. + */ +#define OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS 2 +#endif #endif // OPENTHREAD_CORE_POSIX_CONFIG_H_ diff --git a/src/posix/platform/platform-posix.h b/src/posix/platform/platform-posix.h index ca897973bb35..822f3f48a3e9 100644 --- a/src/posix/platform/platform-posix.h +++ b/src/posix/platform/platform-posix.h @@ -165,6 +165,15 @@ void platformRadioInit(const char *aUrl); */ void platformRadioDeinit(void); +/** + * Handles the state change events for the radio driver. + * + * @param[in] aInstance A pointer to the OpenThread instance. + * @param[in] aFlags Flags that denote the state change events. + * + */ +void platformRadioHandleStateChange(otInstance *aInstance, otChangedFlags aFlags); + /** * Inputs a received radio frame. * diff --git a/src/posix/platform/radio.cpp b/src/posix/platform/radio.cpp index 46c3040b2fcf..218bea06991c 100644 --- a/src/posix/platform/radio.cpp +++ b/src/posix/platform/radio.cpp @@ -216,6 +216,14 @@ ot::Posix::RcpCapsDiag &GetRcpCapsDiag(void) { return sRadio.GetRcpCapsDiag(); } void platformRadioDeinit(void) { GetRadioSpinel().Deinit(); } +void platformRadioHandleStateChange(otInstance *aInstance, otChangedFlags aFlags) +{ + if (OT_CHANGED_THREAD_NETIF_STATE & aFlags) + { + GetRadioSpinel().SetTimeSyncEnabled(otIp6IsEnabled(aInstance)); + } +} + void otPlatRadioGetIeeeEui64(otInstance *aInstance, uint8_t *aIeeeEui64) { OT_UNUSED_VARIABLE(aInstance); diff --git a/src/posix/platform/system.cpp b/src/posix/platform/system.cpp index 89da6af132de..5f3640a56509 100644 --- a/src/posix/platform/system.cpp +++ b/src/posix/platform/system.cpp @@ -65,7 +65,6 @@ bool gDryRun = false; CoprocessorType sCoprocessorType = OT_COPROCESSOR_UNKNOWN; -#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE || OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE static void processStateChange(otChangedFlags aFlags, void *aContext) { otInstance *instance = static_cast(aContext); @@ -80,8 +79,9 @@ static void processStateChange(otChangedFlags aFlags, void *aContext) #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE ot::Posix::InfraNetif::Get().HandleBackboneStateChange(instance, aFlags); #endif + + platformRadioHandleStateChange(instance, aFlags); } -#endif static const char *get802154RadioUrl(const otPlatformCoprocessorUrls &aUrls) { @@ -245,9 +245,7 @@ void platformSetUp(otPlatformConfig *aPlatformConfig) ot::Posix::Daemon::Get().SetUp(); #endif -#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE || OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE SuccessOrDie(otSetStateChangedCallback(gInstance, processStateChange, gInstance)); -#endif exit: return;