You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2018/10/23 17:48:56 UTC
[mynewt-core] branch master updated: Use generated sysdown()
function
This is an automated email from the ASF dual-hosted git repository.
ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push:
new 54b7b38 Use generated sysdown() function
54b7b38 is described below
commit 54b7b38a73811226015a2ac4fa681adafb68f48b
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Thu Oct 4 12:51:55 2018 -0700
Use generated sysdown() function
NOTE: This commit requires a newt tool update
(dfaede5fbdd0c9d798714abed77b54be2d26bc06).
Upon application-triggered restart, execute each package's shutdown
subprocedure. This feature is discussed here:
https://lists.apache.org/thread.html/ebd53c9b56230184650ea57e5534d5bcfbfc170b97547a1a26f100b5@%3Cdev.mynewt.apache.org%3E
---
kernel/os/include/os/mynewt.h | 1 +
kernel/os/include/os/os.h | 11 ++
kernel/os/pkg.yml | 3 +-
kernel/os/src/os.c | 18 ++++
mgmt/newtmgr/nmgr_os/src/newtmgr_os.c | 8 +-
sys/shell/src/shell_os.c | 3 +-
sys/sysdown/include/sysdown/sysdown.h | 118 ++++++++++++++++++++
{kernel/os => sys/sysdown}/pkg.yml | 29 +----
sys/sysdown/src/sysdown.c | 162 ++++++++++++++++++++++++++++
kernel/os/pkg.yml => sys/sysdown/syscfg.yml | 46 ++++----
10 files changed, 336 insertions(+), 63 deletions(-)
diff --git a/kernel/os/include/os/mynewt.h b/kernel/os/include/os/mynewt.h
index ca544ee..910e642 100644
--- a/kernel/os/include/os/mynewt.h
+++ b/kernel/os/include/os/mynewt.h
@@ -21,6 +21,7 @@
#define H_OS_MYNEWT_
#include "syscfg/syscfg.h"
+#include "sysdown/sysdown.h"
#include "sysinit/sysinit.h"
#include "sysflash/sysflash.h"
#include "os/os.h"
diff --git a/kernel/os/include/os/os.h b/kernel/os/include/os/os.h
index 40cbf54..5353832 100644
--- a/kernel/os/include/os/os.h
+++ b/kernel/os/include/os/os.h
@@ -107,6 +107,17 @@ void os_init(int (*fn)(int argc, char **argv));
*/
void os_start(void);
+/**
+ * Reboots the system.
+ */
+void os_reboot(int reason);
+
+/**
+ * Performs a system reset. This is typically done at the end of a reboot
+ * procedure.
+ */
+void os_system_reset(void);
+
#include "os/endian.h"
#include "os/os_callout.h"
#include "os/os_cfg.h"
diff --git a/kernel/os/pkg.yml b/kernel/os/pkg.yml
index b1dffa5..dd0ea64 100644
--- a/kernel/os/pkg.yml
+++ b/kernel/os/pkg.yml
@@ -24,8 +24,9 @@ pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
pkg.deps:
- - "@apache-mynewt-core/sys/sysinit"
- "@apache-mynewt-core/sys/sys"
+ - "@apache-mynewt-core/sys/sysdown"
+ - "@apache-mynewt-core/sys/sysinit"
- "@apache-mynewt-core/util/mem"
pkg.req_apis:
diff --git a/kernel/os/src/os.c b/kernel/os/src/os.c
index 3a3c8e9..3bad696 100644
--- a/kernel/os/src/os.c
+++ b/kernel/os/src/os.c
@@ -24,6 +24,7 @@
#include "hal/hal_os_tick.h"
#include "hal/hal_bsp.h"
+#include "hal/hal_system.h"
#include "hal/hal_watchdog.h"
#if MYNEWT_VAL(RTT)
@@ -258,6 +259,23 @@ os_start(void)
}
void
+os_reboot(int reason)
+{
+ sysdown(reason);
+}
+
+void
+os_system_reset(void)
+{
+ /* Tickle watchdog just before re-entering bootloader. Depending on what
+ * the system has been doing lately, the watchdog timer might be close to
+ * firing.
+ */
+ hal_watchdog_tickle();
+ hal_system_reset();
+}
+
+void
os_pkg_init(void)
{
os_error_t err;
diff --git a/mgmt/newtmgr/nmgr_os/src/newtmgr_os.c b/mgmt/newtmgr/nmgr_os/src/newtmgr_os.c
index c83ee24..6c04186 100644
--- a/mgmt/newtmgr/nmgr_os/src/newtmgr_os.c
+++ b/mgmt/newtmgr/nmgr_os/src/newtmgr_os.c
@@ -307,13 +307,7 @@ nmgr_datetime_set(struct mgmt_cbuf *cb)
static void
nmgr_reset_tmo(struct os_event *ev)
{
- /*
- * Tickle watchdog just before re-entering bootloader.
- * Depending on what system has been doing lately, watchdog
- * timer might be close to firing.
- */
- hal_watchdog_tickle();
- hal_system_reset();
+ os_reboot(HAL_RESET_REQUESTED);
}
static int
diff --git a/sys/shell/src/shell_os.c b/sys/shell/src/shell_os.c
index eea6548..08a5fde 100644
--- a/sys/shell/src/shell_os.c
+++ b/sys/shell/src/shell_os.c
@@ -170,7 +170,8 @@ shell_os_reset_cmd(int argc, char **argv)
}
#endif
os_time_delay(OS_TICKS_PER_SEC / 10);
- hal_system_reset();
+ os_reboot(HAL_RESET_REQUESTED);
+ return 0;
}
#if MYNEWT_VAL(SHELL_CMD_HELP)
diff --git a/sys/sysdown/include/sysdown/sysdown.h b/sys/sysdown/include/sysdown/sysdown.h
new file mode 100644
index 0000000..ebb7d6c
--- /dev/null
+++ b/sys/sysdown/include/sysdown/sysdown.h
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef H_SYSDOWN_
+#define H_SYSDOWN_
+
+#include <inttypes.h>
+#include <assert.h>
+#include <stdbool.h>
+#include "syscfg/syscfg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SYSDOWN_COMPLETE 0
+#define SYSDOWN_IN_PROGRESS 1
+
+/**
+ * Whether the system is currently shutting down
+ */
+extern bool sysdown_active;
+
+typedef int sysdown_fn(int reason);
+typedef void sysdown_panic_fn(const char *file, int line, const char *func,
+ const char *expr, const char *msg);
+typedef void sysdown_complete_fn(int status, void *arg);
+
+extern sysdown_fn * const sysdown_cbs[];
+extern sysdown_panic_fn *sysdown_panic_cb;
+
+void sysdown_panic_set(sysdown_panic_fn *panic_fn);
+
+#if MYNEWT_VAL(SYSDOWN_PANIC_MESSAGE)
+
+#if MYNEWT_VAL(SYSDOWN_PANIC_FILE_LINE)
+#define SYSDOWN_PANIC_MSG(msg) sysdown_panic_cb(__FILE__, __LINE__, 0, 0, msg)
+#else
+#define SYSDOWN_PANIC_MSG(msg) sysdown_panic_cb(0, 0, 0, 0, msg)
+#endif
+
+#else
+
+#if MYNEWT_VAL(SYSDOWN_PANIC_FILE_LINE)
+#define SYSDOWN_PANIC_MSG(msg) sysdown_panic_cb(__FILE__, __LINE__, 0, 0, 0)
+#else
+#define SYSDOWN_PANIC_MSG(msg) sysdown_panic_cb(0, 0, 0, 0, 0)
+#endif
+
+#endif
+
+#define SYSDOWN_PANIC() SYSDOWN_PANIC_MSG(NULL)
+
+#define SYSDOWN_ASSERT_MSG(rc, msg) do \
+{ \
+ if (!(rc)) { \
+ SYSDOWN_PANIC_MSG(msg); \
+ } \
+} while (0)
+
+#define SYSDOWN_ASSERT(rc) SYSDOWN_ASSERT_MSG(rc, NULL)
+
+/**
+ * Asserts that system shutdown is in progress. This macro is used to ensure
+ * packages don't get shut down a second time after system shutdown has
+ * completed.
+ */
+#if MYNEWT_VAL(SYSDOWN_CONSTRAIN_DOWN)
+#define SYSDOWN_ASSERT_ACTIVE() assert(sysdown_active)
+#else
+#define SYSDOWN_ASSERT_ACTIVE()
+#endif
+
+/**
+ * @brief Performs a controlled shutdown and reset of the system.
+ *
+ * This function executes each package's shutdown sequence, then triggers a
+ * reboot.
+ *
+ * @param reason The reason for the shutdown. One of the
+ * HAL_RESET_[...] codes or an
+ * implementation-defined value.
+ *
+ * @return
+ */
+int sysdown(int reason);
+
+/**
+ * @brief Signals completion of an in-progress sysdown subprocedure.
+ *
+ * If a sysdown subprocedure needs to perform additional work after its
+ * callback finishes, it returns SYSDOWN_IN_PROGRESS. Later, when the
+ * subprocedure completes, it signals its completion asynchronously with a call
+ * to this function.
+ */
+void sysdown_release(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/kernel/os/pkg.yml b/sys/sysdown/pkg.yml
similarity index 62%
copy from kernel/os/pkg.yml
copy to sys/sysdown/pkg.yml
index b1dffa5..461da41 100644
--- a/kernel/os/pkg.yml
+++ b/sys/sysdown/pkg.yml
@@ -17,34 +17,11 @@
# under the License.
#
-pkg.name: kernel/os
-pkg.description: Mynewt operating system core.
+pkg.name: sys/sysdown
+pkg.description: Package for kicking off a controlled system shutdown.
pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
pkg.deps:
- - "@apache-mynewt-core/sys/sysinit"
- - "@apache-mynewt-core/sys/sys"
- - "@apache-mynewt-core/util/mem"
-
-pkg.req_apis:
- - console
-
-pkg.deps.OS_CLI:
- - "@apache-mynewt-core/sys/shell"
-
-pkg.deps.OS_COREDUMP:
- - "@apache-mynewt-core/sys/coredump"
-
-pkg.deps.BSP_SIMULATED:
- - "@apache-mynewt-core/kernel/sim"
-
-pkg.deps.OS_SYSVIEW:
- - "@apache-mynewt-core/sys/sysview"
-
-pkg.deps.OS_CRASH_LOG:
- - "@apache-mynewt-core/sys/reboot"
-
-pkg.init:
- os_pkg_init: 0
+ - "@apache-mynewt-core/kernel/os"
diff --git a/sys/sysdown/src/sysdown.c b/sys/sysdown/src/sysdown.c
new file mode 100644
index 0000000..682eadb
--- /dev/null
+++ b/sys/sysdown/src/sysdown.c
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 "os/mynewt.h"
+
+/**
+ * The NEWT_FEATURE_SYSDOWN setting is injected by new-enough versions of the
+ * newt tool.
+ */
+#if !MYNEWT_VAL(NEWT_FEATURE_SYSDOWN)
+
+int
+sysdown(int reason)
+{
+ os_system_reset();
+ return 0;
+}
+
+#else
+
+#include <assert.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <limits.h>
+#include "hal/hal_system.h"
+#include "hal/hal_watchdog.h"
+
+#define SYSDOWN_TIMEOUT_TICKS \
+ (MYNEWT_VAL(SYSDOWN_TIMEOUT_MS) * OS_TICKS_PER_SEC / 1000)
+
+_Static_assert(SYSDOWN_TIMEOUT_TICKS >= 0 && SYSDOWN_TIMEOUT_TICKS < INT32_MAX,
+ "SYSDOWN_TIMEOUT_MS value not in valid range");
+
+static volatile int sysdown_num_in_progress;
+bool sysdown_active;
+static struct os_callout sysdown_timer;
+
+static void
+sysdown_dflt_panic_cb(const char *file, int line, const char *func,
+ const char *expr, const char *msg)
+{
+#if MYNEWT_VAL(SYSDOWN_PANIC_MESSAGE)
+ if (msg != NULL) {
+ fprintf(stderr, "sysdown failure: %s\n", msg);
+ }
+#endif
+
+ __assert_func(file, line, func, expr);
+}
+
+sysdown_panic_fn *sysdown_panic_cb = sysdown_dflt_panic_cb;
+
+/**
+ * Sets the sysdown panic function; i.e., the function which executes when
+ * shutdown fails. By default, a panic triggers a failed assertion.
+ */
+void
+sysdown_panic_set(sysdown_panic_fn *panic_cb)
+{
+ sysdown_panic_cb = panic_cb;
+}
+
+static void
+sysdown_complete(void)
+{
+ os_callout_stop(&sysdown_timer);
+ os_system_reset();
+}
+
+void
+sysdown_release(void)
+{
+ os_sr_t sr;
+ int count;
+
+ OS_ENTER_CRITICAL(sr);
+ count = --sysdown_num_in_progress;
+ OS_EXIT_CRITICAL(sr);
+
+ if (count <= 0) {
+ sysdown_complete();
+ }
+}
+
+static void
+sysdown_timer_exp(struct os_event *unused)
+{
+ assert(0);
+}
+
+int
+sysdown(int reason)
+{
+ os_sr_t sr;
+ int rc;
+ int i;
+
+ /* Only allow one shutdown operation. */
+ OS_ENTER_CRITICAL(sr);
+ if (sysdown_active) {
+ rc = SYS_EALREADY;
+ } else {
+ sysdown_active = true;
+ rc = 0;
+ }
+ OS_EXIT_CRITICAL(sr);
+
+ if (rc != 0) {
+ return rc;
+ }
+
+ os_callout_init(&sysdown_timer, os_eventq_dflt_get(), sysdown_timer_exp,
+ NULL);
+ rc = os_callout_reset(&sysdown_timer, SYSDOWN_TIMEOUT_TICKS);
+ assert(rc == 0);
+
+ /* Call each configured sysdown callback. */
+ for (i = 0; sysdown_cbs[i] != NULL; i++) {
+ rc = sysdown_cbs[i](reason);
+ switch (rc) {
+ case SYSDOWN_COMPLETE:
+ break;
+
+ case SYSDOWN_IN_PROGRESS:
+ OS_ENTER_CRITICAL(sr);
+ sysdown_num_in_progress++;
+ OS_EXIT_CRITICAL(sr);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* If all subprocedures are complete, signal completion of sysdown.
+ * Otherwise, wait for in-progress subprocedures to signal completion
+ * asynchronously.
+ */
+ if (sysdown_num_in_progress == 0) {
+ sysdown_complete();
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/kernel/os/pkg.yml b/sys/sysdown/syscfg.yml
similarity index 52%
copy from kernel/os/pkg.yml
copy to sys/sysdown/syscfg.yml
index b1dffa5..a5697a7 100644
--- a/kernel/os/pkg.yml
+++ b/sys/sysdown/syscfg.yml
@@ -1,4 +1,3 @@
-#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
@@ -17,34 +16,25 @@
# under the License.
#
-pkg.name: kernel/os
-pkg.description: Mynewt operating system core.
-pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-
-pkg.deps:
- - "@apache-mynewt-core/sys/sysinit"
- - "@apache-mynewt-core/sys/sys"
- - "@apache-mynewt-core/util/mem"
-
-pkg.req_apis:
- - console
-
-pkg.deps.OS_CLI:
- - "@apache-mynewt-core/sys/shell"
-
-pkg.deps.OS_COREDUMP:
- - "@apache-mynewt-core/sys/coredump"
+# Package: sys/sysdown
-pkg.deps.BSP_SIMULATED:
- - "@apache-mynewt-core/kernel/sim"
+syscfg.defs:
+ SYSDOWN_CONSTRAIN_DOWN:
+ description: Only allow packages to be shutdown by sysdown.
+ value: 1
-pkg.deps.OS_SYSVIEW:
- - "@apache-mynewt-core/sys/sysview"
+ SYSDOWN_PANIC_FILE_LINE:
+ description: Include filename and line number in sysdown panic.
+ value: 0
-pkg.deps.OS_CRASH_LOG:
- - "@apache-mynewt-core/sys/reboot"
+ SYSDOWN_PANIC_MESSAGE:
+ description: Include descriptive message in sysdown panic.
+ value: 0
-pkg.init:
- os_pkg_init: 0
+ SYSDOWN_TIMEOUT_MS:
+ description: >
+ Total duration, in milliseconds, before the shutdown procedure
+ times out. On timeout, the system triggers a failed assertion.
+ NOTE: This timeout applies to the full shutdown procedure, not to a
+ single subprocedure.
+ value: 10000