Skip to content

Commit

Permalink
[K32W0] Read General Diagnostics cluster attribute at runtime (projec…
Browse files Browse the repository at this point in the history
…t-chip#12468)

* [K32W0] Read General Diagnostics cluster attribute at runtime

Signed-off-by: Doru Gucea <[email protected]>

* Restyled by clang-format

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and step0035 committed Feb 8, 2022
1 parent f7181c0 commit cd9c46a
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 22 deletions.
85 changes: 85 additions & 0 deletions src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <platform/internal/GenericConfigurationManagerImpl.cpp>
#include <platform/nxp/k32w/k32w0/K32W0Config.h>

#include "fsl_power.h"
#include "fsl_reset.h"

namespace chip {
Expand All @@ -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<K32WConfig>::Init();
Expand All @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions src/platform/nxp/k32w/k32w0/ConfigurationManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<>.

Expand Down
62 changes: 62 additions & 0 deletions src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint16_t>(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<System::Clock::Seconds64>(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<uint32_t>(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<uint8_t>(reason);
}

return err;
}

} // namespace DeviceLayer
} // namespace chip
5 changes: 5 additions & 0 deletions src/platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 5 additions & 21 deletions src/platform/nxp/k32w/k32w0/K32W0Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
27 changes: 27 additions & 0 deletions src/platform/nxp/k32w/k32w0/PlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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<uint32_t>(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<PlatformManagerImpl>::_Shutdown();
}

} // namespace DeviceLayer
} // namespace chip
5 changes: 4 additions & 1 deletion src/platform/nxp/k32w/k32w0/PlatformManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,22 @@ 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.

friend PlatformManager & PlatformMgr(void);
friend PlatformManagerImpl & PlatformMgrImpl(void);
friend class Internal::BLEManagerImpl;

System::Clock::Timestamp mStartTime = System::Clock::kZero;

static PlatformManagerImpl sInstance;

using Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::PostEventFromISR;
Expand Down

0 comments on commit cd9c46a

Please sign in to comment.