From 163923608e34c5be71989abc283603ceca5e794b Mon Sep 17 00:00:00 2001 From: doru91 Date: Tue, 4 Jan 2022 18:07:30 +0200 Subject: [PATCH] [K32W0] Read General Diagnostics cluster attribute at runtime (#12468) * [K32W0] Read General Diagnostics cluster attribute at runtime Signed-off-by: Doru Gucea * Restyled by clang-format Co-authored-by: Restyled.io --- .../k32w/k32w0/ConfigurationManagerImpl.cpp | 85 +++++++++++++++++++ .../nxp/k32w/k32w0/ConfigurationManagerImpl.h | 6 ++ .../k32w/k32w0/DiagnosticDataProviderImpl.cpp | 62 ++++++++++++++ .../k32w/k32w0/DiagnosticDataProviderImpl.h | 5 ++ src/platform/nxp/k32w/k32w0/K32W0Config.h | 26 ++---- .../nxp/k32w/k32w0/PlatformManagerImpl.cpp | 27 ++++++ .../nxp/k32w/k32w0/PlatformManagerImpl.h | 5 +- 7 files changed, 194 insertions(+), 22 deletions(-) diff --git a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp index 6bf016200e6aa7..0cfc4ae6708ad6 100644 --- a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp @@ -30,6 +30,7 @@ #include #include +#include "fsl_power.h" #include "fsl_reset.h" namespace chip { @@ -49,6 +50,34 @@ CHIP_ERROR ConfigurationManagerImpl::Init() { CHIP_ERROR err; bool failSafeArmed; + uint32_t rebootCount = 0; + + if (K32WConfig::ConfigValueExists(K32WConfig::kCounterKey_RebootCount)) + { + err = GetRebootCount(rebootCount); + SuccessOrExit(err); + + err = StoreRebootCount(rebootCount + 1); + SuccessOrExit(err); + } + else + { + // The first boot after factory reset of the Node. + err = StoreRebootCount(1); + SuccessOrExit(err); + } + + if (!K32WConfig::ConfigValueExists(K32WConfig::kCounterKey_TotalOperationalHours)) + { + err = StoreTotalOperationalHours(0); + SuccessOrExit(err); + } + + if (!K32WConfig::ConfigValueExists(K32WConfig::kCounterKey_BootReason)) + { + err = StoreBootReason(EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED); + SuccessOrExit(err); + } // Initialize the generic implementation base class. err = Internal::GenericConfigurationManagerImpl::Init(); @@ -68,6 +97,62 @@ CHIP_ERROR ConfigurationManagerImpl::Init() return err; } +CHIP_ERROR ConfigurationManagerImpl::GetRebootCount(uint32_t & rebootCount) +{ + return ReadConfigValue(K32WConfig::kCounterKey_RebootCount, rebootCount); +} + +CHIP_ERROR ConfigurationManagerImpl::StoreRebootCount(uint32_t rebootCount) +{ + return WriteConfigValue(K32WConfig::kCounterKey_RebootCount, rebootCount); +} + +CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours) +{ + return ReadConfigValue(K32WConfig::kCounterKey_TotalOperationalHours, totalOperationalHours); +} + +CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOperationalHours) +{ + return WriteConfigValue(K32WConfig::kCounterKey_TotalOperationalHours, totalOperationalHours); +} + +CHIP_ERROR ConfigurationManagerImpl::GetBootReason(uint32_t & bootReason) +{ + bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED; + uint8_t reason; + reason = POWER_GetResetCause(); + + if (reason == RESET_UNDEFINED) + { + bootReason = EMBER_ZCL_BOOT_REASON_TYPE_UNSPECIFIED; + } + else if ((reason == RESET_POR) || (reason == RESET_EXT_PIN)) + { + bootReason = EMBER_ZCL_BOOT_REASON_TYPE_POWER_ON_REBOOT; + } + else if (reason == RESET_BOR) + { + bootReason = EMBER_ZCL_BOOT_REASON_TYPE_BROWN_OUT_RESET; + } + else if (reason == RESET_SW_REQ) + { + bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_RESET; + } + else if (reason == RESET_WDT) + { + bootReason = EMBER_ZCL_BOOT_REASON_TYPE_SOFTWARE_WATCHDOG_RESET; + /* Reboot can be due to hardware or software watchdog */ + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConfigurationManagerImpl::StoreBootReason(uint32_t bootReason) +{ + return WriteConfigValue(K32WConfig::kCounterKey_BootReason, bootReason); +} + bool ConfigurationManagerImpl::CanFactoryReset() { // TODO: query the application to determine if factory reset is allowed. diff --git a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h b/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h index aa3a6fd6af8ef3..e7825239474125 100644 --- a/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h +++ b/src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h @@ -49,6 +49,12 @@ class ConfigurationManagerImpl final : public Internal::GenericConfigurationMana void InitiateFactoryReset(void) override; CHIP_ERROR ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) override; CHIP_ERROR WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) override; + CHIP_ERROR GetRebootCount(uint32_t & rebootCount) override; + CHIP_ERROR StoreRebootCount(uint32_t rebootCount) override; + CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override; + CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours) override; + CHIP_ERROR GetBootReason(uint32_t & bootReasons) override; + CHIP_ERROR StoreBootReason(uint32_t bootReasons) override; // NOTE: Other public interface methods are implemented by GenericConfigurationManagerImpl<>. diff --git a/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp index 9702e4109ad280..58d6503b869fad 100644 --- a/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp @@ -70,5 +70,67 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & cu return CHIP_NO_ERROR; } +CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount) +{ + uint32_t count = 0; + + CHIP_ERROR err = ConfigurationMgr().GetRebootCount(count); + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(count <= UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + rebootCount = static_cast(count); + } + + return err; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetUpTime(uint64_t & upTime) +{ + System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); + System::Clock::Timestamp startTime = PlatformMgrImpl().GetStartTime(); + + if (currentTime >= startTime) + { + upTime = std::chrono::duration_cast(currentTime - startTime).count(); + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_INVALID_TIME; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours) +{ + uint64_t upTime = 0; + + if (GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalHours = 0; + if (ConfigurationMgr().GetTotalOperationalHours(totalHours) == CHIP_NO_ERROR) + { + VerifyOrReturnError(upTime / 3600 <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + totalOperationalHours = totalHours + static_cast(upTime / 3600); + return CHIP_NO_ERROR; + } + } + + return CHIP_ERROR_INVALID_TIME; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(uint8_t & bootReason) +{ + uint32_t reason = 0; + + CHIP_ERROR err = ConfigurationMgr().GetBootReason(reason); + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(reason <= UINT8_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + bootReason = static_cast(reason); + } + + return err; +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h b/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h index 6505cf5eedff17..cd33af8885df15 100644 --- a/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h +++ b/src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h @@ -42,6 +42,11 @@ class DiagnosticDataProviderImpl : public DiagnosticDataProvider CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override; CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override; CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override; + + CHIP_ERROR GetRebootCount(uint16_t & rebootCount) override; + CHIP_ERROR GetUpTime(uint64_t & upTime) override; + CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override; + CHIP_ERROR GetBootReason(uint8_t & bootReason) override; }; } // namespace DeviceLayer diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.h b/src/platform/nxp/k32w/k32w0/K32W0Config.h index ed7cf9c61f1764..7f1aeb4534902a 100644 --- a/src/platform/nxp/k32w/k32w0/K32W0Config.h +++ b/src/platform/nxp/k32w/k32w0/K32W0Config.h @@ -88,27 +88,11 @@ class K32WConfig static constexpr Key kConfigKey_CountryCode = K32WConfigKey(kPDMId_ChipConfig, 0x08); static constexpr Key kConfigKey_Breadcrumb = K32WConfigKey(kPDMId_ChipConfig, 0x09); - static constexpr Key kConfigKey_GroupKey = K32WConfigKey(kPDMId_ChipConfig, 0x0A); - static constexpr Key kConfigKey_GroupKey0 = K32WConfigKey(kPDMId_ChipConfig, 0x0B); - static constexpr Key kConfigKey_GroupKey1 = K32WConfigKey(kPDMId_ChipConfig, 0x0C); - static constexpr Key kConfigKey_GroupKey2 = K32WConfigKey(kPDMId_ChipConfig, 0x0D); - static constexpr Key kConfigKey_GroupKey3 = K32WConfigKey(kPDMId_ChipConfig, 0x0E); - static constexpr Key kConfigKey_GroupKey4 = K32WConfigKey(kPDMId_ChipConfig, 0x0F); - static constexpr Key kConfigKey_GroupKey5 = K32WConfigKey(kPDMId_ChipConfig, 0x10); - static constexpr Key kConfigKey_GroupKey6 = K32WConfigKey(kPDMId_ChipConfig, 0x11); - static constexpr Key kConfigKey_GroupKey7 = K32WConfigKey(kPDMId_ChipConfig, 0x12); - static constexpr Key kConfigKey_GroupKey8 = K32WConfigKey(kPDMId_ChipConfig, 0x13); - static constexpr Key kConfigKey_GroupKey9 = K32WConfigKey(kPDMId_ChipConfig, 0x14); - static constexpr Key kConfigKey_GroupKey10 = K32WConfigKey(kPDMId_ChipConfig, 0x15); - static constexpr Key kConfigKey_GroupKey11 = K32WConfigKey(kPDMId_ChipConfig, 0x16); - static constexpr Key kConfigKey_GroupKey12 = K32WConfigKey(kPDMId_ChipConfig, 0x17); - static constexpr Key kConfigKey_GroupKey13 = K32WConfigKey(kPDMId_ChipConfig, 0x18); - static constexpr Key kConfigKey_GroupKey14 = K32WConfigKey(kPDMId_ChipConfig, 0x19); - static constexpr Key kConfigKey_GroupKey15 = K32WConfigKey(kPDMId_ChipConfig, 0x1A); - - static constexpr Key kConfigKey_GroupKeyBase = kConfigKey_GroupKey0; - static constexpr Key kConfigKey_GroupKeyMax = K32WConfigKey(kPDMId_ChipConfig, 0x1E); - ; // Allows 16 Group Keys to be created. + // CHIP Counter Keys + static constexpr Key kCounterKey_RebootCount = K32WConfigKey(kPDMId_ChipConfig, 0x0A); + static constexpr Key kCounterKey_UpTime = K32WConfigKey(kPDMId_ChipConfig, 0x0B); + static constexpr Key kCounterKey_TotalOperationalHours = K32WConfigKey(kPDMId_ChipConfig, 0x0C); + static constexpr Key kCounterKey_BootReason = K32WConfigKey(kPDMId_ChipConfig, 0x0D); // Set key id limits for each group. static constexpr Key kMinConfigKey_ChipFactory = K32WConfigKey(kPDMId_ChipFactory, 0x00); diff --git a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp index 434bd07b8cfe93..53fd82e6b3cdfd 100644 --- a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp @@ -73,6 +73,8 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance()); SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance()); + mStartTime = System::SystemClock().GetMonotonicTimestamp(); + // Initialize LwIP. tcpip_init(NULL, NULL); @@ -88,5 +90,30 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) return err; } +CHIP_ERROR PlatformManagerImpl::_Shutdown() +{ + uint64_t upTime = 0; + + if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalOperationalHours = 0; + + if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast(upTime / 3600)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + } + else + { + ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot"); + } + + return Internal::GenericPlatformManagerImpl_FreeRTOS::_Shutdown(); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h index 4e0e355b75bdc2..c3fa03ac8fa3ce 100644 --- a/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h +++ b/src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h @@ -48,12 +48,13 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener public: // ===== Platform-specific members that may be accessed directly by the application. - /* none so far */ + System::Clock::Timestamp GetStartTime() { return mStartTime; } private: // ===== Methods that implement the PlatformManager abstract interface. CHIP_ERROR _InitChipStack(void); + CHIP_ERROR _Shutdown(); // ===== Members for internal use by the following friends. @@ -61,6 +62,8 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener friend PlatformManagerImpl & PlatformMgrImpl(void); friend class Internal::BLEManagerImpl; + System::Clock::Timestamp mStartTime = System::Clock::kZero; + static PlatformManagerImpl sInstance; using Internal::GenericPlatformManagerImpl_FreeRTOS::PostEventFromISR;