blob: a171e673943a2cf96efe3137fbca872bb2e8b789 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../../../img/favicon.ico">
<title>toc - Apache Mynewt</title>
<link href="../../../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../../../css/highlight.css">
<link href="../../../../../css/base.css" rel="stylesheet">
<link href="../../../../../css/custom.css" rel="stylesheet">
<link href="../../../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="toc">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.12.0, Apache NimBLE 1.7.0 </a> released (April 4, 2024)
</div>
</div>
</div>
</div>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li
class=""
>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li
class="important"
>
<a href="/quick-start/">Quick Start</a>
</li>
<li
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</option>
<option value="/v1_12_0/" >
Version: 1.12.0
</option>
<option value="/v1_11_0/" >
Version: 1.11.0
</option>
<option value="/v1_10_0/" >
Version: 1.10.0
</option>
<option value="/v1_9_0/" >
Version: 1.9.0
</option>
<option value="/v1_8_0/" >
Version: 1.8.0
</option>
<option value="/v1_7_0/" >
Version: 1.7.0
</option>
<option value="/v1_6_0/" >
Version: 1.6.0
</option>
<option value="/v1_5_0/" >
Version: 1.5.0
</option>
<option value="/v1_4_0/" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" selected="selected" >
Version: 0.9.0
</option>
</select></li>
<li ><a href="../../../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../../../../tutorials/tutorials/">Tutorials</a>
</li>
<li ><a href="../../../../os_user_guide/">OS User Guide</a>
<ul>
<li ><a href="../../../../core_os/mynewt_os/">OS Core</a>
</li>
<li ><a href="../../../../core_os/porting/port_os/">Porting to your Platform</a>
</li>
<li ><a href="../../../console/console/">Console</a>
</li>
<li ><a href="../../../shell/shell/">Shell</a>
</li>
<li ><a href="../../../bootloader/bootloader/">Bootloader</a>
</li>
<li><a href="
../../fs/fs/
">File System</a>
<ul>
<li ><a href="../../fs/fs/">File System Abstraction</a>
</li>
<li class="active"><a href="./">Newtron Flash File System</a>
<ul>
<li><a href="
../nffs_area_desc/
">Data Structures</a>
</li>
<li><a href="
../nffs_detect/
">Functions</a>
</li>
<li >
<a href="../nffs_internals/">Internals</a>
</li>
</ul>
</li>
<li >
<a href="../../otherfs/">Other File Systems</a>
</li>
</ul>
</li>
<li ><a href="../../../hal/hal/">Hardware Abstraction Layer</a>
</li>
<li ><a href="../../../testutil/testutil/">Test Utilities</a>
</li>
<li ><a href="../../../imgmgr/imgmgr/">Image Manager</a>
</li>
<li >
<a href="../../../baselibc/">Baselibc library</a>
</li>
<li ><a href="../../../elua/elua/">Embedded Lua</a>
</li>
<li ><a href="../../../json/json/">JSON</a>
</li>
<li ><a href="../../../stats/stats/">Stats</a>
</li>
<li ><a href="../../../logs/logs/">Logs</a>
</li>
</ul>
</li>
<li><a href="
../../../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../../../faq/how_to_edit_docs/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; Newtron Flash File System</li>
<li>&raquo; File System</li>
<li>&raquo; <a href="os/os_user_guide/">OS User Guide</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 0.9.0 is not the most recent version of the Apache Mynewt
documentation. Click <a href="/latest">here</a> to read the latest
version.
</p>
</div>
<h1 id="newtron-flash-filesystem-nffs">Newtron Flash Filesystem (nffs)</h1>
<p>Mynewt includes the Newtron Flash File System (nffs). This file system is designed with two priorities that makes it suitable for embedded use: </p>
<ul>
<li>Minimal RAM usage</li>
<li>Reliability</li>
</ul>
<p>Mynewt also provides an abstraction layer API (fs) to allow you to swap out nffs with a different file system of your choice.</p>
<h3 id="description">Description</h3>
<h4 id="areas">Areas</h4>
<p>At the top level, an nffs disk is partitioned into <em>areas</em>. An area is a region of disk with the following properties:</p>
<ol>
<li>An area can be fully erased without affecting any other areas.</li>
<li>Writing to one area does not restrict writes to other areas.</li>
</ol>
<p><strong>Regarding property 1:</strong> Generally, flash hardware divides its memory space into "blocks." When erasing flash, entire blocks must be erased in a single operation; partial erases are not possible.</p>
<p><strong>Regarding property 2:</strong> Furthermore, some flash hardware imposes a restriction with regards to writes: writes within a block must be strictly sequential. For example, if you wish to write to the first 16 bytes of a block, you must write bytes 1 through 15 before writing byte 16. This restriction only applies at the block level; writes to one block have no effect on what parts of other blocks can be written.</p>
<p>Thus, each area must comprise a discrete number of blocks.</p>
<h4 id="initialization">Initialization</h4>
<p>Before nffs can be used, it must be initialized. There are two means of initializing an nffs file system:</p>
<ol>
<li>Restore an existing file system via detection.</li>
<li>Create a new file system via formatting.</li>
</ol>
<p>A typical initialization sequence is the following:</p>
<ol>
<li>Detect an nffs file system in a specific region of flash.</li>
<li>If no file system was detected, format a new file system in the same flash region.</li>
</ol>
<p>Both methods require the user to describe how the flash memory should be divided into nffs areas. This is accomplished with an array of <a href="../nffs_area_desc/">struct nffs_area_desc</a>.</p>
<p>Typically, a product's flash layout is exposed via its BSP-specific <code>bsp_flash_dev()</code> function. This function retrieves the layout of the specified flash device resident in the BSP. The result of this function can then be converted into the <code>struct nffs_area_desc[]</code> that nffs requires. The below example, taken from the slinky project, illustrates the nffs initialization procedure.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/*** hw/hal/include/hal/flash_map.h */</span>
<span style="color: #177500">/*</span>
<span style="color: #177500"> * Flash area types</span>
<span style="color: #177500"> */</span>
<span style="color: #633820">#define FLASH_AREA_BOOTLOADER 0</span>
<span style="color: #633820">#define FLASH_AREA_IMAGE_0 1</span>
<span style="color: #633820">#define FLASH_AREA_IMAGE_1 2</span>
<span style="color: #633820">#define FLASH_AREA_IMAGE_SCRATCH 3</span>
<span style="color: #633820">#define FLASH_AREA_NFFS 4</span>
</code></pre></div>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/*** project/slinky/src/main.c */</span>
<span style="color: #A90D91">int</span>
<span style="color: #000000">main</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">cnt</span>;
<span style="color: #177500">/* NFFS_AREA_MAX is defined in the BSP-specified bsp.h header file. */</span>
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">nffs_area_desc</span> <span style="color: #000000">descs</span>[<span style="color: #000000">NFFS_AREA_MAX</span>];
<span style="color: #177500">/* Initialize nffs&#39;s internal state. */</span>
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">nffs_init</span>();
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
<span style="color: #177500">/* Convert the set of flash blocks we intend to use for nffs into an array</span>
<span style="color: #177500"> * of nffs area descriptors.</span>
<span style="color: #177500"> */</span>
<span style="color: #000000">cnt</span> <span style="color: #000000">=</span> <span style="color: #000000">NFFS_AREA_MAX</span>;
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">flash_area_to_nffs_desc</span>(<span style="color: #000000">FLASH_AREA_NFFS</span>, <span style="color: #000000">&amp;cnt</span>, <span style="color: #000000">descs</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
<span style="color: #177500">/* Attempt to restore an existing nffs file system from flash. */</span>
<span style="color: #A90D91">if</span> (<span style="color: #000000">nffs_detect</span>(<span style="color: #000000">descs</span>) <span style="color: #000000">==</span> <span style="color: #000000">FS_ECORRUPT</span>) {
<span style="color: #177500">/* No valid nffs instance detected; format a new one. */</span>
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">nffs_format</span>(<span style="color: #000000">descs</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
}
<span style="color: #177500">/* [ ... ] */</span>
}
</code></pre></div>
<p>After nffs has been initialized, the application can access the file system via the <a href="../../fs/fs/">file system abstraction layer</a>.</p>
<h3 id="configuration">Configuration</h3>
<p>The nffs file system is configured by populating fields in a global <a href="../nffs_config/">struct nffs_config</a> instance. Each field in the structure corresponds to a setting. All configuration must be done prior to calling nffs_init().</p>
<p>The global <code>struct nffs_config</code> instance is exposed in <code>nffs/nffs.h</code> as follows:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">extern</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">nffs_config</span> <span style="color: #000000">nffs_config</span>;
</code></pre></div>
<h3 id="data-structures">Data Structures</h3>
<p>The <code>fs/nffs</code> package exposes the following data structures:</p>
<table>
<thead>
<tr>
<th>Struct</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="../nffs_area_desc/">struct nffs_area_desc</a></td>
<td>Descriptor for a single nffs area.</td>
</tr>
<tr>
<td><a href="../nffs_config/">struct nffs_config</a></td>
<td>Configuration struct for nffs.</td>
</tr>
</tbody>
</table>
<h3 id="api">API</h3>
<p>The functions available in this OS feature are:</p>
<table>
<thead>
<tr>
<th>Function</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="../nffs_detect/">nffs_detect</a></td>
<td>Searches for a valid nffs file system among the specified areas.</td>
</tr>
<tr>
<td><a href="../nffs_format/">nffs_format</a></td>
<td>Erases all the specified areas and initializes them with a clean nffs file system.</td>
</tr>
<tr>
<td><a href="../nffs_init/">nffs_init</a></td>
<td>Initializes internal nffs memory and data structures.</td>
</tr>
</tbody>
</table>
<h3 id="miscellaneous-measures">Miscellaneous measures</h3>
<ul>
<li>
<p>RAM usage:</p>
<ul>
<li>24 bytes per inode</li>
<li>12 bytes per data block</li>
<li>36 bytes per inode cache entry</li>
<li>32 bytes per data block cache entry</li>
</ul>
</li>
<li>
<p>Maximum filename size: 256 characters (no null terminator required)</p>
</li>
<li>Disallowed filename characters: '/' and '\0'</li>
</ul>
<h3 id="internals">Internals</h3>
<p>nffs implementation details can be found here:</p>
<ul>
<li><a href="../nffs_internals/">nffs_internals</a></li>
</ul>
<h3 id="future-enhancements">Future enhancements</h3>
<ul>
<li>Error correction.</li>
<li>Encryption.</li>
<li>Compression.</li>
</ul>
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt (incubating) is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt
project logo are either registered trademarks or trademarks of the Apache
Software Foundation in the United States and other countries.
</small>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../../../js/highlight.pack.js"></script>
<script src="../../../../../js/base.js"></script>
<script src="../../../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>