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