From f2f8a7a0fc6e57aa36b0b5e1e6d33df37ea37f28 Mon Sep 17 00:00:00 2001 From: Robert Quattlebaum Date: Tue, 26 Jul 2016 12:00:36 -0700 Subject: [PATCH] Added platform APIs for handling resets. (#284) This change includes the addition of two new platform API functions: * `otPlatReset()` * `otPlatGetResetReason()` They are pretty straightforward. Every platform must implement both, but `otPlatReset()` is allowed to simply return if the platform doesn't support being reset (like the posix platform). This commit addresses issue #283. --- examples/platforms/cc2538/Makefile.am | 1 + examples/platforms/cc2538/cc2538-reg.h | 3 + examples/platforms/cc2538/misc.c | 41 +++++++++++++ examples/platforms/posix/Makefile.am | 1 + examples/platforms/posix/misc.c | 40 +++++++++++++ include/platform/Makefile.am | 1 + include/platform/misc.h | 81 ++++++++++++++++++++++++++ src/ncp/ncp_base.cpp | 68 +++++++++++++++++++-- src/ncp/spinel.h | 2 + 9 files changed, 232 insertions(+), 6 deletions(-) create mode 100644 examples/platforms/cc2538/misc.c create mode 100644 examples/platforms/posix/misc.c create mode 100644 include/platform/misc.h diff --git a/examples/platforms/cc2538/Makefile.am b/examples/platforms/cc2538/Makefile.am index ed451a94e..5f9efac62 100644 --- a/examples/platforms/cc2538/Makefile.am +++ b/examples/platforms/cc2538/Makefile.am @@ -37,6 +37,7 @@ libopenthread_cc2538_a_CPPFLAGS = \ libopenthread_cc2538_a_SOURCES = \ alarm.c \ + misc.c \ logging.c \ platform.c \ radio.c \ diff --git a/examples/platforms/cc2538/cc2538-reg.h b/examples/platforms/cc2538/cc2538-reg.h index 3302ec496..5c756bf1e 100644 --- a/examples/platforms/cc2538/cc2538-reg.h +++ b/examples/platforms/cc2538/cc2538-reg.h @@ -98,6 +98,9 @@ #define SYS_CTRL_SYSDIV_32MHZ 0x00000000 // Sys_div for sysclk 32MHz #define SYS_CTRL_CLOCK_CTRL_AMP_DET 0x00200000 +#define SYS_CTRL_PWRDBG 0x400D2074 +#define SYS_CTRL_PWRDBG_FORCE_WARM_RESET 0x00000008 + #define SYS_CTRL_RCGCUART 0x400D2028 #define SYS_CTRL_SCGCUART 0x400D202C #define SYS_CTRL_DCGCUART 0x400D2030 diff --git a/examples/platforms/cc2538/misc.c b/examples/platforms/cc2538/misc.c new file mode 100644 index 000000000..2072590ed --- /dev/null +++ b/examples/platforms/cc2538/misc.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, Nest Labs, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "platform-cc2538.h" + +void otPlatReset(void) +{ + HWREG(SYS_CTRL_PWRDBG) = SYS_CTRL_PWRDBG_FORCE_WARM_RESET; +} + +otPlatResetReason otPlatGetResetReason(void) +{ + // TODO: Write me! + return kPlatResetReason_PowerOn; +} diff --git a/examples/platforms/posix/Makefile.am b/examples/platforms/posix/Makefile.am index 1ce9f7e81..444fda1ed 100644 --- a/examples/platforms/posix/Makefile.am +++ b/examples/platforms/posix/Makefile.am @@ -38,6 +38,7 @@ libopenthread_posix_a_CPPFLAGS = \ libopenthread_posix_a_SOURCES = \ alarm.c \ + misc.c \ logging.c \ platform.c \ radio.c \ diff --git a/examples/platforms/posix/misc.c b/examples/platforms/posix/misc.c new file mode 100644 index 000000000..68fc0dcba --- /dev/null +++ b/examples/platforms/posix/misc.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, Nest Labs, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "platform-posix.h" + +void otPlatReset(void) +{ + // This function does nothing on the Posix platform. +} + +otPlatResetReason otPlatGetResetReason(void) +{ + return kPlatResetReason_PowerOn; +} diff --git a/include/platform/Makefile.am b/include/platform/Makefile.am index d728984bc..36c0a7249 100644 --- a/include/platform/Makefile.am +++ b/include/platform/Makefile.am @@ -30,6 +30,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am ot_platform_headers =\ alarm.h \ + misc.h \ logging.h \ radio.h \ random.h \ diff --git a/include/platform/misc.h b/include/platform/misc.h new file mode 100644 index 000000000..f4821250b --- /dev/null +++ b/include/platform/misc.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016, Nest Labs, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief + * This file includes platform abstractions for miscelaneous behaviors. + */ + +#ifndef OT_PLATFORM_MISC_H +#define OT_PLATFORM_MISC_H 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This function performs a software reset on the platform, if supported. + * + */ +void otPlatReset(void); + +/** + * Enumeration of possible reset reason codes. + * + * These are in the same order as the Spinel reset reason codes. + * + */ +typedef enum +{ + kPlatResetReason_PowerOn = 0, + kPlatResetReason_External = 1, + kPlatResetReason_Software = 2, + kPlatResetReason_Fault = 3, + kPlatResetReason_Crash = 4, + kPlatResetReason_Assert = 5, + kPlatResetReason_Other = 6, + kPlatResetReason_Unknown = 7, + kPlatResetReason_Watchdog = 8, + + kPlatResetReason_Count, +} otPlatResetReason; + +/** + * This function returns the reason for the last platform reset. + * + */ +otPlatResetReason otPlatGetResetReason(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // OT_PLATFORM_MISC_H diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 19e857860..078914acb 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -38,6 +38,7 @@ #include #include #include +#include namespace Thread { @@ -45,6 +46,8 @@ extern ThreadNetif *sThreadNetif; static NcpBase *sNcpContext = NULL; +#define NCP_PLAT_RESET_REASON (1<<31) + // ---------------------------------------------------------------------------- // MARK: Command/Property Jump Tables // ---------------------------------------------------------------------------- @@ -254,6 +257,42 @@ static spinel_status_t ThreadErrorToSpinelStatus(ThreadError error) return ret; } +static spinel_status_t ResetReasonToSpinelStatus(otPlatResetReason reason) +{ + spinel_status_t ret; + switch (reason) + { + case kPlatResetReason_PowerOn: + ret = SPINEL_STATUS_RESET_POWER_ON; + break; + case kPlatResetReason_External: + ret = SPINEL_STATUS_RESET_EXTERNAL; + break; + case kPlatResetReason_Software: + ret = SPINEL_STATUS_RESET_SOFTWARE; + break; + case kPlatResetReason_Fault: + ret = SPINEL_STATUS_RESET_FAULT; + break; + case kPlatResetReason_Crash: + ret = SPINEL_STATUS_RESET_CRASH; + break; + case kPlatResetReason_Assert: + ret = SPINEL_STATUS_RESET_ASSERT; + break; + case kPlatResetReason_Watchdog: + ret = SPINEL_STATUS_RESET_WATCHDOG; + break; + case kPlatResetReason_Other: + ret = SPINEL_STATUS_RESET_OTHER; + break; + default: + ret = SPINEL_STATUS_RESET_UNKNOWN; + break; + } + return ret; +} + // ---------------------------------------------------------------------------- // MARK: Class Boilerplate // ---------------------------------------------------------------------------- @@ -265,7 +304,7 @@ NcpBase::NcpBase(): mChannelMask = mSupportedChannelMask; mScanPeriod = 200; // ms sNcpContext = this; - mChangedFlags = 0; + mChangedFlags = NCP_PLAT_RESET_REASON; mAllowLocalNetworkDataChange = false; for (unsigned i = 0; i < sizeof(mNetifAddresses) / sizeof(mNetifAddresses[0]); i++) @@ -430,7 +469,15 @@ void NcpBase::UpdateChangedProps() { if (!mSending) { - if ((mChangedFlags & OT_IP6_ML_ADDR_CHANGED) != 0) + if ((mChangedFlags & NCP_PLAT_RESET_REASON) != 0) + { + mChangedFlags &= ~NCP_PLAT_RESET_REASON; + SendLastStatus( + SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, + ResetReasonToSpinelStatus(otPlatGetResetReason()) + ); + } + else if ((mChangedFlags & OT_IP6_ML_ADDR_CHANGED) != 0) { mChangedFlags &= ~OT_IP6_ML_ADDR_CHANGED; HandleCommandPropertyGet( @@ -871,14 +918,23 @@ void NcpBase::CommandHandler_NOOP(uint8_t header, unsigned int command, const ui void NcpBase::CommandHandler_RESET(uint8_t header, unsigned int command, const uint8_t *arg_ptr, uint16_t arg_len) { - // TODO: Figure out how to actually perform a reset. - otDisable(); - otEnable(); - SendLastStatus(SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0, SPINEL_STATUS_RESET_SOFTWARE); + // We aren't using any of the arguments to this function. (void)header; (void)command; (void)arg_ptr; (void)arg_len; + + // Signal a platform reset. If implemented, this function + // shouldn't return. + otPlatReset(); + + // We only get to this point if the + // platform doesn't support resetting. + // In such a case we fake it. + + mChangedFlags |= NCP_PLAT_RESET_REASON; + otDisable(); + mUpdateChangedPropsTask.Post(); } void NcpBase::CommandHandler_PROP_VALUE_GET(uint8_t header, unsigned int command, const uint8_t *arg_ptr, diff --git a/src/ncp/spinel.h b/src/ncp/spinel.h index a3f91bd93..ac050f8cc 100644 --- a/src/ncp/spinel.h +++ b/src/ncp/spinel.h @@ -108,6 +108,8 @@ typedef enum SPINEL_STATUS_RESET_CRASH = SPINEL_STATUS_RESET__BEGIN + 4, SPINEL_STATUS_RESET_ASSERT = SPINEL_STATUS_RESET__BEGIN + 5, SPINEL_STATUS_RESET_OTHER = SPINEL_STATUS_RESET__BEGIN + 6, + SPINEL_STATUS_RESET_UNKNOWN = SPINEL_STATUS_RESET__BEGIN + 7, + SPINEL_STATUS_RESET_WATCHDOG = SPINEL_STATUS_RESET__BEGIN + 8, SPINEL_STATUS_RESET__END = 128,