blob: 37c9e8a5616b53c0fd05d8f6302a0288bafb746d [file] [log] [blame]
<!--
Documentation/_templates/layout.html
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.
-->
<!DOCTYPE html>
<html class="writer-html5" lang="en">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Per-Thread Interrupt Controls &mdash; NuttX latest documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<script src="../_static/jquery.js"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx_highlight.js"></script>
<script src="../_static/clipboard.min.js"></script>
<script src="../_static/copybutton.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Effects of Disabling Interrupts or Pre-Emption on Response Latency" href="preemption_latency.html" />
<link rel="prev" title="Critical Sections" href="critical_sections.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home"> NuttX
</a>
<!-- this version selector is quite ugly, should be probably replaced by something
more modern -->
<div class="version-selector">
<select onchange="javascript:location.href = this.value;">
<option value="../../latest" selected="selected">latest</option>
<option value="../../10.0.0" >10.0.0</option>
<option value="../../10.0.1" >10.0.1</option>
<option value="../../10.1.0" >10.1.0</option>
<option value="../../10.2.0" >10.2.0</option>
<option value="../../10.3.0" >10.3.0</option>
<option value="../../11.0.0" >11.0.0</option>
<option value="../../12.0.0" >12.0.0</option>
<option value="../../12.1.0" >12.1.0</option>
<option value="../../12.2.0" >12.2.0</option>
<option value="../../12.2.1" >12.2.1</option>
<option value="../../12.3.0" >12.3.0</option>
<option value="../../12.4.0" >12.4.0</option>
<option value="../../12.5.0" >12.5.0</option>
<option value="../../12.5.1" >12.5.1</option>
<option value="../../12.6.0" >12.6.0</option>
<option value="../../12.7.0" >12.7.0</option>
<option value="../../12.8.0" >12.8.0</option>
<option value="../../12.9.0" >12.9.0</option>
<option value="../../12.10.0" >12.10.0</option>
<option value="../../12.11.0" >12.11.0</option>
</select>
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Home</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../quickstart/index.html">Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributing/index.html">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li>
<li class="toctree-l1"><a class="reference internal" href="../platforms/index.html">Supported Platforms</a></li>
<li class="toctree-l1"><a class="reference internal" href="../components/index.html">OS Components</a></li>
<li class="toctree-l1"><a class="reference internal" href="../applications/index.html">Applications</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Implementation Details</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="processes_vs_tasks.html">Linux Processes vs NuttX Tasks</a></li>
<li class="toctree-l2"><a class="reference internal" href="critical_sections.html">Critical Sections</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Per-Thread Interrupt Controls</a></li>
<li class="toctree-l2"><a class="reference internal" href="preemption_latency.html">Effects of Disabling Interrupts or Pre-Emption on Response Latency</a></li>
<li class="toctree-l2"><a class="reference internal" href="bottomhalf_interrupt.html">Bottom-Half Interrupt Handlers</a></li>
<li class="toctree-l2"><a class="reference internal" href="simulation.html">The NuttX Simulation</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../reference/index.html">API Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../guides/index.html">Guides</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../logos/index.html">NuttX Logos</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">NuttX</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="index.html">Implementation Details</a></li>
<li class="breadcrumb-item active">Per-Thread Interrupt Controls</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/implementation/interrupt_controls.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="per-thread-interrupt-controls">
<h1>Per-Thread Interrupt Controls<a class="headerlink" href="#per-thread-interrupt-controls" title="Permalink to this heading"></a></h1>
<p>Using NuttX, you will find that the interrupts enabled/disabled state is not a
global property. You can not just turn interrupts off and on for all tasks.
Rather, enabling and disabling interrupts effects only while the single task
that is controlling the interrupts runs. Consider the following sequence:</p>
<div class="highlight-C notranslate"><div class="highlight"><pre><span></span><span class="n">irqstate_t</span><span class="w"> </span><span class="n">flags</span><span class="p">;</span>
<span class="n">flags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">irqsave</span><span class="p">();</span><span class="w"> </span><span class="cm">/* Disable interrupts */</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">);</span><span class="w"> </span><span class="cm">/* Sleep for 5 seconds */</span>
<span class="n">irqrestore</span><span class="p">(</span><span class="n">flags</span><span class="p">);</span><span class="w"> </span><span class="cm">/* Re-enable interrupts */</span>
</pre></div>
</div>
<p>What happens while the task sleeps? Does that mean that interrupts will be
disabled for five seconds? No, interrupts will (probably) be re-enabled while
the task is sleeping. How does this work?</p>
<p>It is really very simple. Each time a context switches occurs, a set of
registers are saved for the task that is being suspended. Then those registers
are restored from the previously saved registers for a next task that will run.
This is why we often describe a context switch as just setjmp/longjmp on steroids:
A context switch works just like setjmp (save a set of registers) and longjmp
(restore a set of registers), except that more registers are saved and restored.</p>
<p>For the the ARMv7-M, as an example, you can see the set of registers that are
stored in <code class="docutils literal notranslate"><span class="pre">arch/arm/include/armv7-m/irq.h</span></code></p>
<p>Among those registers are saved and restore are the register(s) that determine if
interrupts are enable or not. For the ARMv7-M family that is either the <code class="docutils literal notranslate"><span class="pre">PRIMASK</span></code>
register or the <code class="docutils literal notranslate"><span class="pre">BASEPRI</span></code> registers. So if a task disables interrupts then suspends,
the current value of <code class="docutils literal notranslate"><span class="pre">PRIMASK</span></code>/<code class="docutils literal notranslate"><span class="pre">BASEPRI</span></code> register is saved and replaced with the
stored value of the <code class="docutils literal notranslate"><span class="pre">PRIMASK</span></code>/<code class="docutils literal notranslate"><span class="pre">BASEPRI</span></code> register for the next task that will run,
thus re-enabling interrupts while the rist task is suspended.</p>
<p>So interrupt enabled/disable is a per-thread property, not a global property.
If you have been working with bare metal systems for a long time, this might seem
foreign to you.</p>
<p>By the way, locking the scheduler via <code class="docutils literal notranslate"><span class="pre">sched_lock()</span></code> behaves in this same way
(but the mechanism is a little different).</p>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="critical_sections.html" class="btn btn-neutral float-left" title="Critical Sections" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="preemption_latency.html" class="btn btn-neutral float-right" title="Effects of Disabling Interrupts or Pre-Emption on Response Latency" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, The Apache Software Foundation.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>