diff --git a/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp b/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp index 6aebf3d2c8a583..6fac30482f6251 100644 --- a/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp +++ b/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp @@ -31,7 +31,9 @@ #include #include -#ifdef CONFIG_MCUBOOT_IMG_MANAGER +#if CHIP_DEVICE_LAYER_TARGET_NRFCONNECT +#include +#elif defined(CONFIG_MCUBOOT_IMG_MANAGER) #include #endif @@ -88,7 +90,12 @@ BootReasonType DetermineBootReason() if (reason & RESET_SOFTWARE) { -#ifdef CONFIG_MCUBOOT_IMG_MANAGER +#if CHIP_DEVICE_LAYER_TARGET_NRFCONNECT + if (GetSoftwareRebootReason() == SoftwareRebootReason::kSoftwareUpdate) + { + return BootReasonType::kSoftwareUpdateCompleted; + } +#elif defined(CONFIG_MCUBOOT_IMG_MANAGER) if (mcuboot_swap_type() == BOOT_SWAP_TYPE_REVERT) { return BootReasonType::kSoftwareUpdateCompleted; diff --git a/src/platform/nrfconnect/BUILD.gn b/src/platform/nrfconnect/BUILD.gn index 928c3c045b4725..3af24f2a72d0b5 100644 --- a/src/platform/nrfconnect/BUILD.gn +++ b/src/platform/nrfconnect/BUILD.gn @@ -46,6 +46,8 @@ static_library("nrfconnect") { "InetPlatformConfig.h", "KeyValueStoreManagerImpl.h", "PlatformManagerImpl.h", + "Reboot.cpp", + "Reboot.h", "SystemPlatformConfig.h", ] diff --git a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp index b558906258e994..bb8f846d8d900c 100644 --- a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp +++ b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp @@ -17,6 +17,8 @@ #include "OTAImageProcessorImpl.h" +#include "Reboot.h" + #include #include #include @@ -35,7 +37,6 @@ #include #include #include -#include #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE // Cd globals are needed to be accessed from dfu image writer lambdas @@ -123,7 +124,7 @@ CHIP_ERROR OTAImageProcessorImpl::Apply() [](System::Layer *, void * /* context */) { PlatformMgr().HandleServerShuttingDown(); k_msleep(CHIP_DEVICE_CONFIG_SERVER_SHUTDOWN_ACTIONS_SLEEP_MS); - sys_reboot(SYS_REBOOT_WARM); + Reboot(SoftwareRebootReason::kSoftwareUpdate); }, nullptr /* context */); } diff --git a/src/platform/nrfconnect/Reboot.cpp b/src/platform/nrfconnect/Reboot.cpp new file mode 100644 index 00000000000000..5b1b6abdde68ad --- /dev/null +++ b/src/platform/nrfconnect/Reboot.cpp @@ -0,0 +1,85 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Reboot.h" + +#include + +#include + +#ifndef CONFIG_ARCH_POSIX +#include +#endif + +namespace chip { +namespace DeviceLayer { + +#ifdef CONFIG_ARCH_POSIX + +void Reboot(SoftwareRebootReason reason) +{ + sys_reboot(SYS_REBOOT_WARM); +} + +SoftwareRebootReason GetSoftwareRebootReason() +{ + return SoftwareRebootReason::kOther; +} + +#else + +using RetainedReason = decltype(nrf_power_gpregret_get(NRF_POWER)); + +constexpr RetainedReason EncodeReason(SoftwareRebootReason reason) +{ + // Set MSB to avoid collission with Zephyr's pre-defined reboot reasons. + constexpr RetainedReason kCustomReasonFlag = 0x80; + + return static_cast(reason) | kCustomReasonFlag; +} + +void Reboot(SoftwareRebootReason reason) +{ + const RetainedReason retainedReason = EncodeReason(reason); + + // The parameter passed to sys_reboot() is retained in GPREGRET (general-purpose + // retention register) on nRF52 SOC family, but nRF53 ignores the parameter, so + // set it manually. + +#ifdef CONFIG_SOC_SERIES_NRF53X + nrf_power_gpregret_set(NRF_POWER, retainedReason); +#endif + + sys_reboot(retainedReason); +} + +SoftwareRebootReason GetSoftwareRebootReason() +{ + switch (nrf_power_gpregret_get(NRF_POWER)) + { + case EncodeReason(SoftwareRebootReason::kSoftwareUpdate): + nrf_power_gpregret_set(NRF_POWER, 0); + return SoftwareRebootReason::kSoftwareUpdate; + default: + return SoftwareRebootReason::kOther; + } +} + +#endif + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nrfconnect/Reboot.h b/src/platform/nrfconnect/Reboot.h new file mode 100644 index 00000000000000..09f5493ebf17ad --- /dev/null +++ b/src/platform/nrfconnect/Reboot.h @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +enum class SoftwareRebootReason : uint8_t +{ + kSoftwareUpdate, + kOther +}; + +[[noreturn]] void Reboot(SoftwareRebootReason reason); +SoftwareRebootReason GetSoftwareRebootReason(); + +} // namespace DeviceLayer +} // namespace chip