blob: 7d4d1f82adbf7f82d7105dbee69148a5b4df9722 [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" selected="selected" >
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" >
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="../../split/split/">Split Images</a>
</li>
<li ><a href="../../bootloader/bootloader/">Bootloader</a>
</li>
<li><a href="
../../fs/fs/fs/
">File System</a>
</li>
<li ><a href="../../hal/hal/">Hardware Abstraction Layer</a>
</li>
<li ><a href="../../sensor_framework/sensor_framework_overview/">Sensor Framework</a>
</li>
<li ><a href="../../drivers/driver/">Drivers</a>
</li>
<li ><a href="../../testutil/testutil/">Test Utilities</a>
</li>
<li ><a href="../../devmgmt/newtmgr/">Device Management with Newt Manager</a>
</li>
<li ><a href="../../imgmgr/imgmgr/">Image Manager</a>
</li>
<li >
<a href="../../baselibc/">Baselibc library</a>
</li>
<li ><a href="../../json/json/">JSON</a>
</li>
<li class="active"><a href="./">Flash Circular Buffer</a>
<ul>
<li><a href="
../fcb_init/
">Functions</a>
</li>
</ul>
</li>
<li ><a href="../../stats/stats/">Stats</a>
</li>
<li ><a href="../../logs/logs/">Logs</a>
</li>
<li ><a href="../../sysinitconfig/sysinitconfig/">System Configuration And Initialization</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="
../../../../newt/install/prev_releases/
">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; Flash Circular Buffer</li>
<li>&raquo; <a href="os/os_user_guide/">OS User Guide</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/modules/fcb/fcb.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.2.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="flash-circular-buffer-fcb">Flash Circular Buffer (FCB)</h1>
<p>Flash circular buffer provides an abstration through which you can treat flash like a FIFO. You append entries to the end, and read data from the beginning.</p>
<h3 id="description">Description</h3>
<p>Elements in the flash contain the length of the element, the data within the element, and checksum over the element contents.</p>
<p>Storage of elements in flash is done in a FIFO fashion. When user requests space for the next element, space is located at the end of the used area. When user starts reading, the first element served is the oldest element in flash.</p>
<p>Elements can be appended to the end of the area until storage space is exhausted. User has control over what happens next; either erase oldest block of data, thereby freeing up some space, or stop writing new data until existing data has been collected. FCB treats underlying storage as an array of flash sectors; when it erases old data, it does this a sector at a time.</p>
<p>Elements in the flash are checksummed. That is how FCB detects whether writing element to flash completed ok. It will skip over entries which don't have a valid checksum.</p>
<h3 id="usage">Usage</h3>
<p>To add an element to circular buffer:</p>
<ul>
<li>Call fcb_append() to get the location where data can be written. If this fails due to lack of space, you can call fcb_rotate() to make some. And then call fcb_append() again.</li>
<li>Use flash_area_write() to write element contents.</li>
<li>Call fcb_append_finish() when done. This completes the entry by calculating the checksum.</li>
</ul>
<p>To read contents of the circular buffer:
* Call fcb_walk() with a pointer to your callback function.
* Within callback function copy in data from the element using flash_area_read(). You can tell when all data from within a sector has been read by monitoring returned element's area pointer. Then you can call fcb_rotate(), if you're done with that data.</p>
<p>Alternatively:
* Call fcb_getnext() with 0 in element offset to get the pointer to oldest element.
* Use flash_area_read() to read element contents.
* Call fcb_getnext() with pointer to current element to get the next one. And so on.</p>
<h3 id="data-structures">Data structures</h3>
<p>This data structure describes the element location in the flash. You would use it figure out what parameters to pass to flash_area_read() to read element contents. Or to flash_area_write() when adding a new element.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">struct</span> <span style="color: #3F6E75">fcb_entry</span> {
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">flash_area</span> <span style="color: #000000">*fe_area</span>;
<span style="color: #A90D91">uint32_t</span> <span style="color: #000000">fe_elem_off</span>;
<span style="color: #A90D91">uint32_t</span> <span style="color: #000000">fe_data_off</span>;
<span style="color: #A90D91">uint16_t</span> <span style="color: #000000">fe_data_len</span>;
};
</code></pre></div>
<table>
<thead>
<tr>
<th>Element</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>fe_area</td>
<td>Pointer to info about the flash sector. Pass this to flash_area_xx() routines.</td>
</tr>
<tr>
<td>fe_elem_off</td>
<td>Byte offset from the start of the sector to beginning of element.</td>
</tr>
<tr>
<td>fe_data_off</td>
<td>Byte offset from start of the sector to beginning of element data. Pass this to to flash_area_xx() routines.</td>
</tr>
<tr>
<td>fe_data_len</td>
<td>Number of bytes in the element.</td>
</tr>
</tbody>
</table>
<p>The following data structure describes the FCB itself. First part should be filled in by the user before calling fcb_init(). The second part is used by FCB for its internal bookkeeping.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">struct</span> <span style="color: #3F6E75">fcb</span> {
<span style="color: #177500">/* Caller of fcb_init fills this in */</span>
<span style="color: #A90D91">uint32_t</span> <span style="color: #000000">f_magic</span>; <span style="color: #177500">/* As placed on the disk */</span>
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">f_version</span>; <span style="color: #177500">/* Current version number of the data */</span>
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">f_sector_cnt</span>; <span style="color: #177500">/* Number of elements in sector array */</span>
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">f_scratch_cnt</span>; <span style="color: #177500">/* How many sectors should be kept empty */</span>
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">flash_area</span> <span style="color: #000000">*f_sectors</span>; <span style="color: #177500">/* Array of sectors, must be contiguous */</span>
<span style="color: #177500">/* Flash circular buffer internal state */</span>
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">os_mutex</span> <span style="color: #000000">f_mtx</span>; <span style="color: #177500">/* Locking for accessing the FCB data */</span>
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">flash_area</span> <span style="color: #000000">*f_oldest</span>;
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">fcb_entry</span> <span style="color: #000000">f_active</span>;
<span style="color: #A90D91">uint16_t</span> <span style="color: #000000">f_active_id</span>;
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">f_align</span>; <span style="color: #177500">/* writes to flash have to aligned to this */</span>
};
</code></pre></div>
<table>
<thead>
<tr>
<th>Element</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>f_magic</td>
<td>Magic number in the beginning of FCB flash sector. FCB uses this when determining whether sector contains valid data or not.</td>
</tr>
<tr>
<td>f_version</td>
<td>Current version number of the data. Also stored in flash sector header.</td>
</tr>
<tr>
<td>f_sector_cnt</td>
<td>Number of elements in the f_sectors array.</td>
</tr>
<tr>
<td>f_scratch_cnt</td>
<td>Number of sectors to keep empty. This can be used if you need to have scratch space for garbage collecting when FCB fills up.</td>
</tr>
<tr>
<td>f_sectors</td>
<td>Array of entries describing flash sectors to use.</td>
</tr>
<tr>
<td>f_mtx</td>
<td>Lock protecting access to FCBs internal data.</td>
</tr>
<tr>
<td>f_oldest</td>
<td>Pointer to flash sector containing the oldest data. This is where data is served when read is started.</td>
</tr>
<tr>
<td>f_active</td>
<td>Flash location where the newest data is. This is used by fcb_append() to figure out where the data should go to.</td>
</tr>
<tr>
<td>f_active_id</td>
<td>Flash sectors are assigned ever-increasing serial numbers. This is how FCB figures out where oldest data is on system restart.</td>
</tr>
<tr>
<td>f_align</td>
<td>Some flashes have restrictions on alignment for writes. FCB keeps a copy of this number for the flash here.</td>
</tr>
</tbody>
</table>
<h3 id="list-of-functions">List of Functions</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="../fcb_init/">fcb_init</a></td>
<td>Initializes the FCB. After calling this, you can start reading/writing data from FCB.</td>
</tr>
<tr>
<td><a href="../fcb_append/">fcb_append</a></td>
<td>Start writing a new element to flash.</td>
</tr>
<tr>
<td><a href="../fcb_append_finish/">fcb_append_finish</a></td>
<td>Finalizes the write of new element. FCB computes the checksum over the element and updates it in flash.</td>
</tr>
<tr>
<td><a href="../fcb_walk/">fcb_walk</a></td>
<td>Walks over all log entries in FCB.</td>
</tr>
<tr>
<td><a href="../fcb_getnext/">fcb_getnext</a></td>
<td>Fills given FCB location with information about next element.</td>
</tr>
<tr>
<td><a href="../fcb_rotate/">fcb_rotate</a></td>
<td>Erase the oldest sector in FCB.</td>
</tr>
<tr>
<td><a href="../fcb_append_to_scratch/">fcb_append_to_scratch</a></td>
<td>If FCB uses scratch blocks, use reserve blocks when FCB is filled.</td>
</tr>
<tr>
<td><a href="../fcb_is_empty/">fcb_is_empty</a></td>
<td>Returns 1 if there are no elements stored in FCB, otherwise returns 0.</td>
</tr>
<tr>
<td><a href="../fcb_offset_last_n/">fcb_offset_last_n</a></td>
<td>Returns the offset of n-th last element.</td>
</tr>
<tr>
<td><a href="../fcb_clear/">fcb_clear</a></td>
<td>Wipes out all data in FCB.</td>
</tr>
</tbody>
</table>
<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 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>