blob: 4303d465f52beb20381f3ac3118f7d8536a7902e [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>Nested Interrupts &mdash; NuttX latest documentation</title>
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../_static/copybutton.css" type="text/css" />
<link rel="stylesheet" href="../_static/tabs.css" type="text/css" />
<link rel="stylesheet" href="../_static/custom.css" type="text/css" />
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<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="Analyzing Cortex-M Hardfaults" href="cortexmhardfaults.html" />
<link rel="prev" title="High Performance, Zero Latency Interrupts" href="zerolatencyinterrupts.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"><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 current"><a class="reference internal" href="index.html">Guides</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="nfs.html">NFS Client How-To</a></li>
<li class="toctree-l2"><a class="reference internal" href="usbtrace.html">USB Device Trace</a></li>
<li class="toctree-l2"><a class="reference internal" href="simulator.html">Simulator</a></li>
<li class="toctree-l2"><a class="reference internal" href="qemugdb.html">How to debug NuttX using QEMU and GDB</a></li>
<li class="toctree-l2"><a class="reference internal" href="rndis.html">How to use RNDIS</a></li>
<li class="toctree-l2"><a class="reference internal" href="drivers.html">Drivers</a></li>
<li class="toctree-l2"><a class="reference internal" href="tasktrace.html">Task Trace</a></li>
<li class="toctree-l2"><a class="reference internal" href="cpp_cmake.html">C++ Example using CMake</a></li>
<li class="toctree-l2"><a class="reference internal" href="pysimcoder.html">pysimCoder integration with NuttX</a></li>
<li class="toctree-l2"><a class="reference internal" href="customboards.html">Custom Boards How-To</a></li>
<li class="toctree-l2"><a class="reference internal" href="customapps.html">Custom Apps How-to</a></li>
<li class="toctree-l2"><a class="reference internal" href="zerolatencyinterrupts.html">High Performance, Zero Latency Interrupts</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Nested Interrupts</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#are-nested-interrupts-needed">Are Nested Interrupts Needed?</a></li>
<li class="toctree-l3"><a class="reference internal" href="#layered-interrupt-handling-architecture">Layered Interrupt Handling Architecture</a></li>
<li class="toctree-l3"><a class="reference internal" href="#how-to-implement-nested-interrupts-in-the-layered-interrupt-handling-architecture">How to Implement Nested Interrupts in the Layered Interrupt Handling Architecture</a></li>
<li class="toctree-l3"><a class="reference internal" href="#svcall-vs-pendsv">SVCall vs PendSV</a></li>
<li class="toctree-l3"><a class="reference internal" href="#what-could-go-wrong">What Could Go Wrong?</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="cortexmhardfaults.html">Analyzing Cortex-M Hardfaults</a></li>
<li class="toctree-l2"><a class="reference internal" href="coredump.html">Core Dump</a></li>
<li class="toctree-l2"><a class="reference internal" href="gdbwithpython.html">GDB with Python</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</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">Guides</a></li>
<li class="breadcrumb-item active">Nested Interrupts</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/guides/nestedinterrupts.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="nested-interrupts">
<h1>Nested Interrupts<a class="headerlink" href="#nested-interrupts" title="Permalink to this heading"></a></h1>
<section id="are-nested-interrupts-needed">
<h2>Are Nested Interrupts Needed?<a class="headerlink" href="#are-nested-interrupts-needed" title="Permalink to this heading"></a></h2>
<p>Most NuttX architectures do not support nested interrupts: Interrupts
are disabled when the interrupt is entered and restored when the
interrupt returns. Being able to handle nested interrupt is critical in
simple architectures where a lot of interrupt level processing is
performed: In this case, you can prioritize interrupts and assure that
the highest priority interrupt processing is not delayed by lower level
interrupt processing.</p>
<p>In an RTOS model, however, all interrupt processing should be as brief
as possible; any extended processing should be deferred to a user task
and not performed in the interrupt handler. However, you may find a need
to have nested interrupt handling in NuttX too. The lack of support of
nested interrupts is not inherently an issue with NuttX and need not be
the case; it should be a simple matter to modify the interrupt handling
so that interrupts are nested.</p>
</section>
<section id="layered-interrupt-handling-architecture">
<h2>Layered Interrupt Handling Architecture<a class="headerlink" href="#layered-interrupt-handling-architecture" title="Permalink to this heading"></a></h2>
<p>Interrupt handling occurs in several files. In most implementations,
there are several layers of interrupt handling logic:</p>
<ol class="arabic simple">
<li><p>Some low-level logic, usually in assembly language, that catches the
interrupt and determines the IRQ number. Consider
<code class="docutils literal notranslate"><span class="pre">arch/arm/src/armv7-m/up_exception.S</span></code> as an example for the
Cortex-M family.</p></li>
<li><p>That low-level logic than calls some MCU-specific, intermediate level
function usually called <code class="docutils literal notranslate"><span class="pre">up_doirq()</span></code>. An example is
<code class="docutils literal notranslate"><span class="pre">arch/arm/src/armv7-m/up_doirq.c</span></code>.</p></li>
<li><p>That MCU-specific function then calls the NuttX common interrupt
dispatching logic <code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code> that can be found at
<code class="docutils literal notranslate"><span class="pre">sched/irq_dispatch.c</span></code>.</p></li>
</ol>
</section>
<section id="how-to-implement-nested-interrupts-in-the-layered-interrupt-handling-architecture">
<h2>How to Implement Nested Interrupts in the Layered Interrupt Handling Architecture<a class="headerlink" href="#how-to-implement-nested-interrupts-in-the-layered-interrupt-handling-architecture" title="Permalink to this heading"></a></h2>
<p>The logic in these first two levels that would have to change to support
nested interrupt handling. Here is one technical approach to do that:</p>
<ol class="arabic simple">
<li><p>Add a global variable, say <code class="docutils literal notranslate"><span class="pre">g_nestlevel</span></code>, that counts the interrupt
nesting level. It would have an initial value of zero; it would be
incremented on each interrupt entry and decremented on interrupt exit
(making sure that interrupts are disabled in each case because
incrementing and decrementing are not usually atomic operations).</p></li>
<li><p>At the lowest level, there is usually some assembly language logic
that will switch from the user’s stack to a special interrupt level
stack. This behavior is controlled <code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_INTERRUPTSTACK</span></code>.
The logic here would have to change in the following way: If
<code class="docutils literal notranslate"><span class="pre">g_nestlevel</span></code> is zero then behave as normal, switching from the
user to the interrupt stack; if <code class="docutils literal notranslate"><span class="pre">g_nestlevel</span></code> is greater than zero,
then do not switch stacks. In this latter case, we are already using
the interrupt stack.</p></li>
<li><p>In the middle-level, MCU-specific is where the <code class="docutils literal notranslate"><span class="pre">g_nestlevel</span></code> would
be increment. And here some additional decision must be made based on
the state of <code class="docutils literal notranslate"><span class="pre">g_nestlevel</span></code>. If <code class="docutils literal notranslate"><span class="pre">g_nestlevel</span></code> is zero, then we
have interrupted user code and we need to handle the context
information specially and handle interrupt level context switches. If
<code class="docutils literal notranslate"><span class="pre">g_nestlevel</span></code> is greater than zero, then the interrupt handler was
interrupt by an interrupt. In this case, the interrupt handling must
always return to the interrupt handler. No context switch can occur
here. No context switch can occur until the outermost, nested
interrupt handler returns to the user task.</p></li>
<li><p>You would also need to support some kind of critical section within
interrupt handlers to prevent nested interrupts. For example, within
the logic of functions like <code class="docutils literal notranslate"><span class="pre">up_block_task()</span></code>. Such logic must be
atomic in any case.</p></li>
</ol>
<p><strong>NOTE 1</strong>: The ARMv7-M could also be configured to use separate MSP and
PSP stacks with the interupt processing using the MSP stack and the
tasks all using the PSP stacks. This is not compatible with certain
parts of the existing design and would be more effort, but could result
in a better solution.</p>
<p><strong>NOTE 2</strong>: SMP has this same issue as 2 but it is addressed
differently: With SMP there is an array of stacks indexed by the CPU
number so that all CPUs get to have an interrupt stack. See for
example,
<a class="reference external" href="https://bitbucket.org/nuttx/nuttx/src/ca4ef377fb789ddc3e70979b28acb6730ff6a98c/arch/arm/src/lc823450/chip.h">LC823450</a>
or
<a class="reference external" href="https://bitbucket.org/nuttx/nuttx/src/ca4ef377fb789ddc3e70979b28acb6730ff6a98c/arch/arm/src/imx6/chip.h">i.MX6</a>
SMP logic.</p>
<p>A generic <code class="docutils literal notranslate"><span class="pre">up_doirq()</span></code> might look like the following. It can be very
simple because interrupts are disabled:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">uint32_t</span><span class="w"> </span><span class="o">*</span><span class="nf">up_doirq</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">irq</span><span class="p">,</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="o">*</span><span class="n">regs</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="cm">/* Current regs non-zero indicates that we are processing an interrupt;</span>
<span class="cm"> * current_regs is also used to manage interrupt level context switches.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">current_regs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">regs</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Deliver the IRQ */</span>
<span class="w"> </span><span class="n">irq_dispatch</span><span class="p">(</span><span class="n">irq</span><span class="p">,</span><span class="w"> </span><span class="n">regs</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* If a context switch occurred while processing the interrupt then</span>
<span class="cm"> * current_regs may have change value. If we return any value different</span>
<span class="cm"> * from the input regs, then the lower level will know that a context</span>
<span class="cm"> * switch occurred during interrupt processing.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">regs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">uint32_t</span><span class="o">*</span><span class="p">)</span><span class="n">current_regs</span><span class="p">;</span>
<span class="w"> </span><span class="n">current_regs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">regs</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>What has to change to support nested interrupts is:</p>
<ol class="arabic simple">
<li><p>If we are nested, then we must retain the original value of
<code class="docutils literal notranslate"><span class="pre">current_regs</span></code>. This will be need when the outermost interrupt
handler returns in order to handle interrupt level context switches.</p></li>
<li><p>If we are nested, then we need to always return the same value of
<code class="docutils literal notranslate"><span class="pre">regs</span></code> that was received.</p></li>
</ol>
<p>So the modified version of <code class="docutils literal notranslate"><span class="pre">up_doirq()</span></code> would be as follows. Here we
assume that interrupts are enabled.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">uint32_t</span><span class="w"> </span><span class="o">*</span><span class="nf">up_doirq</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">irq</span><span class="p">,</span><span class="w"> </span><span class="kt">uint32_t</span><span class="w"> </span><span class="o">*</span><span class="n">regs</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">irqstate_t</span><span class="w"> </span><span class="n">flags</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Current regs non-zero indicates that we are processing an interrupt;</span>
<span class="cm"> * regs holds the state of the interrupted logic; current_regs holds the</span>
<span class="cm"> * state of the interrupted user task. current_regs should, therefor,</span>
<span class="cm"> * only be modified for outermost interrupt handler (when g_nestlevel == 0)</span>
<span class="cm"> */</span>
<span class="w"> </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="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">g_nestlevel</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">current_regs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">regs</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="n">g_nestlevel</span><span class="o">++</span>
<span class="w"> </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">/* Deliver the IRQ */</span>
<span class="w"> </span><span class="n">irq_dispatch</span><span class="p">(</span><span class="n">irq</span><span class="p">,</span><span class="w"> </span><span class="n">regs</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Context switches are indicated by the returned value of this function.</span>
<span class="cm"> * If a context switch occurred while processing the interrupt then</span>
<span class="cm"> * current_regs may have change value. If we return any value different</span>
<span class="cm"> * from the input regs, then the lower level will know that a context</span>
<span class="cm"> * switch occurred during interrupt processing. Context switching should</span>
<span class="cm"> * only be performed when the outermost interrupt handler returns.</span>
<span class="cm"> */</span>
<span class="w"> </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="n">g_nestlevel</span><span class="o">--</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">g_nestlevel</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">regs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">uint32_t</span><span class="o">*</span><span class="p">)</span><span class="n">current_regs</span><span class="p">;</span>
<span class="w"> </span><span class="n">current_regs</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="cm">/* Note that interrupts are left disabled. This needed if context switch</span>
<span class="cm"> * will be performed. But, any case, the correct interrupt state should</span>
<span class="cm"> * be restored when returning from the interrupt.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">regs</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p><strong>NOTE:</strong> An alternative, cleaner design might also be possible. If one
were to defer all context switching to a <em>PendSV</em> handler, then the
interrupts could vector to the <code class="docutils literal notranslate"><span class="pre">do_irq()</span></code> logic and then all
interrupts would be naturally nestable.</p>
</section>
<section id="svcall-vs-pendsv">
<h2>SVCall vs PendSV<a class="headerlink" href="#svcall-vs-pendsv" title="Permalink to this heading"></a></h2>
<p>An issue that may be related to nested interrupt handling is the use of
the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exceptions in NuttX. The <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exception is used as
a classic software interrupt in NuttX for performing context switches,
user- to kernel-mode changes (and vice versa), and also for system calls
when NuttX is built as a kernel.</p>
<p><code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exceptions are never performed from interrupt level, handler
mode processing; only from thread mode logic. The <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exception
is used as follows to perform the system call:</p>
<ul class="simple">
<li><p>All interrupts are disabled: There are a few steps the must be
performed in a critical section. Those setups and the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> must
work as a single, uninterrupted atomic action.</p></li>
<li><p>A special register setup is put in place: Parameters are passed to the
<code class="docutils literal notranslate"><span class="pre">SVCall</span></code> in registers just as with a normal function call.</p></li>
<li><p>The Cortex SVC instruction is executed. This causes the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code>
exception which is dispatched to the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exception handler.
This exception must occur while the input register setup is in place;
it cannot be deferred and perform at some later time. The <code class="docutils literal notranslate"><span class="pre">SVCall</span></code>
exception handler decodes the registers and performs the requested
operation. If no context switch occurs, the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> will return to
the caller immediately.</p></li>
<li><p>Upon return interrupts will be re-enabled.</p></li>
</ul>
<p>So what does this have to do with nested interrupt handling? Since
interrupts are disabled throughout the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> sequence, nothing
really. However, there are some concerns because if the <code class="docutils literal notranslate"><span class="pre">BASEPRI</span></code> is
used to disable interrupts then the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exception must have the
highest priority: The <code class="docutils literal notranslate"><span class="pre">BASEPRI</span></code> register is set to disable all
interrupt except for the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code>.</p>
<p>The motivation for supporting nested interrupts is, presumably, to make
sure that certain high priority interrupts are not delayed by lower
processing interrupt handling. Since the <code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exception has
highest priority, it will delay all other interrupts (but, of course,
disabling interrupt also delays all other interrupts).</p>
<p>The PendSV exception is another mechanism offered by the Cortex
architecture. It has been suggested that some of these issues with the
<code class="docutils literal notranslate"><span class="pre">SVCall</span></code> exception could be avoided by using the PendSV interrupt. The
architecture that would use the PendSV exception instead of the
<code class="docutils literal notranslate"><span class="pre">SVCall</span></code> interrupt is not clear in my mind. But I will keep this note
here for future reference if this were to become as issue.</p>
</section>
<section id="what-could-go-wrong">
<h2>What Could Go Wrong?<a class="headerlink" href="#what-could-go-wrong" title="Permalink to this heading"></a></h2>
<p>Whenever you deal with logic at software hardware interface, lots of
things can go wrong. But, aside from that general risk, the only
specific NuttX risk issue is that you may uncover some subtle interrupt
level logic that assumes that interrupts are already disabled. In those
cases, additional critical sections may be needed inside of the
interrupt level processing. The likelihood of such a thing is probably
pretty low, but cannot be fully discounted.</p>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="zerolatencyinterrupts.html" class="btn btn-neutral float-left" title="High Performance, Zero Latency Interrupts" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="cortexmhardfaults.html" class="btn btn-neutral float-right" title="Analyzing Cortex-M Hardfaults" 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 2020, The Apache Software Foundation.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>