| <!-- |
| 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>OS Drivers Design — 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="Device Drivers" href="device_drivers.html" /> |
| <link rel="prev" title="Implementation Details" href="index.html" /> |
| </head> |
| |
| <body class="wy-body-for-nav"> |
| <div class="wy-grid-for-nav"> |
| <nav data-toggle="wy-nav-shift" class="wy-nav-side"> |
| <div class="wy-side-scroll"> |
| <div class="wy-side-nav-search" > |
| |
| <a href="../index.html" class="icon icon-home"> NuttX |
| |
| |
| |
| </a> |
| |
| <!-- this version selector is quite ugly, should be probably replaced by something |
| more modern --> |
| |
| <div class="version-selector"> |
| <select onchange="javascript:location.href = this.value;"> |
| |
| <option value="../../latest" selected="selected">latest</option> |
| |
| <option value="../../10.0.0" >10.0.0</option> |
| |
| <option value="../../10.0.1" >10.0.1</option> |
| |
| <option value="../../10.1.0" >10.1.0</option> |
| |
| <option value="../../10.2.0" >10.2.0</option> |
| |
| <option value="../../10.3.0" >10.3.0</option> |
| |
| <option value="../../11.0.0" >11.0.0</option> |
| |
| <option value="../../12.0.0" >12.0.0</option> |
| |
| <option value="../../12.1.0" >12.1.0</option> |
| |
| <option value="../../12.2.0" >12.2.0</option> |
| |
| <option value="../../12.2.1" >12.2.1</option> |
| |
| <option value="../../12.3.0" >12.3.0</option> |
| |
| <option value="../../12.4.0" >12.4.0</option> |
| |
| <option value="../../12.5.0" >12.5.0</option> |
| |
| <option value="../../12.5.1" >12.5.1</option> |
| |
| <option value="../../12.6.0" >12.6.0</option> |
| |
| <option value="../../12.7.0" >12.7.0</option> |
| |
| <option value="../../12.8.0" >12.8.0</option> |
| |
| <option value="../../12.9.0" >12.9.0</option> |
| |
| <option value="../../12.10.0" >12.10.0</option> |
| |
| <option value="../../12.11.0" >12.11.0</option> |
| |
| </select> |
| </div> |
| |
| |
| <div role="search"> |
| <form id="rtd-search-form" class="wy-form" action="../search.html" method="get"> |
| <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" /> |
| <input type="hidden" name="check_keywords" value="yes" /> |
| <input type="hidden" name="area" value="default" /> |
| </form> |
| </div> |
| |
| </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> |
| <p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p> |
| <ul class="current"> |
| <li class="toctree-l1"><a class="reference internal" href="../index.html">Home</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../introduction/index.html">Introduction</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../quickstart/index.html">Getting Started</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../contributing/index.html">Contributing</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../platforms/index.html">Supported Platforms</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../components/index.html">OS Components</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../applications/index.html">Applications</a></li> |
| <li class="toctree-l1 current"><a class="reference internal" href="index.html">Implementation Details</a><ul class="current"> |
| <li class="toctree-l2 current"><a class="current reference internal" href="#">OS Drivers Design</a><ul> |
| <li class="toctree-l3"><a class="reference internal" href="#character-and-block-drivers">Character and Block Drivers</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#mtd-drivers">MTD Drivers</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#monolithic-drivers">Monolithic Drivers</a></li> |
| <li class="toctree-l3"><a class="reference internal" href="#upper-half-and-lower-half-drivers">Upper Half and Lower Half Drivers</a><ul> |
| <li class="toctree-l4"><a class="reference internal" href="#one-to-many-encapsulation-and-polymorphism">One to Many: Encapsulation and Polymorphism</a></li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="toctree-l2"><a class="reference internal" href="device_drivers.html">Device Drivers</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="processes_vs_tasks.html">Linux Processes vs NuttX Tasks</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="critical_sections.html">Critical Sections</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="interrupt_controls.html">Per-Thread Interrupt Controls</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="preemption_latency.html">Effects of Disabling Interrupts or Pre-Emption on Response Latency</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="bottomhalf_interrupt.html">Bottom-Half Interrupt Handlers</a></li> |
| <li class="toctree-l2"><a class="reference internal" href="simulation.html">The NuttX Simulation</a></li> |
| </ul> |
| </li> |
| <li class="toctree-l1"><a class="reference internal" href="../reference/index.html">API Reference</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../guides/index.html">Guides</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li> |
| <li class="toctree-l1"><a class="reference internal" href="../logos/index.html">NuttX Logos</a></li> |
| </ul> |
| |
| </div> |
| </div> |
| </nav> |
| |
| <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" > |
| <i data-toggle="wy-nav-top" class="fa fa-bars"></i> |
| <a href="../index.html">NuttX</a> |
| </nav> |
| |
| <div class="wy-nav-content"> |
| <div class="rst-content"> |
| <div role="navigation" aria-label="Page navigation"> |
| <ul class="wy-breadcrumbs"> |
| <li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li> |
| <li class="breadcrumb-item"><a href="index.html">Implementation Details</a></li> |
| <li class="breadcrumb-item active">OS Drivers Design</li> |
| <li class="wy-breadcrumbs-aside"> |
| <a href="../_sources/implementation/drivers_design.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="os-drivers-design"> |
| <h1>OS Drivers Design<a class="headerlink" href="#os-drivers-design" title="Permalink to this heading"></a></h1> |
| <p>There are three kinds of drivers that are recognized by the OS and are visible to |
| applications. Two are POSIX standard device driver types, one is non-standard. |
| There are also internal OS components that may also be considered to be drivers |
| or, more correctly, lower-half drivers. Details about these are given below.</p> |
| <section id="character-and-block-drivers"> |
| <h2>Character and Block Drivers<a class="headerlink" href="#character-and-block-drivers" title="Permalink to this heading"></a></h2> |
| <p>The standard driver types include:</p> |
| <ul class="simple"> |
| <li><p><strong>Character Drivers</strong>. First there are the character drivers These are drivers |
| that support user accessibility via <code class="docutils literal notranslate"><span class="pre">read()</span></code>, <code class="docutils literal notranslate"><span class="pre">write()</span></code> etc. The others do |
| not naturally. Character drivers implement a stream of incoming or outgoing bytes.</p></li> |
| <li><p><strong>Block Drivers</strong>. These are used to support files systems that supported |
| block-oriented I/O, not a character stream. The user cannot <em>directly</em> access |
| block drivers.</p></li> |
| </ul> |
| <p>The user can, however, access block drivers indirectly through a character driver proxy. |
| Both character and block drivers are represented by device nodes, usually in <code class="docutils literal notranslate"><span class="pre">/dev</span></code>. |
| But if you try to open the block driver, something very strange happens: A temporary, |
| nameless proxy character driver is automatically instantiated that maps a character |
| driver’s byte stream into blocks and mediates the driver access to the block driver. |
| This is the logic in <code class="docutils literal notranslate"><span class="pre">drivers/bch</span></code>. BCH stands for block to character. So from the |
| application point of view, the both seem to be character drivers and applications |
| can interact with both in the same way.</p> |
| <p>This capability is exploited, for example, by the NuttX file system formatting |
| applications like mkfatfs to format a FAT system on a block driver.</p> |
| <p>There is also the complement, the loop device that converts a character driver into |
| a block driver. Loop devices are commonly used to format a file system image in RAM.</p> |
| </section> |
| <section id="mtd-drivers"> |
| <h2>MTD Drivers<a class="headerlink" href="#mtd-drivers" title="Permalink to this heading"></a></h2> |
| <p>And the non-standard driver is:</p> |
| <ul class="simple"> |
| <li><p>The <strong>Memory Technology Driver (MTD)</strong>. This naming was borrowed from <code class="docutils literal notranslate"><span class="pre">infradead.org</span></code>, |
| but does not derive from any of their MTD logic. The MTD driver manages memory-based |
| devices like FLASH or EEPROM. And MTD FLASH memory driver is very similar to a block |
| driver but FLASH has some different properties, most notably that you have to erase |
| FLASH before you write to it.</p></li> |
| </ul> |
| <p>MTD has the same conveniences as block drivers: Then can appear as device nodes |
| under <code class="docutils literal notranslate"><span class="pre">/dev</span></code> and can be proxied to behave like character drivers if the opened |
| as character drivers. Plus they have some additional twists: MTD drivers can be |
| stacked one on top of another to extend the capabilities of the lower level MTD |
| driver. For example, <code class="docutils literal notranslate"><span class="pre">drivers/mtd/sector512.c</span></code> is an MTD driver that when layered |
| on top of another MTD driver, it changes the apparent page size of the FLASH to |
| 512 bytes.</p> |
| <p><code class="docutils literal notranslate"><span class="pre">drivers/mtd/mtd_partitions.c</span></code> can be used to break up a large FLASH into |
| separate, independent partitions, each of which looks like another MTD driver.</p> |
| <p><code class="docutils literal notranslate"><span class="pre">drivers/mtd/ftl.c</span></code> is also interesting. FTL stands for FLASH Translation Layer. |
| The FTL driver is an MTD driver that when layered on top of another MTD driver, |
| converts the MTD driver to a block driver. The permutations are endless.</p> |
| </section> |
| <section id="monolithic-drivers"> |
| <h2>Monolithic Drivers<a class="headerlink" href="#monolithic-drivers" title="Permalink to this heading"></a></h2> |
| <p>When one thinks about device drivers in an OS, one thinks of a single thing, |
| a single block in a block diagram with these two primary interfaces:</p> |
| <ul class="simple"> |
| <li><p>The device monolithic driver exposes a single, standard device driver interface. |
| With the <strong>Virtual File System (VFS)</strong>, this provides the application user interface |
| to the driver functionality. And</p></li> |
| <li><p>A low-level interface to the hardware that is managed by the device driver.</p></li> |
| </ul> |
| </section> |
| <section id="upper-half-and-lower-half-drivers"> |
| <h2>Upper Half and Lower Half Drivers<a class="headerlink" href="#upper-half-and-lower-half-drivers" title="Permalink to this heading"></a></h2> |
| <p>NuttX supports many, many different MCU platforms, each with many similar but |
| distinct built-in peripherals. |
| Certainly we could imagine a realization where each such peripheral is supported |
| by monolithic driver as described in the preceding paragraph. |
| That would involve a lot code duplication, however. |
| The MCU peripherals may be unique at a low, register-level interface. |
| However, the peripherals are really very similar at a higher level of abstraction.</p> |
| <p>NuttX reduces the duplication, both in the code and in driver development, |
| using the notion of <em>Upper Half</em> and <em>Lower Half</em> drivers. |
| Such an implementation results in two things; two blocks in the system block |
| diagram: The upper half driver in a group of common, shared drivers, and |
| the MCU-specific lower half driver.</p> |
| <p>As before, each of these two driver components has two functional interfaces. |
| For the upper half driver:</p> |
| <ul class="simple"> |
| <li><p>The upper half device driver exposes a single, standard driver interface. |
| With the <strong>Virtual File System (VFS)</strong>, this, again, provides the application |
| user interface to the driver functionality. And</p></li> |
| <li><p>The upper-half side of the lower-half interface to the MCU-specific hardware |
| that is managed by the lower-half device driver.</p></li> |
| </ul> |
| <p>And for the lower half driver:</p> |
| <ul class="simple"> |
| <li><p>The lower-half side of the interface to the the upper0half driver, and</p></li> |
| <li><p>The low-level interface to the hardware that is managed by the lower half |
| device driver.</p></li> |
| </ul> |
| <section id="one-to-many-encapsulation-and-polymorphism"> |
| <h3>One to Many: Encapsulation and Polymorphism<a class="headerlink" href="#one-to-many-encapsulation-and-polymorphism" title="Permalink to this heading"></a></h3> |
| <p>These modular upper- and lower-half drivers have certain properties that you |
| would associate with an object oriented design: Encapsulation, data abstraction, |
| and polymorphism certainly. |
| Because of this encapsulation, the upper-half driver is complete unaware of any |
| implementation details within the lower-half driver. |
| Everything needed for the upper- and lower-half drivers to integrate is provided |
| by the defined interface between between those two things. |
| In fact, a single upper-half driver may service many lower-half driver instances |
| in a one-to-many relationship.</p> |
| <p>As an example, some MCUs support UARTs, USARTs functioning as UARTs, |
| Low-Power UARTs (LPUARTs), and other Flexible devices that may function as UARTs. |
| Each of these is managed by a separate lower-half driver that can be found in the |
| appropriate <code class="docutils literal notranslate"><span class="pre">src/</span></code> directory under <code class="docutils literal notranslate"><span class="pre">arch/</span></code>. |
| In addition a board could have off-chip, external 16550 UART hardware (which has |
| a common lower-half driver). |
| Yet all of them would be supported by the single, common, serial upper half |
| driver that can be found at <code class="docutils literal notranslate"><span class="pre">drivers/serial/serial.c</span></code>. |
| This is only possible due to the object-like properties of the lower-half driver |
| implementations.</p> |
| </section> |
| </section> |
| </section> |
| |
| |
| </div> |
| </div> |
| <footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer"> |
| <a href="index.html" class="btn btn-neutral float-left" title="Implementation Details" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a> |
| <a href="device_drivers.html" class="btn btn-neutral float-right" title="Device Drivers" 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> |