| <!-- |
| 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.19: https://docutils.sourceforge.io/" /> |
| |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Smaller Vector Tables — 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/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.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/design-tabs.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="How to port" href="port.html" /> |
| <link rel="prev" title="Signaling Semaphores and Priority Inheritance" href="signaling_sem_priority_inheritance.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"><a class="reference internal" href="../debugging/index.html">Debugging</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="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="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"><a class="reference internal" href="zerolatencyinterrupts.html">High Performance: Zero Latency Interrupts, Maskable Nested Interrupts</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="fortify.html">Fortify</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="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="etcromfs.html">etc romfs</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="thread_local_storage.html">Thread Local Storage</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="devicetree.html">Device Tree</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="changing_systemclockconfig.html">Changing the System Clock Configuration</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="usingkernelthreads.html">Using Kernel Threads</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="armv7m_runtimestackcheck.html">ARMv7-M Run Time Stack Checking</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="include_files_board_h.html">Including Files in board.h</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="specialstuff_in_nuttxheaderfiles.html">Why can’t I put my special stuff in NuttX header files?</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="kernel_threads_with_custom_stacks.html">Kernel Threads with Custom Stacks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="versioning_and_task_names.html">Versioning and Task Names</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="logging_rambuffer.html">Logging to a RAM Buffer</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ipv6.html">IPv6</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="integrate_newlib.html">Integrating with Newlib</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="protected_build.html">NuttX Protected Build</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="platform_directories.html">Platform Directories</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="port_drivers_to_stm32f7.html">Porting Drivers to the STM32 F7</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="semihosting.html">Semihosting</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="renode.html">Run NuttX on Renode</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="signal_events_interrupt_handlers.html">Signaling Events from Interrupt Handlers</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="signaling_sem_priority_inheritance.html">Signaling Semaphores and Priority Inheritance</a></li> |
| <li class="toctree-l2 current"><a class="current reference internal" href="#">Smaller Vector Tables</a><ul> |
| <li class="toctree-l3"><a class="reference internal" href="#software-irq-remapping">Software IRQ Remapping</a><ul> |
| <li class="toctree-l4"><a class="reference internal" href="#irq-attach"><code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code></a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#irq-dispatch"><code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code></a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#irq-initialize"><code class="docutils literal notranslate"><span class="pre">irq_initialize()</span></code></a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#g-mapirq"><code class="docutils literal notranslate"><span class="pre">g_mapirq[]</span></code></a></li> |
| </ul> |
| </li> |
| <li class="toctree-l3"><a class="reference internal" href="#hardware-vector-remapping">Hardware Vector Remapping</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#vector-definitions">Vector Definitions</a><ul> |
| <li class="toctree-l4"><a class="reference internal" href="#interrupt-handler-definitions">Interrupt Handler Definitions</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#a-complication">A Complication</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#dubious-performance-improvements">Dubious Performance Improvements</a></li> |
| <li class="toctree-l4"><a class="reference internal" href="#complexity-and-generalizability">Complexity and Generalizability</a></li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="toctree-l2"><a class="reference internal" href="port.html">How to port</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="updating_release_system_elf.html">Updating a Release System with ELF Programs</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="partially_linked_elf.html">ELF Programs – With Symbol Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="fully_linked_elf.html">ELF Programs – No Symbol Tables</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="building_nuttx_with_app_out_of_src_tree.html">Building NuttX with Applications Outside the Source Tree</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="building_uclibcpp.html">Building uClibc++</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="custom_app_directories.html">Custom Application Directories</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="multiple_nsh_sessions.html">Multiple NSH Sessions</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="nsh_network_link_management.html">NSH Network Link Management</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="ram_rom_disks.html">RAM Disks and ROM Disks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="reading_can_msgs.html">Reading CAN Messages</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="remove_device_drivers_nsh.html">Removing Device Drivers with NSH</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="rust.html">Rust in NuttX</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="optee.html">Interfacing with OP-TEE</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> |
| <li class="toctree-l1"><a class="reference internal" href="../_tags/tagsindex.html">Tags</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">Smaller Vector Tables</li> |
| <li class="wy-breadcrumbs-aside"> |
| <a href="https://github.com/apache/nuttx/blob/master/Documentation/guides/smaller_vector_tables.rst" class="fa fa-github"> Edit on GitHub</a> |
| </li> |
| </ul> |
| <hr/> |
| </div> |
| <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> |
| <div itemprop="articleBody"> |
| |
| <section id="smaller-vector-tables"> |
| <h1>Smaller Vector Tables<a class="headerlink" href="#smaller-vector-tables" title="Permalink to this heading"></a></h1> |
| <div class="admonition warning"> |
| <p class="admonition-title">Warning</p> |
| <p>Migrated from: |
| <a class="reference external" href="https://cwiki.apache.org/confluence/display/NUTTX/Smaller+Vector+Tables">https://cwiki.apache.org/confluence/display/NUTTX/Smaller+Vector+Tables</a></p> |
| </div> |
| <p>One of the largest OS data structures is the vector table, |
| <code class="docutils literal notranslate"><span class="pre">g_irqvector[]</span></code>. This is the table that holds the vector |
| information when <code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code> is called and used to |
| dispatch interrupts by <code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code>. Recent changes |
| have made that table even larger, for 32-bit arm the |
| size of that table is given by:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">nbytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">number_of_interrupts</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="p">))</span> |
| </pre></div> |
| </div> |
| <p>We will focus on the STM32 for this discussion to keep |
| things simple. However, this discussion applies to all |
| architectures.</p> |
| <p>The number of (physical) interrupt vectors supported by |
| the MCU hardwared given by the definition <code class="docutils literal notranslate"><span class="pre">NR_IRQ</span></code> which |
| is provided in a header file in <code class="docutils literal notranslate"><span class="pre">arch/arm/include/stm32</span></code>. |
| This is, by default, the value of <code class="docutils literal notranslate"><span class="pre">number_of_interrupts</span></code> |
| in the above equation.</p> |
| <p>For a 32-bit ARM like the STM32 with, say, 100 interrupt |
| vectors, this size would be 800 bytes of memory. That is |
| not a lot for high-end MCUs with a lot of RAM memory, |
| but could be a show stopper for MCUs with minimal RAM.</p> |
| <p>Two approaches for reducing the size of the vector tables |
| are described below. Both depend on the fact that not all |
| interrupts are used on a given MCU. Most of the time, |
| the majority of entries in <code class="docutils literal notranslate"><span class="pre">g_irqvector[]</span></code> are zero because |
| only a small number of interrupts are actually attached |
| and enabled by the application. If you know that certain |
| IRQ numbers are not going to be used, then it is possible |
| to filter those out and reduce the size to the number of |
| supported interrupts.</p> |
| <p>For example, if the actual number of interrupts used were |
| 20, the the above requirement would go from 800 bytes to |
| 160 bytes.</p> |
| <section id="software-irq-remapping"> |
| <h2>Software IRQ Remapping<a class="headerlink" href="#software-irq-remapping" title="Permalink to this heading"></a></h2> |
| <p><cite>[On March 3, 2017, support for this “Software IRQ Remapping” |
| as included in the NuttX repository.]</cite></p> |
| <p>One of the simplest way of reducing the size of |
| <code class="docutils literal notranslate"><span class="pre">g_irqvector[]</span></code> would be to remap the large set of physical |
| interrupt vectors into a much small set of interrupts that |
| are actually used. For the sake of discussion, let’s |
| imagine two new configuration settings:</p> |
| <ul class="simple"> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_MINIMAL_VECTORTABLE</span></code>: Enables IRQ mapping</p></li> |
| <li><p><code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_NUSER_INTERRUPTS</span></code>: The number of IRQs after mapping.</p></li> |
| </ul> |
| <p>Then it could allocate the interrupt vector table to be |
| size <code class="docutils literal notranslate"><span class="pre">CONFIG_IRQ_NMAPPED_IRQ</span></code> instead of the much bigger |
| <code class="docutils literal notranslate"><span class="pre">NR_IRQS</span></code>:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE</span> |
| <span class="k">struct</span><span class="w"> </span><span class="nc">irq_info_s</span><span class="w"> </span><span class="n">g_irqvector</span><span class="p">[</span><span class="n">CONFIG_ARCH_NUSER_INTERRUPTS</span><span class="p">];</span> |
| <span class="cp">#else</span> |
| <span class="k">struct</span><span class="w"> </span><span class="nc">irq_info_s</span><span class="w"> </span><span class="n">g_irqvector</span><span class="p">[</span><span class="n">NR_IRQS</span><span class="p">];</span> |
| <span class="cp">#endif</span> |
| </pre></div> |
| </div> |
| <p>The <code class="docutils literal notranslate"><span class="pre">g_irqvector[]</span></code> table is accessed in only three places:</p> |
| <section id="irq-attach"> |
| <h3><code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code><a class="headerlink" href="#irq-attach" title="Permalink to this heading"></a></h3> |
| <p><code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code> receives the physical vector number along |
| with the information needed later to dispatch interrupts:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span><span class="w"> </span><span class="nf">irq_attach</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="n">xcpt_t</span><span class="w"> </span><span class="n">isr</span><span class="p">,</span><span class="w"> </span><span class="n">FAR</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">);</span> |
| </pre></div> |
| </div> |
| <p>Logic in <code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code> would map the incoming physical |
| vector number to a table index like:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE</span> |
| <span class="kt">int</span><span class="w"> </span><span class="n">ndx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">g_irqmap</span><span class="p">[</span><span class="n">irq</span><span class="p">];</span> |
| <span class="cp">#else</span> |
| <span class="kt">int</span><span class="w"> </span><span class="n">ndx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">irq</span><span class="p">;</span> |
| <span class="cp">#endif</span> |
| </pre></div> |
| </div> |
| <p>where <code class="docutils literal notranslate"><span class="pre">up_mapirq[]</span></code> is an array indexed by the physical |
| interrupt vector number and contains the new, mapped |
| interrupt vector table index. This array must be |
| provided by platform-specific code.</p> |
| <p><code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code> would this use this index to set the <code class="docutils literal notranslate"><span class="pre">g_irqvector[]</span></code>.</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">g_irqvector</span><span class="p">[</span><span class="n">ndx</span><span class="p">].</span><span class="n">handler</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">isr</span><span class="p">;</span> |
| <span class="n">g_irqvector</span><span class="p">[</span><span class="n">ndx</span><span class="p">].</span><span class="n">arg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">arg</span><span class="p">;</span> |
| </pre></div> |
| </div> |
| </section> |
| <section id="irq-dispatch"> |
| <h3><code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code><a class="headerlink" href="#irq-dispatch" title="Permalink to this heading"></a></h3> |
| <p><code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code> is called by MCU logic when an interrupt is received:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">void</span><span class="w"> </span><span class="nf">irq_dispatch</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="n">FAR</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">context</span><span class="p">);</span> |
| </pre></div> |
| </div> |
| <p>Where, again irq is the physical interrupt vector number.</p> |
| <p><code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code> would do essentially the same thing as |
| <code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code>. First it would map the irq number to |
| a table index:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE</span> |
| <span class="kt">int</span><span class="w"> </span><span class="n">ndx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">g_irqmap</span><span class="p">[</span><span class="n">irq</span><span class="p">];</span> |
| <span class="cp">#else</span> |
| <span class="kt">int</span><span class="w"> </span><span class="n">ndx</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">irq</span><span class="p">;</span> |
| <span class="cp">#endif</span> |
| </pre></div> |
| </div> |
| <p>Then dispatch the interrupt handling to the attached |
| interrupt handler. NOTE that the physical vector |
| number is passed to the handler so it is completely |
| unaware of the underlying <cite>shell</cite> game:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">vector</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">g_irqvector</span><span class="p">[</span><span class="n">ndx</span><span class="p">].</span><span class="n">handler</span><span class="p">;</span> |
| <span class="n">arg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">g_irqvector</span><span class="p">[</span><span class="n">ndx</span><span class="p">].</span><span class="n">arg</span><span class="p">;</span> |
| |
| <span class="n">vector</span><span class="p">(</span><span class="n">irq</span><span class="p">,</span><span class="w"> </span><span class="n">context</span><span class="p">,</span><span class="w"> </span><span class="n">arg</span><span class="p">);</span> |
| </pre></div> |
| </div> |
| </section> |
| <section id="irq-initialize"> |
| <h3><code class="docutils literal notranslate"><span class="pre">irq_initialize()</span></code><a class="headerlink" href="#irq-initialize" title="Permalink to this heading"></a></h3> |
| <p><code class="docutils literal notranslate"><span class="pre">irq_initialize()</span></code>: simply set the <code class="docutils literal notranslate"><span class="pre">g_irqvector[]</span></code> table |
| a known state on power-up. It would only have to distinguish |
| the difference in sizes.</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#ifdef CONFIG_ARCH_MINIMAL_VECTORTABLE</span> |
| <span class="cp"># define TAB_SIZE CONFIG_ARCH_NUSER_INTERRUPTS</span> |
| <span class="cp">#else</span> |
| <span class="cp"># define TAB_SIZE NR_IRQS</span> |
| <span class="cp">#endif</span> |
| |
| <span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</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="n">i</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">TAB_SIZE</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span> |
| </pre></div> |
| </div> |
| </section> |
| <section id="g-mapirq"> |
| <h3><code class="docutils literal notranslate"><span class="pre">g_mapirq[]</span></code><a class="headerlink" href="#g-mapirq" title="Permalink to this heading"></a></h3> |
| <p>An implementation of <code class="docutils literal notranslate"><span class="pre">up_mapirq()</span></code> might be something like:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><nuttx/irq.h></span> |
| |
| <span class="k">const</span><span class="w"> </span><span class="n">irq_mapped_t</span><span class="w"> </span><span class="n">g_irqmap</span><span class="p">[</span><span class="n">NR_IRQS</span><span class="p">]</span><span class="w"> </span><span class="o">=</span> |
| <span class="p">{</span> |
| <span class="p">...</span><span class="w"> </span><span class="n">IRQ</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="n">mapping</span><span class="w"> </span><span class="n">values</span><span class="w"> </span><span class="p">...</span> |
| <span class="p">};</span> |
| </pre></div> |
| </div> |
| <p><code class="docutils literal notranslate"><span class="pre">g_irqmap[]</span></code> is a array of mapped irq table indices. It |
| contains the mapped index value and is itself indexed |
| by the physical interrupt vector number. It provides |
| an <code class="docutils literal notranslate"><span class="pre">irq_mapped_t</span></code> value in the range of 0 to |
| <code class="docutils literal notranslate"><span class="pre">CONFIG_ARCH_NUSER_INTERRUPTS</span></code> that is the new, mapped |
| index into the vector table. Unsupported IRQs would |
| simply map to an out of range value like <code class="docutils literal notranslate"><span class="pre">IRQMAPPED_MAX</span></code>. |
| So, for example, if <code class="docutils literal notranslate"><span class="pre">g_irqmap[37]</span> <span class="pre">==</span> <span class="pre">24</span></code>, then the hardware |
| interrupt vector 37 will be mapped to the interrupt vector |
| table at index 24. if <code class="docutils literal notranslate"><span class="pre">g_irqmap[42]</span> <span class="pre">==</span> <span class="pre">IRQMAPPED_MAX</span></code>, then |
| hardware interrupt vector 42 is not used and if it occurs |
| will result in an unexpected interrupt crash.</p> |
| </section> |
| </section> |
| <section id="hardware-vector-remapping"> |
| <h2>Hardware Vector Remapping<a class="headerlink" href="#hardware-vector-remapping" title="Permalink to this heading"></a></h2> |
| <p><cite>[This technical approach is discussed here but is |
| discouraged because of technical “Complications” and |
| “Dubious Performance Improvements” discussed at the |
| end of this section.]</cite></p> |
| <p>Most ARMv7-M architectures support two mechanism for handling interrupts:</p> |
| <ul class="simple"> |
| <li><p>The so-called <cite>common</cite> vector handler logic enabled with |
| <code class="docutils literal notranslate"><span class="pre">CONFIG_ARMV7M_CMNVECTOR=y</span></code> that can be found in |
| <code class="docutils literal notranslate"><span class="pre">arch/arm/src/armv7-m/</span></code>, and</p></li> |
| <li><p>MCU-specific interrupt handling logic. For the |
| STM32, this logic can be found at <code class="docutils literal notranslate"><span class="pre">arch/arm/src/stm32/gnu/stm32_vectors.S</span></code>.</p></li> |
| </ul> |
| <p>The <cite>common</cite> vector logic is slightly more efficient, |
| the MCU-specific logic is slightly more flexible.</p> |
| <p>If we don’t use the <cite>common</cite> vector logic enabled with |
| <code class="docutils literal notranslate"><span class="pre">CONFIG_ARMV7M_CMNVECTOR=y</span></code>, but instead the more |
| flexible MCU-specific implementation, then we can |
| also use this to map the large set of hardware |
| interrupt vector numbers to a smaller set of software |
| interrupt numbers. This involves minimal changes to |
| the OS and does not require any magic software lookup |
| table. But is considerably more complex to implement.</p> |
| <p>This technical approach requires changes to three files:</p> |
| <ul class="simple"> |
| <li><p>A new header file at <code class="docutils literal notranslate"><span class="pre">arch/arm/include/stm32</span></code>, say |
| <code class="docutils literal notranslate"><span class="pre">xyz_irq.h</span></code> for the purposes of this discussion. |
| This new header file is like the other IRQ definition |
| header files in that directory except that it |
| defines only the IRQ number of the interrupts after |
| remapping. So, instead of having the 100 IRQ number |
| definitions of the original IRQ header file based on |
| the physical vector numbers, this header file would |
| define <code class="docutils literal notranslate"><span class="pre">only</span></code> the small set of 20 <code class="docutils literal notranslate"><span class="pre">mapped</span></code> IRQ numbers in |
| the range from 0 through 19. It would also set <code class="docutils literal notranslate"><span class="pre">NR_IRQS</span></code> |
| to the value 20.</p></li> |
| <li><p>A new header file at <code class="docutils literal notranslate"><span class="pre">arch/arm/src/stm32/hardware</span></code>, say |
| <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code>. It would be similar to the other vector |
| definitions files in that directory: It will consist |
| of a sequence of 100 <code class="docutils literal notranslate"><span class="pre">VECTOR</span></code> and <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code> macros. It will |
| define <code class="docutils literal notranslate"><span class="pre">VECTOR</span></code> entries for the 20 valid interrupts and |
| 80 <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code> entries for the unused interrupt vector numbers. |
| More about this below.</p></li> |
| <li><p>Modification of the <code class="docutils literal notranslate"><span class="pre">stm32_vectors.S</span></code> file. These changes |
| are trivial and involve only the conditional inclusion |
| of the new, special <code class="docutils literal notranslate"><span class="pre">xyz_vectors.h</span></code> header file.</p></li> |
| </ul> |
| <p><strong>REVISIT</strong>: This needs to be updated. Neither the <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code> |
| files nor the <code class="docutils literal notranslate"><span class="pre">stm32_vectors.S</span></code> exist in the current realization. |
| This has all been replaced with the common vector handling at |
| <code class="docutils literal notranslate"><span class="pre">arch/arm/src/armv7-m</span></code>.</p> |
| </section> |
| <section id="vector-definitions"> |
| <h2>Vector Definitions<a class="headerlink" href="#vector-definitions" title="Permalink to this heading"></a></h2> |
| <p>In <code class="docutils literal notranslate"><span class="pre">arch/arm/src/stm32/gnu/stm32_vector.S</span></code>, notice that the |
| <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code> file will be included twice. Before each |
| inclusion, the macros <code class="docutils literal notranslate"><span class="pre">VECTOR</span></code> and <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code> are defined.</p> |
| <p>The first time that <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code> included, it defines the |
| hardware vector table. The hardware vector table consists |
| of <code class="docutils literal notranslate"><span class="pre">NR_IRQS</span></code> 32-bit addresses in an array. This is |
| accomplished by setting:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#undef VECTOR</span> |
| <span class="cp">#define VECTOR(l,i) .word l</span> |
| |
| <span class="cp">#undef UNUSED</span> |
| <span class="cp">#define UNUSED(i) .word stm32_reserved</span> |
| </pre></div> |
| </div> |
| <p>Then including <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code>. So consider the following |
| definitions in the original file:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">...</span> |
| <span class="n">VECTOR</span><span class="p">(</span><span class="n">stm32_usart1</span><span class="p">,</span><span class="w"> </span><span class="n">STM32_IRQ_USART1</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Vector 16+37: USART1 global interrupt */</span> |
| <span class="n">VECTOR</span><span class="p">(</span><span class="n">stm32_usart2</span><span class="p">,</span><span class="w"> </span><span class="n">STM32_IRQ_USART2</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Vector 16+38: USART2 global interrupt */</span> |
| <span class="n">VECTOR</span><span class="p">(</span><span class="n">stm32_usart3</span><span class="p">,</span><span class="w"> </span><span class="n">STM32_IRQ_USART3</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Vector 16+39: USART3 global interrupt */</span> |
| <span class="p">...</span> |
| </pre></div> |
| </div> |
| <p>Suppose that we wanted to support only USART1 and that |
| we wanted to have the IRQ number for USART1 to be 12. |
| That would be accomplished in the <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code> header |
| file like this:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">...</span> |
| <span class="n">VECTOR</span><span class="p">(</span><span class="n">stm32_usart1</span><span class="p">,</span><span class="w"> </span><span class="n">STM32_IRQ_USART1</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Vector 16+37: USART1 global interrupt */</span> |
| <span class="n">UNUSED</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Vector 16+38: USART2 global interrupt */</span> |
| <span class="n">UNUSED</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Vector 16+39: USART3 global interrupt */</span> |
| <span class="p">...</span> |
| </pre></div> |
| </div> |
| <p>Where the value of <code class="docutils literal notranslate"><span class="pre">STM32_IRQ_USART1</span></code> was defined to |
| be 12 in the <code class="docutils literal notranslate"><span class="pre">arch/arm/include/stm32/xyz_irq.h</span></code> header |
| file. When <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code> is included by <code class="docutils literal notranslate"><span class="pre">stm32_vectors.S</span></code> |
| with the above definitions for <code class="docutils literal notranslate"><span class="pre">VECTOR</span></code> and <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code>, the |
| following would result:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">...</span> |
| <span class="p">.</span><span class="n">word</span><span class="w"> </span><span class="n">stm32_usart1</span> |
| <span class="p">.</span><span class="n">word</span><span class="w"> </span><span class="n">stm32_reserved</span> |
| <span class="p">.</span><span class="n">word</span><span class="w"> </span><span class="n">stm32_reserved</span> |
| <span class="p">...</span> |
| </pre></div> |
| </div> |
| <p>These are the settings for vector 53, 54, and 55, |
| respectively. The entire vector table would be populated |
| in this way. <code class="docutils literal notranslate"><span class="pre">stm32_reserved</span></code>, if called would result in |
| an “unexpected ISR” crash. <code class="docutils literal notranslate"><span class="pre">stm32_usart1</span></code>, if called will |
| process the USART1 interrupt normally as we will see below.</p> |
| <section id="interrupt-handler-definitions"> |
| <h3>Interrupt Handler Definitions<a class="headerlink" href="#interrupt-handler-definitions" title="Permalink to this heading"></a></h3> |
| <p>in the vector table, all of the valid vectors are set to |
| the address of a <cite>handler</cite> function. All unused vectors |
| are force to vector to <code class="docutils literal notranslate"><span class="pre">stm32_reserved</span></code>. Currently, only |
| vectors that are not supported by the hardware are |
| marked <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code>, but you can mark any vector <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code> in |
| order to eliminate it.</p> |
| <p>The second time that <code class="docutils literal notranslate"><span class="pre">xyz_vector.h</span></code> is included by |
| <code class="docutils literal notranslate"><span class="pre">stm32_vector.S</span></code>, the <cite>handler</cite> functions are generated. |
| Each of the valid vectors point to the matching handler |
| function. In this case, you do NOT have to provide |
| handlers for the <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code> vectors, only for the used |
| <code class="docutils literal notranslate"><span class="pre">VECTOR</span></code> vectors. All of the unused vectors will go |
| to the common <code class="docutils literal notranslate"><span class="pre">stm32_reserved</span></code> handler. The remaining |
| set of handlers is very sparse.</p> |
| <p>These are the values of <code class="docutils literal notranslate"><span class="pre">UNUSED</span></code> and <code class="docutils literal notranslate"><span class="pre">VECTOR</span></code> macros on the |
| second time the <code class="docutils literal notranslate"><span class="pre">xzy_vector.h</span></code> is included by <code class="docutils literal notranslate"><span class="pre">stm32_vectors.S</span></code>:</p> |
| <div class="highlight-asm notranslate"><div class="highlight"><pre><span></span><span class="na">.macro</span><span class="w"> </span><span class="no">HANDLER</span><span class="p">,</span><span class="w"> </span><span class="no">label</span><span class="p">,</span><span class="w"> </span><span class="no">irqno</span> |
| <span class="w"> </span><span class="na">.thumb_func</span> |
| <span class="nl">label:</span> |
| <span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">r0</span><span class="p">,</span><span class="w"> </span><span class="c1">#\irqno</span> |
| <span class="w"> </span><span class="nf">b</span><span class="w"> </span><span class="no">exception_common</span> |
| <span class="na">.endm</span> |
| |
| <span class="c1">#undef VECTOR</span> |
| <span class="c1">#define VECTOR(l,i) HANDLER l, i</span> |
| |
| <span class="c1">#undef UNUSED</span> |
| <span class="c1">#define UNUSED(i)</span> |
| </pre></div> |
| </div> |
| <p>In the above USART1 example, a single handler would be |
| generated that will provide the IRQ number 12. Remember |
| that 12 is the expansion of the macro <code class="docutils literal notranslate"><span class="pre">STM32_IRQ_USART1</span></code> |
| that is provided in the <code class="docutils literal notranslate"><span class="pre">arch/arm/include/stm32/xyz_irq.h</span></code> |
| header file:</p> |
| <div class="highlight-asm notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="na">.thumb_func</span> |
| <span class="nl">stm32_usart1:</span> |
| <span class="w"> </span><span class="nf">mov</span><span class="w"> </span><span class="no">r0</span><span class="p">,</span><span class="w"> </span><span class="mi">#12</span> |
| <span class="w"> </span><span class="nf">b</span><span class="w"> </span><span class="no">exception_common</span> |
| </pre></div> |
| </div> |
| <p>Now, when vector 16+37 occurs it is mapped to IRQ 12 |
| with no significant software overhead.</p> |
| </section> |
| <section id="a-complication"> |
| <h3>A Complication<a class="headerlink" href="#a-complication" title="Permalink to this heading"></a></h3> |
| <p>A complication in the above logic has been noted by David Sidrane: |
| When we access the NVIC in <code class="docutils literal notranslate"><span class="pre">stm32_irq.c</span></code> in order to enable |
| and disable interrupts, the logic requires the physical |
| vector number in order to select the NVIC register and |
| the bit(s) the modify in the NVIC register.</p> |
| <p>This could be handled with another small IRQ lookup table |
| (20 <code class="docutils literal notranslate"><span class="pre">uint8_t</span></code> entries in our example situation above). But |
| then this approach is not so much better than the <cite>Software |
| Vector Mapping</cite> described about which does not suffer from |
| this problem. Certainly enabling/disabling interrupts in a |
| much lower rate operation and at least does not put the |
| lookup in the critical interrupt path.</p> |
| <p>Another option suggested by David Sidrane is equally ugly:</p> |
| <ul class="simple"> |
| <li><p>Don’t change the <code class="docutils literal notranslate"><span class="pre">arch/arm/include/stm32</span></code> IRQ definition file.</p></li> |
| <li><p>Instead, encode the IRQ number so that it has both |
| the index and physical vector number:</p></li> |
| </ul> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="p">...</span> |
| <span class="n">VECTOR</span><span class="p">(</span><span class="n">stm32_usart1</span><span class="p">,</span><span class="w"> </span><span class="n">STM32_IRQ_USART1</span><span class="w"> </span><span class="o"><<</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">STM32_INDEX_USART1</span><span class="p">)</span> |
| <span class="n">UNUSED</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> |
| <span class="n">UNUSED</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> |
| <span class="p">...</span> |
| </pre></div> |
| </div> |
| <p>The STM32_INDEX_USART1 would have the value 12 and |
| STM32_IRQ_USART1 would be as before (53). This encoded |
| value would be received by <code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code> and it would |
| decode both the index and the physical vector number. |
| It would use the index to look up in the <code class="docutils literal notranslate"><span class="pre">g_irqvector[]</span></code> |
| table but would pass the physical vector number to the |
| interrupt handler as the IRQ number.</p> |
| <p>A lookup would still be required in <code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code> in |
| order to convert the physical vector number back to |
| an index (100 <code class="docutils literal notranslate"><span class="pre">uint8_t</span></code> entries in our example). So |
| some lookup is unavoidable.</p> |
| <p>Based upon these analysis, my recommendation is that |
| we do not consider the second option any further. The |
| first option is cleaner, more portable, and generally |
| preferable.is well worth that.</p> |
| </section> |
| <section id="dubious-performance-improvements"> |
| <h3>Dubious Performance Improvements<a class="headerlink" href="#dubious-performance-improvements" title="Permalink to this heading"></a></h3> |
| <p>The intent of this second option was to provide a higher |
| performance mapping of physical interrupt vectors to IRQ |
| numbers compared to the pure software mapping of option 1. However, |
| in order to implement this approach, we had |
| to use the less efficient, non-common vector handling |
| logic. That logic is not terribly less efficient, the |
| cost is probably only a 16 bit load immediate instruction |
| and branch to another location in FLASH (which will cause |
| the CPU pipeline to be flushed).</p> |
| <p>The variant of option 2 where both the physical vector number |
| and vector table index are encoded would require even more |
| processing in <code class="docutils literal notranslate"><span class="pre">irq_dispatch()</span></code> in order to decode the |
| physical vector number and vector table index. |
| Possible just AND and SHIFT instructions.</p> |
| <p>However, the minimal cost of the first pure software |
| mapping approach was possibly as small as a single |
| indexed byte fetch from FLASH in <code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code>. |
| Indexing is, of course, essentially <cite>free</cite> in the ARM |
| ISA, the primary cost would be the FLASH memory access. |
| So my first assessment is that the performance of both |
| approaches is the essentially the same. If anything, the |
| first approach is possibly the more performant if |
| implemented efficiently.</p> |
| <p>Both options would require some minor range checking in |
| <code class="docutils literal notranslate"><span class="pre">irq_attach()</span></code> as well.</p> |
| <p>Because of this and because of the simplicity of the |
| first option, I see no reason to support or consider |
| this second option any further.</p> |
| </section> |
| <section id="complexity-and-generalizability"> |
| <h3>Complexity and Generalizability<a class="headerlink" href="#complexity-and-generalizability" title="Permalink to this heading"></a></h3> |
| <p>Option 2 is overly complex; it depends on a deep understanding |
| on how the MCU interrupt logic works and on a high level of |
| Thumb assembly language skills.</p> |
| <p>Another problem with option 2 is that really only applies to |
| the Cortex-M family of processors and perhaps others that |
| support interrupt vectored interrupts in a similar fashion. |
| It is not a general solution that can be used with any CPU |
| architectures.</p> |
| <p>And even worse, the MCU-specific interrupt handling logic |
| that this support depends upon is is very limited. As soon |
| as the common interrupt handler logic was added, I stopped |
| implementing the MCU specific logic in all newer ARMv7-M |
| ports. So that MCU specific interrupt handler logic is |
| only present for EFM32, Kinetis, LPC17, SAM3/4, STM32, |
| Tiva, and nothing else. Very limited!</p> |
| <p>These are further reasons why option 2 is no recommended and |
| will not be supported explicitly.</p> |
| </section> |
| </section> |
| </section> |
| |
| |
| </div> |
| </div> |
| <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> |
| <a href="signaling_sem_priority_inheritance.html" class="btn btn-neutral float-left" title="Signaling Semaphores and Priority Inheritance" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> |
| <a href="port.html" class="btn btn-neutral float-right" title="How to port" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a> |
| </div> |
| |
| <hr/> |
| |
| <div role="contentinfo"> |
| <p>© Copyright 2023, The Apache Software Foundation.</p> |
| </div> |
| |
| |
| |
| </footer> |
| </div> |
| </div> |
| </section> |
| </div> |
| <script> |
| jQuery(function () { |
| SphinxRtdTheme.Navigation.enable(true); |
| }); |
| </script> |
| |
| </body> |
| </html> |