blob: ad83ba18c31cd051703cc6fcb962e887bfa95101 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>System Initialization and System Shutdown &mdash; Apache Mynewt latest documentation</title>
<link rel="shortcut icon" href="../../../_static/mynewt-logo-only-newt32x32.png"/>
<link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/sphinx_theme.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/bootstrap-3.0.3.min.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/v2.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/restructuredtext.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/css/overrides.css" type="text/css" />
<link rel="index" title="Index"
href="../../../genindex.html"/>
<link rel="search" title="Search" href="../../../search.html"/>
<link rel="top" title="Apache Mynewt latest documentation" href="../../../index.html"/>
<link rel="up" title="OS User Guide" href="../../os_user_guide.html"/>
<link rel="next" title="Build-Time Hooks" href="../extcmd/extcmd.html"/>
<link rel="prev" title="Validation and Error Messages" href="../sysinitconfig/sysconfig_error.html"/>
<script src="../../../_static/js/modernizr.min.js"></script>
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="not-front page-documentation" role="document" >
<div id="wrapper">
<div class="container">
<div id="banner" class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="../../../_static/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released September 7, 2023)
</div>
</div>
</div>
</div>
<header>
<nav id="navbar" class="navbar navbar-inverse" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li class="important">
<a href="/quick-start/">Quick Start</a>
</li>
<li>
<a href="/about/">About</a>
</li>
<li>
<a href="/talks/">Talks</a>
</li>
<li class="active">
<a href="/documentation/">Documentation</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/community/">Community</a>
</li>
<li>
<a href="/events/">Events</a>
</li>
</ul>
<!-- Search, Navigation and Repo links -->
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</header>
<!-- STARTS MAIN CONTENT -->
<div id="main-content">
<div id="breadcrumb">
<div class="container">
<a href="/documentation/">Docs</a> /
<a href="../../os_user_guide.html">OS User Guide</a> /
System Initialization and System Shutdown
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-core/edit/master/docs/os/modules/sysinitdown/sysinitdown.rst" class="icon icon-github"
rel="nofollow"> Edit on GitHub</a>
</div>
</div>
</div>
<!-- STARTS CONTAINER -->
<div class="container">
<!-- STARTS .content -->
<div id="content" class="row">
<!-- STARTS .container-sidebar -->
<div class="container-sidebar col-xs-12 col-sm-3">
<div id="docSidebar" class="sticky-container">
<div role="search" class="sphinx-search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<input type="text" name="q" placeholder="Search documentation" class="search-documentation" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<!-- Note: only works when deployed -->
<select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest" selected>
Version: latest
</option>
<option value="/v1_11_0" selected="selected" >
Version: 1.11.0
</option>
<option value="/v1_10_0" >
Version: 1.10.0
</option>
<option value="/v1_9_0" >
Version: 1.9.0
</option>
<option value="/v1_8_0" >
Version: 1.8.0
</option>
<option value="/v1_7_0" >
Version: 1.7.0
</option>
<option value="/v1_6_0" >
Version: 1.6.0
</option>
<option value="/v1_5_0" >
Version: 1.5.0
</option>
<option value="/v1_4_0" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select>
<div class="region region-sidebar">
<div class="docs-menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../../index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../get_started/index.html">Setup &amp; Get Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../concepts.html">Concepts</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../tutorials/tutorials.html">Tutorials</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../external_links.html">Third-party Resources</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../../os_user_guide.html">OS User Guide</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../../core_os/mynewt_os.html">Kernel</a></li>
<li class="toctree-l2"><a class="reference internal" href="../system_modules.html">System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../hal/hal.html">Hardware Abstraction</a></li>
<li class="toctree-l2"><a class="reference internal" href="../bootloader/bootloader.html">Secure Bootloader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../split/split.html">Split Images</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../core_os/porting/port_os.html">Porting Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../baselibc.html">Baselibc</a></li>
<li class="toctree-l2"><a class="reference internal" href="../drivers/driver.html">Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../devmgmt/newtmgr.html">Device Management with Newt Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mcumgr/mcumgr.html">Device Management with MCUmgr</a></li>
<li class="toctree-l2"><a class="reference internal" href="../imgmgr/imgmgr.html">Image Manager</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sysinitconfig/sysinitconfig.html">Compile-Time Configuration</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">System Initialization and Shutdown</a><ul class="simple">
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../extcmd/extcmd.html">Build-Time Hooks</a></li>
<li class="toctree-l2"><a class="reference internal" href="../fs/fs.html">File System</a></li>
<li class="toctree-l2"><a class="reference internal" href="../fcb/fcb.html">Flash Circular Buffer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sensor_framework/sensor_framework.html">Sensor Framework</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testutil/testutil.html">Test Utilities</a></li>
<li class="toctree-l2"><a class="reference internal" href="../json/json.html">JSON</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mfg/mfg.html">Manufacturing support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../bsp/index.html">Board support</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../network/index.html">BLE User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newt/index.html">Newt Tool Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../newtmgr/index.html">Newt Manager Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../mynewt_faq/index.html">Mynewt FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../misc/index.html">Appendix</a></li>
</ul>
</div>
</div>
</div>
<!-- ENDS STICKY CONTAINER -->
</div>
<!-- ENDS .container-sidebar -->
<div class="col-xs-12 col-sm-9">
<div class="alert alert-warning">
<p>
Version 1.11.0 is not the most recent version of the
Apache Mynewt documentation. Click <a href="/latest">here</a> to
read the latest version.
</p>
</div>
<div class="">
<div class="rst-content">
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="system-initialization-and-system-shutdown">
<h1>System Initialization and System Shutdown<a class="headerlink" href="#system-initialization-and-system-shutdown" title="Permalink to this headline"></a></h1>
<div class="toctree-wrapper compound">
</div>
<p>Mynewt allows a package to designate startup and shutdown functions.
These functions are called automatically by the OS using facilities
called <em>sysinit</em> and <em>sysdown</em>.</p>
<p>This guide:</p>
<ul class="simple">
<li><p>Assumes you have read the
<a class="reference internal" href="../../../concepts.html#concepts"><span class="std std-ref">Concepts</span></a> section that describes
the Mynewt package hierarchy and its use of the <code class="docutils literal notranslate"><span class="pre">pkg.yml</span></code> and
<code class="docutils literal notranslate"><span class="pre">syscfg.yml</span></code> files.</p></li>
<li><p>Assumes you have read the Mynewt <a class="reference internal" href="../../../newt/newt_operation.html"><span class="doc">Theory of Operations</span></a> and are familiar with how newt
determines package dependencies for your target build.</p></li>
</ul>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#system-initialization" id="id1">System Initialization</a></p>
<ul>
<li><p><a class="reference internal" href="#specifying-package-initialization-functions" id="id2">Specifying Package Initialization Functions</a></p></li>
<li><p><a class="reference internal" href="#generated-sysinit-app-function" id="id3">Generated sysinit_app() Function</a></p></li>
</ul>
</li>
<li><p><a class="reference internal" href="#system-shutdown" id="id4">System Shutdown</a></p></li>
</ul>
</div>
<div class="section" id="system-initialization">
<h2><a class="toc-backref" href="#id1">System Initialization</a><a class="headerlink" href="#system-initialization" title="Permalink to this headline"></a></h2>
<p>During system startup, Mynewt creates a default event queue and a main
task to process events from this queue. You can override the
<code class="docutils literal notranslate"><span class="pre">OS_MAIN_TASK_PRIO</span></code> and <code class="docutils literal notranslate"><span class="pre">OS_MAIN_TASK_STACK_SIZE</span></code> setting values
defined by the <code class="docutils literal notranslate"><span class="pre">kernel/os</span></code> package to specify different task priority
and stack size values.</p>
<p>Your application’s <code class="docutils literal notranslate"><span class="pre">main()</span></code> function executes in the context of the
main task and must perform the following:</p>
<ul class="simple">
<li><p>At the start of <code class="docutils literal notranslate"><span class="pre">main()</span></code>, call the Mynewt <code class="docutils literal notranslate"><span class="pre">sysinit()</span></code> function to
initialize the packages before performing any other processing.</p></li>
<li><p>At the end of <code class="docutils literal notranslate"><span class="pre">main()</span></code>, wait for and dispatch events from the
default event queue in an infinite loop.</p></li>
</ul>
<p><strong>Note:</strong> You must include the <code class="docutils literal notranslate"><span class="pre">sysinit/sysinit.h</span></code> header file to
access the <code class="docutils literal notranslate"><span class="pre">sysinit()</span></code> function.</p>
<p>Here is an example of a <code class="docutils literal notranslate"><span class="pre">main()</span></code> function:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span>
<span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="cm">/* First, call sysinit() to perform the system and package initialization */</span>
<span class="w"> </span><span class="n">sysinit</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/* ... other application initialization processing ... */</span>
<span class="w"> </span><span class="cm">/* Last, process events from the default event queue. */</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">os_eventq_run</span><span class="p">(</span><span class="n">os_eventq_dflt_get</span><span class="p">());</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="cm">/* main never returns */</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="section" id="specifying-package-initialization-functions">
<h3><a class="toc-backref" href="#id2">Specifying Package Initialization Functions</a><a class="headerlink" href="#specifying-package-initialization-functions" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">sysinit()</span></code> function calls the <code class="docutils literal notranslate"><span class="pre">sysinit_app()</span></code> function to
perform system initialization for the packages in the target. You can,
optionally, specify one or more package initialization functions that
<code class="docutils literal notranslate"><span class="pre">sysinit_app()</span></code> calls to initialize a package.</p>
<p>A package initialization function must have the following prototype:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="n">init_func_name</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
</pre></div>
</div>
<p>Sysinit functions are not expected to fail. If a sysinit function
encounters an unrecoverable failure, it should invoke one of the
<code class="docutils literal notranslate"><span class="pre">SYSINIT_PANIC</span></code> macros. By default, these macros trigger a crash,
but the behavior can be overridden by configuring the panic function
with <code class="docutils literal notranslate"><span class="pre">sysinit_panic_set()</span></code>.</p>
<p>Package initialization functions are called in stages to ensure that
lower priority packages are initialized before higher priority packages.
A stage is an integer value, 0 or higher, that specifies when an
initialization function is called. Mynewt calls the package
initialization functions in increasing stage number order. When
multiple init functions have the same stage number, they are called in
lexicographic order (by function name).</p>
<p>You use the <code class="docutils literal notranslate"><span class="pre">pkg.init</span></code> parameter in the <code class="docutils literal notranslate"><span class="pre">pkg.yml</span></code> file to specify an
initialization function and the stage number to call the function. You
can specify multiple initialization functions with a different stage
number for each function for the parameter values. This feature allows
packages with interdependencies to perform initialization in multiple
stages.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">pkg.init</span></code> parameter has the following syntax in the <code class="docutils literal notranslate"><span class="pre">pkg.yml</span></code>
file:</p>
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">pkg.init</span><span class="p">:</span>
<span class="w"> </span><span class="nt">pkg_init_func1_name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pkg_init_func1_stage</span>
<span class="w"> </span><span class="nt">pkg_init_func2_name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pkg_init_func2_stage</span>
<span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
<span class="w"> </span><span class="nt">pkg_init_funcN_name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pkg_init_funcN_stage</span>
</pre></div>
</div>
<p>where <code class="docutils literal notranslate"><span class="pre">pkg_init_func#_name</span></code> is the C function name of an
initialization function, and <code class="docutils literal notranslate"><span class="pre">pkg_init_func#_stage</span></code> is an integer
value, 0 or higher, that indicates the stage when the
<code class="docutils literal notranslate"><span class="pre">pkg_init_func#_name</span></code> function is called.</p>
</div>
<div class="section" id="generated-sysinit-app-function">
<h3><a class="toc-backref" href="#id3">Generated sysinit_app() Function</a><a class="headerlink" href="#generated-sysinit-app-function" title="Permalink to this headline"></a></h3>
<p>The newt tool processes the <code class="docutils literal notranslate"><span class="pre">pkg.init</span></code> parameters in all the
<code class="docutils literal notranslate"><span class="pre">pkg.yml</span></code> files for a target, generates the <code class="docutils literal notranslate"><span class="pre">sysinit_app()</span></code> function
in the <code class="docutils literal notranslate"><span class="pre">&lt;target-path&gt;/generated/src/&lt;target-name&gt;-sysinit_app.c</span></code> file,
and includes the file in the build. Here is an example <code class="docutils literal notranslate"><span class="pre">sysinit_app()</span></code>
function:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="cm">/**</span>
<span class="cm"> * This file was generated by Apache Newt (incubating) version: 1.0.0-dev</span>
<span class="cm"> */</span>
<span class="cp">#if !SPLIT_LOADER</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">split_app_init</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">os_pkg_init</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">imgmgr_module_init</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
<span class="cm">/* ... */</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">stats_module_init</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
<span class="kt">void</span>
<span class="nf">sysinit_app</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="cm">/*** Stage 0 */</span>
<span class="w"> </span><span class="cm">/* 0.0: kernel/os */</span>
<span class="w"> </span><span class="n">os_pkg_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/*** Stage 2 */</span>
<span class="w"> </span><span class="cm">/* 2.0: sys/flash_map */</span>
<span class="w"> </span><span class="n">flash_map_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/*** Stage 10 */</span>
<span class="w"> </span><span class="cm">/* 10.0: sys/stats/full */</span>
<span class="w"> </span><span class="n">stats_module_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/*** Stage 20 */</span>
<span class="w"> </span><span class="cm">/* 20.0: sys/console/full */</span>
<span class="w"> </span><span class="n">console_pkg_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/*** Stage 100 */</span>
<span class="w"> </span><span class="cm">/* 100.0: sys/log/full */</span>
<span class="w"> </span><span class="n">log_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/* 100.1: sys/mfg */</span>
<span class="w"> </span><span class="n">mfg_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/* ... */</span>
<span class="w"> </span><span class="cm">/*** Stage 300 */</span>
<span class="w"> </span><span class="cm">/* 300.0: sys/config */</span>
<span class="w"> </span><span class="n">config_pkg_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/*** Stage 500 */</span>
<span class="w"> </span><span class="cm">/* 500.0: sys/id */</span>
<span class="w"> </span><span class="n">id_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/* 500.1: sys/shell */</span>
<span class="w"> </span><span class="n">shell_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/* ... */</span>
<span class="w"> </span><span class="cm">/* 500.4: mgmt/imgmgr */</span>
<span class="w"> </span><span class="n">imgmgr_module_init</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/*** Stage 501 */</span>
<span class="w"> </span><span class="cm">/* 501.0: mgmt/newtmgr/transport/nmgr_shell */</span>
<span class="w"> </span><span class="n">nmgr_shell_pkg_init</span><span class="p">();</span>
<span class="p">}</span>
<span class="cp">#endif</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="system-shutdown">
<h2><a class="toc-backref" href="#id4">System Shutdown</a><a class="headerlink" href="#system-shutdown" title="Permalink to this headline"></a></h2>
<p>A Mynewt package can specify a sequence of system shutdown (“sysdown”)
function calls. As with sysinit, a stage number is associated with
each function. On shutdown, sysdown functions are executed in
ascending order of stage number. In the case of a tie, functions are
executed in lexicographic order (by function name).</p>
<p>The sysdown procedure is only performed for a controlled
shutdown. It is executed when the system processes a newtmgr
“reset” command, for example. It is not be executed when the system
crashes, browns out, or restarts due to the hardware watchdog.</p>
<p>Sysdown functions are specified in a <code class="docutils literal notranslate"><span class="pre">pkg.yml</span></code> file using the
<code class="docutils literal notranslate"><span class="pre">pkg.down</span></code> key. They use the following function type:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="n">func</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">reason</span><span class="p">)</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">reason</span></code> parameter is currently unused and should be ignored.</p>
<p>Each shutdown callback returns one of the following codes:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">SYSDOWN_COMPLETE</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">SYSDOWN_IN_PROGRESS</span></code></p></li>
</ul>
<p>If a sysdown function is able to complete its work synchronously, it
should return <code class="docutils literal notranslate"><span class="pre">SYSDOWN_COMPLETE</span></code>.</p>
<p>The “in progress” case is a bit more complicated. Sysdown functions
should not block on the current task (e.g., they should not tell the
default task to do something and then wait for the result). Blocking
like this will result in a deadlock since the current task is waiting
for the sysdown function to complete.</p>
<p>Instead, if a sysdown function needs to do extra work in the current
task, it should do so asynchronously. That is, it should enqueue an
event to the task’s event queue, then return <code class="docutils literal notranslate"><span class="pre">SYSDOWN_IN_PROGRESS</span></code>.
When the sysdown procedure eventually completes, the task should call
<code class="docutils literal notranslate"><span class="pre">sysdown_release</span></code>.</p>
<p>When all sysdown procedures have completed, Mynewt proceeds to reset
the device. If it takes longer than <code class="docutils literal notranslate"><span class="pre">MYNEWT_VAL(SYSDOWN_TIMEOUT_MS)</span></code>
milliseconds (default: 10s) for all shutdown procedures to complete, a
crash is triggered and the device resets.</p>
<p>As an example, the NimBLE BLE host package configures a sysdown
function that terminates all open connections. Its <code class="docutils literal notranslate"><span class="pre">pkg.yml</span></code>
contains the following map:</p>
<div class="highlight-yaml notranslate"><div class="highlight"><pre><span></span><span class="nt">pkg.down</span><span class="p">:</span>
<span class="w"> </span><span class="nt">ble_hs_shutdown</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">200</span>
</pre></div>
</div>
<p>and <code class="docutils literal notranslate"><span class="pre">ble_hs_shutdown</span></code> is defined as follows:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span>
<span class="nf">ble_hs_shutdown</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">reason</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Ensure this function only gets called by sysdown. */</span>
<span class="w"> </span><span class="n">SYSDOWN_ASSERT_ACTIVE</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/* Initiate a host stop procedure. */</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ble_hs_stop</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ble_hs_shutdown_stop_listener</span><span class="p">,</span><span class="w"> </span><span class="n">ble_hs_shutdown_stop_cb</span><span class="p">,</span>
<span class="w"> </span><span class="nb">NULL</span><span class="p">);</span>
<span class="w"> </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="n">rc</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="mi">0</span><span class="p">:</span>
<span class="w"> </span><span class="cm">/* Stop initiated. Wait for result to be reported asynchronously. */</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">SYSDOWN_IN_PROGRESS</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">BLE_HS_EBUSY</span><span class="p">:</span>
<span class="w"> </span><span class="cm">/* Already stopping. Wait for result to be reported asynchronously. */</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">SYSDOWN_IN_PROGRESS</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">BLE_HS_EALREADY</span><span class="p">:</span>
<span class="w"> </span><span class="cm">/* Already stopped. Shutdown complete. */</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">SYSDOWN_COMPLETE</span><span class="p">;</span>
<span class="w"> </span><span class="k">default</span><span class="o">:</span>
<span class="w"> </span><span class="n">BLE_HS_LOG</span><span class="p">(</span><span class="n">ERROR</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;ble_hs_shutdown: failed to stop host; rc=%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">rc</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">SYSDOWN_COMPLETE</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In the cases where this function returns <code class="docutils literal notranslate"><span class="pre">SYSDOWN_IN_PROGRESS</span></code>, the
host eventually calls <code class="docutils literal notranslate"><span class="pre">sysdown_release</span></code> when the procedure completes.</p>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="../extcmd/extcmd.html" class="btn btn-neutral float-right" title="Build-Time Hooks" accesskey="n">Next: Build-Time Hooks <span class="fa fa-arrow-circle-right"></span></a>
<a href="../sysinitconfig/sysconfig_error.html" class="btn btn-neutral" title="Validation and Error Messages" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: Validation and Error Messages</a>
</div>
</div>
</div>
</div>
<!-- ENDS CONTENT SECTION -->
</div>
<!-- ENDS .content -->
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<img src="../../../_static/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
</small>
<a href="">
<img src="../../../_static/img/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- ENDS #wrapper -->
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../../',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
LINK_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="../../../_static/js/bootstrap-3.0.3.min.js"></script>
<script type="text/javascript" src="../../../_static/js/affix.js"></script>
<script type="text/javascript" src="../../../_static/js/main.js"></script>
</body>
</html>