blob: 8b977cf0c137a5dac55e90aa2b3dbd87da206e80 [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>High Performance: Zero Latency Interrupts, Maskable nested interrupts &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="The Kernel Address Sanitizer (KASAN)" href="kasan.html" />
<link rel="prev" title="Running CI Test Locally" href="citests.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="../implementation/index.html">Implementation Details</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="citests.html">Running CI Test Locally</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">High Performance: Zero Latency Interrupts, Maskable nested interrupts</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#generic-interrupt-handling">Generic Interrupt Handling</a></li>
<li class="toctree-l3"><a class="reference internal" href="#bypassing-the-generic-interrupt-handling">Bypassing the Generic Interrupt Handling</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getting-back-into-the-game">Getting Back into the Game</a></li>
<li class="toctree-l3"><a class="reference internal" href="#maskable-nested-interrupts">Maskable Nested Interrupts</a></li>
<li class="toctree-l3"><a class="reference internal" href="#nested-interrupt-handling">Nested Interrupt Handling</a></li>
<li class="toctree-l3"><a class="reference internal" href="#cortex-m3-4-implementation">Cortex-M3/4 Implementation</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#configuration-options">Configuration Options</a></li>
<li class="toctree-l4"><a class="reference internal" href="#disabling-the-high-priority-interrupt">Disabling the High Priority Interrupt</a></li>
<li class="toctree-l4"><a class="reference internal" href="#dependencies">Dependencies</a></li>
<li class="toctree-l4"><a class="reference internal" href="#configuring-high-priority-interrupts">Configuring High Priority Interrupts</a></li>
<li class="toctree-l4"><a class="reference internal" href="#example-code">Example Code</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="kasan.html">The Kernel Address Sanitizer (KASAN)</a></li>
<li class="toctree-l2"><a class="reference internal" href="nestedinterrupts.html">Nested Interrupts</a></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="coresight.html">Coresight - HW Assisted Tracing on ARM</a></li>
<li class="toctree-l2"><a class="reference internal" href="gdbserver.html">gdbserver</a></li>
<li class="toctree-l2"><a class="reference internal" href="gdbwithpython.html">GDB with Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="ofloader.html">Open Flash Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="testingtcpip.html">Testing TCP/IP Network Stacks</a></li>
<li class="toctree-l2"><a class="reference internal" href="automounter.html">Auto-Mounter</a></li>
<li class="toctree-l2"><a class="reference internal" href="stm32nullpointer.html">STM32 Null Pointer Detection</a></li>
<li class="toctree-l2"><a class="reference internal" href="stm32ccm.html">STM32 CCM Allocator</a></li>
<li class="toctree-l2"><a class="reference internal" href="stackrecord.html">Run time stack statistics</a></li>
<li class="toctree-l2"><a class="reference internal" href="etcromfs.html">etc romfs</a></li>
<li class="toctree-l2"><a class="reference internal" href="thread_local_storage.html">Thread Local Storage</a></li>
</ul>
</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">Guides</a></li>
<li class="breadcrumb-item active">High Performance: Zero Latency Interrupts, Maskable nested interrupts</li>
<li class="wy-breadcrumbs-aside">
<a href="../_sources/guides/zerolatencyinterrupts.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="high-performance-zero-latency-interrupts-maskable-nested-interrupts">
<h1>High Performance: Zero Latency Interrupts, Maskable nested interrupts<a class="headerlink" href="#high-performance-zero-latency-interrupts-maskable-nested-interrupts" title="Permalink to this heading"></a></h1>
<section id="generic-interrupt-handling">
<h2>Generic Interrupt Handling<a class="headerlink" href="#generic-interrupt-handling" title="Permalink to this heading"></a></h2>
<p>NuttX includes a generic interrupt handling subsystem that makes it
convenient to deal with interrupts using only IRQ numbers. In order to
integrate with this generic interrupt handling system, the platform
specific code is expected to collect all thread state into a container,
<code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">xcptcontext</span></code>. This container represents the full state of the
thread and can be saved, restored, and exchanged as a <em>unit of thread</em>.</p>
<p>While this state saving has many useful benefits, it does require
processing time. It was reported to me that this state saving required
about two microseconds on an STM32F4Discovery board. That added
interrupt latency might be an issue in some circumstances.</p>
<p>In addition, critical sections that are required in various places
throughout the RTOS can pause interrupt handling momentarily. This
increases the latency for those interrupts which become pending during a
critical section. As this is likely to occur for some instances of an
interrupt and not others, the interrupt latency varies from time to time
(experiences <em>jitter</em>). Like the added latency discussed above, that
jitter might be an issue in some circumstances.</p>
<p><strong>Terminology:</strong> The concepts discussed in this guide are not unique to
NuttX. Other RTOSes have similar concepts but will use different
terminology. The <a class="reference external" href="https://www.embedded.com/design/operating-systems/4461604/Interrupts-in-the-Nucleus-SE-RTOS">Nucleus</a>
RTOS, for example, uses the terms <em>Native</em> and <em>Managed</em> interrupts.</p>
</section>
<section id="bypassing-the-generic-interrupt-handling">
<h2>Bypassing the Generic Interrupt Handling<a class="headerlink" href="#bypassing-the-generic-interrupt-handling" title="Permalink to this heading"></a></h2>
<p>Most modern MCUs (such as the ARM Cortex-M family) receive and dispatch
interrupts through a <em>vector table</em>. The vector table is a table in
memory. Each entry in the table holds the address of an interrupt
handler corresponding to different interrupts. When the interrupt
occurs, the hardware fetches the corresponding interrupt handler address
and gives control to the interrupt handler.</p>
<p>In the implementation of the generic interrupt handler, these vectored
interrupts are not used as intended by the hardware designer. Rather,
they are used to obtain an IRQ number and then to transfer control to
the common, generic interrupt handling logic.</p>
<p>One way to achieve higher performance interrupts and still retain the
benefits of the generic interrupt handling logic is to simply replace an
interrupt handler address in the vector table with a different interrupt
handler; one that does not vector to the generic interrupt handling
logic logic, but rather to your custom code.</p>
<p>Often, the vector table is in ROM. So you can hard-code a special
interrupt vector by modifying the ROM vector table so that the specific
entry points to your custom interrupt handler. Or, if the architecture
permits, you can use a vector table in RAM. Then you can freely attach
and detach custom vector handlers by writing directly to the vector
table. The ARM Cortex-M port provides interfaces to support this mode
when the <code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_RAMVECTORS</span></code> option is enabled.</p>
<p>So what is the downside? There are two:</p>
<ul class="simple">
<li><p>Your custom interrupt handler will not have collected its state into
the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">xcptcontext</span></code> container. Therefore, it cannot communicate
with operating system. Your custom interrupt handler has been taken
“out of the game” and can no longer work with the system.</p></li>
<li><p>If your custom interrupt is truly going to be <em>high performance</em> then
you will also have to support nested interrupts! The custom interrupt
must have a high priority and must be able interrupt the generic
interrupt handling logic. Otherwise, it will be occasionally delayed
when there is a collision between your custom interrupt and other,
lower priority interrupts.</p></li>
</ul>
</section>
<section id="getting-back-into-the-game">
<h2>Getting Back into the Game<a class="headerlink" href="#getting-back-into-the-game" title="Permalink to this heading"></a></h2>
<p>As mentioned, the custom interrupt handler cannot use most of the
services of the OS since it has not created a <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">xcptcontext</span></code>
container. So it needs a mechanism to “get back into the game” when it
needs to interact with the operating system to, for example, post a
semaphore, signal a thread, or send a message.</p>
<p>The ARM Cortex-M family supports a special way to do this using the
<em>PendSV</em> interrupt:</p>
<ul class="simple">
<li><p>The custom logic would connect with the <em>PendSV</em> interrupt using the
standard <code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code> interface.</p></li>
<li><p>In the custom interrupt handler, it would schedule the <em>PendSV</em>
interrupt when it needs to communicate with the OS.</p></li>
<li><p>The <em>PendSV</em> interrupt is dispatched through the generic interrupt
system so when the attached <em>PendSV</em> interrupt is handled, it will be
in a context where it can perform any necessary OS interactions.</p></li>
</ul>
<p>With the ARMv7_M architecture, the <em>PendSV</em> interrupt can be generated
with:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">up_trigger_irq</span><span class="p">(</span><span class="n">NVIC_IRQ_PENDSV</span><span class="p">);</span>
</pre></div>
</div>
<p>On other architectures, it may be possible to do something like a
software interrupt from the custom interrupt handler to accomplish the
same thing.</p>
<p>The custom logic would be needed to communicate the events of interest
between the high priority interrupt handler and <em>PendSV</em> interrupt
handler. A detailed discussion of that custom logic is beyond the
scope of this Wiki page.</p>
<p>The following table shows the priority levels of the Cortex-M family:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>IRQ type Priority
Dataabort 0x00
High prio IRQ1 0x20 (Zero-latency interrupt)
High prio IRQ2 0x30 (Can&#39;t call OS API in ISR)
SVC 0x70
Disable IRQ 0x80
(critical-section)
Low prio IRQ 0xB0
PendSV 0xE0
</pre></div>
</div>
<p>As you can see, the priority levels of the zero-latency interrupts can
beyond the critical section and SVC.
But High prio IRQ can’t call OS API.</p>
</section>
<section id="maskable-nested-interrupts">
<h2>Maskable Nested Interrupts<a class="headerlink" href="#maskable-nested-interrupts" title="Permalink to this heading"></a></h2>
<p>The ARM Cortex-M family supports a feature called <em>BASEPRI</em> that can be
used to disable interrupts at a priority level below a certain level.
This feature can be used to support maskable nested interrupts.</p>
<p>Maskable nested interrupts differ from zero-latency interrupts in
that they obey the interrupt masking mechanisms of the system.
For example, setting the BASEPRI register to a specific threshold will
block all interrupts of a lower or equal priority.
However, high-priority interrupts (such as Non-Maskable Interrupts
or zero-latency interrupts) are unaffected by these masks.</p>
<p>This is useful when you have a high-priority interrupt that needs to
be able to interrupt the system, but you also have lower-priority
interrupts that you want to be able to mask.</p>
<p>The following table shows the priority levels of the Cortex-M family:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>IRQ type Priority
Dataabort 0x00
SVC 0x70
Disable IRQ 0x80
(critical-section)
High prio IRQ1 0x90 (Maskable nested interrupt)
High prio IRQ2 0xA0 (Can call OS API in ISR)
Low prio IRQ 0xB0
PendSV 0xE0
</pre></div>
</div>
<p>As you can see, the priority levels of the maskable nested interrupts
are between the critical section and the low-priority interrupts.
And High prio IRQ can call OS API in ISR.</p>
</section>
<section id="nested-interrupt-handling">
<h2>Nested Interrupt Handling<a class="headerlink" href="#nested-interrupt-handling" title="Permalink to this heading"></a></h2>
<p>Some general notes about nested interrupt handling are provided in
<a class="reference internal" href="nestedinterrupts.html"><span class="doc">Nested Interrupts</span></a>. In this case, handling the nested custom
interrupt is simpler because the generic interrupt handler is not
re-entered. Rather, the generic interrupt handler must simply be made to
co-exist with the custom interrupt interrupt handler.</p>
<p>Modifications may be required to the generic interrupt handling logic
to accomplish. A few points need to be made here:</p>
<ul class="simple">
<li><p>The MCU should support interrupt prioritization so that the custom
interrupt can be scheduled with a higher priority.</p></li>
<li><p>The generic interrupt handlers currently disable interrupts during
interrupts. Instead, they must be able to keep the custom interrupt
enabled throughout interrupt process but still prevent re-entrancy by
other standard interrupts (This can be done by setting an interrupt
base priority level in the Cortex-M family).</p></li>
<li><p>The custom interrupt handler can now interrupt the generic interrupt
handler at any place. Is the logic safe in all cases to be
interrupted? Sometimes interrupt handlers place the MCU in momentarily
perverse states while registers are being manipulated. Make sure that
it is safe to take interrupts at any time (or else keep the interrupts
disabled in the critical times).</p></li>
<li><p>Will the custom interrupt handler have all of the resources it needs
in place when it occurs? Will it have a valid stack pointer? (In the
Cortex-M implementation, for example, the MSP may not be valid when
the custom interrupt handler is entered).</p></li>
</ul>
<p>Some of these issues are complex and so you should expect some
complexity in getting the nested interrupt handler to work.</p>
</section>
<section id="cortex-m3-4-implementation">
<h2>Cortex-M3/4 Implementation<a class="headerlink" href="#cortex-m3-4-implementation" title="Permalink to this heading"></a></h2>
<p>Such high priority, nested interrupt handler has been implemented for
the Cortex-M3/4 families.</p>
<p>The following paragraphs will summarize that implementation.</p>
<section id="configuration-options">
<h3>Configuration Options<a class="headerlink" href="#configuration-options" title="Permalink to this heading"></a></h3>
<p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_HIPRI_INTERRUPT</span></code></p>
<p>If <code class="docutils literal notranslate"><span class="pre">CONFIG_ARMV7M_USEBASEPRI</span></code> is selected, then interrupts will be
disabled by setting the <em>BASEPRI</em> register to
<code class="docutils literal notranslate"><span class="pre">NVIC_SYSH_DISABLE_PRIORITY</span></code> so that most interrupts will not have
execution priority. <em>SVCall</em> must have execution priority in all
cases.</p>
<p>In the normal cases, interrupts are not nest-able and all interrupts
run at an execution priority between <code class="docutils literal notranslate"><span class="pre">NVIC_SYSH_PRIORITY_MIN</span></code> and
<code class="docutils literal notranslate"><span class="pre">NVIC_SYSH_PRIORITY_MAX</span></code> (with <code class="docutils literal notranslate"><span class="pre">NVIC_SYSH_PRIORITY_MAX</span></code> reserved
for <em>SVCall</em>).</p>
<p>If, in addition, <code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_HIPRI_INTERRUPT</span></code> is defined, then
special high priority interrupts are supported. These are not “nested”
in the normal sense of the word. These high priority interrupts can
interrupt normal processing but execute outside of OS (although they
can “get back into the game” via a <em>PendSV</em> interrupt).</p>
</section>
<section id="disabling-the-high-priority-interrupt">
<h3>Disabling the High Priority Interrupt<a class="headerlink" href="#disabling-the-high-priority-interrupt" title="Permalink to this heading"></a></h3>
<p>In the normal course of things, interrupts must occasionally be
disabled using the <code class="docutils literal notranslate"><span class="pre">up_irq_save()</span></code> inline function to prevent
contention in use of resources that may be shared between interrupt
level and non-interrupt level logic. Now the question arises, if we
are using the <em>BASEPRI</em> to disable interrupts and have high priority
interrupts enabled (<code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_HIPRI_INTERRUPT=y</span></code>), do we disable
all interrupts except <em>SVCall</em> (we cannot disable <em>SVCall</em>
interrupts)? Or do we only disable the “normal” interrupts?</p>
<p>If we are using the <em>BASEPRI</em> register to disable interrupts, then the
answer is that we must disable <em>ONLY</em> the normal interrupts. That is
because we cannot disable <em>SVCall</em> interrupts and we cannot permit
<em>SVCall</em> interrupts running at a higher priority than the high
priority interrupts. Otherwise, they will introduce jitter in the high
priority interrupt response time.</p>
<p>Hence, if you need to disable the high priority interrupt, you will
have to disable the interrupt either at the peripheral that generates
the interrupt or at the interrupt controller, the <em>NVIC</em>. Disabling
global interrupts via the <em>BASEPRI</em> register cannot affect high
priority interrupts.</p>
</section>
<section id="dependencies">
<h3>Dependencies<a class="headerlink" href="#dependencies" title="Permalink to this heading"></a></h3>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_HAVE_IRQPRIO</span></code>. Support for prioritized interrupt
support must be enabled.</p></li>
<li><p>Floating Point Registers. If used with a Cortex-M4 that supports
hardware floating point, you cannot use hardware floating point in the
high priority interrupt handler UNLESS you use the common vector logic
that supports saving of floating point registers on all interrupts.</p></li>
</ul>
</section>
<section id="configuring-high-priority-interrupts">
<h3>Configuring High Priority Interrupts<a class="headerlink" href="#configuring-high-priority-interrupts" title="Permalink to this heading"></a></h3>
<p>How do you specify a high priority interrupt? You need to do two
things:</p>
<p>First, You need to change the address in the vector table so that the
high priority interrupt vectors to your special C interrupt handler.
There are two ways to do this:</p>
<ul class="simple">
<li><p>If you select <code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_RAMVECTORS</span></code>, then vectors will be kept in
RAM and the system will support the interface: <code class="docutils literal notranslate"><span class="pre">int</span>
<span class="pre">up_ramvec_attach(int</span> <span class="pre">irq,</span> <span class="pre">up_vector_t</span> <span class="pre">vector)</span></code>. That interface can be
used to attach your C interrupt handler to the vector at run time.</p></li>
<li><p>Alternatively, you could keep your vectors in FLASH but in order to
this, you would have to develop your own custom vector table.</p></li>
</ul>
<p>Second, you need to set the priority of your interrupt to <em>NVIC</em> to
<code class="docutils literal notranslate"><span class="pre">NVIC_SYSH_HIGH_PRIORITY</span></code> using the standard interface:
<code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">up_prioritize_irq(int</span> <span class="pre">irq,</span> <span class="pre">int</span> <span class="pre">priority);</span></code></p>
</section>
<section id="example-code">
<h3>Example Code<a class="headerlink" href="#example-code" title="Permalink to this heading"></a></h3>
<p>You can find an example that tests the high priority, nested interrupts in the NuttX source:</p>
<ul class="simple">
<li><p><a class="reference internal" href="../platforms/arm/stm32f1/boards/viewtool-stm32f107/index.html"><span class="doc">ViewTool STM32F103/F107</span></a> Description of
the configuration</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">nuttx/boards/arm/stm32/viewtool-stm32f107/highpri</span></code> Test configuration</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">nuttx/boards/arm/stm32/viewtool-stm32f107/src/stm32_highpri</span></code> Test
driver.</p></li>
</ul>
</section>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="citests.html" class="btn btn-neutral float-left" title="Running CI Test Locally" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="kasan.html" class="btn btn-neutral float-right" title="The Kernel Address Sanitizer (KASAN)" 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>