O:23:"Drupal\node\Entity\Node":25:{s:10:"in_preview";N;s:9:"*values";a:22:{s:3:"vid";a:1:{s:9:"x-default";s:3:"606";}s:8:"langcode";a:1:{s:9:"x-default";s:3:"und";}s:18:"revision_timestamp";a:1:{s:9:"x-default";s:10:"1496875984";}s:12:"revision_uid";a:1:{s:9:"x-default";s:1:"1";}s:12:"revision_log";a:1:{s:9:"x-default";N;}s:3:"nid";a:1:{s:9:"x-default";s:3:"453";}s:4:"type";a:1:{s:9:"x-default";s:5:"paper";}s:4:"uuid";a:1:{s:9:"x-default";s:36:"4682c2f9-e73c-487f-9ed4-67796f6f0d82";}s:17:"isDefaultRevision";a:1:{s:9:"x-default";s:1:"1";}s:6:"status";a:1:{s:9:"x-default";s:1:"1";}s:5:"title";a:1:{s:9:"x-default";s:22:"Yaffs Direct Interface";}s:3:"uid";a:1:{s:9:"x-default";s:1:"1";}s:7:"created";a:1:{s:9:"x-default";s:10:"1343000234";}s:7:"changed";a:1:{s:9:"x-default";s:10:"1496875984";}s:7:"promote";a:1:{s:9:"x-default";s:1:"1";}s:6:"sticky";a:1:{s:9:"x-default";s:1:"0";}s:29:"revision_translation_affected";a:1:{s:9:"x-default";s:1:"1";}s:16:"default_langcode";a:1:{s:9:"x-default";s:1:"1";}s:4:"body";a:1:{s:9:"x-default";a:1:{i:0;a:3:{s:5:"value";s:150878:"	<p class="western" align="justify">This document describes the Yaffs
	Direct Interface (YDI),  which allows Yaffs to be simply integrated
	with embedded systems, with or without an RTOS.</p>

<p class="western" style="page-break-before: always"><br/>
<br/>

</p>
<h1 class="western" style="page-break-before: always">1 Background</h1>
<p class="western">The purpose of this document is to describe the
interfacing of the Yaffs Direct Interface (YDI) as well as to provide
sufficient information to allow a preliminary evaluation of Yaffs.
This document tries to focus on the issues important to the system
integrator without getting too detailed about how Yaffs works. Other
documents provide an in-depth discussion of how Yaffs works.</p>
<h1 class="western">2 Licensing</h1>
<p class="western">Yaffs was originally released for Linux under the
GNU Public License (GPL). Various embedded developers soon identified
that Yaffs would be ideal for their applications, but were not able
to use GPL based code in their systems. Aleph One <span style="font-style: normal"><span style="font-weight: normal">has</span></span>
alternative licensing arrangements to support such applications.</p>
<h1 class="western">3 What are Yaffs and Yaffs Direct Interface?</h1>
<p class="western">Yaffs stands for <i>Yet Another Flash File System</i>.
Yaffs was the first file system designed, from the ground up, for
NAND storage.</p>
<p class="western">In 2002 Aleph One set out to identify file system
options for using NAND Flash as a file system. Various file systems
available at the time were evaluated and all were found lacking in
one way or another. The need for a suitable NAND storage file system
was identified and Yaffs was designed to fill that need.</p>
<p class="western">Although Yaffs was originally designed for NAND
flash, it has been used successfully with NOR flash systems and even
as a RAM file system. This allows high reliability file systems to be
constructed using NOR flash, with a future migration path <span style="font-weight: normal">to
NAND</span> flash for higher density and performance.</p>
<p class="western">Yaffs was originally designed for use with the
Linux operating system, but was designed in a very modular way. The
operating-system-specific code was kept separate from the main Yaffs
file system code. This allows Yaffs to be ported quite cleanly to
other operating systems through operating system personality modules.
One such personality module is the Yaffs Direct Interface (YDI) which
allows Yaffs to be simply integrated with embedded systems, with or
without an RTOS. 
</p>
<p class="western">Yaffs has been used for many products using
various operating systems including Windows CE and various RTOSs,
including <span style="font-weight: normal">ThreadX, vXworks, pSOS to
name just a few.</span></p>
<p class="western">Note that there is a native port of Yaffs to eCOS
that does not use YDI. This is supported and distributed by
eCocCentric.(http://www.ecoscentric.com/).</p>
<p class="western">Yaffs2, a more recent release of Yaffs, supports a
wider range of NAND flash components including 2k page devices and
devices with multi-level cells (MLC), and produces equivalent or
better performance. It include Yaffs1 compatibility code so Yaffs1
images still work and migration is quite simple. Yaffs1 or Yaffs2
mode of operation are simply selected by a run-time parameter.</p>
<p class="western">As well as providing a NAND file system, YDI also
provides a RAM emulation layer to allow Yaffs to operate as a RAM
file system too. While the RAM emulation is perhaps not as efficient
as a dedicated RAM file system, this does allow one well proven file
system to use both RAM and flash.</p>
<h1 class="western">4 Why use Yaffs?</h1>
<p class="western">Yaffs is the first, and perhaps only, file system
designed specifically for NAND flash. This means that Yaffs has been
designed to work around the various limitations and quirks of NAND
flash, as well as exploit the various features of NAND to achieve an
effective file system.</p>
<p class="western">Some features to consider:</p>
<ul>
	<li/>
<p class="western">Yaffs has been well proven and has been
	used to ship in <span style="font-weight: normal">large volumes in
	several products using many different operating systems, compilers
	and processors.</span></p>
	<li/>
<p class="western">Yaffs is written in portable C and is
	endian neutral.</p>
	<li/>
<p class="western">Yaffs provides <span style="font-weight: normal">bad</span><b>
	</b><span style="font-weight: normal">block</span> handling and ECC
	algorithms to handle deficiencies in NAND flash.</p>
	<li/>
<p class="western">Yaffs is a log-structured file system which
	makes it very robust to corruptions caused by power failures etc.</p>
	<li/>
<p class="western">Yaffs has highly optimised and predictable
	garbage collection strategies. This makes it high performance and
	very deterministic when compared with similar file systems.</p>
	<li/>
<p class="western">Yaffs has a lower memory footprint than
	most other log-structured flash file systems.</p>
	<li/>
<p class="western">Yaffs provides a wide range of POSIX-style
	file system support including directories, symbolic and hard links
	etc. through standard file system interface calls.</p>
	<li/>
<p class="western"><span style="font-weight: normal">Yaffs is
	h</span>ighly configurable to work with various flash geometries,
	various ECC options, caching options etc.</p>
	<li/>
<p class="western">Yaffs Direct Interface is simple to
	integrate in a system – only a few interface functions are
	required.</p>
	<li/>
<p class="western">Yaffs can be used with a wide range of
	memory technologies.</p>
</ul>
<h1 class="western">5 Source Code and Yaffs Resources 
</h1>
<p class="western"><font face="Liberation Serif, serif">Please note
the licensing terms that apply to using the Yaffs code.</font></p>
<p class="western"><a href="http://www.yaffs.net/"><font face="Liberation Serif, serif">http://www.yaffs.net</font></a><font face="Liberation Serif, serif"><span style="font-style: normal"><span style="font-weight: normal">
serves as the hub for all Yaffs information.</span></span></font></p>
<p class="western"><font face="Liberation Serif, serif">This document
refers to the Yaffs source code extensively.<span style="font-style: normal"><span style="font-weight: normal">
and is available via the download link on this site.</span></span></font></p>
<p class="western"><font face="Liberation Serif, serif">There are
various other documents and a Yaffs mailing list for Yaffs
discussions.</font></p>
<p class="western"><font face="Liberation Serif, serif">Consulting
services are also available.</font></p>
<h1 class="western">6 System Requirements</h1>
<p class="western">Determining minimum system requirements is often
quite difficult. The following are presented as a guideline only.
Contact Aleph One for more detailed analysis if required.</p>
<ul>
	<li/>
<p class="western">Yaffs is endian-neutral and works fine with
	little-endian and big-endian processors.</p>
	<li/>
<p class="western">Yaffs code has been used successfully with
	many different 32-bit and 64-bit CPUs including MIPS, 68000, ARM,
	ColdFire, PowerPC and x86 variants. Yaffs has even been used with
	various DSP architectures. Yaffs should work with 16-bit CPUs too,
	but this is generally untested and might need some tuning, depending
	on compiler options.</p>
	<li/>
<p class="western">Because Yaffs is log structured, RAM is
	required to build up runtime data structures for acceptable
	performance. As a rule of thumb, budget approximately 2 bytes per
	<i>chunk</i> of NAND flash, where a <i>chunk</i> is typically one
	page of NAND. For NAND with 512byte pages, budget approximately
	4kbytes of RAM per 1Mbyte of NAND. For 2kbyte page devices budget
	approximately 1kbyte per 1Mbyte of NAND.</p>
</ul>
<h1 class="western">7 How to integrate Yaffs with an RTOS/Embedded
system</h1>
<p class="western" align="justify">Yaffs Direct Interface (YDI) wraps
Yaffs in a way that is simple to integrate. You need to provide a few
functions for Yaffs to use to talk to your hardware and RTOS. Yaffs
provides a set of POSIX-compliant functions for applications to use
to talk to it.</p>
<p class="western">In addition to the Yaffs core file system, the YDI
has three parts which are each explained in more detail in further
sections:</p>
<ul>
	<li/>
<p class="western"><b>POSIX Application Interface</b>: This is
	the POSIX-like interface that the application code uses to access
	the Yaffs file system. (<font face="Times New Roman"><i>open, close,
	read, write, </i></font>etc) 
	</p>
	<li/>
<p class="western"><b>RTOS Integration Interface</b>: These
	are the functions that must be provided for Yaffs to access the RTOS
	system resources. (<font face="Times New Roman"><i>initialise, lock,
	unlock, get time, </i></font><font face="Times New Roman"><i>memory
	allocation,</i></font><font face="Times New Roman"><i> set error,
	</i></font><font face="Times New Roman"><i>etc</i></font>). Note
	that although we use the term RTOS, the same can be done with other
	OSs or even with no RTOS at all in a bare-metal system.</p>
	<li/>
<p class="western"><img src="data:image/png;base64,[encoded data, 27864 characters]" name="Object1" align="left" width="485" height="530"/>
<b>Flash
	Device </b><b>Interface</b>: This interface support is where the
	flash device and appropriate device drivers are installed to provide
	an access path from Yaffs to the flash device(s). Multiple different
	devices and device types can be supported simultaneously.</p>
</ul>
<h2 class="western">7.1 Source Files</h2>
<p class="western">The following source files contain the core file
system:</p>
<table width="100%" cellpadding="4" cellspacing="0">
	<col width="71*">
	<col width="185*">
	<tr valign="top">
		<td width="28%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_allocator.c</p>
		</td>
		<td width="72%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">Allocates Yaffs object and tnode structures.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><br/>

			</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western"><br/>

			</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_bitmap.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Block and chunk bitmap handling code.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_checkpointrw.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Streamer for writing checkpoint data</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_ecc.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">1-bit Hamming ECC code</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><br/>

			</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western"><br/>

			</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_guts.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">The major Yaffs algorithms.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_nameval.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Name/value code for handling extended
			attributes (xattr).</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_nand.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Flash interfacing abstraction.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_packedtags1.c<br/>
yaffs_packedtags2.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Tags packing code</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_summary.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Code for handling block summaries.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_tagscompat.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Tags compatibility code to support Yaffs1 mode.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_tagsmarshall.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Tags marshalling code.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_verify.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Test verification code.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_yaffs1.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Yaffs1-mode specific code.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_yaffs2.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Yaffs2-mode specific code.</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<p class="western">The Yaffs direct interface is in yaffsfs.c, with
the interface functions and structures defined in yaffsfd.h.</p>
<p class="western"><br/>
<br/>

</p>
<table width="100%" cellpadding="4" cellspacing="0" style="page-break-inside: avoid">
	<col width="72*">
	<col width="184*">
	<tr valign="top">
		<td width="28%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_attribs.c</p>
		</td>
		<td width="72%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">Attribute handling.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_error.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Error reporting code.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">yaffsfs.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Yaffs Direct Interface wrapper
			code.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">yaffs_hweight.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Counts the number of hot bits
			in a byte, word etc.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_qsort.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Qsort used during Yaffs2 scanning</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<p class="western">Example flash drivers, simulators and
configurations used for testing are are in direct/test-framework
directory. These include:</p>
<table width="100%" cellpadding="4" cellspacing="0" style="page-break-inside: avoid">
	<col width="72*">
	<col width="184*">
	<tr valign="top">
		<td width="28%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">nanddrv.c</p>
		</td>
		<td width="72%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western" align="justify">A NAND driver layer that
			performs the commands to access NAND flash in a rudimentary
			manner. This code should work on many styles of CPU with little
			modification.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">yaffs_nanddrv.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">A wrapper around the NAND
			driver which plugs it into Yaffs.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">nandsim.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">A NAND simulator layer that
			works with a nandstore_xxx backing store. This simulates a NAND
			chip.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">nandstore_file.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">A storage backend for a NAND
			simulator that stores the data to file.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">nandsim_file.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">A wrapper around nandsim.c and
			nandstore_file.c which makes a NAND simulator  that saves its data
			in a file.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">yaffs_nandsim_file.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">A wrapper which creates a nand
			simulator  instance, hooks up the yaffs NAND driver and then adds
			it to yaffs for use.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">yaffs_nor_drv.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<ol>
				<p class="western" align="justify">A driver for CFI-style NOR
				flash.</p>
			</ol>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">yaffs_m18_drv.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">A driver for Intel M18-style
			NOR flash.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">yaffs_osglue.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">An OS glue layer example used
			in the test harness.</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<p class="western">Example and testing build files:</p>
<table width="100%" cellpadding="4" cellspacing="0">
	<col width="71*">
	<col width="185*">
	<tr valign="top">
		<td width="28%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">dtest.c</p>
		</td>
		<td width="72%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">A test harness. Also has sample code that can
			be used for better understanding of how some function calls work.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffscfg2k.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">A test configuration.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="28%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">yaffs_fileem.c<br/>
yaffs_fileem2k.c</p>
		</td>
		<td width="72%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Nand flash simulation using a file as backing
			store.</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<p class="western">Further testing files are in direct/tests and
direct/python.</p>
<h2 class="western" style="page-break-before: always">7.2 Integrating
the POSIX Application Interface</h2>
<p class="western">The application interface is defined in yaffsfs.h.
These provide a POSIX file system interface. For the most part, this
interface consists of the standard clib function names prefixed with
<code class="western">yaffs_</code>. For example, <code class="western">yaffs_open(),
yaffs_close()</code> etc.</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">There is a lot of flexibility in how these
functions are used and the system integrator needs to determine the
best strategy for the system.</p>
<p class="western">These functions can be used directly, with the
code written using these names. For example</p>
<p class="code-western"><code class="western">int main(...)<br/>
{<br/>

  // initialisation<br/>
    f = yaffs_open(...);<br/>
   
yaffs_read(f,...);<br/>
    yaffs_close(f);<br/>
}</code></p>
<p class="western">The <font face="Times New Roman">yaffs</font>
functions can also be wrapped in some way to allow existing code to
use yaffs without modification. For example:</p>
<p class="western" align="left" style="margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid">
<br/>

</p>
<p class="code-western"><code class="western">#define open(path,
oflag, mode)  yaffs_open(path, oflag, mode)<br/>
..<br/>
<br/>
int
main(...)<br/>
{<br/>
   // initialisation<br/>
    f = open(...);<br/>

   read(f,...);<br/>
    close(f);<br/>
}</code><br/>
<br/>
<br/>

</p>
<p class="western" align="left" style="margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto">
<br/>

</p>
<p class="western">A more complex approach that can be used if more
than one file-system is used is to provide redirection functions. For
example:</p>
<p class="western" align="left" style="margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid">
<br/>

</p>
<p class="code-western"><code class="western">int open(const char
*path,...)<br/>
{<br/>
    // Determine which file system is being
used<br/>
    </code><code class="western">i</code><code class="western">f(it_is_a_yaffs_path(path))<br/>

       return yaffs_open(...);<br/>
    else {<br/>
        // Do
something else<br/>
    }<br/>
}</code></p>
<p class="western" align="left" style="margin-left: 1.25cm; margin-bottom: 0cm; page-break-inside: avoid; orphans: 0; widows: 0; page-break-before: auto; page-break-after: auto">
<br/>

</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">Some RTOS's provide a flexible way to integrate
file systems in which case YDI can typically use these interfaces to
access yaffs file systems.</p>

<h1 class="western" style="page-break-before: always">8 RTOS
Integration Interface</h1>
<p class="western">Before Yaffs can be used, it needs to be
integrated with the system and configured so that the correct actions
are performed.</p>
<p class="western">To do this, you need to modify the configuration
file. An example configuration file is presented in <font face="Bitstream Vera Sans"><font face="Times New Roman">yaffscfg.c
and yaffscfg2k.c.</font></font></p>
<p class="western">This is a relatively straight forward process and
defines the RTOS access functions.</p>
<p class="western">The RTOS access functions are:</p>
<ul>
	<li/>
<p class="western"><code class="western">void
	yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system
	error.</p>
	<li/>
<p class="western"><code class="western">void
	yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from
	multi-threaded access.</p>
	<li/>
<p class="western"><code class="western">void
	yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p>
	<li/>
<p class="western"><code class="western">u32
	yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p>
	<li/>
<p class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>void
	*yaffsfs_malloc(size_t size)</b></font></font>: Called to allocate
	memory.</p>
	<li/>
<p class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>void
	yaffsfs_free(void *ptr)</b></font></font>: Called to free memory.</p>
	<li/>
<p class="western"><code class="western">void
	yaffsfs_</code><code class="western">OS</code><code class="western">Initialisation(void)</code>:
	Called to initialise RTOS context.</p>
	<li/>
<p class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>void
	yaffs_bug_fn(const char *file_name, int line_no)</b></font></font>:
	Function to report a bug.</p>
	<li/>
<p class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>int
	yaffsfs_CheckMemRegion(const void *addr, size_t size, int
	writ</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>e_request</b></font></font>)
	: Function to check if accesses to a memory region is valid. This
	function must return zero if the test passes and negative if it
	fails.</p>
</ul>
<p class="western"><br/>
<br/>

</p>
<p class="western">If Yaffs is being used in a multi-threaded
environment, then typically <code class="western">yaffs_LocalInitialisation()</code>
will initialise a suitable RTOS semaphore and <code class="western">yaffs_Lock()</code>
and <code class="western">yaffs_Unlock()</code> will call the
appropriate functions to lock and release the semaphore.</p>
<p class="western"><code class="western">yaffs_CurrentTime()</code>
can be any time increment of use to the system. If this is not
required, then it is fine to just use a function that is hard-wired
to return zero.</p>
<p class="western">Before the application code uses Yaffs, the
<code class="western">yaffs</code><code class="western">fs</code><code class="western">_</code><code class="western">OSInitialisation</code><code class="western">()</code>
function must be called.</p>
<p class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>yaffsfs_CheckMemRegion()</b></font></font><font face="Liberation Serif, serif"><font size="3" style="font-size: 12pt"><span style="font-weight: normal">
is used to check addresses passed to the various yaffs_xxx functions
(yaffs_open(), yaffs_read() etc)). If the function returns -1, then
the yaffs_xxx function will return -EFAULT rather than attempt to
dereference the address and crash.</span></font></font></p>
<p class="western" style="font-weight: normal"><font face="Liberation Serif, serif"><font size="3" style="font-size: 12pt">An
 implementation might do something like:</font></font></p>
<p class="western" style="font-weight: normal"><br/>
<br/>

</p>
<p class="code-western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>int
yaffsfs_CheckMemRegion(const void addr, size_t size, <br/>
          
       int write_</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>request</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>)
<br/>
  {<br/>
      u32 uaddr</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>b</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
= (u32) addr;<br/>
      </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>u32
uaddrt = uaddrb + size -1;<br/>
</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b><br/>

     if( uaddr</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>b</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
&gt;= stack_bottom &amp;&amp; uaddr</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>b</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
&lt;= stack_top &amp;&amp;<br/>
          </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>uaddrt
&gt;= stack_bottom &amp;&amp; uaddrt &lt;= stack_top)<br/>
         
return 0; /* </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>r/w
</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>access
is OK */<br/>
</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b><br/>

     if( uaddr</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>b</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
&gt;= </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>heap</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>_bottom
&amp;&amp; uaddr</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>b</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
&lt;= </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>heap</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>_top
&amp;&amp;<br/>
          </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>uaddrt
&gt;= heap_bottom &amp;&amp; uaddrt &lt;= heap_top)<br/>
         
return 0; /* </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>r/w</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
access is OK /<br/>
</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b><br/>

     if( !</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>write_request
&amp;&amp;<br/>
          </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>uaddr</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>b</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
&gt;= </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>rom</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>_bottom
&amp;&amp; uaddr</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>b</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>
&lt;= </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>rom</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>_top
&amp;&amp;<br/>
          </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>uaddrt
&gt;= rom_bottom &amp;&amp; uaddrt &lt;= rom_top)<br/>
         
return 0; / </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>read
</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>access
is OK /</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b><br/>
<br/>

     </b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>return
-1; /* Bad access */</b></font></font><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b><br/>

<br/>
}</b></font></font></p>
<p class="code-western"><br/>
<br/>

</p>
<h1 class="western" style="page-break-before: always">9 Yaffs NAND
Model</h1>
<p class="western">Before defining the flash integration interface,
it is important to understand the model and corresponding
nomenclature used throughout Yaffs and its documentation.</p>
<p class="western">Yaffs uses a fairly abstract model for NAND flash.
This allows a lot of flexibility in the way it can be used.</p>
<p class="western">Yaffs is designed for NAND flash and makes the
following assumptions and definitions:</p>
<ul>
	<li/>
<p class="western">The flash is arranged in <i><b>blocks</b></i>.
	Each block is the same size and comprises an integer number of
	<span style="font-style: normal"><span style="font-weight: normal">chunks</span></span>.
	Each block is treated as a single erasable item. A block contains a
	number of chunks.</p>
	<li/>
<p class="western">A <i><b>chunk</b></i> equates to the
	allocation units of flash. For Yaffs1, each chunk equates to a
	512-byte or larger NAND page (that is, a 512-byte or larger data
	portion and a 16-byte spare area). For Yaffs2, a chunk will
	typically be larger (eg. on 2k page devices, a chunk will typically
	be a single 2k page: 2kbytes of data and 64 bytes of spare). Yaffs2
	is capable of working with smaller chunk sizes by using inband tags.</p>
	<li/>
<p class="western">All accesses (reads and writes) are page
	chunk aligned. Some reads might only read the spare area where the
	tags are kept.</p>
	<li/>
<p class="western">When programming a NAND flash, only the
	zero bits in the pattern being programmed are relevant, and one bits
	are &quot;don't care&quot;. For example, if a byte already contains
	the binary pattern b1010, then programming b1001 will result in the
	pattern which is the logical AND of these two patterns ie. b1000.
	This is different to NOR flash which would typically abort the
	attempt to convert a 0 into a 1.</p>
</ul>
<p class="western"><br/>
<br/>

</p>
<p class="western">Yaffs ide<span style="font-weight: normal">ntifies</span>
blocks by their block number and chunks by the chunk Id. A chunk Id
is calculated as:</p>
<p class="western"><code class="western">chunkId = block_id *
chunks_per_block + chunk_offset_in_block</code></p>
<p class="western">Yaffs treats a blank (0xFF filled) block as being
free or erased. Thus, the equivalent of formatting for a Yaffs
partition is to erase all the blocks that are not bad.</p>
<p class="western">Yaffs2 has a generalised tags interface to provide
better flexibility to cater for a wider range of devices with larger
pages and stricter programming limitations. Yaffs2 thus handles more
abstract constructs than Yaffs1 and, in older versions of Yaffs, more
effort was required to interface to the NAND.</p>
<p class="western">In newer versions of Yaffs, the tags management
has been abstracted out of the driver. This makes the driver
interface far simpler.</p>
<h2 class="western">9.1 Formatting</h2>
<p class="western">Yaffs treats erased blocks as empty. That makes it
really easy to “format” a device: just erase it.. Note that this
should be done while the partition is not mounted.</p>
<p class="western">Unmounting will not normally work when the file
system is busy (eg. files are open), Some extra non-standard unmount
options are provided to enable an unmount to be forced. Note that
using these will break any current handles and you will no longer be
able to use open files.</p>
<p class="western"><code class="western"><font face="Liberation Serif, serif"><font size="3" style="font-size: 12pt"><span style="font-weight: normal">There
is a </span></font></font></code><code class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>yaffs_format()
</b></font></font></code><code class="western"><font face="Liberation Serif, serif"><font size="3" style="font-size: 12pt"><span style="font-weight: normal">function
that will take care of the details.</span></font></font></code></p>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">9.2 NAND Model considerations for Yaffs1</h2>
<p class="western">The historical Yaffs1 tags structure was laid out
in accordance with the SmartMedia specification for use with 512-byte
pages. There is now much more flexibility in the way things can be
configured.</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">Yaffs1 is capable of being used with a variety of
memory layouts so long as the flash supports the ability to overwrite
the tags area to set the deletion marker to zero.</p>
<p class="western">If the yaffs_dev's use_nand_ecc field is not set,
then yaffs will perform the ECC calculations. If this is set then
yaffs will expect the NAND driver to do any required ECC checks. On
devices that are not using ECC, for example NOR, set use_nand_ecc=1
and then don't do any ECC anyway.</p>
<p class="western">The Yaffs1 flash model expects an area of 16 spare
bytes, some of which are used for tags. The mapping between the spare
bytes and the usage of the bytes is specified in yaffs_packedtags1.c</p>
<p class="western">The Yaffs1 model has been used in many NOR-based
systems. One particularly instructive example is in yaffs_nor_drv.c
which implements a driver for Yaffs1 mode on CFI-style NOR flash.
This does not use ECC but uses checksumming instead.</p>
<p class="western">The yaffs_dev structure has a yaffs_driver
structure which holds the function pointers to the driver. For Yaffs1
mode of operations the following are required:</p>
<table width="100%" cellpadding="4" cellspacing="0" style="page-break-inside: avoid">
	<col width="77*">
	<col width="179*">
	<tr valign="top">
		<td width="30%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_write_chunk_fn</p>
		</td>
		<td width="70%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western" align="justify">Write a data chunk</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_read_chunk_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Read a data chunk.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_erase_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Erase a block</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_initialise_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Initialisation.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_deinitialise_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">De-initialise</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<p class="western">These functions are described later.</p>
<h2 class="western">9.3 NAND Model for Yaffs2</h2>
<p class="western">The Yaffs2 interface is far more flexible than
Yaffs1, but that means a bit more effort must be done in the driver.
In particular:</p>
<ul>
	<li/>
<p class="western">There is is no standard spare area/ECC
	layout. The driver must handle all the layout of the spare area and
	ECC handling.</p>
	<li/>
<p class="western">There is not a standard implementation for
	bad block markers. Thus, the driver must provide functions for
	checking and marking bad blocks.</p>
</ul>
<p class="western">The yaffs_driver structure for Yaffs2 mode
requires the following functions:</p>
<p class="western" align="left" style="margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto">
<br/>

</p>
<table width="100%" cellpadding="4" cellspacing="0" style="page-break-inside: avoid">
	<col width="77*">
	<col width="179*">
	<tr valign="top">
		<td width="30%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_write_chunk_fn</p>
		</td>
		<td width="70%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western" align="justify">Write a data chunk</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_read_chunk_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Read a data chunk.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_erase_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Erase a block</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_mark_bad_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Mark a block bad</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_check_bad_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Check bad block status of a
			block.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_initialise_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">Initialisation.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="30%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western" align="justify">drv_deinitialise_fn</p>
		</td>
		<td width="70%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western" align="justify">De-initialise</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">9.4 Overview of flash driver function</h2>
<p class="western">The best way to understand how to write these
functions is to look at the example drivers.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int (*drv_write_chunk_fn) (struct yaffs_dev
*dev, int nand_chunk, 
</p>
<p class="code-western">                            const u8 *data,
int data_len, 
</p>
<p class="code-western">                            const u8 *oob,
int oob_len)</p>
<p class="western">This function writes the specified chunk data and
oob/spare data to flash.</p>
<p class="western">This function should return YAFFS_OK on success or
YAFFS_FAIL on failure.</p>
<p class="western">If this is a Yaffs2 device, or Yaffs1 with
use_nand_ecc set, then this function must take care of any ECC that
is required.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int (*drv_read_chunk_fn) (struct yaffs_dev
*dev, int nand_chunk, 
</p>
<p class="code-western">                           u8 *data, int
data_len, 
</p>
<p class="code-western">                           u8 *oob, int
oob_len,</p>
<p class="code-western">                           enum
yaffs_ecc_result *ecc_result)</p>
<p class="western">This function reads the specified chunk data and
oob/spare data from flash.</p>
<p class="western">This function should return YAFFS_OK on success or
YAFFS_FAIL on failure.</p>
<p class="western">If this is a Yaffs2 device, or Yaffs1 with
use_nand_ecc set, then this function must take care of any ECC that
is required and set the ecc_result.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int (*drv_erase_fn) (struct yaffs_dev *dev,
int block_no) 
</p>
<p class="western">This function erases the specified block.</p>
<p class="western">This function should return YAFFS_OK on success or
YAFFS_FAIL on failure.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int (*drv_mark_bad_fn) (struct yaffs_dev
*dev, int block_no); 
</p>
<p class="code-western">int (*drv_check_bad_fn) (struct yaffs_dev
*dev, int block_no); 
</p>
<p class="western">These functions are only required for Yaffs2 mode.
They mark a block bad or check if it is bad.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int (*drv_initialise_fn) (struct yaffs_dev
*dev); 
</p>
<p class="code-western">int (*drv_deinitialise_fn) (struct yaffs_dev
*dev); 
</p>
<p class="western">These functions provide hooks for initialising or
deinitialising the flash driver.</p>
<p class="western"><br/>
<br/>

</p>
<h1 class="western" style="page-break-before: always">10 Configuration
and flash driver installation</h1>
<p class="western">For an example of how to do the configuration,
refer to yaffs_cfg2k.c and one of the drivers such as
yaffs_nand_drv.c</p>
<p class="western">The old mechanism was static and required a table
of devices that was installed at start up.  This mechanism had
shortcomings – in particular it broke modularity and did not allow
devices to be added dynamically.</p>
<p class="western">Things are different now. As any time, a yaffs_dev
structure can be configured and then registered with Yaffs by using
the yaffs_add_device() function.</p>
<p class="western">A yaffs_dev structure has two parts which must be
configured before yaffs_add_device() is called: the paramers
(dev-&gt;param) and the driver (dev-&gt;drv). The driver
configuration (plugging in the driver functions) has already been
described above, so we will now look at the yaffs parameters.</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">The yaffs_param structure must be set before the
yaffs_dev is added with yaffs_add_device() and should not be modified
after that.</p>
<p class="western">The params are defined in the Yaffs Tuning
Document.</p>
<h1 class="western" style="page-break-before: always">11 Using the
POSIX file system interface</h1>
<p class="western">This section is directed to readers that might not
be very familiar with accessing a  file system via POSIX and
POSIX-like interfaces.</p>
<h2 class="western">11.1 Difference to Windows POSIX-like interfaces</h2>
<p class="western">MSDOS and Windows provide a POSIX-lke interface.
If you are familiar with this then that will help you. There are are
however some slight differences, most importantly:</p>
<ul>
	<li/>
<p class="western">Windows has no concept of  links and has a
	1:1 mapping between file names and files.POSIX supports files with
	zero, one or many names. Refer to the sections on linking and
	unlinking files. For instance POSIX allows you to unlink a file (ie
	delete the name for a file) while it is still in use. You can
	continue to read/write the file but it will be deleted as soon as
	the last file handle to the file is closed. Windows, on the other
	hand, does not allow you to unlink a file while it is in use.</p>
	<li/>
<p class="western">Windows names drives with a letter. POSIX
	has no drive letters. The whole POSIX file system is in a single
	directory tree.</p>
	<li/>
<p class="western">Directories and “folders” are the same
	thing.</p>
</ul>
<h2 class="western">11.2 Fundamental concepts</h2>
<table width="642" cellpadding="4" cellspacing="0">
	<col width="126">
	<col width="499">
	<tr valign="top">
		<td width="126" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">File</p>
		</td>
		<td width="499" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">A file is an object that is stored in the file
			system. yaffs supports the following file types:</p>
			<p class="western">A regular file is a sequence of bytes stored in
			the file system.</p>
			<p class="western">A directory holds links to other files.</p>
			<p class="western">A symbolic link holds a name to another file.</p>
			<p class="western">A special file holds device ids or similar
			information.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">Directory</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">This is a structure that holds links and allows
			a file to be found by name. Note that a single file may have many
			links(ie names) and many be found in many places in the directory
			structure.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">Link</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">This is a name that allows the file to be
			found. There are two types of link: real links (sometimes called
			hard links) and symbolic (or soft) links. 
			</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">Handle</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">A file handle provides a context from which a
			file can be accessed and manipulated. A handle has a current file
			position pointer which points to where the file is being read or
			written. Multiple handles can simultaneously access a single file.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">File mode</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">The mode is the set of flags that define the
			type of file as well as the current permissions associated with
			the file.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">Path</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">This is a string that defines the directories
			and file name. For example:</p>
			<p class="western">“/data/direct-1/file1”</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">File metadata</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">This is the information about the file,
			excluding the file contents. The metadata includes the name, mode,
			size and other details.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">Mount,<br/>
partition,<br/>
file system</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">These terms all refer to a single mounted flash
			area. Each mount is hooked into a common directory structure.<br/>
The
			term file system can sometimes be confusing because it is used
			both for a single mounted partition as well as the the file system
			code. In other words, we might say that both “/boot” is a file
			system and might also say that yaffs is a file system.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="126" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western">inode number</p>
		</td>
		<td width="499" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">The inode number is a unique number that
			identifies the object within the mount. Note that inodes are not
			unique between two or more mounts. There is no way to reach a file
			by inode, only via its links.</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.3 Error code</h2>
<p class="western">Most functions result in error codes if the
function does not execute successfully. In these cases yaffs calls a
function called <code class="western">yaffs_SetError()</code> with
the error value. This function can be configured to deliver the error
into the system's error mechanism.</p>
<p class="western">In the case of functions that return integers, a
returned value smaller than 0 indicates an error occurred. Functions
returning pointers will return NULL if an error occurred.</p>
<h2 class="western">11.4 Links – the hard kind  (not symbolic links)</h2>
<p class="western">At first we're just considering real links and not
symbolic links. Sometimes real links are also called hard links to
differentiate them from symbolic links (which are sometimes called
soft links).</p>
<p class="western">The difference between links and files is subtle
and can be confusing. Briefly:</p>
<ul>
	<li/>
<p class="western">a file is the stored object in the file
	system</p>
	<li/>
<p class="western">the link is how it is hooked into the
	directory structure.</p>
</ul>
<p class="western"><br/>
<br/>

</p>
<p class="western">The first link to a file is created by using the
file creation calls: <code class="western">yaffs_open()</code>,
<code class="western">yaffs_mknod()</code>, <code class="western">yaffs_symlink()</code>
and <code class="western">yaffs_mkdir()</code>.</p>
<p class="western">A link can be destroyed by using the
<code class="western">yaffs_unlink()</code> function. Directories are
destroyed using the <code class="western">yaffs_rmdir()</code>
function (oh, and the directory must be empty).</p>
<p class="western">Once a file is both unused (there are no handles
open to it) and there are no links to it it is then deleted.</p>
<p class="western">A link can be renamed by using the <code class="western">yaffs_rename()</code>
function.</p>
<p class="western">A file may have many links. These may be created
using the <code class="western">yaffs_link()</code> function. All the
links access the same file and there is no one link that is
considered “the real link” and others being “the duplicate
link”. All links to a file have the same priority. If you look at
the inode number for “a” and for “b” then they will be the
same because they are refering to exactly the same file.</p>
<p class="western">Thus:</p>
<ol>
	<li/>
<p class="western">If we start with a file called “a” and
	then call <code class="western">yaffs_link(“a”, “b”)</code>
	we now have two links to the same file. We can't tell them apart.</p>
	<li/>
<p class="western">If we now unlink “a”, the file still
	exists under the link “b”.</p>
	<li/>
<p class="western">If we now unlink “b” the file will no
	longer be linked. If there is a handle open to the file then we can
	still access the file through the handle and continue to read or
	modify the file. If there is no link to the file it is deleted.</p>
	<li/>
<p class="western">If an unlinked file was kept alive because
	of a handle being open, the file will not show up in the directory
	structure (because it has no link) and will be deleted as soon as
	the handle is closed (or if the file system is unmounted).</p>
</ol>
<p class="western">There are some limitations in how links are used:</p>
<ul>
	<li/>
<p class="western">The existing file you are linking to must
	exist.</p>
	<li/>
<p class="western">The file you are linking to must be in the
	same mount (partition) as the link you are creating.</p>
	<li/>
<p class="western">You cannot create a link to a directory
	because this would allow the creation of recursive loops.</p>
	<li/>
<p class="western">The new link name must not exist.</p>
</ul>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.5 Symbolic links</h2>
<p class="western">Now that you understand how hard links work, we'll
introduce symbolic (or soft) links.</p>
<p class="western">A symbolic link holds an alias for a different
object. When you use that symbolic link in a path the alias is used
instead. To that extent symbolic link and hard links are the same.</p>
<p class="western">You can remove symbolic links with the
<code class="western">yaffs_unlink()</code> function, just like hard
links.</p>
<p class="western">There are, however, some important differences. A
symbolic link only does its linking function when the path is being
evaluated and thus:</p>
<ul>
	<li/>
<p class="western">The file you are creating an alias to does
	not have to exist.</p>
	<li/>
<p class="western">The file you are creating an alias to does
	not have to be in the same mount.</p>
	<li/>
<p class="western">You can create symbolic links to
	directories.</p>
	<li/>
<p class="western">A symbolic link will not keep a file alive
	by itself. Only a hard link can do that.</p>
</ul>
<p class="western">Thus:</p>
<ol>
	<li/>
<p class="western">If we start with a file called “a” and
	then call <code class="western">yaffs_symlink(“a”, “b”)</code>
	we now have one link to the file called “a” and a symbolic link
	aliasising from “b” to “a”.</p>
	<li/>
<p class="western">If we use <code class="western">yaffs_open(“a”)</code>
	or <code class="western">yaffs_open(“b”)</code> they will open
	the same file. The path resolution mechanism substitutes in the
	alias and so will look up “a”. The same applies to almost all
	functions that takes a path, such as <code class="western">yaffs_truncate()</code>,
	<code class="western">yaffs_stat()</code> etc. The only exceptions
	are <code class="western">yaffs_lstat()</code> and <code class="western">yaffs_readlink()</code>
	which will treat the path as pointing to the symbolic link and not
	the file.</p>
	<li/>
<p class="western">You can tell “a” and “b” apart by
	using <code class="western">yaffs_lstat()</code>. <code class="western">yaffs_lstat(“a”)</code>
	will show the information for file “a”. <code class="western">yaffs_lstat(“b”)</code>
	will show the information for the symbolic link itself. Note the
	difference with hard links. With hard links <code class="western">yaffs_lstat(“a”)</code>
	and <code class="western">yaffs_lstat(“b”)</code> would show the
	same results since they are EXACTLY the same thing being referenced.</p>
	<li/>
<p class="western">If we now unlink “a”. then the file is
	no longer linked and will no longer be accessible from “b”. Note
	the difference with hard links.</p>
</ol>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.6 Handle-based file handling</h2>
<p class="western">A handle is file accessor that allows us to access
the contents of a regular file. The handle identifies the file being
accessed as well as a position pointer tracking where the next read
or write operation will take place.</p>
<p class="western">A handle is identified by an integer of value 0 or
greater.</p>
<p class="western">A handle is created by using the <code class="western">yaffs_open()</code>
call and returns the handle value. If the handle could not be created
then a negative value is returned and the yaffs error code is set.</p>
<p class="western">A handle remains valid until the handle is closed
by <code class="western">yaffs_close()</code>.</p>
<p class="western">The <code class="western">yaffs_open()</code> call
takes three parameters:</p>
<ul>
	<li/>
<p class="western">name: Full path name of the file being
	opened.</p>
	<li/>
<p class="western">access flags: Flags being used to open this
	handle</p>
	<li/>
<p class="western">creation mode: Mode flags used when
	creating a file.</p>
</ul>
<p class="western">The access flags are one or more of:</p>
<table width="100%" cellpadding="4" cellspacing="0">
	<col width="59*">
	<col width="197*">
	<tr valign="top">
		<td width="23%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier, monospace"><font size="2" style="font-size: 10pt"><code class="western">O_CREAT</code></font></font></p>
		</td>
		<td width="77%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">Create file if it does not already exist.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier, monospace"><font size="2" style="font-size: 10pt"><code class="western">O_EXCL</code></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Only use with O_CREAT. Create file if it does
			not exist. If the file already exists then fail.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier, monospace"><font size="2" style="font-size: 10pt"><code class="western">O_TRUNC</code></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">If the file exists, and opening with write
			access, then truncate the file to zero bytes long.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><br/>

			</p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western"><br/>

			</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier, monospace"><font size="2" style="font-size: 10pt"><code class="western">O_APPEND</code></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Regardless of the handle position, always write
			to the end of the file.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><br/>

			</p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western"><br/>

			</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier, monospace"><font size="2" style="font-size: 10pt"><code class="western">O_RDWR</code></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Open for read/write access.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier, monospace"><font size="2" style="font-size: 10pt"><code class="western">O_WRONLY</code></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Open for write access and no read access.</p>
			<p class="western"><br/>

			</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>0
			(zero)</b></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">If neither O_RDWR or O_WRONLY is set then the
			file will be opened for read-only access.</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<p class="western">Where they are not mutually exclusive, these flags
are typically combined. For example:</p>
<p class="western"><code class="western">O_CREAT | O_TRUNC | O_RDWR</code>
: Create a new file if it does not exist otherwise if the file
already exists then truncate to zero length. Typically used to
overwrite a file or create if it does not already exist.</p>
<p class="western"><code class="western">O_CREAT | OEXCL | O_WRONLY</code>
: Create a new file, opening it for write only. Fails if file already
exists.</p>
<p class="western">There are three mode flags that can be controlled
or set. These flags may be set by the open that creates the file or
later by the <code class="western">yaffs_chmod()</code>.</p>
<table width="100%" cellpadding="4" cellspacing="0">
	<col width="59*">
	<col width="197*">
	<tr valign="top">
		<td width="23%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">S_IREAD</code></font></font></p>
		</td>
		<td width="77%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">The file may be opened for read access.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">S_IWRITE</code></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">The file may be opened for write access.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="23%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">S_IEXEC</code></font></font></p>
		</td>
		<td width="77%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">The file may be opened for execution. This is
			not enforced by yaffs.</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<p class="western">Once you have opened a handle you can then do
various operations on the file.</p>
<table width="605" cellpadding="4" cellspacing="0">
	<col width="248">
	<col width="339">
	<tr valign="top">
		<td width="248" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_close(handle)</code></font></font></p>
		</td>
		<td width="339" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">Close the handle. It is no longer usable.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_fsync(handle)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Flush out any cached writes to the file, as
			well as the file meta-data.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_datasync(handle)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Same as yaffs_fsync() but no file metadata.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_flush(handle)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Same as yaffs_fsync()</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_dup(handle)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Duplicates a handle.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_lseek(handle,
			offset, whence)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Set the handle read/write position. Note that
			this does not modify the file. You can seek past the end of the
			file. This does not modify the file size.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_ftruncate(handle,
			size)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Change the file size. It can be made bigger or
			smaller. This does not change the handle read/write position.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_fstat(handle,
			buf)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Get file status.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_fchmod(handle,
			mode)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Change the file mode.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><br/>

			</p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western"><br/>

			</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_read(handle,
			buffer, nbytes)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Read data from file at file pointer and update
			pointer.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_pread(handle,
			buffer, nbytes, position)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Read data from file at specified position. Does
			not modify file pointer</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_write(handle,
			buffer, nbytes)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Write data to file at file pointer and update
			pointer.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="248" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">yaffs_pread(handle,
			buffer, nbytes, position)</code></font></font></p>
		</td>
		<td width="339" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Write data to file at specified position. Does
			not modify file pointer</p>
		</td>
	</tr>
</table>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.7 Changing file size</h2>
<p class="code-western"><code class="western">yaffs_truncate(path,
newSize)</code></p>
<p class="code-western"><code class="western">yaffs_ftruncate(handle,
newSize)</code></p>
<p class="western"><br/>
<br/>

</p>
<p class="western">These change a file's size. Note that truncating
does not just mean make the file smaller. The file can also be made
larger.</p>
<p class="western">Yaffs does not store bytes that it does not need
to. If you use truncate to make a file larger then this will not
necessarily occupt more flash space.</p>
<p class="western">See also <code class="western">yaffs_lseek()</code>
too. Note that <code class="western">yaffs_lseek() </code>only
changes the position of the write pointer and does not impact on the
file size unless the file is written.</p>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.8 Getting/setting information about files</h2>
<p class="code-western"><code class="western">yaffs_chmod(path, mode)</code></p>
<p class="code-western"><code class="western">yaffs_fchmod(handle,
mode)</code></p>
<p class="code-western"><br/>
<br/>

</p>
<p class="code-western"><code class="western">yaffs_access(path,amode)</code></p>
<p class="code-western"><br/>
<br/>

</p>
<p class="code-western"><code class="western">yaffs_stat(path, struct
yaffs_stat *buf) </code>
</p>
<p class="code-western"><code class="western">yaffs_fstat(handle,
struct yaffs_stat *buf)</code></p>
<p class="code-western"><code class="western">yaffs_lstat(path,
struct yaffs_stat *buf)</code></p>
<p class="code-western"><code class="western">yaffs_readlink(path,
buf, bufsize)</code></p>
<p class="western"><br/>
<br/>

</p>
<p class="western">The chmod calls allow you to set different mode
flags for the file. These can only be used to manipulate the
permissions flags and not change the mode flags relating to the type
of file.</p>
<p class="western"><code class="western">yaffs_access() </code>tests
that the file can be accessed in the specified mode. This call
returns zero on success and -1 is returned</p>
<p class="western">amode is a bitmask of the following values:</p>
<table width="100%" cellpadding="4" cellspacing="0">
	<col width="43*">
	<col width="213*">
	<tr valign="top">
		<td width="17%" style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">R_OK</code></font></font></p>
		</td>
		<td width="83%" style="border: 1px solid #000000; padding: 0.1cm">
			<p class="western">Check read is OK</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="17%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">W_OK</code></font></font></p>
		</td>
		<td width="83%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Check write is OK</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="17%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">X_OK</code></font></font></p>
		</td>
		<td width="83%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Check execute is OK.</p>
		</td>
	</tr>
	<tr valign="top">
		<td width="17%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm">
			<p class="western"><font face="Courier New, monospace"><font size="2" style="font-size: 10pt"><code class="western">0
			(zero)</code></font></font></p>
		</td>
		<td width="83%" style="border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm">
			<p class="western">Just checks the file exists</p>
		</td>
	</tr>
</table>
<p class="western">These can be combined.</p>
<p class="western">For example:</p>
<p class="code-western"><code class="western">if(yaffs_access(path,
R_OK | W_OK) == 0)</code></p>
<p class="code-western"><code class="western">	the file exists and
can be read and written</code></p>
<p class="code-western"><code class="western">if(yaffs_access(path,
0) == 0)</code></p>
<p class="code-western"><code class="western">	the file exists</code></p>
<p class="western"><br/>
<br/>

</p>
<p class="western">The stat calls retrieve a yaffs_stat structure of
data which is defined in yaffsfs.h. There are three versions:</p>
<p class="western"><code class="western">yaffs_fstat</code>: Takes a
handle.</p>
<p class="western"><code class="western">yaffs_stat</code>: Takes a
path name and follows symbolic links.</p>
<p class="western"><code class="western">yaffs_lstat</code>: Takes a
path but does not follow symbolic links.</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">Thus, if path is a symbolic link, <code class="western">yaffs_fstat()
</code>will give information on the file that the link points to
while <code class="western">yaffs_lstat()</code> will give
information about the link itself.</p>
<p class="western"><code class="western">yaffs_readlink()</code> will
read the read the link value into the buffer provided. For example:</p>
<p class="code-western"><code class="western">	yaffs_symlink(“target”,”/link”);
/* create a link called link to target */</code></p>
<p class="code-western"><code class="western">	yaffs_readlink(“/link”,buffer,10);
 /* now buffer contains “target” */</code></p>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.9 Changing the directory structure and names</h2>
<p class="code-western"><code class="western">yaffs_open(path, flags,
mode)</code></p>
<p class="code-western"><code class="western">yaffs_mkdir(path, mode)</code></p>
<p class="code-western"><code class="western">yaffs_symlink(targetPath,
linkPath)</code></p>
<p class="code-western"><code class="western">yaffs_mknod(pathname,
mode, dev)</code></p>
<p class="code-western"><br/>
<br/>

</p>
<p class="code-western"><code class="western">yaffs_link(existingPath,
newath)</code></p>
<p class="code-western"><br/>
<br/>

</p>
<p class="code-western"><code class="western">yaffs_unlink(path)</code></p>
<p class="code-western"><code class="western">yaffs_rmdir(path)</code></p>
<p class="code-western"><br/>
<br/>

</p>
<p class="code-western"><code class="western">yaffs_rename(oldPath,
newPath)</code></p>
<p class="western"><br/>
<br/>

</p>
<p class="western">Files of various types, and their first link, are
created via the <code class="western">yaffs_open()</code><code class="western"><font face="Liberation Serif, serif"><span style="font-weight: normal">,</span></font></code><font face="Courier New, monospace"><font size="2" style="font-size: 10pt">
</font></font><code class="western">yaffs_mkdir()</code><font face="Liberation Serif, serif"><font size="2" style="font-size: 10pt">,
</font></font><code class="western">yaffs_symlink()</code> and
<code class="western">yaffs_mknod()</code><font face="Liberation Serif, serif"><font size="3" style="font-size: 12pt">
</font></font>functions.</p>
<p class="western"><code class="western">yaffs_link()</code> can be
used to create subsequent links to files. Note that you cannot create
a link to a directory.</p>
<p class="western"><code class="western">yaffs_rename()</code> allows
you to rename a link. Note that renaming one link over another link
is an atomic operation. That means that even if the operation is
interrupted by a power failure, the result will either complete or
not happen at all. If the target link is for a directory, then the
rename will only work if the target directory is empty.</p>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.10 Searching directories</h2>
<p class="code-western"><code class="western">yaffs_DIR
*yaffs_opendir(const YCHAR *dirname) ; </code>
</p>
<p class="code-western"><code class="western">struct yaffs_dirent
*yaffs_readdir(yaffs_DIR *dirp) ; </code>
</p>
<p class="code-western"><code class="western">void
yaffs_rewinddir(yaffs_DIR *dirp) ; </code>
</p>
<p class="code-western"><code class="western">int
yaffs_closedir(yaffs_DIR *dirp) ; </code>
</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">Searching is performed by the following sequence
of operations:</p>
<ul>
	<li/>
<p class="western">Open the directory for reading with
	<code class="western">yaffs_opendir()</code>.</p>
	<li/>
<p class="western">Iterate through the entries in the
	directory using <code class="western">yaffs_readdir()</code>. Each
	read will advance the directory read position.</p>
	<li/>
<p class="western">You can reset to the start of the directory
	with <code class="western">yaffs_rewinddir()</code>.</p>
	<li/>
<p class="western">Close the directory when finished with
	<code class="western">yaffs_closedir()</code>.</p>
</ul>
<h2 class="western">11.11 Searching directories (fd interface)</h2>
<p class="code-western"><code class="western">int </code><code class="western">yaffs_open(const
YCHAR *dirname, </code><code class="western">O_RDONLY, 0</code><code class="western">)
; </code>
</p>
<p class="code-western"><code class="western">struct yaffs_dirent
*yaffs_readdir_</code><code class="western">fd</code><code class="western">(</code><code class="western">int
fd</code><code class="western">) ; </code>
</p>
<p class="code-western"><code class="western">void
yaffs_rewinddir_</code><code class="western">fd</code><code class="western">(</code><code class="western">int
fd</code><code class="western">) ; </code>
</p>
<p class="code-western"><code class="western">int yaffs_close(</code><code class="western">int
fd</code><code class="western">) ; </code>
</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">This is not a POSIX interface, but provides an
alternate interface for reading directories.</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">Searching is performed by the following sequence
of operations:</p>
<ul>
	<li/>
<p class="western">Open the directory for reading with
	<code class="western">yaffs_open( </code><code class="western">name,
	O_RDONLY, 0</code><code class="western">)</code>.</p>
	<li/>
<p class="western">Iterate through the entries in the
	directory using <code class="western">yaffs_readdir_</code><code class="western">fd</code><code class="western">()</code>.
	Each read will advance the directory read position.</p>
	<li/>
<p class="western">You can reset to the start of the directory
	with <code class="western">yaffs_rewinddir_</code><code class="western">fd</code><code class="western">()</code>.</p>
	<li/>
<p class="western">Close the directory when finished with
	<code class="western">yaffs_close()</code>.</p>
</ul>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.12 Mount control and similar</h2>
<p class="code-western"><code class="western">yaffs_mount(path) ; </code>
</p>
<p class="code-western"><code class="western">yaffs_mount2(path,
readOnly); </code>
</p>
<p class="code-western"><code class="western">yaffs_unmount(path);</code></p>
<p class="code-western"><code class="western">yaffs_unmount2(path,
int force); </code>
</p>
<p class="code-western"><code class="western">yaffs_remount(path,
force, readOnly);</code></p>
<p class="code-western"><code class="western">yaffs_sync(path) ;</code></p>
<p class="code-western"><code class="western">yaffs_format(const
YCHAR *path, </code>
</p>
<p class="western"><code class="western"> </code><code class="western">		int
unmount_flag, </code>
</p>
<p class="western"><code class="western"> </code><code class="western">		int
force_unmount_flag, </code>
</p>
<p class="western"><code class="western"> </code><code class="western">		int
remount_flag) </code>
</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">A partition must be mounted to be accessed.
<code class="western">yaffs_mount()</code> will mount the partition
for read/write access. <code class="western">yaffs_mount2()</code>
can be used to control whether the access is read/write or read only.</p>
<p class="western">A partition can be unmounted to remove it from
use. <code class="western">yaffs_unmount()</code> will fail if any
files are in use whereas <code class="western">yaffs_unmount2()</code>
allows you to force the unmount even if files are open. Note that any
file handles will then be broken and will no longer access the files.</p>
<p class="western"><code class="western">yaffs_remount()</code> can
be used to change the access to a currently mounted partition and is
equivalent to making an <code class="western">unmount2()</code> call
followed by a <code class="western">mount2()</code> call.</p>
<p class="western"><code class="western">yaffs_sync()</code> does not
change the mount status but flushes out any pending data on a
partition that is mounted with write access.</p>
<p class="western"><font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>yaffs_format()</b></font></font>
provides a mechanism to format a device. It has various
parameters.<br/>
	<font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>unmount_flag</b></font></font>:
If set, yaffs_format() will unmount the device before formatting. If
this flag is not set and the device is mounted, then the format will
fail with EBUSY.</p>
<p class="western">	<font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>force_unmount</b></font></font>:
If set, then an unmount is allowed even if the device is busy (eg.
files open). If not set, then yaffs_format() will fail (EBUSY) if
files are open.</p>
<p class="western">	<font face="Liberation Mono, monospace"><font size="2" style="font-size: 10pt"><b>remount_flag</b></font></font>:
 If set, then the device will be remounted after the format if it was
mounted.</p>
<p class="western">The force_unmount and remount_flag options only
have meaning if unmount_flag is set.</p>
<h2 class="western">11.13 Extended attributes (xattrt)</h2>
<p class="western">Extended attributes provide a mechanism to attach
a limited amount of extra data to a file without actually modifying
the file. Each xattribute is a named pair of name and some data. Each
file can have as many xattribs as there is space for. In Yaffs, this
is around chunk-size – 512 bytes. So on devices with 2kbyte chunks
you can store up to 1.5kbytes of xattribute information.</p>
<p class="western">Although there are 12 xattr functions, there are
really only four basic functions, each with 3 different flavours.</p>
<p class="western">The basic functions are: set an xattr, get an
xattr, remove an xattribute and list the xattribute names.</p>
<p class="code-western">int yaffs_setxattr(const char *path, const
char *name, 
</p>
<p class="code-western">                        const void *data, int
size, int flags); 
</p>
<p class="code-western">int yaffs_lsetxattr(const char *path, const
char *name, 
</p>
<p class="code-western">                        const void *data, int
size, int flags); 
</p>
<p class="code-western">int yaffs_fsetxattr(int fd, const char *name,
</p>
<p class="code-western">                        const void *data, int
size, int flags); 
</p>
<p class="western">These functions are called with name being the
name of the xattr, a pointer to the data and the size of the data,
and flags.</p>
<p class="western">The flags are:</p>
<p class="western">XATTR_CREATE: Create a new xattr, fail with
-EEXIST if the xattrib already exists.</p>
<p class="western">XATTR_REPLACE: Replace an existing xattr, fail
with -ENOATTR if it does not exist.</p>
<p class="western">zero: Just create with no checks, replace if it
already exists.</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">Setting can fail with -ENOSPC if there is not
enough space to store the xattrib.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int yaffs_getxattr(const char *path, const
char *name, 
</p>
<p class="code-western">                        void *data, int
size); 
</p>
<p class="code-western">int yaffs_lgetxattr(const char *path, const
char *name, 
</p>
<p class="code-western">                        void *data, int
size); 
</p>
<p class="code-western">int yaffs_fgetxattr(int fd, const char *name,
</p>
<p class="code-western">                        void *data, int
size); 
</p>
<p class="western">These get (fetch) an xattrib.</p>
<p class="western">If the call succeeds, the length of the retrieved
xattrib is returned. This call can fail with -ENOATTR if the
requested xattr does not exist or -ERANGE if the buffer was too
small.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int yaffs_removexattr(const char *path, const
char *name); 
</p>
<p class="code-western">int yaffs_lremovexattr(const char *path,
const char *name); 
</p>
<p class="code-western">int yaffs_fremovexattr(int fd, const char
*name); 
</p>
<p class="western">These functions delete an existing xattr. If the
xattr does not exist then -ENOATTR is returned.</p>
<p class="western"><br/>
<br/>

</p>
<p class="code-western">int yaffs_listxattr(const char *path, char
*list, int size); 
</p>
<p class="code-western">int yaffs_llistxattr(const char *path, char
*list, int size); 
</p>
<p class="code-western">int yaffs_flistxattr(int fd, char *list, int
size); 
</p>
<p class="western">These functions fetch a list of the xattrib names
into the list buffer. The names are NUL terminated. eg.
“attrib0\0attrib1\0...”.</p>
<p class="western">The function returns the length of the list,
otherwise if the list buffer is too short it returns -ERANGE.</p>
<p class="western">Note: If you call these functions with a list
buffer size of zero, this acts as a query of the required buffer
size. No data is actually transferred into the list.</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">For example we might choose to add some xattribs
to a media file:</p>
<p class="code-western">//Set description</p>
<p class="code-western">yaffs_fsetxattr(fd, “user-comment”, “I
hate this song!”,18);</p>
<p class="code-western">yaffs_fsetxattr(fd, “price-in-cents”,
&amp;cost, sizeof(cost));</p>
<p class="code-western">// Get the comment</p>
<p class="code-western">yaffs_fgetxattr(fd, “user_comment”,
buffer, sizeof(buffer);</p>
<p class="code-western"><br/>
<br/>

</p>
<p class="code-western">//List the attributes in a NUL delimited list</p>
<p class="code-western">yaffs_flistxattr(fd, list_buf,
sizeof(list_buf));</p>
<p class="code-western">// Now list_buf has
user-comment\0price-in-cents\0</p>
<p class="code-western">yaffs_fremovexattr(fd, ”user-comment”);</p>
<p class="western"><br/>
<br/>

</p>
<h2 class="western">11.14 Other</h2>
<p class="code-western"><code class="western">yaffs_freespace(path); </code>
</p>
<p class="code-western"><code class="western">yaffs_totalspace(path);
</code>
</p>
<p class="code-western"><code class="western">yaffs_inodecount(path);
</code>
</p>
<p class="western"><br/>
<br/>

</p>
<p class="western">These functions provide information on the free
and total space (in bytes) for the mount that the path addresses.</p>
<p class="western"><code class="western">yaffs_inodecount()</code>
returns the number of files on the mount that the path addresses.</p>

<h1 class="western" style="page-break-before: always">12 Example:
yaffs_readdir() and yaffs_stat()</h1>
<p class="western">This code snippet illustrates using
<code class="western">yaffs_readdir()</code> and associated functions
to iterate through a directory. It also shows how to use
<code class="western">yaffs_lstat() </code>to get information on a
file and interpret it.</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">void
dump_directory(const char *dname) </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">{
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	yaffs_DIR
*d; </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	yaffs_dirent
*de; </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	struct
yaffs_stat s; </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	char
str[100]; </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	d
= yaffs_opendir(dname); </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	if(!d)
{ </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">		printf(&quot;opendir
failed\n&quot;); </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	}
else { </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">		while((de
= yaffs_readdir(d)) != NULL) { </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			sprintf(str,&quot;%s/%s&quot;,dname,de-&gt;d_name);
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			yaffs_lstat(str,&amp;s);
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			printf(&quot;%s
inode %d length %d mode %X &quot;,</font></code></p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">					str,s.st_ino,(int)s.st_size,s.st_mode);
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			switch(s.st_mode
&amp; S_IFMT) { </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">				case
S_IFREG: printf(&quot;data file&quot;); break; </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">				case
S_IFDIR: printf(&quot;directory&quot;); break; </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">				case
S_IFLNK: printf(&quot;symlink --&gt;&quot;); </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">					if(yaffs_readlink(str,str,100)
&lt; 0) </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">						printf(&quot;no
alias&quot;); </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">					else
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">						printf(&quot;\&quot;%s\&quot;&quot;,str);</font></code></p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">					break;
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">				default:
printf(&quot;unknown&quot;); break; </font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			}</font></code></p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			printf(&quot;\n&quot;);
</font></code>
</p>
<p class="code-western"><br/>
<br/>

</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">			if((s.st_mode
&amp; S_IFMT) == S_IFDIR)</font></code></p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">				dump_directory_tree_worker(str);
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">		}
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">		
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">		yaffs_closedir(d);
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">	}
</font></code>
</p>
<p class="code-western"><code class="western"><font size="2" style="font-size: 10pt">}
</font></code>
</p>
<p class="western"><br/>
<br/>

</p>
";s:7:"summary";s:159:"<p>This describes the Yaffs Direct Interface (YDI), which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS.</p><p>&nbsp;</p>";s:6:"format";s:8:"raw_html";}}}s:19:"field_document_type";a:1:{s:9:"x-default";a:1:{i:0;a:1:{s:9:"target_id";s:3:"344";}}}s:6:"upload";a:1:{s:9:"x-default";a:1:{i:0;a:3:{s:9:"target_id";s:2:"80";s:7:"display";s:1:"1";s:11:"description";s:0:"";}}}s:18:"field_teaser_image";a:1:{s:9:"x-default";a:1:{i:0;a:5:{s:9:"target_id";s:2:"81";s:3:"alt";s:26:"Preview of YaffsDirect.pdf";s:5:"title";N;s:5:"width";N;s:6:"height";N;}}}}s:9:"*fields";a:0:{}s:19:"*fieldDefinitions";N;s:12:"*languages";N;s:14:"*langcodeKey";s:8:"langcode";s:21:"*defaultLangcodeKey";s:16:"default_langcode";s:17:"*activeLangcode";s:9:"x-default";s:18:"*defaultLangcode";s:3:"und";s:15:"*translations";a:1:{s:9:"x-default";a:1:{s:6:"status";i:1;}}s:24:"*translationInitialize";b:0;s:14:"*newRevision";b:0;s:20:"*isDefaultRevision";s:1:"1";s:13:"*entityKeys";a:4:{s:6:"bundle";s:5:"paper";s:2:"id";s:3:"453";s:8:"revision";s:3:"606";s:4:"uuid";s:36:"4682c2f9-e73c-487f-9ed4-67796f6f0d82";}s:25:"*translatableEntityKeys";a:6:{s:5:"label";a:1:{s:9:"x-default";s:22:"Yaffs Direct Interface";}s:8:"langcode";a:1:{s:9:"x-default";s:3:"und";}s:6:"status";a:1:{s:9:"x-default";s:1:"1";}s:9:"published";a:1:{s:9:"x-default";s:1:"1";}s:3:"uid";a:1:{s:9:"x-default";s:1:"1";}s:16:"default_langcode";a:1:{s:9:"x-default";s:1:"1";}}s:12:"*validated";b:0;s:21:"*validationRequired";b:0;s:19:"*loadedRevisionId";s:3:"606";s:15:"*entityTypeId";s:4:"node";s:15:"*enforceIsNew";N;s:12:"*typedData";N;s:16:"*cacheContexts";a:0:{}s:12:"*cacheTags";a:0:{}s:14:"*cacheMaxAge";i:-1;s:14:"*_serviceIds";a:0:{}}