| <!-- |
| 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>Drivers — 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="Task Trace" href="tasktrace.html" /> |
| <link rel="prev" title="How to use RNDIS" href="rndis.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 current"><a class="current reference internal" href="#">Drivers</a><ul> |
| <li class="toctree-l3"><a class="reference internal" href="#porting-a-driver">Porting a Driver</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#nuttx-drivers-as-a-reference">NuttX Drivers as a Reference</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#using-chip-datasheets">Using Chip Datasheets</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#logic-analyzers">Logic Analyzers</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#dma-debugging">DMA Debugging</a></li> |
| </ul> |
| </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"><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="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">Drivers</li> |
| <li class="wy-breadcrumbs-aside"> |
| <a href="../_sources/guides/drivers.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="drivers"> |
| <span id="id1"></span><h1>Drivers<a class="headerlink" href="#drivers" title="Permalink to this heading"></a></h1> |
| <p>Some NuttX boards don’t have full support for all the on-chip peripherals. If you need support for this hardware, |
| you will either need to port a driver from another chip, or write one yourself. This section discusses how to do that.</p> |
| <section id="porting-a-driver"> |
| <span id="drivers-porting"></span><h2>Porting a Driver<a class="headerlink" href="#porting-a-driver" title="Permalink to this heading"></a></h2> |
| <p>Often support for on-chip peripherals exists in a closely related chip, or even a different family or from a different |
| manufacturer. Many chips are made up of different Intellectual Property (IP) blocks that are licensed from vendors like |
| Cadence, Synopsys, and others. The IP blocks may be similar enough to use another chip’s driver with little |
| modification.</p> |
| <ul> |
| <li><p>Find a similar driver in NuttX source code:</p> |
| <ul class="simple"> |
| <li><p>Look at register names listed in the datasheet for the peripheral.</p></li> |
| <li><p>Search the NuttX codebase for the register names (try several different ones).</p></li> |
| <li><p>Note that you’ll have to compare the datasheet to the header and code files to see if there are differences; there |
| will usually be some differences between architectures, and they can be significant.</p></li> |
| </ul> |
| </li> |
| <li><p>Find a similar driver in U-Boot, Zephyr or BSD Unix (OpenBSD, FreeBSD, NetBSD) source code:</p> |
| <ul class="simple"> |
| <li><p>Only for inspiration, you can’t copy code because of license incompatibility and Apache Foundation restrictions. |
| (Apache License 2.0 and BSD code can come in with a software grant agreement from the original authors; this can |
| sometimes be hard to get. Ask on the mailing list if you’re unsure.)</p></li> |
| <li><p>But you can debug to see how the driver works.</p></li> |
| <li><p><a class="reference external" href="https://www.denx.de/wiki/U-Boot">U-Boot</a> drivers are often easier to understand than BSD Unix drivers because |
| U-Boot is simpler.</p></li> |
| </ul> |
| </li> |
| <li><p>Understanding how the driver works</p> |
| <p>Here are a couple of techniques that helped me.</p> |
| <blockquote> |
| <div><ul> |
| <li><p>printf debugging</p> |
| <ul> |
| <li><p>Sprinkle <code class="docutils literal notranslate"><span class="pre">custinfo()</span></code> logging statements through your code to see execution paths and look at variables |
| while the code is running. The reason to use <code class="docutils literal notranslate"><span class="pre">custinfo()</span></code> as opposed to the other logging shortcuts |
| (<code class="docutils literal notranslate"><span class="pre">mcinfo()</span></code>, etc.) is that you can turn on and off other other logging and still see your custom debug |
| logging. Sometimes it’s useful to quiet the flood of logging that comes from a particular debug logging |
| shortcut.</p></li> |
| <li><p>Note that printing info to the console will affect timing.</p></li> |
| <li><p>Keep a file with just your debug settings in it, like this (<code class="docutils literal notranslate"><span class="pre">debugsettings</span></code>):</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">CONFIG_DEBUG_CUSTOM_INFO</span><span class="o">=</span><span class="n">y</span> |
| <span class="p">(</span><span class="n">etc</span><span class="p">..)</span> |
| </pre></div> |
| </div> |
| </li> |
| <li><p>Add the settings to the end of your <code class="docutils literal notranslate"><span class="pre">.config</span></code> file after running <code class="docutils literal notranslate"><span class="pre">make</span> <span class="pre">menuconfig</span></code> (that will reorder |
| the file, making it harder to see and change the debug settings if you need to).</p> |
| <div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>$<span class="w"> </span>cat<span class="w"> </span>.config<span class="w"> </span>debugsettings<span class="w"> </span>><span class="w"> </span>.config1<span class="w"> </span><span class="p">;</span><span class="w"> </span>mv<span class="w"> </span>.config1<span class="w"> </span>.config |
| </pre></div> |
| </div> |
| </li> |
| <li><p>If you are using interrupts and threads (many things in NuttX run in different threads as a response to interrupts), |
| you can use printf debugging to see overlapping execution.</p> |
| <ul> |
| <li><p>Interrupts - here’s how to inspect the C stack frame to see what execution environment is currently running:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">uint32_t</span><span class="w"> </span><span class="n">frame</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="cm">/* MUST be the very first thing in the function */</span> |
| <span class="kt">uint32_t</span><span class="w"> </span><span class="n">p_frame</span><span class="p">;</span> |
| <span class="n">frame</span><span class="o">++</span><span class="p">;</span><span class="w"> </span><span class="cm">/* make sure that frame doesn't get optimized out */</span> |
| <span class="n">p_frame</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="p">)(</span><span class="o">&</span><span class="n">frame</span><span class="p">);</span> |
| <span class="n">custinfo</span><span class="p">(</span><span class="s">"p_frame: %08x</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">p_frame</span><span class="p">);</span> |
| </pre></div> |
| </div> |
| </li> |
| <li><p>Threads - here’s how to get the thread identifier to see which thread is currently executing:</p> |
| <div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">pthread_t</span><span class="w"> </span><span class="n">thread_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pthread_self</span><span class="p">();</span> |
| <span class="n">custinfo</span><span class="p">(</span><span class="s">"pthread_id: %08x</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">thread_id</span><span class="p">);</span> |
| </pre></div> |
| </div> |
| </li> |
| </ul> |
| </li> |
| <li><p>stack frame printf</p></li> |
| <li><p>thread printf</p></li> |
| </ul> |
| </li> |
| <li><p><a class="reference external" href="https://www.gnu.org/software/gdb/">GDB — the GNU Debugger</a></p> |
| <p>GDB is a great tool. In this guide we’ve already used it to load our program and run it. But it can do a lot |
| more. You can single-step through code, examine variables and memory, set breakpoints, and more. I generally use |
| it from the commandline, but have also used it from an IDE like JetBrains’ Clion, where it’s easier to see the |
| code context.</p> |
| <p>One add-on that I found to be essential is the ability to examine blocks of memory, like buffers that NuttX uses |
| for reading and writing to storage media or network adapters. This <a class="reference external" href="https://stackoverflow.com/a/54784260/431222">Stack Overflow question on using GDB to |
| examine memory</a> includes a GDB command that is very handy. Add |
| this to your <code class="docutils literal notranslate"><span class="pre">.gdbinit</span></code> file, and then use the <code class="docutils literal notranslate"><span class="pre">xxd</span></code> command to dump memory in an easy-to-read format:</p> |
| <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>define xxd |
| if $argc < 2 |
| set $size = sizeof(*$arg0) |
| else |
| set $size = $arg1 |
| end |
| dump binary memory dump.bin $arg0 ((void *)$arg0)+$size |
| eval "shell xxd -o %d dump.bin; rm dump.bin", ((void *)$arg0) |
| end |
| document xxd |
| Dump memory with xxd command (keep the address as offset) |
| |
| xxd addr [size] |
| addr -- expression resolvable as an address |
| size -- size (in byte) of memory to dump |
| sizeof(*addr) is used by default end |
| </pre></div> |
| </div> |
| <p>Here’s a short GDB session that shows what this looks like in practice. Note that the memory location being |
| examined (<code class="docutils literal notranslate"><span class="pre">0x200aa9eo</span></code> here) is a buffer being passed to <code class="docutils literal notranslate"><span class="pre">mmcsd_readsingle</span></code>:</p> |
| <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Program received signal SIGTRAP, Trace/breakpoint trap. |
| 0x200166e8 in up_idle () at common/arm_idle.c:78 |
| 78 } |
| (gdb) b mmcsd_readsingle |
| Breakpoint 1 at 0x2006ea70: file mmcsd/mmcsd_sdio.c, line 1371. |
| (gdb) c |
| Continuing. |
| |
| Breakpoint 1, mmcsd_readsingle (priv=0x200aa8c0, buffer=0x200aa9e0 "WRTEST TXT \030", startblock=2432) at mmcsd/mmcsd_sdio.c:1371 |
| 1371 finfo("startblock=%d\n", startblock); |
| (gdb) xxd 0x200aa9e0 200 |
| 200aa9e0: 5752 5445 5354 2020 5458 5420 1800 0000 WRTEST TXT .... |
| 200aa9f0: 0000 0000 0000 0000 0000 5500 1100 0000 ..........U..... |
| 200aaa00: 5752 5445 5354 3520 5458 5420 1800 0000 WRTEST5 TXT .... |
| 200aaa10: 0000 0000 0000 0000 0000 5800 1500 0000 ..........X..... |
| 200aaa20: e552 5445 5854 3620 5458 5420 1800 0000 .RTEXT6 TXT .... |
| 200aaa30: 0000 0000 0000 0000 0000 5600 1200 0000 ..........V..... |
| 200aaa40: 5752 5445 5354 3620 5458 5420 1800 0000 WRTEST6 TXT .... |
| 200aaa50: 0000 0000 0000 0000 0000 5600 1200 0000 ..........V..... |
| 200aaa60: 0000 0000 0000 0000 0000 0000 0000 0000 ................ |
| 200aaa70: 0000 0000 0000 0000 0000 0000 0000 0000 ................ |
| 200aaa80: 0000 0000 0000 0000 0000 0000 0000 0000 ................ |
| 200aaa90: 0000 0000 0000 0000 0000 0000 0000 0000 ................ |
| 200aaaa0: 0000 0000 0000 0000 ........ |
| </pre></div> |
| </div> |
| </li> |
| </ul> |
| </div></blockquote> |
| </li> |
| </ul> |
| </section> |
| <section id="nuttx-drivers-as-a-reference"> |
| <h2>NuttX Drivers as a Reference<a class="headerlink" href="#nuttx-drivers-as-a-reference" title="Permalink to this heading"></a></h2> |
| <p>If you’re not porting a NuttX driver from another architecture, it still helps to look at other similar NuttX |
| drivers, if there are any. For instance, when implementing an Ethernet driver, look at other NuttX Ethernet drivers; |
| for an SD Card driver, look at other NuttX SD Card drivers. Even if the chip-specific code won’t be the same, the |
| structure to interface with NuttX can be used.</p> |
| </section> |
| <section id="using-chip-datasheets"> |
| <h2>Using Chip Datasheets<a class="headerlink" href="#using-chip-datasheets" title="Permalink to this heading"></a></h2> |
| <p>To port or write a driver, you’ll have to be familiar with the information in the chip datasheet. Definitely find |
| the datasheet for your chip, and read the sections relevant to the peripheral you’re working with. Doing so ahead |
| of time will save a lot of time later.</p> |
| <p>Another thing that’s often helpful is to refer to sample code provided by the manufacturer, or driver code from |
| another operating system (like U-Boot, Zephyr, or FreeBSD) while referring to the datasheet — seeing how working |
| code implements the necessary algorithms often helps one understand how the driver needs to work.</p> |
| <ul> |
| <li><p>How to use a datasheet</p> |
| <p>Key pieces of information in System-on-a-Chip (SoC) datasheets are usually:</p> |
| <ul class="simple"> |
| <li><p>Chip Architecture Diagram — shows how the subsections of the chip (CPU, system bus, peripherals, I/O, etc.) connect |
| to each other.</p></li> |
| <li><p>Memory Map — showing the location of peripheral registers in memory. This info usually goes into a header file.</p></li> |
| <li><p>DMA Engine — if Direct Memory Access (DMA) is used, this may have info on how to use it.</p></li> |
| <li><p>Peripheral — the datasheet usually has a section on how the peripheral works. Key parts of this include:</p> |
| <ul> |
| <li><p>Registers List — name and offset from the base memory address of the peripheral. This needs to go into a header |
| file.</p></li> |
| <li><p>Register Map — what is the size of each register, and what do the bits mean? You will need to create <code class="docutils literal notranslate"><span class="pre">#defines</span></code> |
| in a header file that your code will use to operate on the registers. Refer to other driver header files for |
| examples.</p></li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </section> |
| <section id="logic-analyzers"> |
| <h2>Logic Analyzers<a class="headerlink" href="#logic-analyzers" title="Permalink to this heading"></a></h2> |
| <p>For drivers that involve input and output (I/O), especially that involve complex protocols like SD Cards, SPI, I2C, |
| etc., actually seeing the waveform that goes in and out the chip’s pins is extremely helpful. <a class="reference external" href="https://en.wikipedia.org/wiki/Logic_analyzer">Logic Analyzers</a> |
| can capture that information and display it graphically, allowing you to see if the driver is doing the right thing |
| on the wire.</p> |
| </section> |
| <section id="dma-debugging"> |
| <h2>DMA Debugging<a class="headerlink" href="#dma-debugging" title="Permalink to this heading"></a></h2> |
| <ul class="simple"> |
| <li><p>Dump registers before, during, and after transfer. Some NuttX drivers (<code class="docutils literal notranslate"><span class="pre">sam_sdmmc.c</span></code> or <code class="docutils literal notranslate"><span class="pre">imxrt_sdmmc.c</span></code> for |
| example) have built-in code for debugging register states, and can sample registers before, during, and |
| immediately after a DMA transfer, as well as code that can dump the peripheral registers in a nicely-formatted |
| way onto the console device (which can be a serial console, a network console, or memory). Consider using something |
| like this to see what’s happening inside the chip if you’re trying to debug DMA transfer code.</p></li> |
| <li><p>Compare register settings to expected settings determined from the datasheet or from dumping registers from working |
| code in another operating system (U-Boot, Zephyr, FreeBSD, etc.).</p></li> |
| <li><p>Use the <code class="docutils literal notranslate"><span class="pre">xxd</span></code> GDB tool mentioned above to dump NuttX memory buffers before, during, and after a transfer to see if |
| data is being transferred correctly, if there are over- or under-runs, or to diagnose data being stored in incorrect |
| locations.</p></li> |
| <li><p>printf debugging register states can also help here.</p></li> |
| <li><p>Remember that logging can change the timing of any algorithms you might be using, so things may start or stop |
| working when logging is added or removed. Definitely test with logging disabled.</p></li> |
| </ul> |
| </section> |
| </section> |
| |
| |
| </div> |
| </div> |
| <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> |
| <a href="rndis.html" class="btn btn-neutral float-left" title="How to use RNDIS" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> |
| <a href="tasktrace.html" class="btn btn-neutral float-right" title="Task Trace" 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> |