blob: 6f17b4df112b73e5c3f54e6554b441d19cc6ab2b [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">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../../img/favicon.ico">
<title>toc - Apache Mynewt</title>
<link href="../../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../../css/highlight.css">
<link href="../../../../css/base.css" rel="stylesheet">
<link href="../../../../css/custom.css" rel="stylesheet">
<link href="../../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<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="toc">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/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.12.0, Apache NimBLE 1.7.0 </a> released (April 4, 2024)
</div>
</div>
</div>
</div>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" 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
class=""
>
<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
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</option>
<option value="/v1_12_0/" >
Version: 1.12.0
</option>
<option value="/v1_11_0/" >
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" selected="selected" >
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></li>
<li ><a href="../../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../../../tutorials/tutorials/">Tutorials</a>
</li>
<li ><a href="../../../os_user_guide/">OS User Guide</a>
<ul>
<li ><a href="../../mynewt_os/">OS Core</a>
<ul>
<li><a href="
../../os_started/
">Functions</a>
</li>
<li ><a href="../../context_switch/context_switch/">Scheduler</a>
</li>
<li ><a href="../../cputime/os_cputime/">CPU Time</a>
</li>
<li ><a href="../../time/os_time/">OS Time</a>
</li>
<li ><a href="../../task/task/">Tasks</a>
</li>
<li ><a href="../../event_queue/event_queue/">Event Queues</a>
</li>
<li ><a href="../../semaphore/semaphore/">Semaphores</a>
</li>
<li ><a href="../../mutex/mutex/">Mutexes</a>
</li>
<li ><a href="../../memory_pool/memory_pool/">Memory Pools</a>
</li>
<li ><a href="../../heap/heap/">Heap</a>
</li>
<li><a href="
../../mbuf/mbuf/
">Memory Buffers</a>
</li>
<li class="active"><a href="./">Sanity</a>
<ul>
<li><a href="
../os_sanity_check_init/
">Functions</a>
</li>
</ul>
</li>
<li ><a href="../../callout/callout/">Callouts</a>
</li>
</ul>
</li>
<li ><a href="../../porting/port_os/">Porting to your Platform</a>
</li>
<li ><a href="../../../modules/console/console/">Console</a>
</li>
<li ><a href="../../../modules/shell/shell/">Shell</a>
</li>
<li ><a href="../../../modules/split/split/">Split Images</a>
</li>
<li ><a href="../../../modules/bootloader/bootloader/">Bootloader</a>
</li>
<li><a href="
../../../modules/fs/fs/fs/
">File System</a>
</li>
<li ><a href="../../../modules/hal/hal/">Hardware Abstraction Layer</a>
</li>
<li ><a href="../../../modules/sensor_framework/sensor_framework_overview/">Sensor Framework</a>
</li>
<li ><a href="../../../modules/drivers/driver/">Drivers</a>
</li>
<li ><a href="../../../modules/testutil/testutil/">Test Utilities</a>
</li>
<li ><a href="../../../modules/devmgmt/newtmgr/">Device Management with Newt Manager</a>
</li>
<li ><a href="../../../modules/imgmgr/imgmgr/">Image Manager</a>
</li>
<li >
<a href="../../../modules/baselibc/">Baselibc library</a>
</li>
<li ><a href="../../../modules/json/json/">JSON</a>
</li>
<li ><a href="../../../modules/fcb/fcb/">Flash Circular Buffer</a>
</li>
<li ><a href="../../../modules/stats/stats/">Stats</a>
</li>
<li ><a href="../../../modules/logs/logs/">Logs</a>
</li>
<li ><a href="../../../modules/sysinitconfig/sysinitconfig/">System Configuration And Initialization</a>
</li>
</ul>
</li>
<li><a href="
../../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../../newt/install/prev_releases/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; Sanity</li>
<li>&raquo; <a href="os/core_os/mynewt_os/">OS Core</a></li>
<li>&raquo; <a href="os/os_user_guide/">OS User Guide</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/core_os/sanity/sanity.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.3.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>
<h1 id="sanity">Sanity</h1>
<p>The Sanity task is a software watchdog task, which runs periodically to check
system state, and ensure that everything is still operating properly.</p>
<p>In a typical system design, there are multiple stages of watchdog: </p>
<ul>
<li>
<p>Internal Watchdog</p>
</li>
<li>
<p>External Watchdog </p>
</li>
<li>
<p>Sanity Watchdog </p>
</li>
</ul>
<p>The <em>Internal Watchdog</em> is typically an MCU watchdog, which is tickled in
the core of the OS. The internal watchdog is tickled frequently, and is
meant to be an indicator the OS is running.</p>
<p>The <em>External Watchdog</em> is a watchdog that's typically run slower. The
purpose of an external watchdog is to provide the system with a hard reset
when it has lost its mind. </p>
<p>The <em>Sanity Watchdog</em> is the least frequently run watchdog, and is meant as
an application watchdog. </p>
<p>This document is about the operation of the Mynewt Sanity Watchdog.</p>
<h2 id="description">Description</h2>
<h3 id="sanity-task">Sanity Task</h3>
<p>Mynewt OS uses the OS Idle task to check sanity. The <code>SANITY_INTERVAL</code> syscfg setting specifies the interval in seconds to perform the sanity checks.</p>
<p>By default, every operating system task provides the frequency it will
check in with the sanity task, with the <code>sanity_itvl</code> parameter in the
<code>os_task_init()</code> function:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">int</span> <span style="color: #000000">os_task_init</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">*t</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">*name</span>, <span style="color: #000000">os_task_func_t</span> <span style="color: #000000">func</span>,
<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>, <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">prio</span>, <span style="color: #000000">os_time_t</span> <span style="color: #000000">sanity_itvl</span>, <span style="color: #000000">os_stack_t</span> <span style="color: #000000">*bottom</span>,
<span style="color: #A90D91">uint16_t</span> <span style="color: #000000">stack_size</span>);
</code></pre></div>
<p><code>sanity_itvl</code> is the time in OS time ticks that the task being created
must register in with the sanity task. </p>
<h3 id="checking-in-with-sanity-task">Checking in with Sanity Task</h3>
<p>The task must then register in with the sanity task every <code>sanity_itvl</code>
seconds. In order to do that, the task should call the <code>os_sanity_task_checkin</code>
function, which will reset the sanity check associated with this task.
Here is an example of a task that uses a callout to checkin with the
sanity task every 50 seconds:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#define TASK1_SANITY_CHECKIN_ITVL (50 * OS_TICKS_PER_SEC) </span>
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_eventq</span> <span style="color: #000000">task1_evq</span>;
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">task1</span>(<span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_task</span> <span style="color: #000000">*t</span>;
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_event</span> <span style="color: #000000">*ev</span>;
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_callout</span> <span style="color: #000000">c</span>;
<span style="color: #177500">/* Get current OS task */</span>
<span style="color: #000000">t</span> <span style="color: #000000">=</span> <span style="color: #000000">os_sched_get_current_task</span>();
<span style="color: #177500">/* Initialize the event queue. */</span>
<span style="color: #000000">os_eventq_init</span>(<span style="color: #000000">&amp;task1_evq</span>);
<span style="color: #177500">/* Initialize the callout */</span>
<span style="color: #000000">os_callout_init</span>(<span style="color: #000000">&amp;c</span>, <span style="color: #000000">&amp;task1_evq</span>, <span style="color: #A90D91">NULL</span>);
<span style="color: #177500">/* reset the callout to checkin with the sanity task </span>
<span style="color: #177500"> * in 50 seconds to kick off timing.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">os_callout_reset</span>(<span style="color: #000000">&amp;c</span>, <span style="color: #000000">TASK1_SANITY_CHECKIN_ITVL</span>);
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">ev</span> <span style="color: #000000">=</span> <span style="color: #000000">os_eventq_get</span>(<span style="color: #000000">&amp;task1_evq</span>);
<span style="color: #177500">/* The sanity timer has reset */</span>
<span style="color: #A90D91">if</span> (<span style="color: #000000">ev-&gt;ev_arg</span> <span style="color: #000000">==</span> <span style="color: #000000">&amp;c</span>) {
<span style="color: #000000">os_sanity_task_checkin</span>(<span style="color: #000000">t</span>);
} <span style="color: #A90D91">else</span> {
<span style="color: #177500">/* not expecting any other events */</span>
<span style="color: #000000">assert</span>(<span style="color: #1C01CE">0</span>);
}
}
<span style="color: #177500">/* Should never reach */</span>
<span style="color: #000000">assert</span>(<span style="color: #1C01CE">0</span>);
}
</code></pre></div>
<h3 id="registering-a-custom-sanity-check">Registering a Custom Sanity Check</h3>
<p>If a particular task wants to further hook into the sanity framework to
perform other checks during the sanity task's operation, it can do so by
registering a <code>struct os_sanity_check</code> using the <code>os_sanity_check_register</code>
function.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">mymodule_perform_sanity_check</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_sanity_check</span> <span style="color: #000000">*sc</span>, <span style="color: #A90D91">void</span> <span style="color: #000000">*arg</span>)
{
<span style="color: #177500">/* Perform your checking here. In this case, we check if there </span>
<span style="color: #177500"> * are available buffers in mymodule, and return 0 (all good)</span>
<span style="color: #177500"> * if true, and -1 (error) if not.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">if</span> (<span style="color: #000000">mymodule_has_buffers</span>()) {
<span style="color: #A90D91">return</span> (<span style="color: #1C01CE">0</span>);
} <span style="color: #A90D91">else</span> {
<span style="color: #A90D91">return</span> (<span style="color: #1C01CE">-1</span>);
}
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">int</span>
<span style="color: #000000">mymodule_register_sanity_check</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_sanity_check</span> <span style="color: #000000">sc</span>;
<span style="color: #000000">os_sanity_check_init</span>(<span style="color: #000000">&amp;sc</span>);
<span style="color: #177500">/* Only assert() if mymodule_perform_sanity_check() fails 50 </span>
<span style="color: #177500"> * times. SANITY_TASK_INTERVAL is defined by the user, and </span>
<span style="color: #177500"> * is the frequency at which the sanity_task runs in seconds.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">OS_SANITY_CHECK_SETFUNC</span>(<span style="color: #000000">&amp;sc</span>, <span style="color: #000000">mymodule_perform_sanity_check</span>, <span style="color: #A90D91">NULL</span>,
<span style="color: #1C01CE">50</span> <span style="color: #000000">*</span> <span style="color: #000000">SANITY_TASK_INTERVAL</span>);
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">os_sanity_check_register</span>(<span style="color: #000000">&amp;sc</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span> <span style="color: #000000">!=</span> <span style="color: #1C01CE">0</span>) {
<span style="color: #A90D91">goto</span> <span style="color: #000000">err</span>;
}
<span style="color: #A90D91">return</span> (<span style="color: #1C01CE">0</span>);
<span style="color: #000000">err</span>:
<span style="color: #A90D91">return</span> (<span style="color: #000000">rc</span>);
}
</code></pre></div>
<p>In the above example, every time the custom sanity check
<code>mymodule_perform_sanity_check</code> returns successfully (0),
the sanity check is reset. In the <code>OS_SANITY_CHECK_SETFUNC</code> macro,
the sanity checkin interval is specified as 50 * SANITY_TASK_INTERVAL
(which is the interval at which the sanity task runs.) This means
that the <code>mymodule_perform_sanity_check()</code> function needs to fail
50 times consecutively before the sanity task will crash the system.</p>
<p><strong>TIP:</strong> When checking things like memory buffers, which can be temporarily
be exhausted, it's a good idea to have the sanity check fail multiple
consecutive times before crashing the system. This will avoid crashing
for temporary failures.</p>
<h2 id="data-structures">Data structures</h2>
<h3 id="os-sanity-check">OS Sanity Check</h3>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_sanity_check</span> {
<span style="color: #000000">os_time_t</span> <span style="color: #000000">sc_checkin_last</span>;
<span style="color: #000000">os_time_t</span> <span style="color: #000000">sc_checkin_itvl</span>;
<span style="color: #000000">os_sanity_check_func_t</span> <span style="color: #000000">sc_func</span>;
<span style="color: #A90D91">void</span> <span style="color: #000000">*sc_arg</span>;
<span style="color: #000000">SLIST_ENTRY</span>(<span style="color: #000000">os_sanity_check</span>) <span style="color: #000000">sc_next</span>;
};
</code></pre></div>
<table>
<thead>
<tr>
<th><strong>Element</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sc_checkin_last</code></td>
<td>The last time this sanity check checked in with the sanity task, in OS time ticks.</td>
</tr>
<tr>
<td><code>sc_checkin_itvl</code></td>
<td>How frequently the sanity check is supposed to check in with the sanity task, in OS time ticks.</td>
</tr>
<tr>
<td><code>sc_func</code></td>
<td>If not <code>NULL</code>, call this function when running the sanity task. If the function returns 0, reset the sanity check.</td>
</tr>
<tr>
<td><code>sc_arg</code></td>
<td>Argument to pass to <code>sc_func</code> when calling it.</td>
</tr>
<tr>
<td><code>sc_next</code></td>
<td>Sanity checks are chained in the sanity task when <code>os_sanity_check_register()</code> is called.</td>
</tr>
</tbody>
</table>
<h2 id="list-of-functions">List of Functions</h2>
<p>The functions available in sanity are:</p>
<table>
<thead>
<tr>
<th><strong>Function</strong></th>
<th><strong>Description</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="../os_sanity_check_init/">os_sanity_check_init</a></td>
<td>Initialize the given sanity check.</td>
</tr>
<tr>
<td><a href="../os_sanity_check_register/">os_sanity_check_register</a></td>
<td>Register the given sanity check with the sanity task.</td>
</tr>
<tr>
<td><a href="../os_sanity_check_reset/">os_sanity_check_reset</a></td>
<td>Reset the given sanity check.</td>
</tr>
<tr>
<td><a href="../os_sanity_task_checkin/">os_sanity_task_checkin</a></td>
<td>Informs the sanity task that the given task is still alive and working normally.</td>
</tr>
</tbody>
</table>
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer 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">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<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>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../../js/highlight.pack.js"></script>
<script src="../../../../js/base.js"></script>
<script src="../../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>