('paper',0,453,528,'und',0,'<h2>1 Background</h2>\r\n\r\n<p>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>\r\n\r\n<h2>2 Licensing</h2>\r\n\r\n<p>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 has alternative licensing arrangements to support such applications.</p>\r\n\r\n<h2>3 What are Yaffs and Yaffs Direct Interface?</h2>\r\n\r\n<p>Yaffs stands for <em>Yet Another Flash File System</em>. Yaffs was the first file system designed, from the ground up, for NAND storage.</p>\r\n\r\n<p>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>\r\n\r\n<p>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 to NAND flash for higher density and performance.</p>\r\n\r\n<p>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>\r\n\r\n<p><br />\r\nYaffs has been used for many products using various operating systems including Windows CE and various RTOSs, including ThreadX, vXworks, pSOS to name just a few.</p>\r\n\r\n<p>Note that there is a native port to eCOS that does not use YDI. This is supported and distributed by eCocCentric.(http://www.ecoscentric.com/).</p>\r\n\r\n<p>Yaffs2, a more recent release of Yaffs, supports a wider range of NAND flash components including 2k page devices, and produces equivalent or better performance. It include Yaffs1 compatibility code so Yaffs1 images still work and migration is quite simple.</p>\r\n\r\n<p>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>\r\n\r\n<h2>4 Why use Yaffs?</h2>\r\n\r\n<p>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>\r\n\r\n<p>Some features to consider:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs has been well proven and has been used to ship in large volumes in several products using many different operating systems, compilers and processors.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs is written in portable C and is endian neutral.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs provides bad<strong> </strong>block handling and ECC algorithms to handle deficiencies in NAND flash.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs is a log-structured file system which makes it very robust to corruptions caused by power failures etc.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs has highly optimised and predictable garbage collection strategies. This makes it high performance and very deterministic when compared with similar file systems.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs has a lower memory footprint than most other log-structured flash file systems.</p>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs is highly configurable to work with various flash geometries, various ECC options, caching options etc.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs can be used with a wide range of memory technologies.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h2>5 Source Code and Yaffs Resources</h2>\r\n\r\n<p>Please note the licensing terms that apply to using the Yaffs code.</p>\r\n\r\n<p><a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a> serves as the hub for all Yaffs information.</p>\r\n\r\n<p>This document refers to the Yaffs source code extensively. and is available via the download link on this site.</p>\r\n\r\n<p>There are various other documents and a Yaffs mailing list for Yaffs discussions.</p>\r\n\r\n<p>Consulting services are also available.</p>\r\n\r\n<h2>6 System Requirements</h2>\r\n\r\n<p>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>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs is endian-neutral and works fine with little-endian and big-endian processors.</p>\r\n	</li>\r\n	<li>\r\n	<p>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 should work with 16-bit CPUs too, but this is generally untested and might need some tuning, depending on compiler options.</p>\r\n	</li>\r\n	<li>\r\n	<p>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 <em>chunk</em> of NAND flash, where a <em>chunk</em> 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>\r\n	</li>\r\n</ul>\r\n\r\n<h2>7 How to integrate Yaffs with an RTOS/Embedded system</h2>\r\n\r\n<p>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 OS. Yaffs provides a set of POSIX-compliant functions for applications to use to talk to it.</p>\r\n\r\n<p>In addition to the Yaffs core file system, the YDI has three parts which are each explained in more detail in further sections:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><strong>POSIX Application Interface</strong>: This is the interface that the application code uses to access the Yaffs file system. (<em>open, close, read, write, </em>etc)</p>\r\n	</li>\r\n	<li>\r\n	<p><strong>RTOS Integration Interface</strong>: These are the functions that must be provided for Yaffs to access the RTOS system resources. (<em>initialise, lock, unlock, get time, set error</em>)</p>\r\n	</li>\r\n	<li>\r\n	<p><strong>Flash Configuration and Access Interface</strong>: These are the functions that must be provided for Yaffs to access the NAND flash. (<em>initialise, read chunk, write chunk, erase block, </em>etc). These functions might be supplied by a chipset vendor or might need to be written by the integrator.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><img alt=\"Yaffs Direct Interface Layer\" src=\"/sites/yaffs.net/files/images/Yaffs%20Direct%20Interface%20layer.gif\" /></p>\r\n\r\n<h3>7.1 Source Files</h3>\r\n\r\n<p>The following source files contain the core file system:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_allocator.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Allocates Yaffs object and tnode structures.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_checkpointrw.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Streamer for writing checkpoint data</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_ecc.c</p>\r\n			</td>\r\n			<td>\r\n			<p>ECC code</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_guts.c</p>\r\n			</td>\r\n			<td>\r\n			<p>The major Yaffs algorithms.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_nand.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Flash interfacing abstraction.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_packedtags1.c<br />\r\n			yaffs_packedtags2.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Tags packing code</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_qsort.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Qsort used during Yaffs2 scanning</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_tagscompat.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Tags compatibility code to support Yaffs1 mode.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_tagsvalidity.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Tags validity checking.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>The Yaffs direct interface is in yaffsfs.c, with the interface functions and structures defined in yaffsfd.h.</p>\r\n\r\n<p>Example and testing build files:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>dtest.c</p>\r\n			</td>\r\n			<td>\r\n			<p>A test harness. Also has sample code that can be used for better understanding of how some function calls work.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffscfg2k.c</p>\r\n			</td>\r\n			<td>\r\n			<p>A test configuration.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_fileem.c<br />\r\n			yaffs_fileem2k.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Nand flash simulation using a file as backing store.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_norif1.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Nor flash simulation and interfacing example. This is configured for M18 flash.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_ramdisk.c<br />\r\n			yaffs_ramem2k.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Simulations using RAM.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>ynorsim.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Another Nor simulation.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Further testing files are in direct/tests and direct/python.</p>\r\n\r\n<h3>7.2 Integrating the POSIX Application Interface</h3>\r\n\r\n<p>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>yaffs_</code>. For example, <code>yaffs_open(), yaffs_close()</code> etc.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>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>\r\n\r\n<p>These functions can be used directly, with the code written using these names. For example</p>\r\n\r\n<p><code>int main(...)<br />\r\n{<br />\r\n// initialisation<br />\r\nf = yaffs_open(...);<br />\r\nyaffs_read(f,...);<br />\r\nyaffs_close(f);<br />\r\n}</code></p>\r\n\r\n<p>The yaffs functions can also be wrapped in some way to allow existing code to use yaffs without modification. For example:</p>\r\n\r\n<p><code>#define open(path, oflag, mode) yaffs_open(path, oflag, mode)<br />\r\n..<br />\r\n<br />\r\nint main(...)<br />\r\n{<br />\r\n// initialisation<br />\r\nf = open(...);<br />\r\nread(f,...);<br />\r\nclose(f);<br />\r\n}</code><br />\r\n&nbsp;</p>\r\n\r\n<p>A more complex approach that can be used if more than one file-system is used is to provide redirection functions. For example:</p>\r\n\r\n<p><code>int open(const char *path,...)<br />\r\n{<br />\r\n// Determine which file system is being used if(it_is_a_yaffs_path(path))<br />\r\nreturn yaffs_open(...);<br />\r\nelse<br />\r\n{<br />\r\n// Do something else<br />\r\n}<br />\r\n}</code></p>\r\n\r\n<p>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>\r\n\r\n<h3>7.3 RTOS Integration Interface</h3>\r\n\r\n<p>Before Yaffs can be used, it needs to be integrated with the system and configured so that the correct actions are performed.</p>\r\n\r\n<p>To do this, you need to modify the configuration file. An example configuration file is presented in yaffscfg.c and yaffscfg2k.c.</p>\r\n\r\n<p>This is a relatively straight forward process and defines the RTOS access functions.</p>\r\n\r\n<p>The RTOS access functions are:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>void yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system error.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>void yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from multi-threaded access.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>void yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>__u32 yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>void yaffsfs_LocalInitialisation(void)</code>: Called to initialise RTOS context.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>If Yaffs is being used in a multi-threaded environment, then typically <code>yaffs_LocalInitialisation()</code> will initialise a suitable RTOS semaphore and <code>yaffs_Lock()</code> and <code>yaffs_Unlock()</code> will call the appropriate functions to lock and release the semaphore.</p>\r\n\r\n<p><code>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>\r\n\r\n<p>Although not shown here, Yaffs also requires memory allocation/free functions which default to <code>malloc()</code> and <code>free()</code>. These, and some other functions can be tuned in file ydirectenv.h</p>\r\n\r\n<p>Before the application code uses Yaffs, the <code>yaffs_StartUp()</code> function must be called and the appropriate partitions must be mounted. This is typically done in the system boot code:</p>\r\n\r\n<p><code>...</code></p>\r\n\r\n<p><code>/* System boot code: Start up Yaffs. */<br />\r\nyaffs_StartUp();<br />\r\nyaffs_mount(\"/boot\");</code></p>\r\n\r\n<p><code>...</code></p>\r\n\r\n<h2>8 Yaffs NAND Model</h2>\r\n\r\n<p>Before defining the flash integration interface, it is important to understand the model and corresponding nomenclature used throughout Yaffs and its documentation.</p>\r\n\r\n<p>Yaffs uses a fairly abstract model for NAND flash. This allows a lot of flexibility in the way it can be used.</p>\r\n\r\n<p>Yaffs is designed for NAND flash and makes the following assumptions and definitions:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The flash is arranged in <em><strong>blocks</strong></em>. Each block is the same size and comprises an integer number of chunks. Each block is treated as a single erasable item. A block contains a number of chunks.</p>\r\n	</li>\r\n	<li>\r\n	<p>A <em><strong>chunk</strong></em> 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>\r\n	</li>\r\n	<li>\r\n	<p>All accesses (reads and writes) are page chunk aligned. Some reads might only read the spare area where the tags are kept.</p>\r\n	</li>\r\n	<li>\r\n	<p>When programming a NAND flash, only the zero bits in the pattern being programmed are relevant, and one bits are \"don\'t care\". For example, if a byte already contains the binary pattern 1010, then programming 1001 will result in the pattern which is the logical AND of these two patterns ie. 1000. This is different to NOR flash which would typically abort the attempt to convert a 0 into a 1.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Yaffs identifies blocks by their block number and chunks by the chunk Id. A chunk Id is calculated as:</p>\r\n\r\n<p><code>chunkId = block_id * chunks_per_block + chunk_offset_in_block</code></p>\r\n\r\n<p>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>\r\n\r\n<p>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 more effort is required to interface to the NAND.</p>\r\n\r\n<h3>8.1 NAND Model considerations for Yaffs1</h3>\r\n\r\n<p>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>\r\n\r\n<p>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>\r\n\r\n<p>If the yaffs_Device\'s useNANDECC filed is not set, then yaffs will perform the ECC calculations. If this iset then yaffs will expect the NAND driver todo any required ECC checks. On devices that are not using ECC, for example NOR, set useNANDECC=1 and then don\'t do any ECC anyway.</p>\r\n\r\n<p>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>\r\n\r\n<p>The Yaffs1 model has been used in many NOR-based systems. One particularly instructive example is in yaffs_norif1.c which implements Yaffs1 mode on Intel M18 flash using 1k data pages and simulating a spare area on re-writable areas of flash. This does not use ECC but uses checksumming instead.</p>\r\n\r\n<h3>8.2 NAND Model for Yaffs2</h3>\r\n\r\n<p>Yaffs2 uses a different tags layout than Yaffs1. Yaffs2 uses a yaffs_ExtendedTags structure.which is packed according to the code in yaffs_packedtags2.c.</p>\r\n\r\n<p>The NAND handler layer must use or populate the fields. The fields have the following meaning:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>validMarker0</code> Set to 0xAAAAAAAA</p>\r\n	</li>\r\n	<li>\r\n	<p><code>chunkUsed</code> If 0 then this chunk is not in use</p>\r\n	</li>\r\n	<li>\r\n	<p><code>objectId</code> The object this chunk belongs to. If 0 then this is not part of an object (ie. unused).</p>\r\n	</li>\r\n	<li>\r\n	<p><code>chunkId</code> If 0 then this is a header, else a data chunk at the specified position in the file</p>\r\n	</li>\r\n	<li>\r\n	<p><code>byteCount</code> Number of data bytes in the chunk. Only valid for data chunks</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The following fields only have meaning when we read</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>eccResult</code> Result of ECC check when reading</p>\r\n	</li>\r\n</ul>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>blockBad</code> If 0 then the block is not bad.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The following fields have meaning for Yaffs1 and should be zero for Yaffs:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>chunkDeleted</code> if non-zero, the chunk is marked deleted.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>serialNumber</code> 2-bit serial number.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The following field has meaning for Yaffs1 and should be zero for Yaffs2:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>sequenceNumber</code> The sequence number of this block</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Optional extra info if this is an object header (Yaffs2 only). Make zero for Yaffs1.</p>\r\n\r\n<p>If <code>extraHeaderInfoAvailable</code> is set, then all the <code>extraXXX</code> fields must be valid.</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>extraHeaderInfoAvailable</code> There is extra info available if this is not zero.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraParentObjectId</code> The parent object id.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraIsShrinkHeader</code> Is it a shrink header?</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraShadows</code> Does this shadow another object?</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraObjectType</code> What object type?</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraFileLength</code> Length if it is a file.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraEquivalentObjectId</code> Equivalent object Id if it is a hard link.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>And finally:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>validMarker1</code> Must be 0x55555555.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>There are quite a few fields, some of which are optional. All the <code>extraXXXX</code> fields are a way of stuffing more data into object header tags in a way that speeds up scanning. These are optional and should all be zero if not supported.</p>\r\n\r\n<p>The easiest way to process the <code>yaffs_ExtendedTags</code> is to use the functions presented in yaffs_packedtags2.h to do the packing and unpacking. These are:</p>\r\n\r\n<p><code>yaffs_PackTags2()</code> and <code>yaffs_UnpackTags2()</code>.</p>\r\n\r\n<p>These functions create or use a packed tags structure which can be stored in the NAND spare area. An example of how to do this is presented in yaffs_fileem2.c</p>\r\n\r\n<h2>9 NAND Configuration and Access Interface</h2>\r\n\r\n<p>For an example of how to do the configuration, refer to yaffs_cfg.c and yaffs_cfg2k.c.</p>\r\n\r\n<p>This part of the configuration involves configuring the chips and suitable access functions.</p>\r\n\r\n<p>This is done in <code>yaffs_StartUp().</code></p>\r\n\r\n<p>Before launching into the device configuration, it is important to understand that Yaffs supports two different modes of operation:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs1: This is the original mode of operation and is only available for 512-byte-per-page devices.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs2: This mode of operation supports larger page sizes.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Most configuration options are the same for both, but they have different NAND access functions.</p>\r\n\r\n<p>You may have a system that uses a mix of Yaffs1 and Yaffs2 partitions.</p>\r\n\r\n<h3>9.1 Common configuration items (Yaffs1 and Yaffs2)</h3>\r\n\r\n<p>The configuration involves two parts:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Setting up the mount point table.</p>\r\n	</li>\r\n	<li>\r\n	<p>Setting up the devices.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>A <em>yaffsfs_DeviceConfiguration</em> is an entry that has two parts: a mount point name and a pointer to a <em>yaffs_Device</em> structure. The mount point name is used to determine where the particular <em>yaffs_Device</em> may be found in the directory structure. There can be any number of mount points and they may be nested. For example:</p>\r\n\r\n<p><code>static yaffsfs_DeviceConfiguration yaffsfs_config[] = {</code></p>\r\n\r\n<p><code>{ \"/\", &amp;ramDev},</code></p>\r\n\r\n<p><code>{ \"/flash/boot\", &amp;bootDev},</code></p>\r\n\r\n<p><code>{ \"/flash/flash\", &amp;flashDev},</code></p>\r\n\r\n<p><code>{ \"/ram2k\", &amp;ram2kDev},</code></p>\r\n\r\n<p><code>{(void *)0,(void *)0} /* Terminate list */</code></p>\r\n\r\n<p><code>};</code></p>\r\n\r\n<p>Each logical storage entity is called a <em>yaffs_Device</em> and is probably best though of as a partition descriptor. Each <em>yaffs_Device</em> can correspond to:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>A whole flash device.</p>\r\n	</li>\r\n	<li>\r\n	<p>Part of a flash device.</p>\r\n	</li>\r\n	<li>\r\n	<p>Something other than a flash device (e.g. perhaps a RAM emulation). During testing, this emulation capability is often employed to use a host system hard-disk file or nfs-mounted file as an alternative storage mechanism.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Two or more yaffs_Devices can reside in a single physical flash device by specifying different start and end blocks. For example here is a case where a single device is split into two partitions:</p>\r\n\r\n<p><code>// /boot<br />\r\n......<br />\r\nbootDev.param.startBlock = 0; // First block.<br />\r\nbootDev.param.endBlock = 55; // Last block in 2MB.<br />\r\n<br />\r\n// /disk<br />\r\n...<br />\r\ndiskDev.param.startBlock = 56; // First block after 2MB<br />\r\ndiskDev.param.endBlock = 1023; // Last block in 16MB</code></p>\r\n\r\n<p>All <em>yaffs_Device</em> structures must be configured according to the Yaffs Tuning document.</p>\r\n\r\n<h3>9.2 Common Access Functions (Yaffs1 and Yaffs2)</h3>\r\n\r\n<p>Both Yaffs1 and Yaffs2 configurations must provide pointers to the following functions:</p>\r\n\r\n<p><code>int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND)</code></p>\r\n\r\n<p>Yaffs calls this function to erase a block of flash.</p>\r\n\r\n<p><code>int (*initialiseNAND)(struct yaffs_DeviceStruct *dev)</code></p>\r\n\r\n<p>Yaffs calls this function at start up before other functions get called to access the <em>yaffs_Device</em>. This allows the system integrator a control point to perform any required initialisation (eg. set up chip selects etc.).</p>\r\n\r\n<h3>9.3 Yaffs1 Access Functions</h3>\r\n\r\n<p>For Yaffs1 partitions, the yaffs_Device configuration also specifies pointers to two further functions that Yaffs calls to access the NAND for this yaffs_Device. For a better understanding of these functions, see the section on the Yaffs NAND Model. These functions are:</p>\r\n\r\n<p><code>int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare)</code></p>\r\n\r\n<p>Yaffs calls this function to write data to NAND. The data pointer may be NULL if only the spare area is being written, as happens when the chunk is being deleted or retired. If the data pointer is NULL then do not write the data. The spare pointer will never be NULL.</p>\r\n\r\n<p><code>int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)</code></p>\r\n\r\n<p>Yaffs calls this function when reading a chunk from flash. The meanings of the arguments are obvious from the above, but note that the data and spare fields might be NULL, in which case those pointers should not be dereferenced.</p>\r\n\r\n<h3>9.4 Yaffs2 Access Functions</h3>\r\n\r\n<p>The Yaffs2 mode of operation is far more flexible than the Yaffs1 mode of operation. That allows for far more different types of flash to be used, but slightly increases the complexity of the NAND access functions.</p>\r\n\r\n<p>With the Yaffs1 mode of operation, Yaffs performs bad block detection and marking and can optionally perform ECC. It can do this because it assumes that the NAND spare area is structured in a certain way. The Yaffs2 mode of operation can no longer make those assumptions which means that the system integrator must provide slightly more complex functions. However, the interface is still relatively simple, particularly if existing code is used as a basis.</p>\r\n\r\n<p><code>int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,</code></p>\r\n\r\n<p><code>int chunkInNAND, const __u8 * data,</code></p>\r\n\r\n<p><code>const yaffs_ExtendedTags * tags)</code></p>\r\n\r\n<p><code>int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,</code></p>\r\n\r\n<p><code>int chunkInNAND, __u8 * data,</code></p>\r\n\r\n<p><code>yaffs_ExtendedTags * tags)</code></p>\r\n\r\n<p><code>int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);</code></p>\r\n\r\n<p><code>int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,</code></p>\r\n\r\n<p><code>yaffs_BlockState * state, int *sequenceNumber)</code></p>\r\n\r\n<p>The <code>writeChunkWithTagsToNAND()</code> and <code>readChunkWithTagsFromNAND()</code> functions must save or retrieve the data and extended tags. Please refer to the explanation of the Yaffs2 NAND model for a better understanding of how to handle the tags. Please note that under certain circumstances, the data and tags pointers may be NULL and the driver code should ignore transfers from or to pointers that are NULL.</p>\r\n\r\n<p>The NAND access functions must also provide a mechanism for marking and tracking bad blocks. If a bad block is detected and Yaffs decides to mark that block bad, the <code>markNANDBlockBad()</code> function is called.</p>\r\n\r\n<p>The <code>queryNANDBlock()</code> function does two things:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>It determines the block state</p>\r\n	</li>\r\n	<li>\r\n	<p>If the block is in use it also retrieves the block’s sequence number.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>By far the easiest way to understand this all is to refer to the example code provided.</p>\r\n\r\n<h2>10 Using the POSIX file system interface</h2>\r\n\r\n<p>This section is directed to readers that might not be very familiar with accessing a file system via POSIX and POSIX-like interfaces.</p>\r\n\r\n<h3>10.1 Difference to Windows POSIX-like interfaces</h3>\r\n\r\n<p>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>\r\n\r\n<ul>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n	<li>\r\n	<p>Windows names drives with a letter. POSIX has no drive letters. The whole POSIX file system is in a single directory tree.</p>\r\n	</li>\r\n	<li>\r\n	<p>Directories and “folders” are the same thing.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>10.2 Fundamental concepts</h3>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>File</p>\r\n			</td>\r\n			<td>\r\n			<p>A file is an object that is stored in the file system. yaffs supports the following file types:</p>\r\n\r\n			<p>A regular file is a sequence of bytes stored in the file system.</p>\r\n\r\n			<p>A directory holds links to other files.</p>\r\n\r\n			<p>A symbolic link holds a name to another file.</p>\r\n\r\n			<p>A special file holds device ids or similar information.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Directory</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Link</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Handle</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>File mode</p>\r\n			</td>\r\n			<td>\r\n			<p>The mode is the set of flags that define the type of file as well as the current permissions associated with the file.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Path</p>\r\n			</td>\r\n			<td>\r\n			<p>This is a string that defines the directories and file name. For example:</p>\r\n\r\n			<p>“/data/direct-1/file1”</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>File metadata</p>\r\n			</td>\r\n			<td>\r\n			<p>This is the information about the file, excluding the file contents. The metadata includes the name, mode, size and other details.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Mount,<br />\r\n			partition,<br />\r\n			file system</p>\r\n			</td>\r\n			<td>\r\n			<p>These terms all refer to a single mounted flash area. Each mount is hooked into a common directory structure.<br />\r\n			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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>inode number</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h3>10.3 Error code</h3>\r\n\r\n<p>Most functions result in error codes if the function does not execute successfully.In these cases yaffs calls a function called <code>yaffs_SetError()</code> with the error value. This function can be configured to deliver the error into the system\'s error mechanism.</p>\r\n\r\n<p>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>\r\n\r\n<h3>10.4 Links – the hard kind (not symbolic links)</h3>\r\n\r\n<p>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>\r\n\r\n<p>The difference between links and files is subtle and can be confusing. Briefly:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>a file is the stored object in the file system</p>\r\n	</li>\r\n	<li>\r\n	<p>the link is how it is hooked into the directory structure.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The first link to a file is created by using the file creation calls: <code>yaffs_open()</code>, <code>yaffs_mknod()</code>, <code>yaffs_symlink()</code> and <code>yaffs_mkdir()</code>.</p>\r\n\r\n<p>A link can be destroyed by using the <code>yaffs_unlink()</code> function. Directories are destroyed using the <code>yaffs_rmdir()</code> function (oh, and the directory must be empty).</p>\r\n\r\n<p>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>\r\n\r\n<p>A link can be renamed by using the <code>yaffs_rename()</code> function.</p>\r\n\r\n<p>A file may have many links. These may be created using the <code>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>\r\n\r\n<p>Thus:</p>\r\n\r\n<ol>\r\n	<li>\r\n	<p>If we start with a file called “a” and then call <code>yaffs_link(“a”, “b”)</code> we now have two links to the same file. We can\'t tell them apart.</p>\r\n	</li>\r\n	<li>\r\n	<p>If we now unlink “a”, the file still exists under the link “b”.</p>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n</ol>\r\n\r\n<p>There are some limitations in how links are used:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The existing file you are linking to must exist.</p>\r\n	</li>\r\n	<li>\r\n	<p>The file you are linking to must be in the same mount (partition) as the link you are creating.</p>\r\n	</li>\r\n	<li>\r\n	<p>You cannot create a link to a directory because this would allow the creation of recursive loops.</p>\r\n	</li>\r\n	<li>\r\n	<p>The new link name must not exist.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>10.5 Symbolic links</h3>\r\n\r\n<p>Now that you understand how hard links work, we\'ll introduce symbolic (or soft) links.</p>\r\n\r\n<p>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>\r\n\r\n<p>You can remove symbolic links with the <code>yaffs_unlink()</code> function, just like hard links.</p>\r\n\r\n<p>There are, however, some important differences. A symbolic link only does its linking function when the path is being evaluated and thus:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The file you are creating an alias to does not have to exist.</p>\r\n	</li>\r\n	<li>\r\n	<p>The file you are creating an alias to does not have to be in the same mount.</p>\r\n	</li>\r\n	<li>\r\n	<p>You can create symbolic links to directories.</p>\r\n	</li>\r\n	<li>\r\n	<p>A symbolic link will not keep a file alive by itself. Only a hard link can do that.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Thus:</p>\r\n\r\n<ol>\r\n	<li>\r\n	<p>If we start with a file called “a” and then call <code>yaffs_symlink(“a”, “b”)</code> we now have one links to the file called “a” and a symbolic link aliasising from “b” to “a”.</p>\r\n	</li>\r\n	<li>\r\n	<p>If we use <code>yaffs_open(“a”)</code> or <code>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>yaffs_truncate()</code>, <code>yaffs_stat()</code> etc. The only exceptions are <code>yaffs_lstat()</code> and <code>yaffs_readlink()</code> which will treat the path as pointing to the symbolic link and not the file.</p>\r\n	</li>\r\n	<li>\r\n	<p>You can tell “a” and “b” apart by using <code>yaffs_lstat()</code>. <code>yaffs_lstat(“a”)</code> will show the information for file “a”. <code>yaffs_lstat(“b”)</code> will show the information for the symbolic link itself. Note the difference with hard links. With hard links <code>yaffs_lstat(“a”)</code> and <code>yaffs_lstat(“b”)</code> would show the same results since they are EXACTLY the same thing being referenced.</p>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n</ol>\r\n\r\n<h3>10.6 Handle-based file handling</h3>\r\n\r\n<p>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>\r\n\r\n<p>A handle is identified by an integer of value 0 or greater.</p>\r\n\r\n<p>A handle is created by using the <code>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>\r\n\r\n<p>A handle remains valid until the handle is closed by <code>yaffs_close()</code>.</p>\r\n\r\n<p>The <code>yaffs_open()</code> call takes three parameters:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>name: Full path name of the file being opened.</p>\r\n	</li>\r\n	<li>\r\n	<p>access flags: Flags being used to open this handle</p>\r\n	</li>\r\n	<li>\r\n	<p>creation mode: Mode flags used when creating a file.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The access flags are one or more of:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_CREAT</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Create file if it does not already exist.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_EXCL</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Only use with O_CREAT. Create file if it does not exist. If the file already exists then fail.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_TRUNC</code></p>\r\n			</td>\r\n			<td>\r\n			<p>If the file exists, and opening with write access, then truncate the file to zero bytes long.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_APPEND</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Regardless of the handle position, always write to the end of the file.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_RDWR</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Open for read/write access.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_WRONLY</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Open for write access and no read access.</p>\r\n\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>If neither O_RDWR or O_WRONLY is set then the file will be opened for read-only access.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Where they are not mutually exclusive, these flags are typically combined. For example:</p>\r\n\r\n<p><code>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>\r\n\r\n<p><code>O_CREAT | OEXCL | O_WRONLY</code> : Create a new file, opening it for write only. Fails if file already exists.</p>\r\n\r\n<p>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>yaffs_chmod()</code>.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>S_IREAD</code></p>\r\n			</td>\r\n			<td>\r\n			<p>The file may be opened for read access.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>S_IWRITE</code></p>\r\n			</td>\r\n			<td>\r\n			<p>The file may be opened for write access.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>S_IEXEC</code></p>\r\n			</td>\r\n			<td>\r\n			<p>The file may be opened for execution. This is not enforced by yaffs.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Once you have opened a handle you can then do various operations on the file.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_close(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Close the handle. It is no longer usable.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_fsync(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Flush out any cached writes to the file, as well as the file meta-data.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_datasync(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Same as yaffs_fsync() but no file metadata.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_flush(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Same as yaffs_fsync()</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_dup(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Duplicates a handle.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_lseek(handle, offset, whence)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_ftruncate(handle, size)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Change the file size. It can be made bigger or smaller. This does not change the handle read/write position.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_fstat(handle, buf)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Get file status.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_fchmod(handle, mode)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Change the file mose.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_read(handle, buffer, nbytes)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Read data from file at file pointer and update pointer.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_pread(handle, buffer, nbytes, position)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Read data from file at specified position. Does not modify file pointer</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_write(handle, buffer, nbytes)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Write data to file at file pointer and update pointer.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_pread(handle, buffer, nbytes, position)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Write data to file at specified position. Does not modify file pointer</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h3>10.7 Changing file size</h3>\r\n\r\n<p><code>yaffs_truncate(path, newSize)</code></p>\r\n\r\n<p><code>yaffs_ftruncate(handle, newSize)</code></p>\r\n\r\n<p>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>\r\n\r\n<p>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>\r\n\r\n<p>See also <code>yaffs_lseek()</code> too. Note that <code>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>\r\n\r\n<h3>10.8 Getting/setting information about files</h3>\r\n\r\n<p><code>yaffs_chmod(path, mode)</code></p>\r\n\r\n<p><code>yaffs_fchmod(handle, mode)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_access(path,amode)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_stat(path, struct yaffs_stat *buf) </code></p>\r\n\r\n<p><code>yaffs_fstat(handle, struct yaffs_stat *buf)</code></p>\r\n\r\n<p><code>yaffs_lstat(path, struct yaffs_stat *buf)</code></p>\r\n\r\n<p><code>yaffs_readlink(path, buf, bufsize)</code></p>\r\n\r\n<p>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>\r\n\r\n<p><code>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>\r\n\r\n<p>amode is a bitmask of the following values:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>R_OK</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Check read is OK</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>W_OK</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Check write is OK</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>X_OK</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Check execute is OK.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>0 (zero)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Just checks the file exists</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>These can be combined.</p>\r\n\r\n<p>For example:</p>\r\n\r\n<p><code>if(yaffs_access(path, R_OK | W_OK) == 0)</code></p>\r\n\r\n<p><code>the file exists and can be read and written</code></p>\r\n\r\n<p><code>if(yaffs_access(path, 0) == 0)</code></p>\r\n\r\n<p><code>the file exists</code></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The stat calls retrieve a yaffs_stat structure of data which is defined in yaffsfs.h. There are three versions:</p>\r\n\r\n<p><code>yaffs_fstat</code>: Takes a handle.</p>\r\n\r\n<p><code>yaffs_stat</code>: Takes a path name and follows symbolic links.</p>\r\n\r\n<p><code>yaffs_lstat</code>: Takes a path but does not follow symbolic links.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>Thus, if path is a symbolic link, <code>yaffs_fstat() </code>will give information on the file that the link points to while <code>yaffs_lstat()</code> will give information about the link itself.</p>\r\n\r\n<p><code>yaffs_readlink()</code> will read the read the link value into the buffer provided. For example:</p>\r\n\r\n<p><code>yaffs_symlink(“target”,”/link”); /* create a link called link to target */</code></p>\r\n\r\n<p><code>yaffs_readlink(“/link”,buffer,10); /* now buffer contains “target” */</code></p>\r\n\r\n<h3>10.9 Changing the directory structure and names</h3>\r\n\r\n<p><code>yaffs_open(path, flags, mode)</code></p>\r\n\r\n<p><code>yaffs_mkdir(path, mode)</code></p>\r\n\r\n<p><code>yaffs_symlink(targetPath, linkPath)</code></p>\r\n\r\n<p><code>yaffs_mknod(pathname, mode, dev)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_link(existingPath, newath)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_unlink(path)</code></p>\r\n\r\n<p><code>yaffs_rmdir(path)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_rename(oldPath, newPath)</code></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>Files of various types, and their first link, are created via the <code>yaffs_open()</code><code>,</code> <code>yaffs_mkdir()</code>, <code>yaffs_symlink()</code> and <code>yaffs_mknod()</code> functions.</p>\r\n\r\n<p><code>yaffs_link()</code> can be used to create subsequent links to files. Note that you cannot create a link to a directory.</p>\r\n\r\n<p><code>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>\r\n\r\n<h3>10.10 Searching directories</h3>\r\n\r\n<p><code>yaffs_DIR *yaffs_opendir(const YCHAR *dirname) ; </code></p>\r\n\r\n<p><code>struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ; </code></p>\r\n\r\n<p><code>void yaffs_rewinddir(yaffs_DIR *dirp) ; </code></p>\r\n\r\n<p><code>int yaffs_closedir(yaffs_DIR *dirp) ;</code></p>\r\n\r\n<p>Searching is performed by the following sequence of operations:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Open the directory for reading with <code>yaffs_opendir()</code>.</p>\r\n	</li>\r\n	<li>\r\n	<p>Iterate through the entries in the directory using <code>yaffs_readdir()</code>. Each read will advance the directory read position.</p>\r\n	</li>\r\n	<li>\r\n	<p>You can reset to the start of the directory with <code>yaffs_rewinddir()</code>.</p>\r\n	</li>\r\n	<li>\r\n	<p>Close the directory when finished with <code>yaffs_closedir()</code>.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>10.11 Mount control</h3>\r\n\r\n<p><code>yaffs_mount(path) ; </code></p>\r\n\r\n<p><code>yaffs_mount2(path, readOnly); </code></p>\r\n\r\n<p><code>yaffs_unmount(path);</code></p>\r\n\r\n<p><code>yaffs_unmount2(path, int force); </code></p>\r\n\r\n<p><code>yaffs_remount(path, force, readOnly);</code></p>\r\n\r\n<p><code>yaffs_sync(path) ;</code></p>\r\n\r\n<p>A partition must be mounted to be accessed. <code>yaffs_mount()</code> will mount the partition for read/write access. <code>yaffs_mount2()</code> can be used to control whether the access is read/write or read only.</p>\r\n\r\n<p>A partition can be unmounted to remove it from use. <code>yaffs_unmount()</code> will fail if any files are in use whereas <code>yaffs_unmount2()</code> allows you to force the unmount even if files are open.</p>\r\n\r\n<p><code>yaffs_remount()</code> can be used to change the access to a currently mounted partition and is equivalent to making an <code>unmount2()</code> call followed by a <code>mount2()</code> call.</p>\r\n\r\n<p><code>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>\r\n\r\n<h3>10.12 Other</h3>\r\n\r\n<p><code>yaffs_freespace(path); </code></p>\r\n\r\n<p><code>yaffs_totalspace(path); </code></p>\r\n\r\n<p><code>yaffs_inodecount(path);</code></p>\r\n\r\n<p>These functions provide information on the free and total space (in bytes) for the mount that the path addresses.</p>\r\n\r\n<p><code>yaffs_inodecount()</code> returns the number of files on the mount that the path addresses.</p>\r\n\r\n<h3>11 Example: yaffs_readdir() and yaffs_stat()</h3>\r\n\r\n<p>This code snippet illustrates using <code>yaffs_readdir()</code> and associated functions to iterate through a directory. It also shows how to use <code>yaffs_lstat() </code>to get information on a file and interpret it.</p>\r\n\r\n<p><code>void dump_directory(const char *dname) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>yaffs_DIR *d; </code></p>\r\n\r\n<p><code>yaffs_dirent *de; </code></p>\r\n\r\n<p><code>struct yaffs_stat s; </code></p>\r\n\r\n<p><code>char str[100]; </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>d = yaffs_opendir(dname); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>if(!d) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>printf(\"opendir failed\\n\"); </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p><code>else </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>while((de = yaffs_readdir(d)) != NULL) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>sprintf(str,\"%s/%s\",dname,de-&gt;d_name); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_lstat(str,&amp;s); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>printf(\"%s inode %d length %d mode %X \",</code></p>\r\n\r\n<p><code>str,s.st_ino,(int)s.st_size,s.st_mode); </code></p>\r\n\r\n<p><code>switch(s.st_mode &amp; S_IFMT) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>case S_IFREG: printf(\"data file\"); break; </code></p>\r\n\r\n<p><code>case S_IFDIR: printf(\"directory\"); break; </code></p>\r\n\r\n<p><code>case S_IFLNK: printf(\"symlink --&gt;\"); </code></p>\r\n\r\n<p><code>if(yaffs_readlink(str,str,100) &lt; 0) </code></p>\r\n\r\n<p><code>printf(\"no alias\"); </code></p>\r\n\r\n<p><code>else </code></p>\r\n\r\n<p><code>printf(\"\\\"%s\\\"\",str);</code></p>\r\n\r\n<p><code>break; </code></p>\r\n\r\n<p><code>default: printf(\"unknown\"); break; </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p><code>printf(\"\\n\"); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>if((s.st_mode &amp; S_IFMT) == S_IFDIR) </code></p>\r\n\r\n<p><code>dump_directory_tree_worker(str); </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_closedir(d); </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p><code>}&nbsp;</code></p>\r\n\r\n<p>&nbsp;</p>\r\n','<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>','filtered_html');
INSERT INTO `node_revision__body` VALUES ('paper',0,453,586,'und',0,'<h2>1 Background</h2>\r\n\r\n<p>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>\r\n\r\n<h2>2 Licensing</h2>\r\n\r\n<p>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 has alternative licensing arrangements to support such applications.</p>\r\n\r\n<h2>3 What are Yaffs and Yaffs Direct Interface?</h2>\r\n\r\n<p>Yaffs stands for <em>Yet Another Flash File System</em>. Yaffs was the first file system designed, from the ground up, for NAND storage.</p>\r\n\r\n<p>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>\r\n\r\n<p>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 to NAND flash for higher density and performance.</p>\r\n\r\n<p>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>\r\n\r\n<p><br />\r\nYaffs has been used for many products using various operating systems including Windows CE and various RTOSs, including ThreadX, vXworks, pSOS to name just a few.</p>\r\n\r\n<p>Note that there is a native port to eCOS that does not use YDI. This is supported and distributed by eCocCentric.(http://www.ecoscentric.com/).</p>\r\n\r\n<p>Yaffs2, a more recent release of Yaffs, supports a wider range of NAND flash components including 2k page devices, and produces equivalent or better performance. It include Yaffs1 compatibility code so Yaffs1 images still work and migration is quite simple.</p>\r\n\r\n<p>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>\r\n\r\n<h2>4 Why use Yaffs?</h2>\r\n\r\n<p>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>\r\n\r\n<p>Some features to consider:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs has been well proven and has been used to ship in large volumes in several products using many different operating systems, compilers and processors.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs is written in portable C and is endian neutral.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs provides bad<strong> </strong>block handling and ECC algorithms to handle deficiencies in NAND flash.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs is a log-structured file system which makes it very robust to corruptions caused by power failures etc.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs has highly optimised and predictable garbage collection strategies. This makes it high performance and very deterministic when compared with similar file systems.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs has a lower memory footprint than most other log-structured flash file systems.</p>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs is highly configurable to work with various flash geometries, various ECC options, caching options etc.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs can be used with a wide range of memory technologies.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h2>5 Source Code and Yaffs Resources</h2>\r\n\r\n<p>Please note the licensing terms that apply to using the Yaffs code.</p>\r\n\r\n<p><a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a> serves as the hub for all Yaffs information.</p>\r\n\r\n<p>This document refers to the Yaffs source code extensively. and is available via the download link on this site.</p>\r\n\r\n<p>There are various other documents and a Yaffs mailing list for Yaffs discussions.</p>\r\n\r\n<p>Consulting services are also available.</p>\r\n\r\n<h2>6 System Requirements</h2>\r\n\r\n<p>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>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs is endian-neutral and works fine with little-endian and big-endian processors.</p>\r\n	</li>\r\n	<li>\r\n	<p>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 should work with 16-bit CPUs too, but this is generally untested and might need some tuning, depending on compiler options.</p>\r\n	</li>\r\n	<li>\r\n	<p>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 <em>chunk</em> of NAND flash, where a <em>chunk</em> 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>\r\n	</li>\r\n</ul>\r\n\r\n<h2>7 How to integrate Yaffs with an RTOS/Embedded system</h2>\r\n\r\n<p>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 OS. Yaffs provides a set of POSIX-compliant functions for applications to use to talk to it.</p>\r\n\r\n<p>In addition to the Yaffs core file system, the YDI has three parts which are each explained in more detail in further sections:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><strong>POSIX Application Interface</strong>: This is the interface that the application code uses to access the Yaffs file system. (<em>open, close, read, write, </em>etc)</p>\r\n	</li>\r\n	<li>\r\n	<p><strong>RTOS Integration Interface</strong>: These are the functions that must be provided for Yaffs to access the RTOS system resources. (<em>initialise, lock, unlock, get time, set error</em>)</p>\r\n	</li>\r\n	<li>\r\n	<p><strong>Flash Configuration and Access Interface</strong>: These are the functions that must be provided for Yaffs to access the NAND flash. (<em>initialise, read chunk, write chunk, erase block, </em>etc). These functions might be supplied by a chipset vendor or might need to be written by the integrator.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><img alt=\"Yaffs Direct Interface Layer\" src=\"/sites/yaffs.net/files/images/Yaffs%20Direct%20Interface%20layer.gif\" /></p>\r\n\r\n<h3>7.1 Source Files</h3>\r\n\r\n<p>The following source files contain the core file system:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_allocator.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Allocates Yaffs object and tnode structures.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_checkpointrw.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Streamer for writing checkpoint data</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_ecc.c</p>\r\n			</td>\r\n			<td>\r\n			<p>ECC code</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_guts.c</p>\r\n			</td>\r\n			<td>\r\n			<p>The major Yaffs algorithms.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_nand.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Flash interfacing abstraction.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_packedtags1.c<br />\r\n			yaffs_packedtags2.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Tags packing code</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_qsort.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Qsort used during Yaffs2 scanning</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_tagscompat.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Tags compatibility code to support Yaffs1 mode.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_tagsvalidity.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Tags validity checking.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>The Yaffs direct interface is in yaffsfs.c, with the interface functions and structures defined in yaffsfd.h.</p>\r\n\r\n<p>Example and testing build files:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>dtest.c</p>\r\n			</td>\r\n			<td>\r\n			<p>A test harness. Also has sample code that can be used for better understanding of how some function calls work.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffscfg2k.c</p>\r\n			</td>\r\n			<td>\r\n			<p>A test configuration.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_fileem.c<br />\r\n			yaffs_fileem2k.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Nand flash simulation using a file as backing store.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_norif1.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Nor flash simulation and interfacing example. This is configured for M18 flash.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>yaffs_ramdisk.c<br />\r\n			yaffs_ramem2k.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Simulations using RAM.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>ynorsim.c</p>\r\n			</td>\r\n			<td>\r\n			<p>Another Nor simulation.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Further testing files are in direct/tests and direct/python.</p>\r\n\r\n<h3>7.2 Integrating the POSIX Application Interface</h3>\r\n\r\n<p>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>yaffs_</code>. For example, <code>yaffs_open(), yaffs_close()</code> etc.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>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>\r\n\r\n<p>These functions can be used directly, with the code written using these names. For example</p>\r\n\r\n<p><code>int main(...)<br />\r\n{<br />\r\n// initialisation<br />\r\nf = yaffs_open(...);<br />\r\nyaffs_read(f,...);<br />\r\nyaffs_close(f);<br />\r\n}</code></p>\r\n\r\n<p>The yaffs functions can also be wrapped in some way to allow existing code to use yaffs without modification. For example:</p>\r\n\r\n<p><code>#define open(path, oflag, mode) yaffs_open(path, oflag, mode)<br />\r\n..<br />\r\n<br />\r\nint main(...)<br />\r\n{<br />\r\n// initialisation<br />\r\nf = open(...);<br />\r\nread(f,...);<br />\r\nclose(f);<br />\r\n}</code><br />\r\n&nbsp;</p>\r\n\r\n<p>A more complex approach that can be used if more than one file-system is used is to provide redirection functions. For example:</p>\r\n\r\n<p><code>int open(const char *path,...)<br />\r\n{<br />\r\n// Determine which file system is being used if(it_is_a_yaffs_path(path))<br />\r\nreturn yaffs_open(...);<br />\r\nelse<br />\r\n{<br />\r\n// Do something else<br />\r\n}<br />\r\n}</code></p>\r\n\r\n<p>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>\r\n\r\n<h3>7.3 RTOS Integration Interface</h3>\r\n\r\n<p>Before Yaffs can be used, it needs to be integrated with the system and configured so that the correct actions are performed.</p>\r\n\r\n<p>To do this, you need to modify the configuration file. An example configuration file is presented in yaffscfg.c and yaffscfg2k.c.</p>\r\n\r\n<p>This is a relatively straight forward process and defines the RTOS access functions.</p>\r\n\r\n<p>The RTOS access functions are:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>void yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system error.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>void yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from multi-threaded access.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>void yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>__u32 yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>void yaffsfs_LocalInitialisation(void)</code>: Called to initialise RTOS context.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>If Yaffs is being used in a multi-threaded environment, then typically <code>yaffs_LocalInitialisation()</code> will initialise a suitable RTOS semaphore and <code>yaffs_Lock()</code> and <code>yaffs_Unlock()</code> will call the appropriate functions to lock and release the semaphore.</p>\r\n\r\n<p><code>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>\r\n\r\n<p>Although not shown here, Yaffs also requires memory allocation/free functions which default to <code>malloc()</code> and <code>free()</code>. These, and some other functions can be tuned in file ydirectenv.h</p>\r\n\r\n<p>Before the application code uses Yaffs, the <code>yaffs_StartUp()</code> function must be called and the appropriate partitions must be mounted. This is typically done in the system boot code:</p>\r\n\r\n<p><code>...</code></p>\r\n\r\n<p><code>/* System boot code: Start up Yaffs. */<br />\r\nyaffs_StartUp();<br />\r\nyaffs_mount(\"/boot\");</code></p>\r\n\r\n<p><code>...</code></p>\r\n\r\n<h2>8 Yaffs NAND Model</h2>\r\n\r\n<p>Before defining the flash integration interface, it is important to understand the model and corresponding nomenclature used throughout Yaffs and its documentation.</p>\r\n\r\n<p>Yaffs uses a fairly abstract model for NAND flash. This allows a lot of flexibility in the way it can be used.</p>\r\n\r\n<p>Yaffs is designed for NAND flash and makes the following assumptions and definitions:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The flash is arranged in <em><strong>blocks</strong></em>. Each block is the same size and comprises an integer number of chunks. Each block is treated as a single erasable item. A block contains a number of chunks.</p>\r\n	</li>\r\n	<li>\r\n	<p>A <em><strong>chunk</strong></em> 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>\r\n	</li>\r\n	<li>\r\n	<p>All accesses (reads and writes) are page chunk aligned. Some reads might only read the spare area where the tags are kept.</p>\r\n	</li>\r\n	<li>\r\n	<p>When programming a NAND flash, only the zero bits in the pattern being programmed are relevant, and one bits are \"don\'t care\". For example, if a byte already contains the binary pattern 1010, then programming 1001 will result in the pattern which is the logical AND of these two patterns ie. 1000. This is different to NOR flash which would typically abort the attempt to convert a 0 into a 1.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Yaffs identifies blocks by their block number and chunks by the chunk Id. A chunk Id is calculated as:</p>\r\n\r\n<p><code>chunkId = block_id * chunks_per_block + chunk_offset_in_block</code></p>\r\n\r\n<p>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>\r\n\r\n<p>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 more effort is required to interface to the NAND.</p>\r\n\r\n<h3>8.1 NAND Model considerations for Yaffs1</h3>\r\n\r\n<p>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>\r\n\r\n<p>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>\r\n\r\n<p>If the yaffs_Device\'s useNANDECC filed is not set, then yaffs will perform the ECC calculations. If this iset then yaffs will expect the NAND driver todo any required ECC checks. On devices that are not using ECC, for example NOR, set useNANDECC=1 and then don\'t do any ECC anyway.</p>\r\n\r\n<p>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>\r\n\r\n<p>The Yaffs1 model has been used in many NOR-based systems. One particularly instructive example is in yaffs_norif1.c which implements Yaffs1 mode on Intel M18 flash using 1k data pages and simulating a spare area on re-writable areas of flash. This does not use ECC but uses checksumming instead.</p>\r\n\r\n<h3>8.2 NAND Model for Yaffs2</h3>\r\n\r\n<p>Yaffs2 uses a different tags layout than Yaffs1. Yaffs2 uses a yaffs_ExtendedTags structure.which is packed according to the code in yaffs_packedtags2.c.</p>\r\n\r\n<p>The NAND handler layer must use or populate the fields. The fields have the following meaning:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>validMarker0</code> Set to 0xAAAAAAAA</p>\r\n	</li>\r\n	<li>\r\n	<p><code>chunkUsed</code> If 0 then this chunk is not in use</p>\r\n	</li>\r\n	<li>\r\n	<p><code>objectId</code> The object this chunk belongs to. If 0 then this is not part of an object (ie. unused).</p>\r\n	</li>\r\n	<li>\r\n	<p><code>chunkId</code> If 0 then this is a header, else a data chunk at the specified position in the file</p>\r\n	</li>\r\n	<li>\r\n	<p><code>byteCount</code> Number of data bytes in the chunk. Only valid for data chunks</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The following fields only have meaning when we read</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>eccResult</code> Result of ECC check when reading</p>\r\n	</li>\r\n</ul>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>blockBad</code> If 0 then the block is not bad.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The following fields have meaning for Yaffs1 and should be zero for Yaffs:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>chunkDeleted</code> if non-zero, the chunk is marked deleted.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>serialNumber</code> 2-bit serial number.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The following field has meaning for Yaffs1 and should be zero for Yaffs2:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>sequenceNumber</code> The sequence number of this block</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Optional extra info if this is an object header (Yaffs2 only). Make zero for Yaffs1.</p>\r\n\r\n<p>If <code>extraHeaderInfoAvailable</code> is set, then all the <code>extraXXX</code> fields must be valid.</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>extraHeaderInfoAvailable</code> There is extra info available if this is not zero.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraParentObjectId</code> The parent object id.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraIsShrinkHeader</code> Is it a shrink header?</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraShadows</code> Does this shadow another object?</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraObjectType</code> What object type?</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraFileLength</code> Length if it is a file.</p>\r\n	</li>\r\n	<li>\r\n	<p><code>extraEquivalentObjectId</code> Equivalent object Id if it is a hard link.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>And finally:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p><code>validMarker1</code> Must be 0x55555555.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>There are quite a few fields, some of which are optional. All the <code>extraXXXX</code> fields are a way of stuffing more data into object header tags in a way that speeds up scanning. These are optional and should all be zero if not supported.</p>\r\n\r\n<p>The easiest way to process the <code>yaffs_ExtendedTags</code> is to use the functions presented in yaffs_packedtags2.h to do the packing and unpacking. These are:</p>\r\n\r\n<p><code>yaffs_PackTags2()</code> and <code>yaffs_UnpackTags2()</code>.</p>\r\n\r\n<p>These functions create or use a packed tags structure which can be stored in the NAND spare area. An example of how to do this is presented in yaffs_fileem2.c</p>\r\n\r\n<h2>9 NAND Configuration and Access Interface</h2>\r\n\r\n<p>For an example of how to do the configuration, refer to yaffs_cfg.c and yaffs_cfg2k.c.</p>\r\n\r\n<p>This part of the configuration involves configuring the chips and suitable access functions.</p>\r\n\r\n<p>This is done in <code>yaffs_StartUp().</code></p>\r\n\r\n<p>Before launching into the device configuration, it is important to understand that Yaffs supports two different modes of operation:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs1: This is the original mode of operation and is only available for 512-byte-per-page devices.</p>\r\n	</li>\r\n	<li>\r\n	<p>Yaffs2: This mode of operation supports larger page sizes.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Most configuration options are the same for both, but they have different NAND access functions.</p>\r\n\r\n<p>You may have a system that uses a mix of Yaffs1 and Yaffs2 partitions.</p>\r\n\r\n<h3>9.1 Common configuration items (Yaffs1 and Yaffs2)</h3>\r\n\r\n<p>The configuration involves two parts:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Setting up the mount point table.</p>\r\n	</li>\r\n	<li>\r\n	<p>Setting up the devices.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>A <em>yaffsfs_DeviceConfiguration</em> is an entry that has two parts: a mount point name and a pointer to a <em>yaffs_Device</em> structure. The mount point name is used to determine where the particular <em>yaffs_Device</em> may be found in the directory structure. There can be any number of mount points and they may be nested. For example:</p>\r\n\r\n<p><code>static yaffsfs_DeviceConfiguration yaffsfs_config[] = {</code></p>\r\n\r\n<p><code>{ \"/\", &amp;ramDev},</code></p>\r\n\r\n<p><code>{ \"/flash/boot\", &amp;bootDev},</code></p>\r\n\r\n<p><code>{ \"/flash/flash\", &amp;flashDev},</code></p>\r\n\r\n<p><code>{ \"/ram2k\", &amp;ram2kDev},</code></p>\r\n\r\n<p><code>{(void *)0,(void *)0} /* Terminate list */</code></p>\r\n\r\n<p><code>};</code></p>\r\n\r\n<p>Each logical storage entity is called a <em>yaffs_Device</em> and is probably best though of as a partition descriptor. Each <em>yaffs_Device</em> can correspond to:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>A whole flash device.</p>\r\n	</li>\r\n	<li>\r\n	<p>Part of a flash device.</p>\r\n	</li>\r\n	<li>\r\n	<p>Something other than a flash device (e.g. perhaps a RAM emulation). During testing, this emulation capability is often employed to use a host system hard-disk file or nfs-mounted file as an alternative storage mechanism.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Two or more yaffs_Devices can reside in a single physical flash device by specifying different start and end blocks. For example here is a case where a single device is split into two partitions:</p>\r\n\r\n<p><code>// /boot<br />\r\n......<br />\r\nbootDev.param.startBlock = 0; // First block.<br />\r\nbootDev.param.endBlock = 55; // Last block in 2MB.<br />\r\n<br />\r\n// /disk<br />\r\n...<br />\r\ndiskDev.param.startBlock = 56; // First block after 2MB<br />\r\ndiskDev.param.endBlock = 1023; // Last block in 16MB</code></p>\r\n\r\n<p>All <em>yaffs_Device</em> structures must be configured according to the Yaffs Tuning document.</p>\r\n\r\n<h3>9.2 Common Access Functions (Yaffs1 and Yaffs2)</h3>\r\n\r\n<p>Both Yaffs1 and Yaffs2 configurations must provide pointers to the following functions:</p>\r\n\r\n<p><code>int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND)</code></p>\r\n\r\n<p>Yaffs calls this function to erase a block of flash.</p>\r\n\r\n<p><code>int (*initialiseNAND)(struct yaffs_DeviceStruct *dev)</code></p>\r\n\r\n<p>Yaffs calls this function at start up before other functions get called to access the <em>yaffs_Device</em>. This allows the system integrator a control point to perform any required initialisation (eg. set up chip selects etc.).</p>\r\n\r\n<h3>9.3 Yaffs1 Access Functions</h3>\r\n\r\n<p>For Yaffs1 partitions, the yaffs_Device configuration also specifies pointers to two further functions that Yaffs calls to access the NAND for this yaffs_Device. For a better understanding of these functions, see the section on the Yaffs NAND Model. These functions are:</p>\r\n\r\n<p><code>int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare)</code></p>\r\n\r\n<p>Yaffs calls this function to write data to NAND. The data pointer may be NULL if only the spare area is being written, as happens when the chunk is being deleted or retired. If the data pointer is NULL then do not write the data. The spare pointer will never be NULL.</p>\r\n\r\n<p><code>int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)</code></p>\r\n\r\n<p>Yaffs calls this function when reading a chunk from flash. The meanings of the arguments are obvious from the above, but note that the data and spare fields might be NULL, in which case those pointers should not be dereferenced.</p>\r\n\r\n<h3>9.4 Yaffs2 Access Functions</h3>\r\n\r\n<p>The Yaffs2 mode of operation is far more flexible than the Yaffs1 mode of operation. That allows for far more different types of flash to be used, but slightly increases the complexity of the NAND access functions.</p>\r\n\r\n<p>With the Yaffs1 mode of operation, Yaffs performs bad block detection and marking and can optionally perform ECC. It can do this because it assumes that the NAND spare area is structured in a certain way. The Yaffs2 mode of operation can no longer make those assumptions which means that the system integrator must provide slightly more complex functions. However, the interface is still relatively simple, particularly if existing code is used as a basis.</p>\r\n\r\n<p><code>int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,</code></p>\r\n\r\n<p><code>int chunkInNAND, const __u8 * data,</code></p>\r\n\r\n<p><code>const yaffs_ExtendedTags * tags)</code></p>\r\n\r\n<p><code>int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,</code></p>\r\n\r\n<p><code>int chunkInNAND, __u8 * data,</code></p>\r\n\r\n<p><code>yaffs_ExtendedTags * tags)</code></p>\r\n\r\n<p><code>int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);</code></p>\r\n\r\n<p><code>int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,</code></p>\r\n\r\n<p><code>yaffs_BlockState * state, int *sequenceNumber)</code></p>\r\n\r\n<p>The <code>writeChunkWithTagsToNAND()</code> and <code>readChunkWithTagsFromNAND()</code> functions must save or retrieve the data and extended tags. Please refer to the explanation of the Yaffs2 NAND model for a better understanding of how to handle the tags. Please note that under certain circumstances, the data and tags pointers may be NULL and the driver code should ignore transfers from or to pointers that are NULL.</p>\r\n\r\n<p>The NAND access functions must also provide a mechanism for marking and tracking bad blocks. If a bad block is detected and Yaffs decides to mark that block bad, the <code>markNANDBlockBad()</code> function is called.</p>\r\n\r\n<p>The <code>queryNANDBlock()</code> function does two things:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>It determines the block state</p>\r\n	</li>\r\n	<li>\r\n	<p>If the block is in use it also retrieves the block’s sequence number.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>By far the easiest way to understand this all is to refer to the example code provided.</p>\r\n\r\n<h2>10 Using the POSIX file system interface</h2>\r\n\r\n<p>This section is directed to readers that might not be very familiar with accessing a file system via POSIX and POSIX-like interfaces.</p>\r\n\r\n<h3>10.1 Difference to Windows POSIX-like interfaces</h3>\r\n\r\n<p>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>\r\n\r\n<ul>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n	<li>\r\n	<p>Windows names drives with a letter. POSIX has no drive letters. The whole POSIX file system is in a single directory tree.</p>\r\n	</li>\r\n	<li>\r\n	<p>Directories and “folders” are the same thing.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>10.2 Fundamental concepts</h3>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>File</p>\r\n			</td>\r\n			<td>\r\n			<p>A file is an object that is stored in the file system. yaffs supports the following file types:</p>\r\n\r\n			<p>A regular file is a sequence of bytes stored in the file system.</p>\r\n\r\n			<p>A directory holds links to other files.</p>\r\n\r\n			<p>A symbolic link holds a name to another file.</p>\r\n\r\n			<p>A special file holds device ids or similar information.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Directory</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Link</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Handle</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>File mode</p>\r\n			</td>\r\n			<td>\r\n			<p>The mode is the set of flags that define the type of file as well as the current permissions associated with the file.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Path</p>\r\n			</td>\r\n			<td>\r\n			<p>This is a string that defines the directories and file name. For example:</p>\r\n\r\n			<p>“/data/direct-1/file1”</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>File metadata</p>\r\n			</td>\r\n			<td>\r\n			<p>This is the information about the file, excluding the file contents. The metadata includes the name, mode, size and other details.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Mount,<br />\r\n			partition,<br />\r\n			file system</p>\r\n			</td>\r\n			<td>\r\n			<p>These terms all refer to a single mounted flash area. Each mount is hooked into a common directory structure.<br />\r\n			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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>inode number</p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h3>10.3 Error code</h3>\r\n\r\n<p>Most functions result in error codes if the function does not execute successfully.In these cases yaffs calls a function called <code>yaffs_SetError()</code> with the error value. This function can be configured to deliver the error into the system\'s error mechanism.</p>\r\n\r\n<p>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>\r\n\r\n<h3>10.4 Links – the hard kind (not symbolic links)</h3>\r\n\r\n<p>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>\r\n\r\n<p>The difference between links and files is subtle and can be confusing. Briefly:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>a file is the stored object in the file system</p>\r\n	</li>\r\n	<li>\r\n	<p>the link is how it is hooked into the directory structure.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The first link to a file is created by using the file creation calls: <code>yaffs_open()</code>, <code>yaffs_mknod()</code>, <code>yaffs_symlink()</code> and <code>yaffs_mkdir()</code>.</p>\r\n\r\n<p>A link can be destroyed by using the <code>yaffs_unlink()</code> function. Directories are destroyed using the <code>yaffs_rmdir()</code> function (oh, and the directory must be empty).</p>\r\n\r\n<p>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>\r\n\r\n<p>A link can be renamed by using the <code>yaffs_rename()</code> function.</p>\r\n\r\n<p>A file may have many links. These may be created using the <code>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>\r\n\r\n<p>Thus:</p>\r\n\r\n<ol>\r\n	<li>\r\n	<p>If we start with a file called “a” and then call <code>yaffs_link(“a”, “b”)</code> we now have two links to the same file. We can\'t tell them apart.</p>\r\n	</li>\r\n	<li>\r\n	<p>If we now unlink “a”, the file still exists under the link “b”.</p>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n</ol>\r\n\r\n<p>There are some limitations in how links are used:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The existing file you are linking to must exist.</p>\r\n	</li>\r\n	<li>\r\n	<p>The file you are linking to must be in the same mount (partition) as the link you are creating.</p>\r\n	</li>\r\n	<li>\r\n	<p>You cannot create a link to a directory because this would allow the creation of recursive loops.</p>\r\n	</li>\r\n	<li>\r\n	<p>The new link name must not exist.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>10.5 Symbolic links</h3>\r\n\r\n<p>Now that you understand how hard links work, we\'ll introduce symbolic (or soft) links.</p>\r\n\r\n<p>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>\r\n\r\n<p>You can remove symbolic links with the <code>yaffs_unlink()</code> function, just like hard links.</p>\r\n\r\n<p>There are, however, some important differences. A symbolic link only does its linking function when the path is being evaluated and thus:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The file you are creating an alias to does not have to exist.</p>\r\n	</li>\r\n	<li>\r\n	<p>The file you are creating an alias to does not have to be in the same mount.</p>\r\n	</li>\r\n	<li>\r\n	<p>You can create symbolic links to directories.</p>\r\n	</li>\r\n	<li>\r\n	<p>A symbolic link will not keep a file alive by itself. Only a hard link can do that.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Thus:</p>\r\n\r\n<ol>\r\n	<li>\r\n	<p>If we start with a file called “a” and then call <code>yaffs_symlink(“a”, “b”)</code> we now have one links to the file called “a” and a symbolic link aliasising from “b” to “a”.</p>\r\n	</li>\r\n	<li>\r\n	<p>If we use <code>yaffs_open(“a”)</code> or <code>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>yaffs_truncate()</code>, <code>yaffs_stat()</code> etc. The only exceptions are <code>yaffs_lstat()</code> and <code>yaffs_readlink()</code> which will treat the path as pointing to the symbolic link and not the file.</p>\r\n	</li>\r\n	<li>\r\n	<p>You can tell “a” and “b” apart by using <code>yaffs_lstat()</code>. <code>yaffs_lstat(“a”)</code> will show the information for file “a”. <code>yaffs_lstat(“b”)</code> will show the information for the symbolic link itself. Note the difference with hard links. With hard links <code>yaffs_lstat(“a”)</code> and <code>yaffs_lstat(“b”)</code> would show the same results since they are EXACTLY the same thing being referenced.</p>\r\n	</li>\r\n	<li>\r\n	<p>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>\r\n	</li>\r\n</ol>\r\n\r\n<h3>10.6 Handle-based file handling</h3>\r\n\r\n<p>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>\r\n\r\n<p>A handle is identified by an integer of value 0 or greater.</p>\r\n\r\n<p>A handle is created by using the <code>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>\r\n\r\n<p>A handle remains valid until the handle is closed by <code>yaffs_close()</code>.</p>\r\n\r\n<p>The <code>yaffs_open()</code> call takes three parameters:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>name: Full path name of the file being opened.</p>\r\n	</li>\r\n	<li>\r\n	<p>access flags: Flags being used to open this handle</p>\r\n	</li>\r\n	<li>\r\n	<p>creation mode: Mode flags used when creating a file.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>The access flags are one or more of:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_CREAT</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Create file if it does not already exist.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_EXCL</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Only use with O_CREAT. Create file if it does not exist. If the file already exists then fail.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_TRUNC</code></p>\r\n			</td>\r\n			<td>\r\n			<p>If the file exists, and opening with write access, then truncate the file to zero bytes long.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_APPEND</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Regardless of the handle position, always write to the end of the file.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_RDWR</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Open for read/write access.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>O_WRONLY</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Open for write access and no read access.</p>\r\n\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>If neither O_RDWR or O_WRONLY is set then the file will be opened for read-only access.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Where they are not mutually exclusive, these flags are typically combined. For example:</p>\r\n\r\n<p><code>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>\r\n\r\n<p><code>O_CREAT | OEXCL | O_WRONLY</code> : Create a new file, opening it for write only. Fails if file already exists.</p>\r\n\r\n<p>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>yaffs_chmod()</code>.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>S_IREAD</code></p>\r\n			</td>\r\n			<td>\r\n			<p>The file may be opened for read access.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>S_IWRITE</code></p>\r\n			</td>\r\n			<td>\r\n			<p>The file may be opened for write access.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>S_IEXEC</code></p>\r\n			</td>\r\n			<td>\r\n			<p>The file may be opened for execution. This is not enforced by yaffs.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Once you have opened a handle you can then do various operations on the file.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_close(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Close the handle. It is no longer usable.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_fsync(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Flush out any cached writes to the file, as well as the file meta-data.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_datasync(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Same as yaffs_fsync() but no file metadata.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_flush(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Same as yaffs_fsync()</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_dup(handle)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Duplicates a handle.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_lseek(handle, offset, whence)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>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>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_ftruncate(handle, size)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Change the file size. It can be made bigger or smaller. This does not change the handle read/write position.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_fstat(handle, buf)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Get file status.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_fchmod(handle, mode)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Change the file mose.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_read(handle, buffer, nbytes)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Read data from file at file pointer and update pointer.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_pread(handle, buffer, nbytes, position)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Read data from file at specified position. Does not modify file pointer</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_write(handle, buffer, nbytes)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Write data to file at file pointer and update pointer.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>yaffs_pread(handle, buffer, nbytes, position)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Write data to file at specified position. Does not modify file pointer</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h3>10.7 Changing file size</h3>\r\n\r\n<p><code>yaffs_truncate(path, newSize)</code></p>\r\n\r\n<p><code>yaffs_ftruncate(handle, newSize)</code></p>\r\n\r\n<p>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>\r\n\r\n<p>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>\r\n\r\n<p>See also <code>yaffs_lseek()</code> too. Note that <code>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>\r\n\r\n<h3>10.8 Getting/setting information about files</h3>\r\n\r\n<p><code>yaffs_chmod(path, mode)</code></p>\r\n\r\n<p><code>yaffs_fchmod(handle, mode)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_access(path,amode)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_stat(path, struct yaffs_stat *buf) </code></p>\r\n\r\n<p><code>yaffs_fstat(handle, struct yaffs_stat *buf)</code></p>\r\n\r\n<p><code>yaffs_lstat(path, struct yaffs_stat *buf)</code></p>\r\n\r\n<p><code>yaffs_readlink(path, buf, bufsize)</code></p>\r\n\r\n<p>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>\r\n\r\n<p><code>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>\r\n\r\n<p>amode is a bitmask of the following values:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><code>R_OK</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Check read is OK</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>W_OK</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Check write is OK</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>X_OK</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Check execute is OK.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><code>0 (zero)</code></p>\r\n			</td>\r\n			<td>\r\n			<p>Just checks the file exists</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>These can be combined.</p>\r\n\r\n<p>For example:</p>\r\n\r\n<p><code>if(yaffs_access(path, R_OK | W_OK) == 0)</code></p>\r\n\r\n<p><code>the file exists and can be read and written</code></p>\r\n\r\n<p><code>if(yaffs_access(path, 0) == 0)</code></p>\r\n\r\n<p><code>the file exists</code></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The stat calls retrieve a yaffs_stat structure of data which is defined in yaffsfs.h. There are three versions:</p>\r\n\r\n<p><code>yaffs_fstat</code>: Takes a handle.</p>\r\n\r\n<p><code>yaffs_stat</code>: Takes a path name and follows symbolic links.</p>\r\n\r\n<p><code>yaffs_lstat</code>: Takes a path but does not follow symbolic links.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>Thus, if path is a symbolic link, <code>yaffs_fstat() </code>will give information on the file that the link points to while <code>yaffs_lstat()</code> will give information about the link itself.</p>\r\n\r\n<p><code>yaffs_readlink()</code> will read the read the link value into the buffer provided. For example:</p>\r\n\r\n<p><code>yaffs_symlink(“target”,”/link”); /* create a link called link to target */</code></p>\r\n\r\n<p><code>yaffs_readlink(“/link”,buffer,10); /* now buffer contains “target” */</code></p>\r\n\r\n<h3>10.9 Changing the directory structure and names</h3>\r\n\r\n<p><code>yaffs_open(path, flags, mode)</code></p>\r\n\r\n<p><code>yaffs_mkdir(path, mode)</code></p>\r\n\r\n<p><code>yaffs_symlink(targetPath, linkPath)</code></p>\r\n\r\n<p><code>yaffs_mknod(pathname, mode, dev)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_link(existingPath, newath)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_unlink(path)</code></p>\r\n\r\n<p><code>yaffs_rmdir(path)</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_rename(oldPath, newPath)</code></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>Files of various types, and their first link, are created via the <code>yaffs_open()</code><code>,</code> <code>yaffs_mkdir()</code>, <code>yaffs_symlink()</code> and <code>yaffs_mknod()</code> functions.</p>\r\n\r\n<p><code>yaffs_link()</code> can be used to create subsequent links to files. Note that you cannot create a link to a directory.</p>\r\n\r\n<p><code>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>\r\n\r\n<h3>10.10 Searching directories</h3>\r\n\r\n<p><code>yaffs_DIR *yaffs_opendir(const YCHAR *dirname) ; </code></p>\r\n\r\n<p><code>struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ; </code></p>\r\n\r\n<p><code>void yaffs_rewinddir(yaffs_DIR *dirp) ; </code></p>\r\n\r\n<p><code>int yaffs_closedir(yaffs_DIR *dirp) ;</code></p>\r\n\r\n<p>Searching is performed by the following sequence of operations:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Open the directory for reading with <code>yaffs_opendir()</code>.</p>\r\n	</li>\r\n	<li>\r\n	<p>Iterate through the entries in the directory using <code>yaffs_readdir()</code>. Each read will advance the directory read position.</p>\r\n	</li>\r\n	<li>\r\n	<p>You can reset to the start of the directory with <code>yaffs_rewinddir()</code>.</p>\r\n	</li>\r\n	<li>\r\n	<p>Close the directory when finished with <code>yaffs_closedir()</code>.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>10.11 Mount control</h3>\r\n\r\n<p><code>yaffs_mount(path) ; </code></p>\r\n\r\n<p><code>yaffs_mount2(path, readOnly); </code></p>\r\n\r\n<p><code>yaffs_unmount(path);</code></p>\r\n\r\n<p><code>yaffs_unmount2(path, int force); </code></p>\r\n\r\n<p><code>yaffs_remount(path, force, readOnly);</code></p>\r\n\r\n<p><code>yaffs_sync(path) ;</code></p>\r\n\r\n<p>A partition must be mounted to be accessed. <code>yaffs_mount()</code> will mount the partition for read/write access. <code>yaffs_mount2()</code> can be used to control whether the access is read/write or read only.</p>\r\n\r\n<p>A partition can be unmounted to remove it from use. <code>yaffs_unmount()</code> will fail if any files are in use whereas <code>yaffs_unmount2()</code> allows you to force the unmount even if files are open.</p>\r\n\r\n<p><code>yaffs_remount()</code> can be used to change the access to a currently mounted partition and is equivalent to making an <code>unmount2()</code> call followed by a <code>mount2()</code> call.</p>\r\n\r\n<p><code>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>\r\n\r\n<h3>10.12 Other</h3>\r\n\r\n<p><code>yaffs_freespace(path); </code></p>\r\n\r\n<p><code>yaffs_totalspace(path); </code></p>\r\n\r\n<p><code>yaffs_inodecount(path);</code></p>\r\n\r\n<p>These functions provide information on the free and total space (in bytes) for the mount that the path addresses.</p>\r\n\r\n<p><code>yaffs_inodecount()</code> returns the number of files on the mount that the path addresses.</p>\r\n\r\n<h3>11 Example: yaffs_readdir() and yaffs_stat()</h3>\r\n\r\n<p>This code snippet illustrates using <code>yaffs_readdir()</code> and associated functions to iterate through a directory. It also shows how to use <code>yaffs_lstat() </code>to get information on a file and interpret it.</p>\r\n\r\n<p><code>void dump_directory(const char *dname) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>yaffs_DIR *d; </code></p>\r\n\r\n<p><code>yaffs_dirent *de; </code></p>\r\n\r\n<p><code>struct yaffs_stat s; </code></p>\r\n\r\n<p><code>char str[100]; </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>d = yaffs_opendir(dname); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>if(!d) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>printf(\"opendir failed\\n\"); </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p><code>else </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>while((de = yaffs_readdir(d)) != NULL) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>sprintf(str,\"%s/%s\",dname,de-&gt;d_name); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_lstat(str,&amp;s); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>printf(\"%s inode %d length %d mode %X \",</code></p>\r\n\r\n<p><code>str,s.st_ino,(int)s.st_size,s.st_mode); </code></p>\r\n\r\n<p><code>switch(s.st_mode &amp; S_IFMT) </code></p>\r\n\r\n<p><code>{ </code></p>\r\n\r\n<p><code>case S_IFREG: printf(\"data file\"); break; </code></p>\r\n\r\n<p><code>case S_IFDIR: printf(\"directory\"); break; </code></p>\r\n\r\n<p><code>case S_IFLNK: printf(\"symlink --&gt;\"); </code></p>\r\n\r\n<p><code>if(yaffs_readlink(str,str,100) &lt; 0) </code></p>\r\n\r\n<p><code>printf(\"no alias\"); </code></p>\r\n\r\n<p><code>else </code></p>\r\n\r\n<p><code>printf(\"\\\"%s\\\"\",str);</code></p>\r\n\r\n<p><code>break; </code></p>\r\n\r\n<p><code>default: printf(\"unknown\"); break; </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p><code>printf(\"\\n\"); </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>if((s.st_mode &amp; S_IFMT) == S_IFDIR) </code></p>\r\n\r\n<p><code>dump_directory_tree_worker(str); </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>yaffs_closedir(d); </code></p>\r\n\r\n<p><code>} </code></p>\r\n\r\n<p><code>}&nbsp;</code></p>\r\n\r\n<p>&nbsp;</p>\r\n','<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>','full_html'),('paper',0,453,606,'und',0,'	<p class=\"western\" align=\"justify\">This document describes the Yaffs\r\n	Direct Interface (YDI),  which allows Yaffs to be simply integrated\r\n	with embedded systems, with or without an RTOS.</p>\r\n\r\n<p class=\"western\" style=\"page-break-before: always\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">1 Background</h1>\r\n<p class=\"western\">The purpose of this document is to describe the\r\ninterfacing of the Yaffs Direct Interface (YDI) as well as to provide\r\nsufficient information to allow a preliminary evaluation of Yaffs.\r\nThis document tries to focus on the issues important to the system\r\nintegrator without getting too detailed about how Yaffs works. Other\r\ndocuments provide an in-depth discussion of how Yaffs works.</p>\r\n<h1 class=\"western\">2 Licensing</h1>\r\n<p class=\"western\">Yaffs was originally released for Linux under the\r\nGNU Public License (GPL). Various embedded developers soon identified\r\nthat Yaffs would be ideal for their applications, but were not able\r\nto use GPL based code in their systems. Aleph One <span style=\"font-style: normal\"><span style=\"font-weight: normal\">has</span></span>\r\nalternative licensing arrangements to support such applications.</p>\r\n<h1 class=\"western\">3 What are Yaffs and Yaffs Direct Interface?</h1>\r\n<p class=\"western\">Yaffs stands for <i>Yet Another Flash File System</i>.\r\nYaffs was the first file system designed, from the ground up, for\r\nNAND storage.</p>\r\n<p class=\"western\">In 2002 Aleph One set out to identify file system\r\noptions for using NAND Flash as a file system. Various file systems\r\navailable at the time were evaluated and all were found lacking in\r\none way or another. The need for a suitable NAND storage file system\r\nwas identified and Yaffs was designed to fill that need.</p>\r\n<p class=\"western\">Although Yaffs was originally designed for NAND\r\nflash, it has been used successfully with NOR flash systems and even\r\nas a RAM file system. This allows high reliability file systems to be\r\nconstructed using NOR flash, with a future migration path <span style=\"font-weight: normal\">to\r\nNAND</span> flash for higher density and performance.</p>\r\n<p class=\"western\">Yaffs was originally designed for use with the\r\nLinux operating system, but was designed in a very modular way. The\r\noperating-system-specific code was kept separate from the main Yaffs\r\nfile system code. This allows Yaffs to be ported quite cleanly to\r\nother operating systems through operating system personality modules.\r\nOne such personality module is the Yaffs Direct Interface (YDI) which\r\nallows Yaffs to be simply integrated with embedded systems, with or\r\nwithout an RTOS. \r\n</p>\r\n<p class=\"western\">Yaffs has been used for many products using\r\nvarious operating systems including Windows CE and various RTOSs,\r\nincluding <span style=\"font-weight: normal\">ThreadX, vXworks, pSOS to\r\nname just a few.</span></p>\r\n<p class=\"western\">Note that there is a native port of Yaffs to eCOS\r\nthat does not use YDI. This is supported and distributed by\r\neCocCentric.(http://www.ecoscentric.com/).</p>\r\n<p class=\"western\">Yaffs2, a more recent release of Yaffs, supports a\r\nwider range of NAND flash components including 2k page devices and\r\ndevices with multi-level cells (MLC), and produces equivalent or\r\nbetter performance. It include Yaffs1 compatibility code so Yaffs1\r\nimages still work and migration is quite simple. Yaffs1 or Yaffs2\r\nmode of operation are simply selected by a run-time parameter.</p>\r\n<p class=\"western\">As well as providing a NAND file system, YDI also\r\nprovides a RAM emulation layer to allow Yaffs to operate as a RAM\r\nfile system too. While the RAM emulation is perhaps not as efficient\r\nas a dedicated RAM file system, this does allow one well proven file\r\nsystem to use both RAM and flash.</p>\r\n<h1 class=\"western\">4 Why use Yaffs?</h1>\r\n<p class=\"western\">Yaffs is the first, and perhaps only, file system\r\ndesigned specifically for NAND flash. This means that Yaffs has been\r\ndesigned to work around the various limitations and quirks of NAND\r\nflash, as well as exploit the various features of NAND to achieve an\r\neffective file system.</p>\r\n<p class=\"western\">Some features to consider:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Yaffs has been well proven and has been\r\n	used to ship in <span style=\"font-weight: normal\">large volumes in\r\n	several products using many different operating systems, compilers\r\n	and processors.</span></p>\r\n	<li/>\r\n<p class=\"western\">Yaffs is written in portable C and is\r\n	endian neutral.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs provides <span style=\"font-weight: normal\">bad</span><b>\r\n	</b><span style=\"font-weight: normal\">block</span> handling and ECC\r\n	algorithms to handle deficiencies in NAND flash.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs is a log-structured file system which\r\n	makes it very robust to corruptions caused by power failures etc.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs has highly optimised and predictable\r\n	garbage collection strategies. This makes it high performance and\r\n	very deterministic when compared with similar file systems.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs has a lower memory footprint than\r\n	most other log-structured flash file systems.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs provides a wide range of POSIX-style\r\n	file system support including directories, symbolic and hard links\r\n	etc. through standard file system interface calls.</p>\r\n	<li/>\r\n<p class=\"western\"><span style=\"font-weight: normal\">Yaffs is\r\n	h</span>ighly configurable to work with various flash geometries,\r\n	various ECC options, caching options etc.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs Direct Interface is simple to\r\n	integrate in a system – only a few interface functions are\r\n	required.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs can be used with a wide range of\r\n	memory technologies.</p>\r\n</ul>\r\n<h1 class=\"western\">5 Source Code and Yaffs Resources \r\n</h1>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Please note\r\nthe licensing terms that apply to using the Yaffs code.</font></p>\r\n<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\">\r\nserves as the hub for all Yaffs information.</span></span></font></p>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">This document\r\nrefers to the Yaffs source code extensively.<span style=\"font-style: normal\"><span style=\"font-weight: normal\">\r\nand is available via the download link on this site.</span></span></font></p>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">There are\r\nvarious other documents and a Yaffs mailing list for Yaffs\r\ndiscussions.</font></p>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Consulting\r\nservices are also available.</font></p>\r\n<h1 class=\"western\">6 System Requirements</h1>\r\n<p class=\"western\">Determining minimum system requirements is often\r\nquite difficult. The following are presented as a guideline only.\r\nContact Aleph One for more detailed analysis if required.</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Yaffs is endian-neutral and works fine with\r\n	little-endian and big-endian processors.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs code has been used successfully with\r\n	many different 32-bit and 64-bit CPUs including MIPS, 68000, ARM,\r\n	ColdFire, PowerPC and x86 variants. Yaffs has even been used with\r\n	various DSP architectures. Yaffs should work with 16-bit CPUs too,\r\n	but this is generally untested and might need some tuning, depending\r\n	on compiler options.</p>\r\n	<li/>\r\n<p class=\"western\">Because Yaffs is log structured, RAM is\r\n	required to build up runtime data structures for acceptable\r\n	performance. As a rule of thumb, budget approximately 2 bytes per\r\n	<i>chunk</i> of NAND flash, where a <i>chunk</i> is typically one\r\n	page of NAND. For NAND with 512byte pages, budget approximately\r\n	4kbytes of RAM per 1Mbyte of NAND. For 2kbyte page devices budget\r\n	approximately 1kbyte per 1Mbyte of NAND.</p>\r\n</ul>\r\n<h1 class=\"western\">7 How to integrate Yaffs with an RTOS/Embedded\r\nsystem</h1>\r\n<p class=\"western\" align=\"justify\">Yaffs Direct Interface (YDI) wraps\r\nYaffs in a way that is simple to integrate. You need to provide a few\r\nfunctions for Yaffs to use to talk to your hardware and RTOS. Yaffs\r\nprovides a set of POSIX-compliant functions for applications to use\r\nto talk to it.</p>\r\n<p class=\"western\">In addition to the Yaffs core file system, the YDI\r\nhas three parts which are each explained in more detail in further\r\nsections:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><b>POSIX Application Interface</b>: This is\r\n	the POSIX-like interface that the application code uses to access\r\n	the Yaffs file system. (<font face=\"Times New Roman\"><i>open, close,\r\n	read, write, </i></font>etc) \r\n	</p>\r\n	<li/>\r\n<p class=\"western\"><b>RTOS Integration Interface</b>: These\r\n	are the functions that must be provided for Yaffs to access the RTOS\r\n	system resources. (<font face=\"Times New Roman\"><i>initialise, lock,\r\n	unlock, get time, </i></font><font face=\"Times New Roman\"><i>memory\r\n	allocation,</i></font><font face=\"Times New Roman\"><i> set error,\r\n	</i></font><font face=\"Times New Roman\"><i>etc</i></font>). Note\r\n	that although we use the term RTOS, the same can be done with other\r\n	OSs or even with no RTOS at all in a bare-metal system.</p>\r\n	<li/>\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 27864 characters]\" name=\"Object1\" align=\"left\" width=\"485\" height=\"530\"/>\r\n<b>Flash\r\n	Device </b><b>Interface</b>: This interface support is where the\r\n	flash device and appropriate device drivers are installed to provide\r\n	an access path from Yaffs to the flash device(s). Multiple different\r\n	devices and device types can be supported simultaneously.</p>\r\n</ul>\r\n<h2 class=\"western\">7.1 Source Files</h2>\r\n<p class=\"western\">The following source files contain the core file\r\nsystem:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"71*\">\r\n	<col width=\"185*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_allocator.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Allocates Yaffs object and tnode structures.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_bitmap.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Block and chunk bitmap handling code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_checkpointrw.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Streamer for writing checkpoint data</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_ecc.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">1-bit Hamming ECC code</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_guts.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">The major Yaffs algorithms.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_nameval.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Name/value code for handling extended\r\n			attributes (xattr).</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_nand.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Flash interfacing abstraction.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_packedtags1.c<br/>\r\nyaffs_packedtags2.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Tags packing code</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_summary.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Code for handling block summaries.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_tagscompat.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Tags compatibility code to support Yaffs1 mode.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_tagsmarshall.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Tags marshalling code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_verify.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Test verification code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_yaffs1.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Yaffs1-mode specific code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_yaffs2.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Yaffs2-mode specific code.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The Yaffs direct interface is in yaffsfs.c, with\r\nthe interface functions and structures defined in yaffsfd.h.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"72*\">\r\n	<col width=\"184*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_attribs.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Attribute handling.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_error.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Error reporting code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">yaffsfs.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Yaffs Direct Interface wrapper\r\n			code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">yaffs_hweight.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Counts the number of hot bits\r\n			in a byte, word etc.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_qsort.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Qsort used during Yaffs2 scanning</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Example flash drivers, simulators and\r\nconfigurations used for testing are are in direct/test-framework\r\ndirectory. These include:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"72*\">\r\n	<col width=\"184*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">nanddrv.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A NAND driver layer that\r\n			performs the commands to access NAND flash in a rudimentary\r\n			manner. This code should work on many styles of CPU with little\r\n			modification.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">yaffs_nanddrv.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">A wrapper around the NAND\r\n			driver which plugs it into Yaffs.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">nandsim.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">A NAND simulator layer that\r\n			works with a nandstore_xxx backing store. This simulates a NAND\r\n			chip.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">nandstore_file.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">A storage backend for a NAND\r\n			simulator that stores the data to file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">nandsim_file.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">A wrapper around nandsim.c and\r\n			nandstore_file.c which makes a NAND simulator  that saves its data\r\n			in a file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">yaffs_nandsim_file.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">A wrapper which creates a nand\r\n			simulator  instance, hooks up the yaffs NAND driver and then adds\r\n			it to yaffs for use.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">yaffs_nor_drv.c</p>\r\n		</td>\r\n		<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\">\r\n			<ol>\r\n				<p class=\"western\" align=\"justify\">A driver for CFI-style NOR\r\n				flash.</p>\r\n			</ol>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">yaffs_m18_drv.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">A driver for Intel M18-style\r\n			NOR flash.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">yaffs_osglue.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">An OS glue layer example used\r\n			in the test harness.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Example and testing build files:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"71*\">\r\n	<col width=\"185*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">dtest.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">A test harness. Also has sample code that can\r\n			be used for better understanding of how some function calls work.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffscfg2k.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">A test configuration.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">yaffs_fileem.c<br/>\r\nyaffs_fileem2k.c</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Nand flash simulation using a file as backing\r\n			store.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Further testing files are in direct/tests and\r\ndirect/python.</p>\r\n<h2 class=\"western\" style=\"page-break-before: always\">7.2 Integrating\r\nthe POSIX Application Interface</h2>\r\n<p class=\"western\">The application interface is defined in yaffsfs.h.\r\nThese provide a POSIX file system interface. For the most part, this\r\ninterface consists of the standard clib function names prefixed with\r\n<code class=\"western\">yaffs_</code>. For example, <code class=\"western\">yaffs_open(),\r\nyaffs_close()</code> etc.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">There is a lot of flexibility in how these\r\nfunctions are used and the system integrator needs to determine the\r\nbest strategy for the system.</p>\r\n<p class=\"western\">These functions can be used directly, with the\r\ncode written using these names. For example</p>\r\n<p class=\"code-western\"><code class=\"western\">int main(...)<br/>\r\n{<br/>\r\n\r\n  // initialisation<br/>\r\n    f = yaffs_open(...);<br/>\r\n   \r\nyaffs_read(f,...);<br/>\r\n    yaffs_close(f);<br/>\r\n}</code></p>\r\n<p class=\"western\">The <font face=\"Times New Roman\">yaffs</font>\r\nfunctions can also be wrapped in some way to allow existing code to\r\nuse yaffs without modification. For example:</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">#define open(path,\r\noflag, mode)  yaffs_open(path, oflag, mode)<br/>\r\n..<br/>\r\n<br/>\r\nint\r\nmain(...)<br/>\r\n{<br/>\r\n   // initialisation<br/>\r\n    f = open(...);<br/>\r\n\r\n   read(f,...);<br/>\r\n    close(f);<br/>\r\n}</code><br/>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">A more complex approach that can be used if more\r\nthan one file-system is used is to provide redirection functions. For\r\nexample:</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">int open(const char\r\n*path,...)<br/>\r\n{<br/>\r\n    // Determine which file system is being\r\nused<br/>\r\n    </code><code class=\"western\">i</code><code class=\"western\">f(it_is_a_yaffs_path(path))<br/>\r\n\r\n       return yaffs_open(...);<br/>\r\n    else {<br/>\r\n        // Do\r\nsomething else<br/>\r\n    }<br/>\r\n}</code></p>\r\n<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\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Some RTOS\'s provide a flexible way to integrate\r\nfile systems in which case YDI can typically use these interfaces to\r\naccess yaffs file systems.</p>\r\n\r\n<h1 class=\"western\" style=\"page-break-before: always\">8 RTOS\r\nIntegration Interface</h1>\r\n<p class=\"western\">Before Yaffs can be used, it needs to be\r\nintegrated with the system and configured so that the correct actions\r\nare performed.</p>\r\n<p class=\"western\">To do this, you need to modify the configuration\r\nfile. An example configuration file is presented in <font face=\"Bitstream Vera Sans\"><font face=\"Times New Roman\">yaffscfg.c\r\nand yaffscfg2k.c.</font></font></p>\r\n<p class=\"western\">This is a relatively straight forward process and\r\ndefines the RTOS access functions.</p>\r\n<p class=\"western\">The RTOS access functions are:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system\r\n	error.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from\r\n	multi-threaded access.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">u32\r\n	yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>void\r\n	*yaffsfs_malloc(size_t size)</b></font></font>: Called to allocate\r\n	memory.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>void\r\n	yaffsfs_free(void *ptr)</b></font></font>: Called to free memory.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_</code><code class=\"western\">OS</code><code class=\"western\">Initialisation(void)</code>:\r\n	Called to initialise RTOS context.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>void\r\n	yaffs_bug_fn(const char *file_name, int line_no)</b></font></font>:\r\n	Function to report a bug.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>int\r\n	yaffsfs_CheckMemRegion(const void *addr, size_t size, int\r\n	writ</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>e_request</b></font></font>)\r\n	: Function to check if accesses to a memory region is valid. This\r\n	function must return zero if the test passes and negative if it\r\n	fails.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">If Yaffs is being used in a multi-threaded\r\nenvironment, then typically <code class=\"western\">yaffs_LocalInitialisation()</code>\r\nwill initialise a suitable RTOS semaphore and <code class=\"western\">yaffs_Lock()</code>\r\nand <code class=\"western\">yaffs_Unlock()</code> will call the\r\nappropriate functions to lock and release the semaphore.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_CurrentTime()</code>\r\ncan be any time increment of use to the system. If this is not\r\nrequired, then it is fine to just use a function that is hard-wired\r\nto return zero.</p>\r\n<p class=\"western\">Before the application code uses Yaffs, the\r\n<code class=\"western\">yaffs</code><code class=\"western\">fs</code><code class=\"western\">_</code><code class=\"western\">OSInitialisation</code><code class=\"western\">()</code>\r\nfunction must be called.</p>\r\n<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\">\r\nis used to check addresses passed to the various yaffs_xxx functions\r\n(yaffs_open(), yaffs_read() etc)). If the function returns -1, then\r\nthe yaffs_xxx function will return -EFAULT rather than attempt to\r\ndereference the address and crash.</span></font></font></p>\r\n<p class=\"western\" style=\"font-weight: normal\"><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\">An\r\n implementation might do something like:</font></font></p>\r\n<p class=\"western\" style=\"font-weight: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>int\r\nyaffsfs_CheckMemRegion(const void addr, size_t size, <br/>\r\n          \r\n       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>)\r\n<br/>\r\n  {<br/>\r\n      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>\r\n= (u32) addr;<br/>\r\n      </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>u32\r\nuaddrt = uaddrb + size -1;<br/>\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n     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>\r\n&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>\r\n&lt;= stack_top &amp;&amp;<br/>\r\n          </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>uaddrt\r\n&gt;= stack_bottom &amp;&amp; uaddrt &lt;= stack_top)<br/>\r\n         \r\nreturn 0; /* </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>r/w\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>access\r\nis OK */<br/>\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n     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>\r\n&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\r\n&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>\r\n&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\r\n&amp;&amp;<br/>\r\n          </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>uaddrt\r\n&gt;= heap_bottom &amp;&amp; uaddrt &lt;= heap_top)<br/>\r\n         \r\nreturn 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>\r\naccess is OK /<br/>\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n     if( !</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>write_request\r\n&amp;&amp;<br/>\r\n          </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>\r\n&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\r\n&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>\r\n&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\r\n&amp;&amp;<br/>\r\n          </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>uaddrt\r\n&gt;= rom_bottom &amp;&amp; uaddrt &lt;= rom_top)<br/>\r\n         \r\nreturn 0; / </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>read\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>access\r\nis OK /</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n<br/>\r\n\r\n     </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>return\r\n-1; /* Bad access */</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n<br/>\r\n}</b></font></font></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">9 Yaffs NAND\r\nModel</h1>\r\n<p class=\"western\">Before defining the flash integration interface,\r\nit is important to understand the model and corresponding\r\nnomenclature used throughout Yaffs and its documentation.</p>\r\n<p class=\"western\">Yaffs uses a fairly abstract model for NAND flash.\r\nThis allows a lot of flexibility in the way it can be used.</p>\r\n<p class=\"western\">Yaffs is designed for NAND flash and makes the\r\nfollowing assumptions and definitions:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The flash is arranged in <i><b>blocks</b></i>.\r\n	Each block is the same size and comprises an integer number of\r\n	<span style=\"font-style: normal\"><span style=\"font-weight: normal\">chunks</span></span>.\r\n	Each block is treated as a single erasable item. A block contains a\r\n	number of chunks.</p>\r\n	<li/>\r\n<p class=\"western\">A <i><b>chunk</b></i> equates to the\r\n	allocation units of flash. For Yaffs1, each chunk equates to a\r\n	512-byte or larger NAND page (that is, a 512-byte or larger data\r\n	portion and a 16-byte spare area). For Yaffs2, a chunk will\r\n	typically be larger (eg. on 2k page devices, a chunk will typically\r\n	be a single 2k page: 2kbytes of data and 64 bytes of spare). Yaffs2\r\n	is capable of working with smaller chunk sizes by using inband tags.</p>\r\n	<li/>\r\n<p class=\"western\">All accesses (reads and writes) are page\r\n	chunk aligned. Some reads might only read the spare area where the\r\n	tags are kept.</p>\r\n	<li/>\r\n<p class=\"western\">When programming a NAND flash, only the\r\n	zero bits in the pattern being programmed are relevant, and one bits\r\n	are &quot;don\'t care&quot;. For example, if a byte already contains\r\n	the binary pattern b1010, then programming b1001 will result in the\r\n	pattern which is the logical AND of these two patterns ie. b1000.\r\n	This is different to NOR flash which would typically abort the\r\n	attempt to convert a 0 into a 1.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Yaffs ide<span style=\"font-weight: normal\">ntifies</span>\r\nblocks by their block number and chunks by the chunk Id. A chunk Id\r\nis calculated as:</p>\r\n<p class=\"western\"><code class=\"western\">chunkId = block_id *\r\nchunks_per_block + chunk_offset_in_block</code></p>\r\n<p class=\"western\">Yaffs treats a blank (0xFF filled) block as being\r\nfree or erased. Thus, the equivalent of formatting for a Yaffs\r\npartition is to erase all the blocks that are not bad.</p>\r\n<p class=\"western\">Yaffs2 has a generalised tags interface to provide\r\nbetter flexibility to cater for a wider range of devices with larger\r\npages and stricter programming limitations. Yaffs2 thus handles more\r\nabstract constructs than Yaffs1 and, in older versions of Yaffs, more\r\neffort was required to interface to the NAND.</p>\r\n<p class=\"western\">In newer versions of Yaffs, the tags management\r\nhas been abstracted out of the driver. This makes the driver\r\ninterface far simpler.</p>\r\n<h2 class=\"western\">9.1 Formatting</h2>\r\n<p class=\"western\">Yaffs treats erased blocks as empty. That makes it\r\nreally easy to “format” a device: just erase it.. Note that this\r\nshould be done while the partition is not mounted.</p>\r\n<p class=\"western\">Unmounting will not normally work when the file\r\nsystem is busy (eg. files are open), Some extra non-standard unmount\r\noptions are provided to enable an unmount to be forced. Note that\r\nusing these will break any current handles and you will no longer be\r\nable to use open files.</p>\r\n<p class=\"western\"><code class=\"western\"><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\"><span style=\"font-weight: normal\">There\r\nis a </span></font></font></code><code class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>yaffs_format()\r\n</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\r\nthat will take care of the details.</span></font></font></code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">9.2 NAND Model considerations for Yaffs1</h2>\r\n<p class=\"western\">The historical Yaffs1 tags structure was laid out\r\nin accordance with the SmartMedia specification for use with 512-byte\r\npages. There is now much more flexibility in the way things can be\r\nconfigured.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Yaffs1 is capable of being used with a variety of\r\nmemory layouts so long as the flash supports the ability to overwrite\r\nthe tags area to set the deletion marker to zero.</p>\r\n<p class=\"western\">If the yaffs_dev\'s use_nand_ecc field is not set,\r\nthen yaffs will perform the ECC calculations. If this is set then\r\nyaffs will expect the NAND driver to do any required ECC checks. On\r\ndevices that are not using ECC, for example NOR, set use_nand_ecc=1\r\nand then don\'t do any ECC anyway.</p>\r\n<p class=\"western\">The Yaffs1 flash model expects an area of 16 spare\r\nbytes, some of which are used for tags. The mapping between the spare\r\nbytes and the usage of the bytes is specified in yaffs_packedtags1.c</p>\r\n<p class=\"western\">The Yaffs1 model has been used in many NOR-based\r\nsystems. One particularly instructive example is in yaffs_nor_drv.c\r\nwhich implements a driver for Yaffs1 mode on CFI-style NOR flash.\r\nThis does not use ECC but uses checksumming instead.</p>\r\n<p class=\"western\">The yaffs_dev structure has a yaffs_driver\r\nstructure which holds the function pointers to the driver. For Yaffs1\r\nmode of operations the following are required:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"77*\">\r\n	<col width=\"179*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_write_chunk_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Write a data chunk</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_read_chunk_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Read a data chunk.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_erase_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Erase a block</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_initialise_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Initialisation.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_deinitialise_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">De-initialise</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">These functions are described later.</p>\r\n<h2 class=\"western\">9.3 NAND Model for Yaffs2</h2>\r\n<p class=\"western\">The Yaffs2 interface is far more flexible than\r\nYaffs1, but that means a bit more effort must be done in the driver.\r\nIn particular:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">There is is no standard spare area/ECC\r\n	layout. The driver must handle all the layout of the spare area and\r\n	ECC handling.</p>\r\n	<li/>\r\n<p class=\"western\">There is not a standard implementation for\r\n	bad block markers. Thus, the driver must provide functions for\r\n	checking and marking bad blocks.</p>\r\n</ul>\r\n<p class=\"western\">The yaffs_driver structure for Yaffs2 mode\r\nrequires the following functions:</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\">\r\n<br/>\r\n\r\n</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"77*\">\r\n	<col width=\"179*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_write_chunk_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Write a data chunk</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_read_chunk_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Read a data chunk.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_erase_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Erase a block</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_mark_bad_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Mark a block bad</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_check_bad_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Check bad block status of a\r\n			block.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_initialise_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">Initialisation.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">drv_deinitialise_fn</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\" align=\"justify\">De-initialise</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">9.4 Overview of flash driver function</h2>\r\n<p class=\"western\">The best way to understand how to write these\r\nfunctions is to look at the example drivers.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_write_chunk_fn) (struct yaffs_dev\r\n*dev, int nand_chunk, \r\n</p>\r\n<p class=\"code-western\">                            const u8 *data,\r\nint data_len, \r\n</p>\r\n<p class=\"code-western\">                            const u8 *oob,\r\nint oob_len)</p>\r\n<p class=\"western\">This function writes the specified chunk data and\r\noob/spare data to flash.</p>\r\n<p class=\"western\">This function should return YAFFS_OK on success or\r\nYAFFS_FAIL on failure.</p>\r\n<p class=\"western\">If this is a Yaffs2 device, or Yaffs1 with\r\nuse_nand_ecc set, then this function must take care of any ECC that\r\nis required.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_read_chunk_fn) (struct yaffs_dev\r\n*dev, int nand_chunk, \r\n</p>\r\n<p class=\"code-western\">                           u8 *data, int\r\ndata_len, \r\n</p>\r\n<p class=\"code-western\">                           u8 *oob, int\r\noob_len,</p>\r\n<p class=\"code-western\">                           enum\r\nyaffs_ecc_result *ecc_result)</p>\r\n<p class=\"western\">This function reads the specified chunk data and\r\noob/spare data from flash.</p>\r\n<p class=\"western\">This function should return YAFFS_OK on success or\r\nYAFFS_FAIL on failure.</p>\r\n<p class=\"western\">If this is a Yaffs2 device, or Yaffs1 with\r\nuse_nand_ecc set, then this function must take care of any ECC that\r\nis required and set the ecc_result.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_erase_fn) (struct yaffs_dev *dev,\r\nint block_no) \r\n</p>\r\n<p class=\"western\">This function erases the specified block.</p>\r\n<p class=\"western\">This function should return YAFFS_OK on success or\r\nYAFFS_FAIL on failure.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_mark_bad_fn) (struct yaffs_dev\r\n*dev, int block_no); \r\n</p>\r\n<p class=\"code-western\">int (*drv_check_bad_fn) (struct yaffs_dev\r\n*dev, int block_no); \r\n</p>\r\n<p class=\"western\">These functions are only required for Yaffs2 mode.\r\nThey mark a block bad or check if it is bad.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_initialise_fn) (struct yaffs_dev\r\n*dev); \r\n</p>\r\n<p class=\"code-western\">int (*drv_deinitialise_fn) (struct yaffs_dev\r\n*dev); \r\n</p>\r\n<p class=\"western\">These functions provide hooks for initialising or\r\ndeinitialising the flash driver.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">10 Configuration\r\nand flash driver installation</h1>\r\n<p class=\"western\">For an example of how to do the configuration,\r\nrefer to yaffs_cfg2k.c and one of the drivers such as\r\nyaffs_nand_drv.c</p>\r\n<p class=\"western\">The old mechanism was static and required a table\r\nof devices that was installed at start up.  This mechanism had\r\nshortcomings – in particular it broke modularity and did not allow\r\ndevices to be added dynamically.</p>\r\n<p class=\"western\">Things are different now. As any time, a yaffs_dev\r\nstructure can be configured and then registered with Yaffs by using\r\nthe yaffs_add_device() function.</p>\r\n<p class=\"western\">A yaffs_dev structure has two parts which must be\r\nconfigured before yaffs_add_device() is called: the paramers\r\n(dev-&gt;param) and the driver (dev-&gt;drv). The driver\r\nconfiguration (plugging in the driver functions) has already been\r\ndescribed above, so we will now look at the yaffs parameters.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The yaffs_param structure must be set before the\r\nyaffs_dev is added with yaffs_add_device() and should not be modified\r\nafter that.</p>\r\n<p class=\"western\">The params are defined in the Yaffs Tuning\r\nDocument.</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">11 Using the\r\nPOSIX file system interface</h1>\r\n<p class=\"western\">This section is directed to readers that might not\r\nbe very familiar with accessing a  file system via POSIX and\r\nPOSIX-like interfaces.</p>\r\n<h2 class=\"western\">11.1 Difference to Windows POSIX-like interfaces</h2>\r\n<p class=\"western\">MSDOS and Windows provide a POSIX-lke interface.\r\nIf you are familiar with this then that will help you. There are are\r\nhowever some slight differences, most importantly:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Windows has no concept of  links and has a\r\n	1:1 mapping between file names and files.POSIX supports files with\r\n	zero, one or many names. Refer to the sections on linking and\r\n	unlinking files. For instance POSIX allows you to unlink a file (ie\r\n	delete the name for a file) while it is still in use. You can\r\n	continue to read/write the file but it will be deleted as soon as\r\n	the last file handle to the file is closed. Windows, on the other\r\n	hand, does not allow you to unlink a file while it is in use.</p>\r\n	<li/>\r\n<p class=\"western\">Windows names drives with a letter. POSIX\r\n	has no drive letters. The whole POSIX file system is in a single\r\n	directory tree.</p>\r\n	<li/>\r\n<p class=\"western\">Directories and “folders” are the same\r\n	thing.</p>\r\n</ul>\r\n<h2 class=\"western\">11.2 Fundamental concepts</h2>\r\n<table width=\"642\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"126\">\r\n	<col width=\"499\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">File</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">A file is an object that is stored in the file\r\n			system. yaffs supports the following file types:</p>\r\n			<p class=\"western\">A regular file is a sequence of bytes stored in\r\n			the file system.</p>\r\n			<p class=\"western\">A directory holds links to other files.</p>\r\n			<p class=\"western\">A symbolic link holds a name to another file.</p>\r\n			<p class=\"western\">A special file holds device ids or similar\r\n			information.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">Directory</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">This is a structure that holds links and allows\r\n			a file to be found by name. Note that a single file may have many\r\n			links(ie names) and many be found in many places in the directory\r\n			structure.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">Link</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">This is a name that allows the file to be\r\n			found. There are two types of link: real links (sometimes called\r\n			hard links) and symbolic (or soft) links. \r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">Handle</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">A file handle provides a context from which a\r\n			file can be accessed and manipulated. A handle has a current file\r\n			position pointer which points to where the file is being read or\r\n			written. Multiple handles can simultaneously access a single file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">File mode</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">The mode is the set of flags that define the\r\n			type of file as well as the current permissions associated with\r\n			the file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">Path</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">This is a string that defines the directories\r\n			and file name. For example:</p>\r\n			<p class=\"western\">“/data/direct-1/file1”</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">File metadata</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">This is the information about the file,\r\n			excluding the file contents. The metadata includes the name, mode,\r\n			size and other details.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">Mount,<br/>\r\npartition,<br/>\r\nfile system</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">These terms all refer to a single mounted flash\r\n			area. Each mount is hooked into a common directory structure.<br/>\r\nThe\r\n			term file system can sometimes be confusing because it is used\r\n			both for a single mounted partition as well as the the file system\r\n			code. In other words, we might say that both “/boot” is a file\r\n			system and might also say that yaffs is a file system.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\">inode number</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">The inode number is a unique number that\r\n			identifies the object within the mount. Note that inodes are not\r\n			unique between two or more mounts. There is no way to reach a file\r\n			by inode, only via its links.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.3 Error code</h2>\r\n<p class=\"western\">Most functions result in error codes if the\r\nfunction does not execute successfully. In these cases yaffs calls a\r\nfunction called <code class=\"western\">yaffs_SetError()</code> with\r\nthe error value. This function can be configured to deliver the error\r\ninto the system\'s error mechanism.</p>\r\n<p class=\"western\">In the case of functions that return integers, a\r\nreturned value smaller than 0 indicates an error occurred. Functions\r\nreturning pointers will return NULL if an error occurred.</p>\r\n<h2 class=\"western\">11.4 Links – the hard kind  (not symbolic links)</h2>\r\n<p class=\"western\">At first we\'re just considering real links and not\r\nsymbolic links. Sometimes real links are also called hard links to\r\ndifferentiate them from symbolic links (which are sometimes called\r\nsoft links).</p>\r\n<p class=\"western\">The difference between links and files is subtle\r\nand can be confusing. Briefly:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">a file is the stored object in the file\r\n	system</p>\r\n	<li/>\r\n<p class=\"western\">the link is how it is hooked into the\r\n	directory structure.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The first link to a file is created by using the\r\nfile creation calls: <code class=\"western\">yaffs_open()</code>,\r\n<code class=\"western\">yaffs_mknod()</code>, <code class=\"western\">yaffs_symlink()</code>\r\nand <code class=\"western\">yaffs_mkdir()</code>.</p>\r\n<p class=\"western\">A link can be destroyed by using the\r\n<code class=\"western\">yaffs_unlink()</code> function. Directories are\r\ndestroyed using the <code class=\"western\">yaffs_rmdir()</code>\r\nfunction (oh, and the directory must be empty).</p>\r\n<p class=\"western\">Once a file is both unused (there are no handles\r\nopen to it) and there are no links to it it is then deleted.</p>\r\n<p class=\"western\">A link can be renamed by using the <code class=\"western\">yaffs_rename()</code>\r\nfunction.</p>\r\n<p class=\"western\">A file may have many links. These may be created\r\nusing the <code class=\"western\">yaffs_link()</code> function. All the\r\nlinks access the same file and there is no one link that is\r\nconsidered “the real link” and others being “the duplicate\r\nlink”. All links to a file have the same priority. If you look at\r\nthe inode number for “a” and for “b” then they will be the\r\nsame because they are refering to exactly the same file.</p>\r\n<p class=\"western\">Thus:</p>\r\n<ol>\r\n	<li/>\r\n<p class=\"western\">If we start with a file called “a” and\r\n	then call <code class=\"western\">yaffs_link(“a”, “b”)</code>\r\n	we now have two links to the same file. We can\'t tell them apart.</p>\r\n	<li/>\r\n<p class=\"western\">If we now unlink “a”, the file still\r\n	exists under the link “b”.</p>\r\n	<li/>\r\n<p class=\"western\">If we now unlink “b” the file will no\r\n	longer be linked. If there is a handle open to the file then we can\r\n	still access the file through the handle and continue to read or\r\n	modify the file. If there is no link to the file it is deleted.</p>\r\n	<li/>\r\n<p class=\"western\">If an unlinked file was kept alive because\r\n	of a handle being open, the file will not show up in the directory\r\n	structure (because it has no link) and will be deleted as soon as\r\n	the handle is closed (or if the file system is unmounted).</p>\r\n</ol>\r\n<p class=\"western\">There are some limitations in how links are used:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The existing file you are linking to must\r\n	exist.</p>\r\n	<li/>\r\n<p class=\"western\">The file you are linking to must be in the\r\n	same mount (partition) as the link you are creating.</p>\r\n	<li/>\r\n<p class=\"western\">You cannot create a link to a directory\r\n	because this would allow the creation of recursive loops.</p>\r\n	<li/>\r\n<p class=\"western\">The new link name must not exist.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.5 Symbolic links</h2>\r\n<p class=\"western\">Now that you understand how hard links work, we\'ll\r\nintroduce symbolic (or soft) links.</p>\r\n<p class=\"western\">A symbolic link holds an alias for a different\r\nobject. When you use that symbolic link in a path the alias is used\r\ninstead. To that extent symbolic link and hard links are the same.</p>\r\n<p class=\"western\">You can remove symbolic links with the\r\n<code class=\"western\">yaffs_unlink()</code> function, just like hard\r\nlinks.</p>\r\n<p class=\"western\">There are, however, some important differences. A\r\nsymbolic link only does its linking function when the path is being\r\nevaluated and thus:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The file you are creating an alias to does\r\n	not have to exist.</p>\r\n	<li/>\r\n<p class=\"western\">The file you are creating an alias to does\r\n	not have to be in the same mount.</p>\r\n	<li/>\r\n<p class=\"western\">You can create symbolic links to\r\n	directories.</p>\r\n	<li/>\r\n<p class=\"western\">A symbolic link will not keep a file alive\r\n	by itself. Only a hard link can do that.</p>\r\n</ul>\r\n<p class=\"western\">Thus:</p>\r\n<ol>\r\n	<li/>\r\n<p class=\"western\">If we start with a file called “a” and\r\n	then call <code class=\"western\">yaffs_symlink(“a”, “b”)</code>\r\n	we now have one link to the file called “a” and a symbolic link\r\n	aliasising from “b” to “a”.</p>\r\n	<li/>\r\n<p class=\"western\">If we use <code class=\"western\">yaffs_open(“a”)</code>\r\n	or <code class=\"western\">yaffs_open(“b”)</code> they will open\r\n	the same file. The path resolution mechanism substitutes in the\r\n	alias and so will look up “a”. The same applies to almost all\r\n	functions that takes a path, such as <code class=\"western\">yaffs_truncate()</code>,\r\n	<code class=\"western\">yaffs_stat()</code> etc. The only exceptions\r\n	are <code class=\"western\">yaffs_lstat()</code> and <code class=\"western\">yaffs_readlink()</code>\r\n	which will treat the path as pointing to the symbolic link and not\r\n	the file.</p>\r\n	<li/>\r\n<p class=\"western\">You can tell “a” and “b” apart by\r\n	using <code class=\"western\">yaffs_lstat()</code>. <code class=\"western\">yaffs_lstat(“a”)</code>\r\n	will show the information for file “a”. <code class=\"western\">yaffs_lstat(“b”)</code>\r\n	will show the information for the symbolic link itself. Note the\r\n	difference with hard links. With hard links <code class=\"western\">yaffs_lstat(“a”)</code>\r\n	and <code class=\"western\">yaffs_lstat(“b”)</code> would show the\r\n	same results since they are EXACTLY the same thing being referenced.</p>\r\n	<li/>\r\n<p class=\"western\">If we now unlink “a”. then the file is\r\n	no longer linked and will no longer be accessible from “b”. Note\r\n	the difference with hard links.</p>\r\n</ol>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.6 Handle-based file handling</h2>\r\n<p class=\"western\">A handle is file accessor that allows us to access\r\nthe contents of a regular file. The handle identifies the file being\r\naccessed as well as a position pointer tracking where the next read\r\nor write operation will take place.</p>\r\n<p class=\"western\">A handle is identified by an integer of value 0 or\r\ngreater.</p>\r\n<p class=\"western\">A handle is created by using the <code class=\"western\">yaffs_open()</code>\r\ncall and returns the handle value. If the handle could not be created\r\nthen a negative value is returned and the yaffs error code is set.</p>\r\n<p class=\"western\">A handle remains valid until the handle is closed\r\nby <code class=\"western\">yaffs_close()</code>.</p>\r\n<p class=\"western\">The <code class=\"western\">yaffs_open()</code> call\r\ntakes three parameters:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">name: Full path name of the file being\r\n	opened.</p>\r\n	<li/>\r\n<p class=\"western\">access flags: Flags being used to open this\r\n	handle</p>\r\n	<li/>\r\n<p class=\"western\">creation mode: Mode flags used when\r\n	creating a file.</p>\r\n</ul>\r\n<p class=\"western\">The access flags are one or more of:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"59*\">\r\n	<col width=\"197*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_CREAT</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Create file if it does not already exist.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_EXCL</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Only use with O_CREAT. Create file if it does\r\n			not exist. If the file already exists then fail.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_TRUNC</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">If the file exists, and opening with write\r\n			access, then truncate the file to zero bytes long.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_APPEND</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Regardless of the handle position, always write\r\n			to the end of the file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_RDWR</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Open for read/write access.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_WRONLY</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Open for write access and no read access.</p>\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>0\r\n			(zero)</b></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">If neither O_RDWR or O_WRONLY is set then the\r\n			file will be opened for read-only access.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Where they are not mutually exclusive, these flags\r\nare typically combined. For example:</p>\r\n<p class=\"western\"><code class=\"western\">O_CREAT | O_TRUNC | O_RDWR</code>\r\n: Create a new file if it does not exist otherwise if the file\r\nalready exists then truncate to zero length. Typically used to\r\noverwrite a file or create if it does not already exist.</p>\r\n<p class=\"western\"><code class=\"western\">O_CREAT | OEXCL | O_WRONLY</code>\r\n: Create a new file, opening it for write only. Fails if file already\r\nexists.</p>\r\n<p class=\"western\">There are three mode flags that can be controlled\r\nor set. These flags may be set by the open that creates the file or\r\nlater by the <code class=\"western\">yaffs_chmod()</code>.</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"59*\">\r\n	<col width=\"197*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">S_IREAD</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">The file may be opened for read access.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">S_IWRITE</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">The file may be opened for write access.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">S_IEXEC</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">The file may be opened for execution. This is\r\n			not enforced by yaffs.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Once you have opened a handle you can then do\r\nvarious operations on the file.</p>\r\n<table width=\"605\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"248\">\r\n	<col width=\"339\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<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>\r\n		</td>\r\n		<td width=\"339\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Close the handle. It is no longer usable.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<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>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Flush out any cached writes to the file, as\r\n			well as the file meta-data.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<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>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Same as yaffs_fsync() but no file metadata.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<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>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Same as yaffs_fsync()</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<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>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Duplicates a handle.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_lseek(handle,\r\n			offset, whence)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Set the handle read/write position. Note that\r\n			this does not modify the file. You can seek past the end of the\r\n			file. This does not modify the file size.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_ftruncate(handle,\r\n			size)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Change the file size. It can be made bigger or\r\n			smaller. This does not change the handle read/write position.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_fstat(handle,\r\n			buf)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Get file status.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_fchmod(handle,\r\n			mode)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Change the file mode.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_read(handle,\r\n			buffer, nbytes)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Read data from file at file pointer and update\r\n			pointer.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_pread(handle,\r\n			buffer, nbytes, position)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Read data from file at specified position. Does\r\n			not modify file pointer</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_write(handle,\r\n			buffer, nbytes)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Write data to file at file pointer and update\r\n			pointer.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_pread(handle,\r\n			buffer, nbytes, position)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Write data to file at specified position. Does\r\n			not modify file pointer</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.7 Changing file size</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_truncate(path,\r\nnewSize)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_ftruncate(handle,\r\nnewSize)</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">These change a file\'s size. Note that truncating\r\ndoes not just mean make the file smaller. The file can also be made\r\nlarger.</p>\r\n<p class=\"western\">Yaffs does not store bytes that it does not need\r\nto. If you use truncate to make a file larger then this will not\r\nnecessarily occupt more flash space.</p>\r\n<p class=\"western\">See also <code class=\"western\">yaffs_lseek()</code>\r\ntoo. Note that <code class=\"western\">yaffs_lseek() </code>only\r\nchanges the position of the write pointer and does not impact on the\r\nfile size unless the file is written.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.8 Getting/setting information about files</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_chmod(path, mode)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_fchmod(handle,\r\nmode)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_access(path,amode)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_stat(path, struct\r\nyaffs_stat *buf) </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_fstat(handle,\r\nstruct yaffs_stat *buf)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_lstat(path,\r\nstruct yaffs_stat *buf)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_readlink(path,\r\nbuf, bufsize)</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The chmod calls allow you to set different mode\r\nflags for the file. These can only be used to manipulate the\r\npermissions flags and not change the mode flags relating to the type\r\nof file.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_access() </code>tests\r\nthat the file can be accessed in the specified mode. This call\r\nreturns zero on success and -1 is returned</p>\r\n<p class=\"western\">amode is a bitmask of the following values:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"43*\">\r\n	<col width=\"213*\">\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">R_OK</code></font></font></p>\r\n		</td>\r\n		<td width=\"83%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Check read is OK</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">W_OK</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Check write is OK</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">X_OK</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Check execute is OK.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<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\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">0\r\n			(zero)</code></font></font></p>\r\n		</td>\r\n		<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\">\r\n			<p class=\"western\">Just checks the file exists</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\">These can be combined.</p>\r\n<p class=\"western\">For example:</p>\r\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path,\r\nR_OK | W_OK) == 0)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">	the file exists and\r\ncan be read and written</code></p>\r\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path,\r\n0) == 0)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">	the file exists</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The stat calls retrieve a yaffs_stat structure of\r\ndata which is defined in yaffsfs.h. There are three versions:</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_fstat</code>: Takes a\r\nhandle.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_stat</code>: Takes a\r\npath name and follows symbolic links.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_lstat</code>: Takes a\r\npath but does not follow symbolic links.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Thus, if path is a symbolic link, <code class=\"western\">yaffs_fstat()\r\n</code>will give information on the file that the link points to\r\nwhile <code class=\"western\">yaffs_lstat()</code> will give\r\ninformation about the link itself.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_readlink()</code> will\r\nread the read the link value into the buffer provided. For example:</p>\r\n<p class=\"code-western\"><code class=\"western\">	yaffs_symlink(“target”,”/link”);\r\n/* create a link called link to target */</code></p>\r\n<p class=\"code-western\"><code class=\"western\">	yaffs_readlink(“/link”,buffer,10);\r\n /* now buffer contains “target” */</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.9 Changing the directory structure and names</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_open(path, flags,\r\nmode)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mkdir(path, mode)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_symlink(targetPath,\r\nlinkPath)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mknod(pathname,\r\nmode, dev)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_link(existingPath,\r\nnewath)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_unlink(path)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_rmdir(path)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_rename(oldPath,\r\nnewPath)</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Files of various types, and their first link, are\r\ncreated 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\">\r\n</font></font><code class=\"western\">yaffs_mkdir()</code><font face=\"Liberation Serif, serif\"><font size=\"2\" style=\"font-size: 10pt\">,\r\n</font></font><code class=\"western\">yaffs_symlink()</code> and\r\n<code class=\"western\">yaffs_mknod()</code><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\">\r\n</font></font>functions.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_link()</code> can be\r\nused to create subsequent links to files. Note that you cannot create\r\na link to a directory.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_rename()</code> allows\r\nyou to rename a link. Note that renaming one link over another link\r\nis an atomic operation. That means that even if the operation is\r\ninterrupted by a power failure, the result will either complete or\r\nnot happen at all. If the target link is for a directory, then the\r\nrename will only work if the target directory is empty.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.10 Searching directories</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_DIR\r\n*yaffs_opendir(const YCHAR *dirname) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent\r\n*yaffs_readdir(yaffs_DIR *dirp) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">void\r\nyaffs_rewinddir(yaffs_DIR *dirp) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">int\r\nyaffs_closedir(yaffs_DIR *dirp) ; </code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Searching is performed by the following sequence\r\nof operations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Open the directory for reading with\r\n	<code class=\"western\">yaffs_opendir()</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Iterate through the entries in the\r\n	directory using <code class=\"western\">yaffs_readdir()</code>. Each\r\n	read will advance the directory read position.</p>\r\n	<li/>\r\n<p class=\"western\">You can reset to the start of the directory\r\n	with <code class=\"western\">yaffs_rewinddir()</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Close the directory when finished with\r\n	<code class=\"western\">yaffs_closedir()</code>.</p>\r\n</ul>\r\n<h2 class=\"western\">11.11 Searching directories (fd interface)</h2>\r\n<p class=\"code-western\"><code class=\"western\">int </code><code class=\"western\">yaffs_open(const\r\nYCHAR *dirname, </code><code class=\"western\">O_RDONLY, 0</code><code class=\"western\">)\r\n; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent\r\n*yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int\r\nfd</code><code class=\"western\">) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">void\r\nyaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int\r\nfd</code><code class=\"western\">) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">int yaffs_close(</code><code class=\"western\">int\r\nfd</code><code class=\"western\">) ; </code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">This is not a POSIX interface, but provides an\r\nalternate interface for reading directories.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Searching is performed by the following sequence\r\nof operations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Open the directory for reading with\r\n	<code class=\"western\">yaffs_open( </code><code class=\"western\">name,\r\n	O_RDONLY, 0</code><code class=\"western\">)</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Iterate through the entries in the\r\n	directory using <code class=\"western\">yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>.\r\n	Each read will advance the directory read position.</p>\r\n	<li/>\r\n<p class=\"western\">You can reset to the start of the directory\r\n	with <code class=\"western\">yaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Close the directory when finished with\r\n	<code class=\"western\">yaffs_close()</code>.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.12 Mount control and similar</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mount(path) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mount2(path,\r\nreadOnly); </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount(path);</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount2(path,\r\nint force); </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_remount(path,\r\nforce, readOnly);</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_sync(path) ;</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_format(const\r\nYCHAR *path, </code>\r\n</p>\r\n<p class=\"western\"><code class=\"western\"> </code><code class=\"western\">		int\r\nunmount_flag, </code>\r\n</p>\r\n<p class=\"western\"><code class=\"western\"> </code><code class=\"western\">		int\r\nforce_unmount_flag, </code>\r\n</p>\r\n<p class=\"western\"><code class=\"western\"> </code><code class=\"western\">		int\r\nremount_flag) </code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">A partition must be mounted to be accessed.\r\n<code class=\"western\">yaffs_mount()</code> will mount the partition\r\nfor read/write access. <code class=\"western\">yaffs_mount2()</code>\r\ncan be used to control whether the access is read/write or read only.</p>\r\n<p class=\"western\">A partition can be unmounted to remove it from\r\nuse. <code class=\"western\">yaffs_unmount()</code> will fail if any\r\nfiles are in use whereas <code class=\"western\">yaffs_unmount2()</code>\r\nallows you to force the unmount even if files are open. Note that any\r\nfile handles will then be broken and will no longer access the files.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_remount()</code> can\r\nbe used to change the access to a currently mounted partition and is\r\nequivalent to making an <code class=\"western\">unmount2()</code> call\r\nfollowed by a <code class=\"western\">mount2()</code> call.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_sync()</code> does not\r\nchange the mount status but flushes out any pending data on a\r\npartition that is mounted with write access.</p>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>yaffs_format()</b></font></font>\r\nprovides a mechanism to format a device. It has various\r\nparameters.<br/>\r\n	<font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>unmount_flag</b></font></font>:\r\nIf set, yaffs_format() will unmount the device before formatting. If\r\nthis flag is not set and the device is mounted, then the format will\r\nfail with EBUSY.</p>\r\n<p class=\"western\">	<font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>force_unmount</b></font></font>:\r\nIf set, then an unmount is allowed even if the device is busy (eg.\r\nfiles open). If not set, then yaffs_format() will fail (EBUSY) if\r\nfiles are open.</p>\r\n<p class=\"western\">	<font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>remount_flag</b></font></font>:\r\n If set, then the device will be remounted after the format if it was\r\nmounted.</p>\r\n<p class=\"western\">The force_unmount and remount_flag options only\r\nhave meaning if unmount_flag is set.</p>\r\n<h2 class=\"western\">11.13 Extended attributes (xattrt)</h2>\r\n<p class=\"western\">Extended attributes provide a mechanism to attach\r\na limited amount of extra data to a file without actually modifying\r\nthe file. Each xattribute is a named pair of name and some data. Each\r\nfile can have as many xattribs as there is space for. In Yaffs, this\r\nis around chunk-size – 512 bytes. So on devices with 2kbyte chunks\r\nyou can store up to 1.5kbytes of xattribute information.</p>\r\n<p class=\"western\">Although there are 12 xattr functions, there are\r\nreally only four basic functions, each with 3 different flavours.</p>\r\n<p class=\"western\">The basic functions are: set an xattr, get an\r\nxattr, remove an xattribute and list the xattribute names.</p>\r\n<p class=\"code-western\">int yaffs_setxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        const void *data, int\r\nsize, int flags); \r\n</p>\r\n<p class=\"code-western\">int yaffs_lsetxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        const void *data, int\r\nsize, int flags); \r\n</p>\r\n<p class=\"code-western\">int yaffs_fsetxattr(int fd, const char *name,\r\n</p>\r\n<p class=\"code-western\">                        const void *data, int\r\nsize, int flags); \r\n</p>\r\n<p class=\"western\">These functions are called with name being the\r\nname of the xattr, a pointer to the data and the size of the data,\r\nand flags.</p>\r\n<p class=\"western\">The flags are:</p>\r\n<p class=\"western\">XATTR_CREATE: Create a new xattr, fail with\r\n-EEXIST if the xattrib already exists.</p>\r\n<p class=\"western\">XATTR_REPLACE: Replace an existing xattr, fail\r\nwith -ENOATTR if it does not exist.</p>\r\n<p class=\"western\">zero: Just create with no checks, replace if it\r\nalready exists.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Setting can fail with -ENOSPC if there is not\r\nenough space to store the xattrib.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int yaffs_getxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        void *data, int\r\nsize); \r\n</p>\r\n<p class=\"code-western\">int yaffs_lgetxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        void *data, int\r\nsize); \r\n</p>\r\n<p class=\"code-western\">int yaffs_fgetxattr(int fd, const char *name,\r\n</p>\r\n<p class=\"code-western\">                        void *data, int\r\nsize); \r\n</p>\r\n<p class=\"western\">These get (fetch) an xattrib.</p>\r\n<p class=\"western\">If the call succeeds, the length of the retrieved\r\nxattrib is returned. This call can fail with -ENOATTR if the\r\nrequested xattr does not exist or -ERANGE if the buffer was too\r\nsmall.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int yaffs_removexattr(const char *path, const\r\nchar *name); \r\n</p>\r\n<p class=\"code-western\">int yaffs_lremovexattr(const char *path,\r\nconst char *name); \r\n</p>\r\n<p class=\"code-western\">int yaffs_fremovexattr(int fd, const char\r\n*name); \r\n</p>\r\n<p class=\"western\">These functions delete an existing xattr. If the\r\nxattr does not exist then -ENOATTR is returned.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int yaffs_listxattr(const char *path, char\r\n*list, int size); \r\n</p>\r\n<p class=\"code-western\">int yaffs_llistxattr(const char *path, char\r\n*list, int size); \r\n</p>\r\n<p class=\"code-western\">int yaffs_flistxattr(int fd, char *list, int\r\nsize); \r\n</p>\r\n<p class=\"western\">These functions fetch a list of the xattrib names\r\ninto the list buffer. The names are NUL terminated. eg.\r\n“attrib0\\0attrib1\\0...”.</p>\r\n<p class=\"western\">The function returns the length of the list,\r\notherwise if the list buffer is too short it returns -ERANGE.</p>\r\n<p class=\"western\">Note: If you call these functions with a list\r\nbuffer size of zero, this acts as a query of the required buffer\r\nsize. No data is actually transferred into the list.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">For example we might choose to add some xattribs\r\nto a media file:</p>\r\n<p class=\"code-western\">//Set description</p>\r\n<p class=\"code-western\">yaffs_fsetxattr(fd, “user-comment”, “I\r\nhate this song!”,18);</p>\r\n<p class=\"code-western\">yaffs_fsetxattr(fd, “price-in-cents”,\r\n&amp;cost, sizeof(cost));</p>\r\n<p class=\"code-western\">// Get the comment</p>\r\n<p class=\"code-western\">yaffs_fgetxattr(fd, “user_comment”,\r\nbuffer, sizeof(buffer);</p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">//List the attributes in a NUL delimited list</p>\r\n<p class=\"code-western\">yaffs_flistxattr(fd, list_buf,\r\nsizeof(list_buf));</p>\r\n<p class=\"code-western\">// Now list_buf has\r\nuser-comment\\0price-in-cents\\0</p>\r\n<p class=\"code-western\">yaffs_fremovexattr(fd, ”user-comment”);</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.14 Other</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_freespace(path); </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_totalspace(path);\r\n</code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_inodecount(path);\r\n</code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">These functions provide information on the free\r\nand total space (in bytes) for the mount that the path addresses.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_inodecount()</code>\r\nreturns the number of files on the mount that the path addresses.</p>\r\n\r\n<h1 class=\"western\" style=\"page-break-before: always\">12 Example:\r\nyaffs_readdir() and yaffs_stat()</h1>\r\n<p class=\"western\">This code snippet illustrates using\r\n<code class=\"western\">yaffs_readdir()</code> and associated functions\r\nto iterate through a directory. It also shows how to use\r\n<code class=\"western\">yaffs_lstat() </code>to get information on a\r\nfile and interpret it.</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">void\r\ndump_directory(const char *dname) </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">{\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	yaffs_DIR\r\n*d; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	yaffs_dirent\r\n*de; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	struct\r\nyaffs_stat s; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	char\r\nstr[100]; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	d\r\n= yaffs_opendir(dname); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	if(!d)\r\n{ </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		printf(&quot;opendir\r\nfailed\\n&quot;); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	}\r\nelse { </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		while((de\r\n= yaffs_readdir(d)) != NULL) { </font></code>\r\n</p>\r\n<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);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			yaffs_lstat(str,&amp;s);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			printf(&quot;%s\r\ninode %d length %d mode %X &quot;,</font></code></p>\r\n<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);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			switch(s.st_mode\r\n&amp; S_IFMT) { </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				case\r\nS_IFREG: printf(&quot;data file&quot;); break; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				case\r\nS_IFDIR: printf(&quot;directory&quot;); break; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				case\r\nS_IFLNK: printf(&quot;symlink --&gt;&quot;); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">					if(yaffs_readlink(str,str,100)\r\n&lt; 0) </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">						printf(&quot;no\r\nalias&quot;); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">					else\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">						printf(&quot;\\&quot;%s\\&quot;&quot;,str);</font></code></p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">					break;\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				default:\r\nprintf(&quot;unknown&quot;); break; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			}</font></code></p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			printf(&quot;\\n&quot;);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			if((s.st_mode\r\n&amp; S_IFMT) == S_IFDIR)</font></code></p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				dump_directory_tree_worker(str);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		}\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		yaffs_closedir(d);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	}\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">}\r\n</font></code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n','<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>','raw_html'),('article',0,454,470,'und',0,'<p>&nbsp;</p><h2 class=\"western\">1 Background</h2><p class=\"western\">This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p><h2 class=\"western\">2 Running the tests</h2><p class=\"western\"><font face=\"Liberation Serif, serif\">All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests. </font></p><h2 class=\"western\">3 Tests</h2><ul><li><p class=\"western\"><font face=\"Liberation Serif, serif\">is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</font></p></li><li><p class=\"western\"><font face=\"Liberation Serif, serif\">stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</font></p></li><li><p class=\"western\"><font face=\"Liberation Serif, serif\">handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle. </font></p></li><li><p class=\"western\"><font face=\"Liberation Serif, serif\">The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</font></p></li><li><p class=\"western\"><font face=\"Liberation Serif, serif\">quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes. </font></p></li><li><p class=\"western\"><font face=\"Liberation Serif, serif\">The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</font></p></li></ul><p class=\"western\">&nbsp;</p><p class=\"western\"><font face=\"Liberation Serif, serif\">The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</font></p>','<p>This provides a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>','filtered_html'),('article',0,454,527,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Background</h2>\r\n\r\n<p>This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\r\n\r\n<h2>2 Running the tests</h2>\r\n\r\n<p>All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests.</p>\r\n\r\n<h2>3 Tests</h2>\r\n\r\n<ul>\r\n	<li>\r\n	<p>is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</p>\r\n	</li>\r\n	<li>\r\n	<p>stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</p>\r\n	</li>\r\n	<li>\r\n	<p>handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle.</p>\r\n	</li>\r\n	<li>\r\n	<p>The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</p>\r\n	</li>\r\n	<li>\r\n	<p>quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes.</p>\r\n	</li>\r\n	<li>\r\n	<p>The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</p>\r\n','<p>This provides a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>','filtered_html'),('article',0,454,529,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Background</h2>\r\n\r\n<p>This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\r\n\r\n<h2>2 Running the tests</h2>\r\n\r\n<p>All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests.</p>\r\n\r\n<h2>3 Tests</h2>\r\n\r\n<ul>\r\n	<li>\r\n	<p>is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</p>\r\n	</li>\r\n	<li>\r\n	<p>stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</p>\r\n	</li>\r\n	<li>\r\n	<p>handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle.</p>\r\n	</li>\r\n	<li>\r\n	<p>The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</p>\r\n	</li>\r\n	<li>\r\n	<p>quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes.</p>\r\n	</li>\r\n	<li>\r\n	<p>The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</p>\r\n','<p>This provides a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>','filtered_html'),('article',0,454,587,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Background</h2>\r\n\r\n<p>This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\r\n\r\n<h2>2 Running the tests</h2>\r\n\r\n<p>All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests.</p>\r\n\r\n<h2>3 Tests</h2>\r\n\r\n<ul>\r\n	<li>\r\n	<p>is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</p>\r\n	</li>\r\n	<li>\r\n	<p>stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</p>\r\n	</li>\r\n	<li>\r\n	<p>handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle.</p>\r\n	</li>\r\n	<li>\r\n	<p>The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</p>\r\n	</li>\r\n	<li>\r\n	<p>quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes.</p>\r\n	</li>\r\n	<li>\r\n	<p>The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</p>\r\n','<p>This provides a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>','full_html'),('article',0,454,607,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Background</h2>\r\n\r\n<p>This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\r\n\r\n<h2>2 Running the tests</h2>\r\n\r\n<p>All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests.</p>\r\n\r\n<h2>3 Tests</h2>\r\n\r\n<ul>\r\n	<li>\r\n	<p>is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</p>\r\n	</li>\r\n	<li>\r\n	<p>stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</p>\r\n	</li>\r\n	<li>\r\n	<p>handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle.</p>\r\n	</li>\r\n	<li>\r\n	<p>The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</p>\r\n	</li>\r\n	<li>\r\n	<p>quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes.</p>\r\n	</li>\r\n	<li>\r\n	<p>The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</p>\r\n','<p>This provides a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>','full_html'),('paper',0,455,471,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Purpose</h2>\r\n\r\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\r\n\r\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\r\n\r\n<h2>2 The NAND Cell</h2>\r\n\r\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\r\n\r\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\r\n\r\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\r\n\r\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\r\n\r\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\r\n\r\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\r\n\r\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off (0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\r\n\r\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\r\n\r\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\r\n\r\n<h3>2.2 NAND array layout</h3>\r\n\r\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\r\n\r\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\r\n\r\n<p>This means we have a matrix where:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>All unselected cells are on.</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected unprogrammed cells are on</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected programmed cells are off.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\r\n\r\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\r\n\r\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\r\n\r\n<h3>3 Fault Modes</h3>\r\n\r\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\r\n	</li>\r\n	<li>\r\n	<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\r\n	</li>\r\n	<li>\r\n	<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\r\n	</li>\r\n	<li>\r\n	<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\r\n	</li>\r\n	<li>\r\n	<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>4 Fault Mechanisms</h2>\r\n\r\n<p>This section explains some of the common NAND flash failure modes.</p>\r\n\r\n<h3>4.1 General chip fault</h3>\r\n\r\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\r\n\r\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\r\n\r\n<h3>4.2 Oxide degradation</h3>\r\n\r\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\r\n\r\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\r\n\r\n<p>As a result of this field disruption, two things happen:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\r\n	</li>\r\n	<li>\r\n	<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\r\n\r\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\r\n\r\n<p>Blocks that become too unreliable are retired from use.</p>\r\n\r\n<h3>4.3 Program/erase failure</h3>\r\n\r\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\r\n\r\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\r\n\r\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\r\n\r\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\r\n\r\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\r\n\r\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\r\n\r\n<h3>4.4 Charge leakage</h3>\r\n\r\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\r\n\r\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\r\n\r\n<h3>4.5 Program disturb</h3>\r\n\r\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\r\n\r\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\r\n\r\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\r\n\r\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\r\n\r\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\r\n\r\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\r\n\r\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\r\n\r\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\r\n\r\n<h3>4.6 Read disturb</h3>\r\n\r\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\r\n\r\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em><strong> </strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\r\n\r\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\r\n\r\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\r\n\r\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\r\n\r\n<p>Read disturb effects are cleared by erasing the block.</p>\r\n\r\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\r\n\r\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\r\n\r\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\r\n\r\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\r\n\r\n<h2>5 Decoding NAND reliability statistics</h2>\r\n\r\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>Temperature</p>\r\n			</td>\r\n			<td>\r\n			<p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Storage time</p>\r\n			</td>\r\n			<td>\r\n			<p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Manufacturing variance</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Operating voltage</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Erasure/programming cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Read cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>6 MLC vs SLC</h2>\r\n\r\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\r\n\r\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\r\n\r\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\r\n\r\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\r\n\r\n<p>But MLC is cheaper!</p>\r\n\r\n<h2>7 Summary</h2>\r\n\r\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Chip Fault</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Degradation</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>P/E failure</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Leakage</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Write Disturb</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Read Disturb</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>NAND self check</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Block retirement</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Wear levelling</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Write Verification</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Read counting/ re-write</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Infrequent read checking</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>ECC</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Occasional rewrite of oldest data</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\r\n\r\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','NAND flash is one of very few types of electronic device which are knowingly shipped with errors and are expected to generate further errors without causing system failure.\r\n\r\nThis document describes the most important failure modes and how they may be addressed in software.','filtered_html'),('paper',0,455,530,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Purpose</h2>\r\n\r\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\r\n\r\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\r\n\r\n<h2>2 The NAND Cell</h2>\r\n\r\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\r\n\r\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\r\n\r\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\r\n\r\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\r\n\r\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\r\n\r\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\r\n\r\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off (0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\r\n\r\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\r\n\r\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\r\n\r\n<h3>2.2 NAND array layout</h3>\r\n\r\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\r\n\r\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\r\n\r\n<p>This means we have a matrix where:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>All unselected cells are on.</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected unprogrammed cells are on</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected programmed cells are off.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\r\n\r\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\r\n\r\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\r\n\r\n<h3>3 Fault Modes</h3>\r\n\r\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\r\n	</li>\r\n	<li>\r\n	<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\r\n	</li>\r\n	<li>\r\n	<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\r\n	</li>\r\n	<li>\r\n	<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\r\n	</li>\r\n	<li>\r\n	<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>4 Fault Mechanisms</h2>\r\n\r\n<p>This section explains some of the common NAND flash failure modes.</p>\r\n\r\n<h3>4.1 General chip fault</h3>\r\n\r\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\r\n\r\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\r\n\r\n<h3>4.2 Oxide degradation</h3>\r\n\r\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\r\n\r\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\r\n\r\n<p>As a result of this field disruption, two things happen:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\r\n	</li>\r\n	<li>\r\n	<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\r\n\r\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\r\n\r\n<p>Blocks that become too unreliable are retired from use.</p>\r\n\r\n<h3>4.3 Program/erase failure</h3>\r\n\r\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\r\n\r\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\r\n\r\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\r\n\r\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\r\n\r\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\r\n\r\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\r\n\r\n<h3>4.4 Charge leakage</h3>\r\n\r\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\r\n\r\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\r\n\r\n<h3>4.5 Program disturb</h3>\r\n\r\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\r\n\r\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\r\n\r\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\r\n\r\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\r\n\r\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\r\n\r\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\r\n\r\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\r\n\r\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\r\n\r\n<h3>4.6 Read disturb</h3>\r\n\r\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\r\n\r\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em><strong> </strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\r\n\r\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\r\n\r\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\r\n\r\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\r\n\r\n<p>Read disturb effects are cleared by erasing the block.</p>\r\n\r\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\r\n\r\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\r\n\r\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\r\n\r\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\r\n\r\n<h2>5 Decoding NAND reliability statistics</h2>\r\n\r\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>Temperature</p>\r\n			</td>\r\n			<td>\r\n			<p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Storage time</p>\r\n			</td>\r\n			<td>\r\n			<p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Manufacturing variance</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Operating voltage</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Erasure/programming cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Read cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>6 MLC vs SLC</h2>\r\n\r\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\r\n\r\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\r\n\r\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\r\n\r\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\r\n\r\n<p>But MLC is cheaper!</p>\r\n\r\n<h2>7 Summary</h2>\r\n\r\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Chip Fault</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Degradation</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>P/E failure</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Leakage</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Write Disturb</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Read Disturb</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>NAND self check</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Block retirement</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Wear levelling</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Write Verification</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Read counting/ re-write</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Infrequent read checking</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>ECC</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Occasional rewrite of oldest data</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\r\n\r\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','NAND flash is one of very few types of electronic device which are knowingly shipped with errors and are expected to generate further errors without causing system failure.\r\n\r\nThis document describes the most important failure modes and how they may be addressed in software.','filtered_html'),('paper',0,455,588,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Purpose</h2>\r\n\r\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\r\n\r\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\r\n\r\n<h2>2 The NAND Cell</h2>\r\n\r\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\r\n\r\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\r\n\r\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\r\n\r\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\r\n\r\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\r\n\r\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\r\n\r\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off (0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\r\n\r\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\r\n\r\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\r\n\r\n<h3>2.2 NAND array layout</h3>\r\n\r\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\r\n\r\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\r\n\r\n<p>This means we have a matrix where:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>All unselected cells are on.</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected unprogrammed cells are on</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected programmed cells are off.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\r\n\r\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\r\n\r\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\r\n\r\n<h3>3 Fault Modes</h3>\r\n\r\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\r\n	</li>\r\n	<li>\r\n	<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\r\n	</li>\r\n	<li>\r\n	<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\r\n	</li>\r\n	<li>\r\n	<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\r\n	</li>\r\n	<li>\r\n	<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>4 Fault Mechanisms</h2>\r\n\r\n<p>This section explains some of the common NAND flash failure modes.</p>\r\n\r\n<h3>4.1 General chip fault</h3>\r\n\r\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\r\n\r\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\r\n\r\n<h3>4.2 Oxide degradation</h3>\r\n\r\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\r\n\r\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\r\n\r\n<p>As a result of this field disruption, two things happen:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\r\n	</li>\r\n	<li>\r\n	<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\r\n\r\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\r\n\r\n<p>Blocks that become too unreliable are retired from use.</p>\r\n\r\n<h3>4.3 Program/erase failure</h3>\r\n\r\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\r\n\r\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\r\n\r\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\r\n\r\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\r\n\r\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\r\n\r\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\r\n\r\n<h3>4.4 Charge leakage</h3>\r\n\r\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\r\n\r\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\r\n\r\n<h3>4.5 Program disturb</h3>\r\n\r\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\r\n\r\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\r\n\r\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\r\n\r\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\r\n\r\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\r\n\r\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\r\n\r\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\r\n\r\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\r\n\r\n<h3>4.6 Read disturb</h3>\r\n\r\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\r\n\r\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em><strong> </strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\r\n\r\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\r\n\r\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\r\n\r\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\r\n\r\n<p>Read disturb effects are cleared by erasing the block.</p>\r\n\r\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\r\n\r\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\r\n\r\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\r\n\r\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\r\n\r\n<h2>5 Decoding NAND reliability statistics</h2>\r\n\r\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>Temperature</p>\r\n			</td>\r\n			<td>\r\n			<p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Storage time</p>\r\n			</td>\r\n			<td>\r\n			<p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Manufacturing variance</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Operating voltage</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Erasure/programming cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Read cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>6 MLC vs SLC</h2>\r\n\r\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\r\n\r\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\r\n\r\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\r\n\r\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\r\n\r\n<p>But MLC is cheaper!</p>\r\n\r\n<h2>7 Summary</h2>\r\n\r\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Chip Fault</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Degradation</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>P/E failure</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Leakage</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Write Disturb</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Read Disturb</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>NAND self check</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Block retirement</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Wear levelling</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Write Verification</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Read counting/ re-write</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Infrequent read checking</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>ECC</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Occasional rewrite of oldest data</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\r\n\r\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','NAND flash is one of very few types of electronic device which are knowingly shipped with errors and are expected to generate further errors without causing system failure.\r\n\r\nThis document describes the most important failure modes and how they may be addressed in software.','full_html'),('paper',0,455,608,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Purpose</h2>\r\n\r\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\r\n\r\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\r\n\r\n<h2>2 The NAND Cell</h2>\r\n\r\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\r\n\r\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\r\n\r\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\r\n\r\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\r\n\r\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\r\n\r\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\r\n\r\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off (0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\r\n\r\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\r\n\r\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\r\n\r\n<h3>2.2 NAND array layout</h3>\r\n\r\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\r\n\r\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\r\n\r\n<p>This means we have a matrix where:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>All unselected cells are on.</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected unprogrammed cells are on</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected programmed cells are off.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\r\n\r\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\r\n\r\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\r\n\r\n<h3>3 Fault Modes</h3>\r\n\r\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\r\n	</li>\r\n	<li>\r\n	<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\r\n	</li>\r\n	<li>\r\n	<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\r\n	</li>\r\n	<li>\r\n	<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\r\n	</li>\r\n	<li>\r\n	<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>4 Fault Mechanisms</h2>\r\n\r\n<p>This section explains some of the common NAND flash failure modes.</p>\r\n\r\n<h3>4.1 General chip fault</h3>\r\n\r\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\r\n\r\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\r\n\r\n<h3>4.2 Oxide degradation</h3>\r\n\r\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\r\n\r\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\r\n\r\n<p>As a result of this field disruption, two things happen:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\r\n	</li>\r\n	<li>\r\n	<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\r\n\r\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\r\n\r\n<p>Blocks that become too unreliable are retired from use.</p>\r\n\r\n<h3>4.3 Program/erase failure</h3>\r\n\r\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\r\n\r\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\r\n\r\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\r\n\r\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\r\n\r\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\r\n\r\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\r\n\r\n<h3>4.4 Charge leakage</h3>\r\n\r\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\r\n\r\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\r\n\r\n<h3>4.5 Program disturb</h3>\r\n\r\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\r\n\r\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\r\n\r\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\r\n\r\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\r\n\r\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\r\n\r\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\r\n\r\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\r\n\r\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\r\n\r\n<h3>4.6 Read disturb</h3>\r\n\r\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\r\n\r\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em><strong> </strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\r\n\r\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\r\n\r\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\r\n\r\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\r\n\r\n<p>Read disturb effects are cleared by erasing the block.</p>\r\n\r\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\r\n\r\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\r\n\r\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\r\n\r\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\r\n\r\n<h2>5 Decoding NAND reliability statistics</h2>\r\n\r\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>Temperature</p>\r\n			</td>\r\n			<td>\r\n			<p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Storage time</p>\r\n			</td>\r\n			<td>\r\n			<p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Manufacturing variance</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Operating voltage</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Erasure/programming cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Read cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>6 MLC vs SLC</h2>\r\n\r\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\r\n\r\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\r\n\r\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\r\n\r\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\r\n\r\n<p>But MLC is cheaper!</p>\r\n\r\n<h2>7 Summary</h2>\r\n\r\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Chip Fault</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Degradation</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>P/E failure</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Leakage</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Write Disturb</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Read Disturb</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>NAND self check</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Block retirement</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Wear levelling</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Write Verification</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Read counting/ re-write</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Infrequent read checking</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>ECC</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Occasional rewrite of oldest data</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\r\n\r\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','NAND flash is one of very few types of electronic device which are knowingly shipped with errors and are expected to generate further errors without causing system failure.\r\n\r\nThis document describes the most important failure modes and how they may be addressed in software.','full_html'),('image',0,456,474,'und',0,'<p>This diagram shows the relationships between the Yaffs filesystem, the <a href=\"/documents/yaffs-direct-interface\">Yaffs Direct Interface</a>, Posix, the operating system and the flash hardware.</p>\r\n\r\n<p>&nbsp;</p>\r\n','<p>This diagram shows the relationships between the Yaffs filesystem, the Yaffs Direct Interface, Posix, the operating system and the flash hardware.</p>','basic_html'),('yaffs_user_logo',0,457,475,'und',0,'<p>Google Android and all the phone manufacturers who use it, use Yaffs as the default filesystem in some versions of Android.</p>\r\n\r\n<p>The Android Robot logo is reproduced from work created and&nbsp;<a href=\"http://code.google.com/policies.html\">shared by the Android Open Source Project</a>&nbsp;and used according to terms described in the&nbsp;<a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons 2.5 Attribution License</a>.</p>\r\n','Google Android and all the phone manufacturers who use it, use Yaffs as the default filesystem in some versions of Android.','basic_html'),('help_video',0,458,476,'und',0,'<p>&nbsp;</p>\r\n\r\n<p>This video covers the preparation needed to include Linux in Yaffs - describing the kernel build-tools needed, how to get the kernel source code and Yaffs source code. It\'s about 175Mb and 6m30 long.</p>\r\n\r\n<p><em>Here\'s the script for the video:</em></p>\r\n\r\n<p>Hello, today I\'m going to show you the tools you need to compile Yaffs into the Linux kernel. If you\'ve compiled Linux before, then this tutorial is not appropriate for you, and you should skip to the next one.</p>\r\n\r\n<p>Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the GNU Public Licence – the GPL – and commercial terms. You can find out more about Yaffs at yaffs.net.</p>\r\n\r\n<p>This demo is being run on Intel x86 because the end result is available for you to experiment with under Vagrant and Virtualbox, but with some slight changes we could target another architecture – for instance ARM. If you\'ve never used Vagrant, it provides a way to get a virtual system up and running in a few minutes. You can download the Vagrant box from the Yaffs web site.</p>\r\n\r\n<p><em>Login</em></p>\r\n\r\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running Virtualbox, but this works just as well for 64 bit architecture.</p>\r\n\r\n<p>Here we are at the command-line of a brand-new installation. The server has been configured for the minimum – it only has ssh, and a couple of othre things required for Vagrant. Of course there\'s no requirement for any of this for Yaffs.</p>\r\n\r\n<p>We need git version control to download Yaffs and the kernel source</p>\r\n\r\n<p><strong>sudo apt-get install git</strong></p>\r\n\r\n<p>We need these tools to build the kernel</p>\r\n\r\n<p><strong>sudo apt-get install crash kexec-tools makedumpfile kernel-wedge</strong></p>\r\n\r\n<p><strong>sudo apt-get install ncurses-dev libncurses5-dev</strong></p>\r\n\r\n<p><strong>sudo apt-get install build-essential fakeroot</strong></p>\r\n\r\n<p>And we need this to automate the job of creating a debian kernel package</p>\r\n\r\n<p><strong>sudo apt-get install kernel-package</strong></p>\r\n\r\n<p>Okay, we have all the tools I\'ll be needing, so I\'m going to go ahead and make a working directory.</p>\r\n\r\n<p><strong>mkdir kernel</strong></p>\r\n\r\n<p><strong>cd kernel</strong></p>\r\n\r\n<p>Of course we\'re going to need Yaffs, so I\'ll go ahead and download that</p>\r\n\r\n<p><strong>git clone git://www.aleph1.co.uk/yaffs2</strong></p>\r\n\r\n<p>That puts it into the Yaffs directory.</p>\r\n\r\n<p><strong>ls</strong></p>\r\n\r\n<p>This copy of Yaffs is licensed under the GNU Public Licence – the GPL, so I must make changes available under the GPL too. We also license Yaffs under commercial terms, removing the need to make your code available to others. Check our website for details.</p>\r\n\r\n<p>Now I need a copy of the kernel source code. I could have used one directly from kernel.org, but because this demo is running on ubuntu, I\'m going to grab the ubuntu kernel. This has the benefit of including the debian build rules.</p>\r\n\r\n<p><strong>git clone git://kernel.ubuntu.com/ubuntu/ubuntu-precise.git source</strong></p>\r\n\r\n<p><strong>cd source</strong></p>\r\n\r\n<p>Here it is</p>\r\n\r\n<p><strong>ls</strong></p>\r\n\r\n<p>And that\'s everything necessary to build the kernel with Yaffs. In the next video we\'ll show you how to configure and compile the kernel with Yaffs. More information about Yaffs is available at www.yaffs.net. Thanks for watching.</p>\r\n','<p>This video covers the preparation needed to include Linux in Yaffs - describing the kernel build-tools needed, how to get the kernel source code and Yaffs source code. It&#39;s about 175Mb and 6m30 long.</p>','basic_html'),('help_video',0,459,477,'und',0,'<p>&nbsp;</p>\r\n\r\n<p>This video shows you how to compile Yaffs into Linux. It’s just over 10 minutes long, and if you download it, it’s&nbsp;325MB. After watching this video you should be able to include Yaffs in Linux. Once you have Yaffs available you will be able to mount a simulated&nbsp;NAND&nbsp;device, or if you have a Flash device attached, you will be able to use it.&nbsp;The demo was run in a Virtualbox system, and is available as a&nbsp;<a href=\"http://www.yaffs.net/test-yaffs-under-linux-using-virtualbox-and-vagrant\">Vagrant box from our Downloads section</a>&nbsp;with details of how to build and use a simulated&nbsp;NAND&nbsp;device. &nbsp;</p>\r\n\r\n<p><em>The script for the video:</em></p>\r\n\r\n<p>Hello, today I\'m going to show you how to compile Yaffs into the linux kernel.&nbsp;Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the Gnu Public Licence – the GPL – and commercial terms.&nbsp;You can find out more about Yaffs at yaffs.net.</p>\r\n\r\n<p>Today we\'ll be targetting intel x86 but with some slight changes we could target another &nbsp;architecture – for instance ARM.&nbsp;This demo is being run in a Virtualbox machine, and the resulting system is available as a Vagrant box, so you can download the image and test it yourself.&nbsp;If you\'ve never used vagrant, it provides&nbsp; a way to get a virtual system up and running in a few minutes.</p>\r\n\r\n<p><strong>Login</strong></p>\r\n\r\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running virtualbox, but this works just as well for 64 bit architecture.</p>\r\n\r\n<p>Here we are at the command-line of a brand-new installation.&nbsp;To make a kernel with Yaffs you will need all the usual kernel-build tools for your distribution, the kernel source code, and the Yaffs source code.</p>\r\n\r\n<p>If you skipped the first video, you won\'t have seen how to download Yaffs. Here\'s a brief clip of retrieving a GPL licenced copy of the Yaffs source.</p>\r\n\r\n<p><strong>git clone git://www.aleph1.co.uk/yaffs2</strong><br />\r\n<strong>ls</strong></p>\r\n\r\n<p>We\'re starting off in the directory where I stored the kernel and Yaffs source.<br />\r\nThe next step isn\'t strictly necessary, but it\'s useful to if you are going to be doing development: I\'m going to make a branch for my changes to the kernel. Of course if you are using subversion, cvs or some other system for version control then you\'ll want to skip this step or replace it</p>\r\n\r\n<p>Let\'s list the branches<br />\r\n<strong>git branch</strong><br />\r\nOnly one makes it easy.<br />\r\n<strong>Git checkout master -b yaffs-demo-x86</strong><br />\r\nOkay, so we\'ve created a branch.<br />\r\n<strong>git branch</strong><br />\r\nAnd the star indicates that we are working in our new branch.<br />\r\nNow we have the kernel source, but we need to include Yaffs.<br />\r\nLuckily Yaffs comes with a script which automates the source changes necessary to include it.<br />\r\n<strong>cd ../yaffs</strong><br />\r\nIt\'s always a good idea to check the README file. Especially if you are doing this yourself.<br />\r\n<strong>less readme-linux.txt</strong><br />\r\nSo the script we use to patch the kernel is<br />\r\n<strong>./patch-ker.sh c m ~/kernel/source</strong><br />\r\nThe c tells the script to copy the changes rather than linking them, and the m indicates that we want the multiprocess option because more than one process might be using Yaffs at one time.</p>\r\n\r\n<p>Right, Yaffs has been patched into the kernel.&nbsp;Now we need to configure the kernel build.<br />\r\nBecause I\'m working on a virtual machine, I don\'t need to worry about different flavours of the kernel configuration. I can just go ahead and edit the default configuration.&nbsp;To avoid a long compile, I\'m going to remove pretty much all of the non-essential drivers, and most of the hardware – remember this is running on a virtual machine.<br />\r\n<strong>make menuconfig</strong><br />\r\nTo include Yaffs we need to enable two things.&nbsp;<br />\r\nThe memory technology device support (MTD) and the caching block device access for MTD.<br />\r\nThe MTD settings are in the Device drivers section. Usually it will be on. The caching should be on too.&nbsp;Once those are enabled, Yaffs becomes available as an optional file system.<br />\r\nGo into File systems, Miscellaneous and enable Yaffs.</p>\r\n\r\n<p>Here\'s a look at the various options.</p>\r\n\r\n<p>I\'ve set up Yaffs. Now I\'m going to go ahead and turn off all the things that I don\'t need in this kernel. There are a lot of them, and there\'s no need to watch hundreds of items being unticked.<br />\r\n...Skipping ahead....<br />\r\nOnce the config is suitable, we can exit and save.</p>\r\n\r\n<p>Okay, we\'re ready to build the kernel.&nbsp;Just to make sure that everything is fine..</p>\r\n\r\n<p><strong>fakeroot make-kpkg clean</strong></p>\r\n\r\n<p>and let\'s kick the build off</p>\r\n\r\n<p><strong>fakeroot make-kpkg –initrd –append-to-version=yaffs kernel-image</strong></p>\r\n\r\n<p>and now, since this is running on a uniprocessor virtual machine, I\'ll be going for some lunch. But there\'s no need for you to wait...</p>\r\n\r\n<p>So, the build is finished. It took about 1/2 hour. Your mileage will vary.</p>\r\n\r\n<p>We have a Debian package, and I\'m going to go ahead and install that.</p>\r\n\r\n<p><strong>sudo dpkg&nbsp;–install</strong></p>\r\n\r\n<p>We should have our new build in the grub.&nbsp;If we reboot, we’ll have Yaffs available.&nbsp;In the next video we’ll show you how to set up a Yaffs file system.&nbsp;You can download a copy of the virtual machine but you’ll need vagrant to use it. Details are on the&nbsp;site.</p>\r\n\r\n<p>Thanks for&nbsp;watching.</p>\r\n','<p>This video shows you how to compile Yaffs into Linux. It&rsquo;s just over 10 minutes long, and if you download it, it&rsquo;s&nbsp;325MB. After watching this video you should be able to include Yaffs in Linux.</p>','full_html'),('yaffs_user_logo',0,460,478,'und',0,'<p>Leica Geosystems products and services are trusted by professionals worldwide to help them capture, analyze, and present spatial information. Leica Geosystems is best known for its broad array of products that capture accurately, model quickly, analyze easily, and visualize and present spatial information.</p>\r\n\r\n<p>Leica Geosystems use Yaffs.</p>\r\n\r\n<p>&nbsp;</p>\r\n','Leica Geosystems products and services are trusted by professionals worldwide to help them capture, analyze, and present spatial information. Leica Geosystems is best known for its broad array of products that capture accurately, model quickly, analyze easily, and visualize and present spatial information.','basic_html'),('article',0,461,479,'und',0,'<style type=\"text/css\">\r\n<!--\r\n		@page { margin-left: 2cm; margin-right: 1.8cm; margin-top: 1.6cm; margin-bottom: 1.4cm }\r\n		P { margin-bottom: 0.21cm }\r\n	--></style>\r\n<p class=\"western\" style=\"margin-bottom: 0cm; font-style: normal\" align=\"CENTER\"><font style=\"font-size: 15pt\" size=\"4\"><b>Draft Agreement Between Aleph One Limited and Licence-holder</b></font></p><p class=\"western\" style=\"margin-bottom: 0cm\" align=\"CENTER\"><font style=\"font-size: 15pt\" size=\"4\"><b>for the use of YAFFS1, YAFFS2 and YAFFS/direct</b></font></p><p class=\"western\" style=\"margin-bottom: 0cm\" align=\"CENTER\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\"><b>1. Definitions:</b></font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">ALEPH ONE Ltd, a company registered in England and Wales, Number 1017960, having its Registered Office at The Old Courthouse, 123 High Street, Bottisham, CAMBRIDGE CB25 9BA UK</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">LICENCE-HOLDER - The firm of Licence-holder having its administrative offices at </font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">SOURCE CODE - Code owned by Aleph One Ltd and supplied under this Licence</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">BINARY CODE - Code which has been compiled from source code </font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">PRODUCT is To Be Agreed</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">YAFFS FILESYSTEMS - any Filesystem Images made using YAFFS source code or YAFFS binary code </font></p><p class=\"western\" style=\"margin-bottom: 0cm\" align=\"CENTER\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\"><b>2. The Licence:</b> </font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Allows Licence-holder to use software of Aleph One Ltd to create the File System, FS and incorporate the FS in the defined product .</font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">Entitles Licence-holder to distribute binary code compiled from the source code provided.</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Does not entail any obligation to reveal the Binary code .</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Prohibits Licence-holder from releasing the source code to other parties, except to the extent necessary to permit sub-contractors to work with Licence-holder on a project using the code. Licence-holder is responsible for ensuring compliance with all the terms of this licence by any sub-contractor used.</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Is only available in a non-exclusive form. </font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Is applicable worldwide. </font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Has no time limit or per-unit royalty, but a fixed price paid at the time of signature as specified in Section 4 below.</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Applies to use of the FS only for the Product described in Section 1, rather than to a company/user/person. It cannot be transferred to another product .</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Provides the Source Code and any derived filesystems without any warranty but &gt;AS IS&lt; save that (to the best of Aleph One\'s knowledge) the use of the Source Code does not infringe the intellectual property rights of any third party.</font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><br>&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\"><b>3. Supporting information:</b></font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">Aleph One Ltd supplies certain pieces of software, with different licences associated with them:</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">~~ Source Code for YAFFS1, YAFFS2 and YAFFS/direct and Bootloader, being the subject of this Licence Agreement, for incorporation in a Product. </font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">~~ YAFFS Development Tools; images created with the tools may be incorporated into a Product. The images are not affected by the licence status of the Tools. When these Tool files are supplied in the tarball we send they will appear with a header saying they are used under the GNU Public Licence, GPL. That term applies only to the Tools; the other files in the tarball will have headers making clear they are used under a paid licence from Aleph One Ltd.</font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">~~ Access to all information on YAFFS published by Aleph One Ltd at http://www.yaffs.net</font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">Source code modifications and enhancements made by Licence-holder remain the property of Licence-holder , but may not be redistributed or sold to third parties by Licence-holder without consent of Aleph One Ltd.</font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><br>&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\"><b>4. Price: </b> </font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Ten Thousand Pounds Sterling, £10,000. payable at the time of signature of this licence.</font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">After payment for the Licence is received, Aleph One Ltd will provide a tarball with file headers showing the code is being used by the Licence-holder under a paid licence from Aleph One Ltd.</font></p><p class=\"western\" style=\"margin-bottom: 0cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\"><b>Signed by:</b></font></p><p class=\"western\" style=\"margin-bottom: 0cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">Laurence van Someren&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>Name</i></font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Director&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <i>Position</i></font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">for Aleph One Limited&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for <i>Licence-holder</i></font></p><p class=\"western\" style=\"margin-bottom: 0.2cm\">&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0.2cm\"><font style=\"font-size: 13pt\" size=\"3\">Date 2014 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date 2014</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">Version 23</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><font style=\"font-size: 13pt\" size=\"3\">The following section does not form part of the Agreement:-</font></p><p class=\"western\" style=\"margin-bottom: 0cm\"><em>We use a Licence Agreement written in English.&nbsp; We do not do this because English is our first language, but because English is the language understood by almost all our customers.&nbsp; We remain constantly aware&nbsp; of our good fortune in having it as a first language, and try to be sensitive to the needs of customers who use other languages more easily.</em></p><p class=\"western\" style=\"margin-bottom: 0cm\"><br>&nbsp;</p><p class=\"western\" style=\"margin-bottom: 0cm\">&nbsp;</p>','<p>An example of the framework Licence Agreement showing the necessary elements and open to negotiation</p>','filtered_html'),('article',0,461,522,'und',0,'<p><strong>Draft Agreement Between Aleph One Limited and Licence-holder</strong></p>\r\n\r\n<p><strong>for the use of YAFFS1, YAFFS2 and YAFFS/direct</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>1. Definitions:</strong></p>\r\n\r\n<p>ALEPH ONE Ltd, a company registered in England and Wales, Number 1017960, having its Registered Office at The Old Courthouse, 123 High Street, Bottisham, CAMBRIDGE CB25 9BA UK</p>\r\n\r\n<p>LICENCE-HOLDER - The firm of Licence-holder having its administrative offices at</p>\r\n\r\n<p>SOURCE CODE - Code owned by Aleph One Ltd and supplied under this Licence</p>\r\n\r\n<p>BINARY CODE - Code which has been compiled from source code</p>\r\n\r\n<p>PRODUCT is To Be Agreed</p>\r\n\r\n<p>YAFFS FILESYSTEMS - any Filesystem Images made using YAFFS source code or YAFFS binary code</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>2. The Licence:</strong></p>\r\n\r\n<p>Allows Licence-holder to use software of Aleph One Ltd to create the File System, FS and incorporate the FS in the defined product .</p>\r\n\r\n<p>Entitles Licence-holder to distribute binary code compiled from the source code provided.</p>\r\n\r\n<p>Does not entail any obligation to reveal the Binary code .</p>\r\n\r\n<p>Prohibits Licence-holder from releasing the source code to other parties, except to the extent necessary to permit sub-contractors to work with Licence-holder on a project using the code. Licence-holder is responsible for ensuring compliance with all the terms of this licence by any sub-contractor used.</p>\r\n\r\n<p>Is only available in a non-exclusive form.</p>\r\n\r\n<p>Is applicable worldwide.</p>\r\n\r\n<p>Has no time limit or per-unit royalty, but a fixed price paid at the time of signature as specified in Section 4 below.</p>\r\n\r\n<p>Applies to use of the FS only for the Product described in Section 1, rather than to a company/user/person. It cannot be transferred to another product .</p>\r\n\r\n<p>Provides the Source Code and any derived filesystems without any warranty but &gt;AS IS&lt; save that (to the best of Aleph One\'s knowledge) the use of the Source Code does not infringe the intellectual property rights of any third party.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p><strong>3. Supporting information:</strong></p>\r\n\r\n<p>Aleph One Ltd supplies certain pieces of software, with different licences associated with them:</p>\r\n\r\n<p>~~ Source Code for YAFFS1, YAFFS2 and YAFFS/direct and Bootloader, being the subject of this Licence Agreement, for incorporation in a Product.</p>\r\n\r\n<p>~~ YAFFS Development Tools; images created with the tools may be incorporated into a Product. The images are not affected by the licence status of the Tools. When these Tool files are supplied in the tarball we send they will appear with a header saying they are used under the GNU Public Licence, GPL. That term applies only to the Tools; the other files in the tarball will have headers making clear they are used under a paid licence from Aleph One Ltd.</p>\r\n\r\n<p>~~ Access to all information on YAFFS published by Aleph One Ltd at http://www.yaffs.net</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Source code modifications and enhancements made by Licence-holder remain the property of Licence-holder , but may not be redistributed or sold to third parties by Licence-holder without consent of Aleph One Ltd.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p><strong>4. Price: </strong></p>\r\n\r\n<p>Ten Thousand Pounds Sterling, £10,000. payable at the time of signature of this licence.</p>\r\n\r\n<p>After payment for the Licence is received, Aleph One Ltd will provide a tarball with file headers showing the code is being used by the Licence-holder under a paid licence from Aleph One Ltd.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>Signed by:</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Laurence van Someren&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Name</em></p>\r\n\r\n<p>Director&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Position</em></p>\r\n\r\n<p>for Aleph One Limited&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for <em>Licence-holder</em></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Date 2014 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date 2014</p>\r\n\r\n<p>Version 23</p>\r\n\r\n<p>The following section does not form part of the Agreement:-</p>\r\n\r\n<p><em>We use a Licence Agreement written in English.&nbsp; We do not do this because English is our first language, but because English is the language understood by almost all our customers.&nbsp; We remain constantly aware&nbsp; of our good fortune in having it as a first language, and try to be sensitive to the needs of customers who use other languages more easily.</em></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','<p>An example of the framework Licence Agreement showing the necessary elements and open to negotiation</p>','filtered_html'),('article',0,461,589,'und',0,'<p><strong>Draft Agreement Between Aleph One Limited and Licence-holder</strong></p>\r\n\r\n<p><strong>for the use of YAFFS1, YAFFS2 and YAFFS/direct</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>1. Definitions:</strong></p>\r\n\r\n<p>ALEPH ONE Ltd, a company registered in England and Wales, Number 1017960, having its Registered Office at The Old Courthouse, 123 High Street, Bottisham, CAMBRIDGE CB25 9BA UK</p>\r\n\r\n<p>LICENCE-HOLDER - The firm of Licence-holder having its administrative offices at</p>\r\n\r\n<p>SOURCE CODE - Code owned by Aleph One Ltd and supplied under this Licence</p>\r\n\r\n<p>BINARY CODE - Code which has been compiled from source code</p>\r\n\r\n<p>PRODUCT is To Be Agreed</p>\r\n\r\n<p>YAFFS FILESYSTEMS - any Filesystem Images made using YAFFS source code or YAFFS binary code</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>2. The Licence:</strong></p>\r\n\r\n<p>Allows Licence-holder to use software of Aleph One Ltd to create the File System, FS and incorporate the FS in the defined product .</p>\r\n\r\n<p>Entitles Licence-holder to distribute binary code compiled from the source code provided.</p>\r\n\r\n<p>Does not entail any obligation to reveal the Binary code .</p>\r\n\r\n<p>Prohibits Licence-holder from releasing the source code to other parties, except to the extent necessary to permit sub-contractors to work with Licence-holder on a project using the code. Licence-holder is responsible for ensuring compliance with all the terms of this licence by any sub-contractor used.</p>\r\n\r\n<p>Is only available in a non-exclusive form.</p>\r\n\r\n<p>Is applicable worldwide.</p>\r\n\r\n<p>Has no time limit or per-unit royalty, but a fixed price paid at the time of signature as specified in Section 4 below.</p>\r\n\r\n<p>Applies to use of the FS only for the Product described in Section 1, rather than to a company/user/person. It cannot be transferred to another product .</p>\r\n\r\n<p>Provides the Source Code and any derived filesystems without any warranty but &gt;AS IS&lt; save that (to the best of Aleph One\'s knowledge) the use of the Source Code does not infringe the intellectual property rights of any third party.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p><strong>3. Supporting information:</strong></p>\r\n\r\n<p>Aleph One Ltd supplies certain pieces of software, with different licences associated with them:</p>\r\n\r\n<p>~~ Source Code for YAFFS1, YAFFS2 and YAFFS/direct and Bootloader, being the subject of this Licence Agreement, for incorporation in a Product.</p>\r\n\r\n<p>~~ YAFFS Development Tools; images created with the tools may be incorporated into a Product. The images are not affected by the licence status of the Tools. When these Tool files are supplied in the tarball we send they will appear with a header saying they are used under the GNU Public Licence, GPL. That term applies only to the Tools; the other files in the tarball will have headers making clear they are used under a paid licence from Aleph One Ltd.</p>\r\n\r\n<p>~~ Access to all information on YAFFS published by Aleph One Ltd at http://www.yaffs.net</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Source code modifications and enhancements made by Licence-holder remain the property of Licence-holder , but may not be redistributed or sold to third parties by Licence-holder without consent of Aleph One Ltd.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p><strong>4. Price: </strong></p>\r\n\r\n<p>Ten Thousand Pounds Sterling, £10,000. payable at the time of signature of this licence.</p>\r\n\r\n<p>After payment for the Licence is received, Aleph One Ltd will provide a tarball with file headers showing the code is being used by the Licence-holder under a paid licence from Aleph One Ltd.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>Signed by:</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Laurence van Someren&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Name</em></p>\r\n\r\n<p>Director&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Position</em></p>\r\n\r\n<p>for Aleph One Limited&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for <em>Licence-holder</em></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Date 2014 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date 2014</p>\r\n\r\n<p>Version 23</p>\r\n\r\n<p>The following section does not form part of the Agreement:-</p>\r\n\r\n<p><em>We use a Licence Agreement written in English.&nbsp; We do not do this because English is our first language, but because English is the language understood by almost all our customers.&nbsp; We remain constantly aware&nbsp; of our good fortune in having it as a first language, and try to be sensitive to the needs of customers who use other languages more easily.</em></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','<p>An example of the framework Licence Agreement showing the necessary elements and open to negotiation</p>','basic_html'),('page',0,462,482,'und',0,'<h3>What sorts of licence are there?</h3>\r\n\r\n<p>There are two; GNU General Public Licence version 2, and Paid licences.<br />\r\nAnyone can take our Yaffs file system from http://www.yaffs.net&nbsp; free of charge; you can work and play with and test the code as much as you like, and make sure it suits your purposes. You will be doing so under the well known GNU GPL, described in detail at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</p>\r\n\r\n<h3>That sounds great! Why should I want a paid licence?</h3>\r\n\r\n<p>The GPL obliges you to release all associated code of your own that you use with any GPL software to anyone who asks for it.&nbsp; If you do not wish to release your own code, then you can buy a Licence from Aleph One Ltd which does not have that obligation.</p>\r\n\r\n<h3>What sorts of systems use Yaffs?</h3>\r\n\r\n<p>There is a wide range including GPS equipment for surveyors, sewing machines, traffic control equipment, Point-of-Sale tills, Set-Top-Boxes, DVD writers, high-end video-filming equipment and so on and on - including Android telephones!&nbsp; These have provided a very large test-bed for Yaffs, and of course they use it under GPL since Android is an Open Source project.</p>\r\n\r\n<h3>Who uses Yaffs now?</h3>\r\n\r\n<p>The Yaffs.net Home page shows (at its foot) the logos of some of the users, but the range is much wider than those displayed there.&nbsp; They tend to have in common a need for great confidence in the robustness of the FS in demanding circumstances like heavy work, accumulated cell-failures, and random power failures.&nbsp; A number of them have bought more than one Licence at different times because they know it works!</p>\r\n\r\n<h3>What are the terms of the paid licences like?</h3>\r\n\r\n<p>All Yaffs licences from Aleph One are non-exclusive, worldwide, perpetual, irrevocable and free of any royalty; they are paid for once when an agreement is signed, and they apply only to the one or more products specified at the time of the agreement.</p>\r\n\r\n<h3>What do we do next?</h3>\r\n\r\n<p>Tell us some more about the product you will use Yaffs in.&nbsp; We like the Agreement to contain a brief description of the hardware involved and the part number or product name and any internal code name.&nbsp; If you want us to sign a Non-Disclosure Agreement before you give us these details, send it to us; we are used to signing them.&nbsp; We can send you a standard form if you do not have one.<br />\r\nThen we will send a draft Agreement and price to you, and negotiate until we are both satisfied.&nbsp; Next we each sign and exchange copies of the Agreement and you pay us.</p>\r\n\r\n<h3>How does that help us?</h3>\r\n\r\n<p>After you pay for a Licence you get a tarball of files to put in your product which make clear in the file headers that you are using Yaffs under a licence from Aleph One Ltd.&nbsp; That makes a paid licence different from a GNU General Public Licence.&nbsp; We can do that because Aleph One Ltd owns Yaffs completely.<br />\r\nIts other virtues are that it handles different page sizes and large numbers of files, and it is economical on other resources such as RAM.&nbsp; Like everyone else, Licence Holders have access to the continuing improvements which are being made in Yaffs.</p>\r\n\r\n<h3>What about the OS?</h3>\r\n\r\n<p>Yaffs is agnostic about the OS it is used with.&nbsp; While many users combine it with Linux, it has been used with 32-bit and 64-bit OSs and with no OS at all.&nbsp; Cases such as VxWorks and WinCE are a bit more complex.&nbsp; We have done work on a wrapper to make it easier to use Yaffs with WinCE.&nbsp; We are working on making Yaffs easy to use with VxWorks too; let us know if you are interested in the resuults.&nbsp;<br />\r\nThe relationship between the OS and the rest of Yaffs is illustrated in the diagram on the Home Page.&nbsp; At the heart of Yaffs is the Yaffs Direct Interface, which is a well-documented sub-set of Yaffs.&nbsp; Click on it in the diagram for more information.</p>\r\n\r\n<h3>How does this relate to the GPL?</h3>\r\n\r\n<p>The point of GNU General Public Licence v2 is to share work to improve Open Source software for the common good.&nbsp; A huge amount of development takes place quietly and out of the public eye, and it is released into the common pool of software so others can both benefit from it and contribute to it.<br />\r\nOpen Source software is transparent to all who use it, and its development therefore requires sharing your contributions with anyone else who wants them.&nbsp; The GPL was devised to make this possible.&nbsp; It also makes perfectly clear that the open source code is supplied AS IS and without any warranty. This shields developers and contributors from litigators who want to blame them for a fault.<br />\r\nOne user of Yaffs makes seismic monitoring equipment capable of detecting underground nuclear explosions; they require Open Source software.</p>\r\n\r\n<h3>How does the LGPL bear on all of this?</h3>\r\n\r\n<p>Because Bootloaders are often proprietary we provide with Yaffs a few kBytes of bootloader code which is licensed under LGPL, the GNU Lesser Public Licence, rather than under GPL.&nbsp; This avoids the risk of what proprietary code owners often describe as contamination of their code by code useful to Yaffs.<br />\r\nThe LGPL is shown at&nbsp; http://www.gnu.org/licenses/lgpl.html&nbsp; The tarball with modified headers you get from us will have your name only in the Yaffs file headers and not in the headers of tools such as the bootloader.&nbsp; This practice is common in the Open Source world.</p>\r\n\r\n<h3>How much does a licence from Aleph One cost?</h3>\r\n\r\n<p>The price depends a bit on the sort of market you are working in; a firm making industrial control equipment or office copiers pays a base price, but a mobile phone maker pays more.&nbsp; The base price is GBP10k. Note that is not US$ but GB Pounds Sterling.</p>\r\n\r\n<p><br />\r\nApril 2015</p>\r\n\r\n<p><br />\r\n<br />\r\n<br />\r\n<br />\r\n<br />\r\n&nbsp;</p>\r\n','<p>More on the details and background of Licences for Yaffs</p>','filtered_html'),('page',0,462,590,'und',0,'<h3>What sorts of licence are there?</h3>\r\n\r\n<p>There are two; GNU General Public Licence version 2, and Paid licences.<br />\r\nAnyone can take our Yaffs file system from http://www.yaffs.net&nbsp; free of charge; you can work and play with and test the code as much as you like, and make sure it suits your purposes. You will be doing so under the well known GNU GPL, described in detail at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</p>\r\n\r\n<h3>That sounds great! Why should I want a paid licence?</h3>\r\n\r\n<p>The GPL obliges you to release all associated code of your own that you use with any GPL software to anyone who asks for it.&nbsp; If you do not wish to release your own code, then you can buy a Licence from Aleph One Ltd which does not have that obligation.</p>\r\n\r\n<h3>What sorts of systems use Yaffs?</h3>\r\n\r\n<p>There is a wide range including GPS equipment for surveyors, sewing machines, traffic control equipment, Point-of-Sale tills, Set-Top-Boxes, DVD writers, high-end video-filming equipment and so on and on - including Android telephones!&nbsp; These have provided a very large test-bed for Yaffs, and of course they use it under GPL since Android is an Open Source project.</p>\r\n\r\n<h3>Who uses Yaffs now?</h3>\r\n\r\n<p>The Yaffs.net Home page shows (at its foot) the logos of some of the users, but the range is much wider than those displayed there.&nbsp; They tend to have in common a need for great confidence in the robustness of the FS in demanding circumstances like heavy work, accumulated cell-failures, and random power failures.&nbsp; A number of them have bought more than one Licence at different times because they know it works!</p>\r\n\r\n<h3>What are the terms of the paid licences like?</h3>\r\n\r\n<p>All Yaffs licences from Aleph One are non-exclusive, worldwide, perpetual, irrevocable and free of any royalty; they are paid for once when an agreement is signed, and they apply only to the one or more products specified at the time of the agreement.</p>\r\n\r\n<h3>What do we do next?</h3>\r\n\r\n<p>Tell us some more about the product you will use Yaffs in.&nbsp; We like the Agreement to contain a brief description of the hardware involved and the part number or product name and any internal code name.&nbsp; If you want us to sign a Non-Disclosure Agreement before you give us these details, send it to us; we are used to signing them.&nbsp; We can send you a standard form if you do not have one.<br />\r\nThen we will send a draft Agreement and price to you, and negotiate until we are both satisfied.&nbsp; Next we each sign and exchange copies of the Agreement and you pay us.</p>\r\n\r\n<h3>How does that help us?</h3>\r\n\r\n<p>After you pay for a Licence you get a tarball of files to put in your product which make clear in the file headers that you are using Yaffs under a licence from Aleph One Ltd.&nbsp; That makes a paid licence different from a GNU General Public Licence.&nbsp; We can do that because Aleph One Ltd owns Yaffs completely.<br />\r\nIts other virtues are that it handles different page sizes and large numbers of files, and it is economical on other resources such as RAM.&nbsp; Like everyone else, Licence Holders have access to the continuing improvements which are being made in Yaffs.</p>\r\n\r\n<h3>What about the OS?</h3>\r\n\r\n<p>Yaffs is agnostic about the OS it is used with.&nbsp; While many users combine it with Linux, it has been used with 32-bit and 64-bit OSs and with no OS at all.&nbsp; Cases such as VxWorks and WinCE are a bit more complex.&nbsp; We have done work on a wrapper to make it easier to use Yaffs with WinCE.&nbsp; We are working on making Yaffs easy to use with VxWorks too; let us know if you are interested in the resuults.&nbsp;<br />\r\nThe relationship between the OS and the rest of Yaffs is illustrated in the diagram on the Home Page.&nbsp; At the heart of Yaffs is the Yaffs Direct Interface, which is a well-documented sub-set of Yaffs.&nbsp; Click on it in the diagram for more information.</p>\r\n\r\n<h3>How does this relate to the GPL?</h3>\r\n\r\n<p>The point of GNU General Public Licence v2 is to share work to improve Open Source software for the common good.&nbsp; A huge amount of development takes place quietly and out of the public eye, and it is released into the common pool of software so others can both benefit from it and contribute to it.<br />\r\nOpen Source software is transparent to all who use it, and its development therefore requires sharing your contributions with anyone else who wants them.&nbsp; The GPL was devised to make this possible.&nbsp; It also makes perfectly clear that the open source code is supplied AS IS and without any warranty. This shields developers and contributors from litigators who want to blame them for a fault.<br />\r\nOne user of Yaffs makes seismic monitoring equipment capable of detecting underground nuclear explosions; they require Open Source software.</p>\r\n\r\n<h3>How does the LGPL bear on all of this?</h3>\r\n\r\n<p>Because Bootloaders are often proprietary we provide with Yaffs a few kBytes of bootloader code which is licensed under LGPL, the GNU Lesser Public Licence, rather than under GPL.&nbsp; This avoids the risk of what proprietary code owners often describe as contamination of their code by code useful to Yaffs.<br />\r\nThe LGPL is shown at&nbsp; http://www.gnu.org/licenses/lgpl.html&nbsp; The tarball with modified headers you get from us will have your name only in the Yaffs file headers and not in the headers of tools such as the bootloader.&nbsp; This practice is common in the Open Source world.</p>\r\n\r\n<h3>How much does a licence from Aleph One cost?</h3>\r\n\r\n<p>The price depends a bit on the sort of market you are working in; a firm making industrial control equipment or office copiers pays a base price, but a mobile phone maker pays more.&nbsp; The base price is GBP10k. Note that is not US$ but GB Pounds Sterling.</p>\r\n\r\n<p><br />\r\nApril 2015</p>\r\n\r\n<p><br />\r\n<br />\r\n<br />\r\n<br />\r\n<br />\r\n&nbsp;</p>\r\n','<p>More on the details and background of Licences for Yaffs</p>','basic_html'),('paper',0,466,486,'und',0,'<h2>Introduction</h2>\r\n\r\n<p>As embedded system complexity increases and flash storage prices decrease, we see more use of embedded file systems to store data, and so data corruption and loss has become an important cause of system failure.</p>\r\n\r\n<p>When Aleph One began the development of Yaffs in late 2001, we built on experience in flash file system design since 1995. This experience helped to identify the key factors in making Yaffs a fast and robust flash file system now being widely used around the world.</p>\r\n\r\n<p>Although it was originally developed for Linux, Yaffs was designed to be highly portable. This has allowed Yaffs to be ported to many different OSs (including Linux, BSD, Windows CE) and numerous RTOSs (including VxWorks, eCos and pSOS).</p>\r\n\r\n<p>Yaffs is written in fully portable C code and has been used on many different CPU architectures – both little- and big-endian. These include ARM, x86 and PowerPC, soft cores such as NIOS and Microblaze and even various DSP architectures.</p>\r\n\r\n<p>We believe that the Yaffs code base has been used on more OS types and more CPU types than any other file system code base.</p>\r\n\r\n<p>Since its introduction, Yaffs has been used in hundreds of different products and hundreds of millions of different devices in widely diverse application areas from mining to aerospace and everything in between.</p>\r\n\r\n<p>Specific examples include:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>communications (two-way radios and infrastructure, mobile phones, cell towers, modems, routers...)</p>\r\n	</li>\r\n	<li>\r\n	<p>retail (point of sale, inventory control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>entertaiment (video cameras, TV sets, DVD players, set-top boxes...)</p>\r\n	</li>\r\n	<li>\r\n	<p>sewing machines and office copiers</p>\r\n	</li>\r\n	<li>\r\n	<p>industrial equipment (PLCs, machinery control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>construction/surveying equipment (theodolites, machinery control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>avionics and satellite equipment</p>\r\n	</li>\r\n	<li>\r\n	<p>transport (bus, train and traffic-signal management/information systems...)</p>\r\n	</li>\r\n	<li>\r\n	<p>and many more.<br />\r\n	&nbsp;</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>You may be using Yaffs every day without even realising it.</strong></em></p>\r\n\r\n<p><em><strong>We have a gratifying number of repeat customers for licences.</strong></em></p>\r\n\r\n<h2>Do Embedded Systems have different file system needs?</h2>\r\n\r\n<p>To answer this question, we really have to start by asking a slightly different question:</p>\r\n\r\n<p><em>How are embedded systems different than regular computers?</em></p>\r\n\r\n<p>When a customer buys a regular computer system, they go shopping for a computer. They talk to the salesperson about Gigabytes, Megahertz and operating systems. They treat it as a computer and expect it to behave like a computer (including shutting it down properly and occasionally having file system problems or needing upgrades).</p>\r\n\r\n<p>When they buy a fancy sewing machine, it probably has an embedded file system controlling it. The customer went shopping for a sewing machine and bought a computer that they don\'t even know about. They don\'t treat it like a computer, but like a sewing machine; they certainly do not expect it to have file system problems.</p>\r\n\r\n<h4>How people treat computers differently from embedded systems</h4>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Issue</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Computer</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Embedded system</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Shut down</p>\r\n			</td>\r\n			<td>\r\n			<p>User expects to do a clean shut down.</p>\r\n			</td>\r\n			<td>\r\n			<p>User just unplugs device.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Reinstalling software</p>\r\n			</td>\r\n			<td>\r\n			<p>Users expect to have to deal with corruption and reinstall software occasionally.</p>\r\n			</td>\r\n			<td>\r\n			<p>Users do not expect to deal with upgrades or data loss or corruption.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Software Upgrade Failure</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying</p>\r\n			</td>\r\n			<td>\r\n			<p>Can be devastating</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Attitude to data loss</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying, but expected</p>\r\n			</td>\r\n			<td>\r\n			<p>System has failed.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Cost of failure</p>\r\n			</td>\r\n			<td>\r\n			<p>Relatively minor</p>\r\n			</td>\r\n			<td>\r\n			<p>Can shut down factory or even cause injury/death.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Delayed boot due to file system recovery</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying, but expected.</p>\r\n			</td>\r\n			<td>\r\n			<p>This is as bad as a failure.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>So people have different attitudes to computers and embedded systems. As a result, embedded systems need to be designed differently from computers. That is particularly important with reliability issues.</p>\r\n\r\n<p><em><strong>Data corruption is a leading cause of embedded system failure, product returns and warranty costs.</strong></em></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The differences outlined above show some of the reasons why embedded systems must perform differently to regular computers, particularly in the way data storage is handled. These examples allow us to identify some very important product-level criteria for embedded file systems:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>High resilience against data corruption, particularly in the event of power loss.</p>\r\n	</li>\r\n	<li>\r\n	<p>Prompt file system recovery after power loss - no excessive time penalty</p>\r\n	</li>\r\n	<li>\r\n	<p>Simple data integrity model to ensure data is not compromised.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Of course we also want the embedded file system to have some other very useful features:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>High read/write performance with low latency.</p>\r\n	</li>\r\n	<li>\r\n	<p>Familiar programming models to facilitate development.</p>\r\n	</li>\r\n	<li>\r\n	<p>Proven track record to reduce risk.</p>\r\n	</li>\r\n	<li>\r\n	<p>Full source code access to aid development.</p>\r\n	</li>\r\n	<li>\r\n	<p>Portability to provide a future-proof solution for new products.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>Selecting an appropriate file system is crucial to product success.</strong></em></p>\r\n\r\n<h2>Why does power failure corrupt data?</h2>\r\n\r\n<p>Most power fail data loss in a File System is caused through two mechanisms:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Corruption of allocation tables</p>\r\n	</li>\r\n	<li>\r\n	<p>Loss of cached data that was not yet written to the flash.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>Corruption of allocation tables and similar structures.</h3>\r\n\r\n<p>Most file systems have allocation tables, bitmaps or similar structures which hold pointers showing which parts of the file storage medium are being used and which parts of which file are stored there. These tables are critical to looking up files and data in the file system. If they are corrupted, then files and data become corrupted. In the most dramatic cases, table corruption can destroy the whole system.</p>\r\n\r\n<p>Some file systems make these tables more robust by keeping two copies, or by using journaling (which keeps a short log of changes, allowing the tables to be fixed up if the table changing gets interrupted) but this causes extra writes to the media, making the file system slower.</p>\r\n\r\n<p>These tables are typically updated many times during writing any file, so there are multiple opportunities for the tables to be corrupted or left in an inconsistent state due to a power loss.</p>\r\n\r\n<p>If power is interrupted at a critical point, then some restoration (such as Microsoft chkdsk or booting in safe mode) is often required to try to restore the tables. This may be automatic, but then system start-up is delayed.</p>\r\n\r\n<p>Yaffs is very different; it is a log structured file system which writes tagged data to the flash, and does not store allocation tables or such.</p>\r\n\r\n<p><em><strong>If it isn\'t even stored, it can\'t be corrupted!</strong></em></p>\r\n\r\n<p>This has three dramatic effects:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs has no tables, so is immune to these failure modes.</p>\r\n	</li>\r\n	<li>\r\n	<p>There are no extra tables to be written, so Yaffs does not have to resort to caching to achieve good performance.</p>\r\n	</li>\r\n	<li>\r\n	<p>Less flash writes means less flash wear, improving product life and reducing power consumption.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>When a Yaffs file system is booted, the normal boot up sequence takes care of building up system state. There is thus no need for any special restoration code to be run. A boot up after a power failure is not a special recovery condition, it is just a normal boot up.</p>\r\n\r\n<p><em><strong>Yaffs does not have, or need, special recovery handling.</strong></em></p>\r\n\r\n<h3><em><strong>Trade-off in cached data</strong></em></h3>\r\n\r\n<p>File systems tend to be inefficient in the way they write data. Writing just one file requires many changes to the allocation tables; writing many files requires far more changes, often to those same tables. By delaying those writes and holding data in RAM briefly the file system can do fewer writes to achieve the same set of changes. This can improve write speed, at a price.</p>\r\n\r\n<p>Data which has not been written but just cached in RAM is vulnerable while it is there; it can all be lost if power fails, even including some that the FS had apparently written already.</p>\r\n\r\n<p>Most file systems support functions to reduce this inefficiency and force the cache to be written out, but this may take many seconds, leaving a significant period of vulnerability, and delaying system operations. Excessive use of these functions to improve reliability will typically impair write performance.</p>\r\n\r\n<p>A particlarly serious example of critical data loss can occur if power or communication fails during a firmware upgrade. Such a failure cripples the product, which must be returned for servicing. Yaffs has caching policies and data integrity models which make it easier to avoid this kind of fatal failure, and which have been tested very extensively.</p>\r\n\r\n<p>Since Yaffs is inherently faster and simpler, it does not need deep caching. The Yaffs cache is small and used only for data alignment purposes and improving the throughput of very small reads and writes. Yaffs files are always flushed from the cache when they are closed. Yaffs also provides its own cache-flushing functions, but these are very fast because the cache is small.</p>\r\n\r\n<p><em><strong>By the time Yaffs closes a file, all the data is guaranteed to be safe on the flash.</strong></em></p>\r\n\r\n<p>This simple caching policy makes it very easy for programmers to write software that is robust against power loss and avoids obscure failure modes. The simplicity confers more reliable operation, faster product development and huge savings in development and maintenance costs.</p>\r\n\r\n<p><em><strong>Reliable file systems pay for themselves many times over.</strong></em></p>\r\n\r\n<h2>Product risk reduction</h2>\r\n\r\n<p>At first glance, a file system seems like it should be a simple body of code: just a few functions that read, write data and look things up by name. However, the reality is much more complex than that.</p>\r\n\r\n<p>One of the most challenging aspects of file systems is that errors are stored and incremental. Unlike most software errors which can be cleared by a reset, storage errors are persistent.</p>\r\n\r\n<p><em><strong>A reboot will typically not fix file-system errors.</strong></em></p>\r\n\r\n<p>Customers might tolerate a product that needs to be reset once in a while, but file system failures are often fatal. As a result, file system issues can be very damaging to long-term product reliability.</p>\r\n\r\n<p>This is further complicated by flash memory. NAND flash is the only type of semiconductor hardware which leaves the factory with known variable errors, expecting the file system software to handle the problems.</p>\r\n\r\n<p>Flash, NAND in particular, has its own failure modes and these are best handled by a file system specifically designed for NAND.</p>\r\n\r\n<p><em><strong>Yaffs was specifically designed to use with NAND and NOR flash chips.</strong></em></p>\r\n\r\n<p>Flash memory chip errors may only show up after the product has been used a while, or in a fraction of the flash parts. Typical testing during development (e.g. bench testing) will often fail to expose all types of flash chip error, and others will only be exposed during pilot- or early-production. These put release dates at risk, which can cause huge revenue losses.</p>\r\n\r\n<p>We have a few clients who only determined that they had file system issues when they did a pilot run. That prompted them to try Yaffs and get their products shipping. While we are glad they ended up with a good product, unfortunately they lost revenue and customer goodwill.</p>\r\n\r\n<p><em><strong>Finding problems late in development creates business risk.</strong></em></p>\r\n\r\n<p>It is thus not surprising that much of our business is repeat business.</p>\r\n\r\n<h2>Yaffs testing</h2>\r\n\r\n<p>Testing on its own does not create good software but it does help to verify that the software is working correctly.</p>\r\n\r\n<p>Yaffs has many automated tests that are run on a regular basis. Automated tests allow the testing to be run without human intervention, thus allowing more testing to be done.</p>\r\n\r\n<p>The tests are too numerous to discuss completely (see the Further Information below). We highlight one: the power-fail stress test.</p>\r\n\r\n<p>The power-fail stress test is a test harness that uses software simulations of flash devices and some software and scripts to simulate the effects of removing power from a Yaffs-based system while it is writing to flash. This test is normally run for 100,0000 to 1 million power-fail simulation cycles, taking many days.</p>\r\n\r\n<p>This particular test suite was originally developed in 2008 during the development of some new features. The tests are very rigorous. In the beginning, this test suite would find a problem after less than 100 power fail iterations. As we identified and fixed the bugs, this number crept up and we now run millions of cycles without seeing a single problem.</p>\r\n\r\n<p><em><strong>Yaffs survives millions of power failures in simulation test benches.</strong></em></p>\r\n\r\n<p>In addition, many of our clients have also run hardware power failure tests, using a relay and a micro-controller to kill power to the device under test. They have been very satisfied with the results.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>Licensing</h2>\r\n\r\n<p>Yaffs is available under GNU Public License V2, GPL2, from our git repository at <a href=\"http://www.yaffs.net/\">www.yaffs.net</a>. You may use that code for testing free of charge and for as long as you want.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><em>You will be using it under the conditions of GPL2 with the obligation to release your associated source code when you start to sell or distribute a product.</em></p>\r\n\r\n<p><em>We can then sell you a Licence to use Yaffs which removes that obligation and protects your intellectual property.</em></p>\r\n\r\n<p><em><strong>With Yaffs you can try before you buy!</strong></em></p>\r\n\r\n<h2>Conclusions</h2>\r\n\r\n<p>Selecting a robust flash file system is key to :</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>building a successful product.</p>\r\n	</li>\r\n	<li>\r\n	<p>reducing risk, warranty costs and liability.</p>\r\n	</li>\r\n	<li>\r\n	<p>reducing development costs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>Yaffs has proven itself and can pay for itself many times over.</strong></em></p>\r\n\r\n<h2>Further information</h2>\r\n\r\n<p>This document is intentionally brief. There are many documents at <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a> for those that want more information, including:</p>\r\n\r\n<p><strong>How Yaffs Works:</strong> detailed description of internal design.</p>\r\n\r\n<p><strong>Yaffs Robustness and Testing:</strong> how we know Yaffs handles various flash failure scenarios.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>For further information please contact <a href=\"mailto:info@yaffs.net\">info@yaffs.net</a> or access <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a></p>\r\n','Failures in an embedded File System in a product are much more serious to the user than failures in an office computer.&nbsp; Power failures and failures to cache data properly can be avoided by choosing a FFS specifically designed for reliability from the ground up.','filtered_html'),('paper',0,466,564,'und',0,'<h2>Introduction</h2>\r\n\r\n<p>As embedded system complexity increases and flash storage prices decrease, we see more use of embedded file systems to store data, and so data corruption and loss has become an important cause of system failure.</p>\r\n\r\n<p>When Aleph One began the development of Yaffs in late 2001, we built on experience in flash file system design since 1995. This experience helped to identify the key factors in making Yaffs a fast and robust flash file system now being widely used around the world.</p>\r\n\r\n<p>Although it was originally developed for Linux, Yaffs was designed to be highly portable. This has allowed Yaffs to be ported to many different OSs (including Linux, BSD, Windows CE) and numerous RTOSs (including VxWorks, eCos and pSOS).</p>\r\n\r\n<p>Yaffs is written in fully portable C code and has been used on many different CPU architectures – both little- and big-endian. These include ARM, x86 and PowerPC, soft cores such as NIOS and Microblaze and even various DSP architectures.</p>\r\n\r\n<p>We believe that the Yaffs code base has been used on more OS types and more CPU types than any other file system code base.</p>\r\n\r\n<p>Since its introduction, Yaffs has been used in hundreds of different products and hundreds of millions of different devices in widely diverse application areas from mining to aerospace and everything in between.</p>\r\n\r\n<p>Specific examples include:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>communications (two-way radios and infrastructure, mobile phones, cell towers, modems, routers...)</p>\r\n	</li>\r\n	<li>\r\n	<p>retail (point of sale, inventory control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>entertaiment (video cameras, TV sets, DVD players, set-top boxes...)</p>\r\n	</li>\r\n	<li>\r\n	<p>sewing machines and office copiers</p>\r\n	</li>\r\n	<li>\r\n	<p>industrial equipment (PLCs, machinery control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>construction/surveying equipment (theodolites, machinery control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>avionics and satellite equipment</p>\r\n	</li>\r\n	<li>\r\n	<p>transport (bus, train and traffic-signal management/information systems...)</p>\r\n	</li>\r\n	<li>\r\n	<p>and many more.<br />\r\n	&nbsp;</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>You may be using Yaffs every day without even realising it.</strong></em></p>\r\n\r\n<p><em><strong>We have a gratifying number of repeat customers for licences.</strong></em></p>\r\n\r\n<h2>Do Embedded Systems have different file system needs?</h2>\r\n\r\n<p>To answer this question, we really have to start by asking a slightly different question:</p>\r\n\r\n<p><em>How are embedded systems different than regular computers?</em></p>\r\n\r\n<p>When a customer buys a regular computer system, they go shopping for a computer. They talk to the salesperson about Gigabytes, Megahertz and operating systems. They treat it as a computer and expect it to behave like a computer (including shutting it down properly and occasionally having file system problems or needing upgrades).</p>\r\n\r\n<p>When they buy a fancy sewing machine, it probably has an embedded file system controlling it. The customer went shopping for a sewing machine and bought a computer that they don\'t even know about. They don\'t treat it like a computer, but like a sewing machine; they certainly do not expect it to have file system problems.</p>\r\n\r\n<h4>How people treat computers differently from embedded systems</h4>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Issue</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Computer</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Embedded system</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Shut down</p>\r\n			</td>\r\n			<td>\r\n			<p>User expects to do a clean shut down.</p>\r\n			</td>\r\n			<td>\r\n			<p>User just unplugs device.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Reinstalling software</p>\r\n			</td>\r\n			<td>\r\n			<p>Users expect to have to deal with corruption and reinstall software occasionally.</p>\r\n			</td>\r\n			<td>\r\n			<p>Users do not expect to deal with upgrades or data loss or corruption.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Software Upgrade Failure</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying</p>\r\n			</td>\r\n			<td>\r\n			<p>Can be devastating</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Attitude to data loss</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying, but expected</p>\r\n			</td>\r\n			<td>\r\n			<p>System has failed.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Cost of failure</p>\r\n			</td>\r\n			<td>\r\n			<p>Relatively minor</p>\r\n			</td>\r\n			<td>\r\n			<p>Can shut down factory or even cause injury/death.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Delayed boot due to file system recovery</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying, but expected.</p>\r\n			</td>\r\n			<td>\r\n			<p>This is as bad as a failure.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>So people have different attitudes to computers and embedded systems. As a result, embedded systems need to be designed differently from computers. That is particularly important with reliability issues.</p>\r\n\r\n<p><em><strong>Data corruption is a leading cause of embedded system failure, product returns and warranty costs.</strong></em></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The differences outlined above show some of the reasons why embedded systems must perform differently to regular computers, particularly in the way data storage is handled. These examples allow us to identify some very important product-level criteria for embedded file systems:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>High resilience against data corruption, particularly in the event of power loss.</p>\r\n	</li>\r\n	<li>\r\n	<p>Prompt file system recovery after power loss - no excessive time penalty</p>\r\n	</li>\r\n	<li>\r\n	<p>Simple data integrity model to ensure data is not compromised.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Of course we also want the embedded file system to have some other very useful features:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>High read/write performance with low latency.</p>\r\n	</li>\r\n	<li>\r\n	<p>Familiar programming models to facilitate development.</p>\r\n	</li>\r\n	<li>\r\n	<p>Proven track record to reduce risk.</p>\r\n	</li>\r\n	<li>\r\n	<p>Full source code access to aid development.</p>\r\n	</li>\r\n	<li>\r\n	<p>Portability to provide a future-proof solution for new products.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>Selecting an appropriate file system is crucial to product success.</strong></em></p>\r\n\r\n<h2>Why does power failure corrupt data?</h2>\r\n\r\n<p>Most power fail data loss in a File System is caused through two mechanisms:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Corruption of allocation tables</p>\r\n	</li>\r\n	<li>\r\n	<p>Loss of cached data that was not yet written to the flash.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>Corruption of allocation tables and similar structures.</h3>\r\n\r\n<p>Most file systems have allocation tables, bitmaps or similar structures which hold pointers showing which parts of the file storage medium are being used and which parts of which file are stored there. These tables are critical to looking up files and data in the file system. If they are corrupted, then files and data become corrupted. In the most dramatic cases, table corruption can destroy the whole system.</p>\r\n\r\n<p>Some file systems make these tables more robust by keeping two copies, or by using journaling (which keeps a short log of changes, allowing the tables to be fixed up if the table changing gets interrupted) but this causes extra writes to the media, making the file system slower.</p>\r\n\r\n<p>These tables are typically updated many times during writing any file, so there are multiple opportunities for the tables to be corrupted or left in an inconsistent state due to a power loss.</p>\r\n\r\n<p>If power is interrupted at a critical point, then some restoration (such as Microsoft chkdsk or booting in safe mode) is often required to try to restore the tables. This may be automatic, but then system start-up is delayed.</p>\r\n\r\n<p>Yaffs is very different; it is a log structured file system which writes tagged data to the flash, and does not store allocation tables or such.</p>\r\n\r\n<p><em><strong>If it isn\'t even stored, it can\'t be corrupted!</strong></em></p>\r\n\r\n<p>This has three dramatic effects:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs has no tables, so is immune to these failure modes.</p>\r\n	</li>\r\n	<li>\r\n	<p>There are no extra tables to be written, so Yaffs does not have to resort to caching to achieve good performance.</p>\r\n	</li>\r\n	<li>\r\n	<p>Less flash writes means less flash wear, improving product life and reducing power consumption.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>When a Yaffs file system is booted, the normal boot up sequence takes care of building up system state. There is thus no need for any special restoration code to be run. A boot up after a power failure is not a special recovery condition, it is just a normal boot up.</p>\r\n\r\n<p><em><strong>Yaffs does not have, or need, special recovery handling.</strong></em></p>\r\n\r\n<h3><em><strong>Trade-off in cached data</strong></em></h3>\r\n\r\n<p>File systems tend to be inefficient in the way they write data. Writing just one file requires many changes to the allocation tables; writing many files requires far more changes, often to those same tables. By delaying those writes and holding data in RAM briefly the file system can do fewer writes to achieve the same set of changes. This can improve write speed, at a price.</p>\r\n\r\n<p>Data which has not been written but just cached in RAM is vulnerable while it is there; it can all be lost if power fails, even including some that the FS had apparently written already.</p>\r\n\r\n<p>Most file systems support functions to reduce this inefficiency and force the cache to be written out, but this may take many seconds, leaving a significant period of vulnerability, and delaying system operations. Excessive use of these functions to improve reliability will typically impair write performance.</p>\r\n\r\n<p>A particlarly serious example of critical data loss can occur if power or communication fails during a firmware upgrade. Such a failure cripples the product, which must be returned for servicing. Yaffs has caching policies and data integrity models which make it easier to avoid this kind of fatal failure, and which have been tested very extensively.</p>\r\n\r\n<p>Since Yaffs is inherently faster and simpler, it does not need deep caching. The Yaffs cache is small and used only for data alignment purposes and improving the throughput of very small reads and writes. Yaffs files are always flushed from the cache when they are closed. Yaffs also provides its own cache-flushing functions, but these are very fast because the cache is small.</p>\r\n\r\n<p><em><strong>By the time Yaffs closes a file, all the data is guaranteed to be safe on the flash.</strong></em></p>\r\n\r\n<p>This simple caching policy makes it very easy for programmers to write software that is robust against power loss and avoids obscure failure modes. The simplicity confers more reliable operation, faster product development and huge savings in development and maintenance costs.</p>\r\n\r\n<p><em><strong>Reliable file systems pay for themselves many times over.</strong></em></p>\r\n\r\n<h2>Product risk reduction</h2>\r\n\r\n<p>At first glance, a file system seems like it should be a simple body of code: just a few functions that read, write data and look things up by name. However, the reality is much more complex than that.</p>\r\n\r\n<p>One of the most challenging aspects of file systems is that errors are stored and incremental. Unlike most software errors which can be cleared by a reset, storage errors are persistent.</p>\r\n\r\n<p><em><strong>A reboot will typically not fix file-system errors.</strong></em></p>\r\n\r\n<p>Customers might tolerate a product that needs to be reset once in a while, but file system failures are often fatal. As a result, file system issues can be very damaging to long-term product reliability.</p>\r\n\r\n<p>This is further complicated by flash memory. NAND flash is the only type of semiconductor hardware which leaves the factory with known variable errors, expecting the file system software to handle the problems.</p>\r\n\r\n<p>Flash, NAND in particular, has its own failure modes and these are best handled by a file system specifically designed for NAND.</p>\r\n\r\n<p><em><strong>Yaffs was specifically designed to use with NAND and NOR flash chips.</strong></em></p>\r\n\r\n<p>Flash memory chip errors may only show up after the product has been used a while, or in a fraction of the flash parts. Typical testing during development (e.g. bench testing) will often fail to expose all types of flash chip error, and others will only be exposed during pilot- or early-production. These put release dates at risk, which can cause huge revenue losses.</p>\r\n\r\n<p>We have a few clients who only determined that they had file system issues when they did a pilot run. That prompted them to try Yaffs and get their products shipping. While we are glad they ended up with a good product, unfortunately they lost revenue and customer goodwill.</p>\r\n\r\n<p><em><strong>Finding problems late in development creates business risk.</strong></em></p>\r\n\r\n<p>It is thus not surprising that much of our business is repeat business.</p>\r\n\r\n<h2>Yaffs testing</h2>\r\n\r\n<p>Testing on its own does not create good software but it does help to verify that the software is working correctly.</p>\r\n\r\n<p>Yaffs has many automated tests that are run on a regular basis. Automated tests allow the testing to be run without human intervention, thus allowing more testing to be done.</p>\r\n\r\n<p>The tests are too numerous to discuss completely (see the Further Information below). We highlight one: the power-fail stress test.</p>\r\n\r\n<p>The power-fail stress test is a test harness that uses software simulations of flash devices and some software and scripts to simulate the effects of removing power from a Yaffs-based system while it is writing to flash. This test is normally run for 100,0000 to 1 million power-fail simulation cycles, taking many days.</p>\r\n\r\n<p>This particular test suite was originally developed in 2008 during the development of some new features. The tests are very rigorous. In the beginning, this test suite would find a problem after less than 100 power fail iterations. As we identified and fixed the bugs, this number crept up and we now run millions of cycles without seeing a single problem.</p>\r\n\r\n<p><em><strong>Yaffs survives millions of power failures in simulation test benches.</strong></em></p>\r\n\r\n<p>In addition, many of our clients have also run hardware power failure tests, using a relay and a micro-controller to kill power to the device under test. They have been very satisfied with the results.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>Licensing</h2>\r\n\r\n<p>Yaffs is available under GNU Public License V2, GPL2, from our git repository at <a href=\"http://www.yaffs.net/\">www.yaffs.net</a>. You may use that code for testing free of charge and for as long as you want.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><em>You will be using it under the conditions of GPL2 with the obligation to release your associated source code when you start to sell or distribute a product.</em></p>\r\n\r\n<p><em>We can then sell you a Licence to use Yaffs which removes that obligation and protects your intellectual property.</em></p>\r\n\r\n<p><em><strong>With Yaffs you can try before you buy!</strong></em></p>\r\n\r\n<h2>Conclusions</h2>\r\n\r\n<p>Selecting a robust flash file system is key to :</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>building a successful product.</p>\r\n	</li>\r\n	<li>\r\n	<p>reducing risk, warranty costs and liability.</p>\r\n	</li>\r\n	<li>\r\n	<p>reducing development costs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>Yaffs has proven itself and can pay for itself many times over.</strong></em></p>\r\n\r\n<h2>Further information</h2>\r\n\r\n<p>This document is intentionally brief. There are many documents at <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a> for those that want more information, including:</p>\r\n\r\n<p><strong>How Yaffs Works:</strong> detailed description of internal design.</p>\r\n\r\n<p><strong>Yaffs Robustness and Testing:</strong> how we know Yaffs handles various flash failure scenarios.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>For further information please contact <a href=\"mailto:info@yaffs.net\">info@yaffs.net</a> or access <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a></p>\r\n','Failures in an embedded File System in a product are much more serious to the user than failures in an office computer.&nbsp; Power failures and failures to cache data properly can be avoided by choosing a FFS specifically designed for reliability from the ground up.','filtered_html'),('paper',0,466,591,'und',0,'<h2>Introduction</h2>\r\n\r\n<p>As embedded system complexity increases and flash storage prices decrease, we see more use of embedded file systems to store data, and so data corruption and loss has become an important cause of system failure.</p>\r\n\r\n<p>When Aleph One began the development of Yaffs in late 2001, we built on experience in flash file system design since 1995. This experience helped to identify the key factors in making Yaffs a fast and robust flash file system now being widely used around the world.</p>\r\n\r\n<p>Although it was originally developed for Linux, Yaffs was designed to be highly portable. This has allowed Yaffs to be ported to many different OSs (including Linux, BSD, Windows CE) and numerous RTOSs (including VxWorks, eCos and pSOS).</p>\r\n\r\n<p>Yaffs is written in fully portable C code and has been used on many different CPU architectures – both little- and big-endian. These include ARM, x86 and PowerPC, soft cores such as NIOS and Microblaze and even various DSP architectures.</p>\r\n\r\n<p>We believe that the Yaffs code base has been used on more OS types and more CPU types than any other file system code base.</p>\r\n\r\n<p>Since its introduction, Yaffs has been used in hundreds of different products and hundreds of millions of different devices in widely diverse application areas from mining to aerospace and everything in between.</p>\r\n\r\n<p>Specific examples include:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>communications (two-way radios and infrastructure, mobile phones, cell towers, modems, routers...)</p>\r\n	</li>\r\n	<li>\r\n	<p>retail (point of sale, inventory control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>entertaiment (video cameras, TV sets, DVD players, set-top boxes...)</p>\r\n	</li>\r\n	<li>\r\n	<p>sewing machines and office copiers</p>\r\n	</li>\r\n	<li>\r\n	<p>industrial equipment (PLCs, machinery control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>construction/surveying equipment (theodolites, machinery control...)</p>\r\n	</li>\r\n	<li>\r\n	<p>avionics and satellite equipment</p>\r\n	</li>\r\n	<li>\r\n	<p>transport (bus, train and traffic-signal management/information systems...)</p>\r\n	</li>\r\n	<li>\r\n	<p>and many more.<br />\r\n	&nbsp;</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>You may be using Yaffs every day without even realising it.</strong></em></p>\r\n\r\n<p><em><strong>We have a gratifying number of repeat customers for licences.</strong></em></p>\r\n\r\n<h2>Do Embedded Systems have different file system needs?</h2>\r\n\r\n<p>To answer this question, we really have to start by asking a slightly different question:</p>\r\n\r\n<p><em>How are embedded systems different than regular computers?</em></p>\r\n\r\n<p>When a customer buys a regular computer system, they go shopping for a computer. They talk to the salesperson about Gigabytes, Megahertz and operating systems. They treat it as a computer and expect it to behave like a computer (including shutting it down properly and occasionally having file system problems or needing upgrades).</p>\r\n\r\n<p>When they buy a fancy sewing machine, it probably has an embedded file system controlling it. The customer went shopping for a sewing machine and bought a computer that they don\'t even know about. They don\'t treat it like a computer, but like a sewing machine; they certainly do not expect it to have file system problems.</p>\r\n\r\n<h4>How people treat computers differently from embedded systems</h4>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Issue</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Computer</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Embedded system</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Shut down</p>\r\n			</td>\r\n			<td>\r\n			<p>User expects to do a clean shut down.</p>\r\n			</td>\r\n			<td>\r\n			<p>User just unplugs device.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Reinstalling software</p>\r\n			</td>\r\n			<td>\r\n			<p>Users expect to have to deal with corruption and reinstall software occasionally.</p>\r\n			</td>\r\n			<td>\r\n			<p>Users do not expect to deal with upgrades or data loss or corruption.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Software Upgrade Failure</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying</p>\r\n			</td>\r\n			<td>\r\n			<p>Can be devastating</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Attitude to data loss</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying, but expected</p>\r\n			</td>\r\n			<td>\r\n			<p>System has failed.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Cost of failure</p>\r\n			</td>\r\n			<td>\r\n			<p>Relatively minor</p>\r\n			</td>\r\n			<td>\r\n			<p>Can shut down factory or even cause injury/death.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Delayed boot due to file system recovery</p>\r\n			</td>\r\n			<td>\r\n			<p>Annoying, but expected.</p>\r\n			</td>\r\n			<td>\r\n			<p>This is as bad as a failure.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>So people have different attitudes to computers and embedded systems. As a result, embedded systems need to be designed differently from computers. That is particularly important with reliability issues.</p>\r\n\r\n<p><em><strong>Data corruption is a leading cause of embedded system failure, product returns and warranty costs.</strong></em></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The differences outlined above show some of the reasons why embedded systems must perform differently to regular computers, particularly in the way data storage is handled. These examples allow us to identify some very important product-level criteria for embedded file systems:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>High resilience against data corruption, particularly in the event of power loss.</p>\r\n	</li>\r\n	<li>\r\n	<p>Prompt file system recovery after power loss - no excessive time penalty</p>\r\n	</li>\r\n	<li>\r\n	<p>Simple data integrity model to ensure data is not compromised.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Of course we also want the embedded file system to have some other very useful features:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>High read/write performance with low latency.</p>\r\n	</li>\r\n	<li>\r\n	<p>Familiar programming models to facilitate development.</p>\r\n	</li>\r\n	<li>\r\n	<p>Proven track record to reduce risk.</p>\r\n	</li>\r\n	<li>\r\n	<p>Full source code access to aid development.</p>\r\n	</li>\r\n	<li>\r\n	<p>Portability to provide a future-proof solution for new products.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>Selecting an appropriate file system is crucial to product success.</strong></em></p>\r\n\r\n<h2>Why does power failure corrupt data?</h2>\r\n\r\n<p>Most power fail data loss in a File System is caused through two mechanisms:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Corruption of allocation tables</p>\r\n	</li>\r\n	<li>\r\n	<p>Loss of cached data that was not yet written to the flash.</p>\r\n	</li>\r\n</ul>\r\n\r\n<h3>Corruption of allocation tables and similar structures.</h3>\r\n\r\n<p>Most file systems have allocation tables, bitmaps or similar structures which hold pointers showing which parts of the file storage medium are being used and which parts of which file are stored there. These tables are critical to looking up files and data in the file system. If they are corrupted, then files and data become corrupted. In the most dramatic cases, table corruption can destroy the whole system.</p>\r\n\r\n<p>Some file systems make these tables more robust by keeping two copies, or by using journaling (which keeps a short log of changes, allowing the tables to be fixed up if the table changing gets interrupted) but this causes extra writes to the media, making the file system slower.</p>\r\n\r\n<p>These tables are typically updated many times during writing any file, so there are multiple opportunities for the tables to be corrupted or left in an inconsistent state due to a power loss.</p>\r\n\r\n<p>If power is interrupted at a critical point, then some restoration (such as Microsoft chkdsk or booting in safe mode) is often required to try to restore the tables. This may be automatic, but then system start-up is delayed.</p>\r\n\r\n<p>Yaffs is very different; it is a log structured file system which writes tagged data to the flash, and does not store allocation tables or such.</p>\r\n\r\n<p><em><strong>If it isn\'t even stored, it can\'t be corrupted!</strong></em></p>\r\n\r\n<p>This has three dramatic effects:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Yaffs has no tables, so is immune to these failure modes.</p>\r\n	</li>\r\n	<li>\r\n	<p>There are no extra tables to be written, so Yaffs does not have to resort to caching to achieve good performance.</p>\r\n	</li>\r\n	<li>\r\n	<p>Less flash writes means less flash wear, improving product life and reducing power consumption.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>When a Yaffs file system is booted, the normal boot up sequence takes care of building up system state. There is thus no need for any special restoration code to be run. A boot up after a power failure is not a special recovery condition, it is just a normal boot up.</p>\r\n\r\n<p><em><strong>Yaffs does not have, or need, special recovery handling.</strong></em></p>\r\n\r\n<h3><em><strong>Trade-off in cached data</strong></em></h3>\r\n\r\n<p>File systems tend to be inefficient in the way they write data. Writing just one file requires many changes to the allocation tables; writing many files requires far more changes, often to those same tables. By delaying those writes and holding data in RAM briefly the file system can do fewer writes to achieve the same set of changes. This can improve write speed, at a price.</p>\r\n\r\n<p>Data which has not been written but just cached in RAM is vulnerable while it is there; it can all be lost if power fails, even including some that the FS had apparently written already.</p>\r\n\r\n<p>Most file systems support functions to reduce this inefficiency and force the cache to be written out, but this may take many seconds, leaving a significant period of vulnerability, and delaying system operations. Excessive use of these functions to improve reliability will typically impair write performance.</p>\r\n\r\n<p>A particlarly serious example of critical data loss can occur if power or communication fails during a firmware upgrade. Such a failure cripples the product, which must be returned for servicing. Yaffs has caching policies and data integrity models which make it easier to avoid this kind of fatal failure, and which have been tested very extensively.</p>\r\n\r\n<p>Since Yaffs is inherently faster and simpler, it does not need deep caching. The Yaffs cache is small and used only for data alignment purposes and improving the throughput of very small reads and writes. Yaffs files are always flushed from the cache when they are closed. Yaffs also provides its own cache-flushing functions, but these are very fast because the cache is small.</p>\r\n\r\n<p><em><strong>By the time Yaffs closes a file, all the data is guaranteed to be safe on the flash.</strong></em></p>\r\n\r\n<p>This simple caching policy makes it very easy for programmers to write software that is robust against power loss and avoids obscure failure modes. The simplicity confers more reliable operation, faster product development and huge savings in development and maintenance costs.</p>\r\n\r\n<p><em><strong>Reliable file systems pay for themselves many times over.</strong></em></p>\r\n\r\n<h2>Product risk reduction</h2>\r\n\r\n<p>At first glance, a file system seems like it should be a simple body of code: just a few functions that read, write data and look things up by name. However, the reality is much more complex than that.</p>\r\n\r\n<p>One of the most challenging aspects of file systems is that errors are stored and incremental. Unlike most software errors which can be cleared by a reset, storage errors are persistent.</p>\r\n\r\n<p><em><strong>A reboot will typically not fix file-system errors.</strong></em></p>\r\n\r\n<p>Customers might tolerate a product that needs to be reset once in a while, but file system failures are often fatal. As a result, file system issues can be very damaging to long-term product reliability.</p>\r\n\r\n<p>This is further complicated by flash memory. NAND flash is the only type of semiconductor hardware which leaves the factory with known variable errors, expecting the file system software to handle the problems.</p>\r\n\r\n<p>Flash, NAND in particular, has its own failure modes and these are best handled by a file system specifically designed for NAND.</p>\r\n\r\n<p><em><strong>Yaffs was specifically designed to use with NAND and NOR flash chips.</strong></em></p>\r\n\r\n<p>Flash memory chip errors may only show up after the product has been used a while, or in a fraction of the flash parts. Typical testing during development (e.g. bench testing) will often fail to expose all types of flash chip error, and others will only be exposed during pilot- or early-production. These put release dates at risk, which can cause huge revenue losses.</p>\r\n\r\n<p>We have a few clients who only determined that they had file system issues when they did a pilot run. That prompted them to try Yaffs and get their products shipping. While we are glad they ended up with a good product, unfortunately they lost revenue and customer goodwill.</p>\r\n\r\n<p><em><strong>Finding problems late in development creates business risk.</strong></em></p>\r\n\r\n<p>It is thus not surprising that much of our business is repeat business.</p>\r\n\r\n<h2>Yaffs testing</h2>\r\n\r\n<p>Testing on its own does not create good software but it does help to verify that the software is working correctly.</p>\r\n\r\n<p>Yaffs has many automated tests that are run on a regular basis. Automated tests allow the testing to be run without human intervention, thus allowing more testing to be done.</p>\r\n\r\n<p>The tests are too numerous to discuss completely (see the Further Information below). We highlight one: the power-fail stress test.</p>\r\n\r\n<p>The power-fail stress test is a test harness that uses software simulations of flash devices and some software and scripts to simulate the effects of removing power from a Yaffs-based system while it is writing to flash. This test is normally run for 100,0000 to 1 million power-fail simulation cycles, taking many days.</p>\r\n\r\n<p>This particular test suite was originally developed in 2008 during the development of some new features. The tests are very rigorous. In the beginning, this test suite would find a problem after less than 100 power fail iterations. As we identified and fixed the bugs, this number crept up and we now run millions of cycles without seeing a single problem.</p>\r\n\r\n<p><em><strong>Yaffs survives millions of power failures in simulation test benches.</strong></em></p>\r\n\r\n<p>In addition, many of our clients have also run hardware power failure tests, using a relay and a micro-controller to kill power to the device under test. They have been very satisfied with the results.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>Licensing</h2>\r\n\r\n<p>Yaffs is available under GNU Public License V2, GPL2, from our git repository at <a href=\"http://www.yaffs.net/\">www.yaffs.net</a>. You may use that code for testing free of charge and for as long as you want.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><em>You will be using it under the conditions of GPL2 with the obligation to release your associated source code when you start to sell or distribute a product.</em></p>\r\n\r\n<p><em>We can then sell you a Licence to use Yaffs which removes that obligation and protects your intellectual property.</em></p>\r\n\r\n<p><em><strong>With Yaffs you can try before you buy!</strong></em></p>\r\n\r\n<h2>Conclusions</h2>\r\n\r\n<p>Selecting a robust flash file system is key to :</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>building a successful product.</p>\r\n	</li>\r\n	<li>\r\n	<p>reducing risk, warranty costs and liability.</p>\r\n	</li>\r\n	<li>\r\n	<p>reducing development costs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p><em><strong>Yaffs has proven itself and can pay for itself many times over.</strong></em></p>\r\n\r\n<h2>Further information</h2>\r\n\r\n<p>This document is intentionally brief. There are many documents at <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a> for those that want more information, including:</p>\r\n\r\n<p><strong>How Yaffs Works:</strong> detailed description of internal design.</p>\r\n\r\n<p><strong>Yaffs Robustness and Testing:</strong> how we know Yaffs handles various flash failure scenarios.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>For further information please contact <a href=\"mailto:info@yaffs.net\">info@yaffs.net</a> or access <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a></p>\r\n','Failures in an embedded File System in a product are much more serious to the user than failures in an office computer.&nbsp; Power failures and failures to cache data properly can be avoided by choosing a FFS specifically designed for reliability from the ground up.','full_html'),('paper',0,466,602,'und',0,'	<p class=\"western\">We have been developing flash file system for\r\n	embedded systems since 1995. During that time, we have gained a\r\n	wealth of knowledge and experience.</p>\r\n	<p class=\"western\">This document outlines some of the major issues\r\n	that must be considered when selecting a Flash File system for\r\n	embedded use. It also explains how using the Yaffs File System\r\n	increases reliability, reduces risk and saves money.</p>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Introduction</h1>\r\n<p class=\"western\" align=\"left\">As embedded system complexity\r\nincreases and flash storage prices decrease, we see more use of\r\nembedded file systems to store data, and so data corruption and loss\r\nhas become an important cause of system failure.</p>\r\n<p class=\"western\" align=\"left\">When Aleph One began the development\r\nof Yaffs in late 2001, we built on experience in flash file system\r\ndesign since 1995. This experience helped to identify the key factors\r\nin making Yaffs a fast and robust flash file system now being widely\r\nused around the world.</p>\r\n<p class=\"western\" align=\"left\">Although it was originally developed\r\nfor Linux, Yaffs was designed to be highly portable. This has allowed\r\nYaffs to be ported to many different OSs (including Linux, BSD,\r\nWindows CE) and numerous RTOSs (including VxWorks, eCos and pSOS).</p>\r\n<p class=\"western\" align=\"left\">Yaffs is written in fully portable C\r\ncode and has been used on many different CPU architectures – both\r\nlittle- and big-endian. These include ARM, x86 and PowerPC, soft\r\ncores such as NIOS and Microblaze and even various DSP architectures.</p>\r\n<p class=\"western\" align=\"left\">We believe that the Yaffs code base\r\nhas been used on more OS types and more CPU types than any other file\r\nsystem code base.</p>\r\n<p class=\"western\" align=\"left\">Since its introduction, Yaffs has\r\nbeen used in hundreds of different products and hundreds of millions\r\nof different devices in widely diverse application areas from mining\r\nto aerospace and everything in between.</p>\r\n<p class=\"western\" align=\"left\">Specific examples include:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">communications (two-way radios\r\n	and infrastructure, mobile phones, cell towers, modems, routers...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">retail (point of sale,\r\n	inventory control...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">entertaiment (video cameras,\r\n	TV sets, DVD players, set-top boxes...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">sewing machines and office\r\n	copiers</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">industrial equipment (PLCs,\r\n	machinery control...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">construction/surveying\r\n	equipment (theodolites, machinery control...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">avionics and satellite\r\n	equipment</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">transport (bus, train and\r\n	traffic-signal management/information systems...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">and many more.</p>\r\n</ul>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"center\"><i><b>You may be using Yaffs every\r\nday without even realising it.</b></i></p>\r\n<p class=\"western\" align=\"center\"><i><b>We have a gratifying number\r\nof repeat customers for licences.</b></i></p>\r\n<h1 class=\"western\"><br/>\r\n<br/>\r\n\r\n</h1>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Do Embedded\r\nSystems have different file system needs?</h1>\r\n<p class=\"western\">To answer this question, we really have to start\r\nby asking a slightly different question:</p>\r\n<p class=\"western\" align=\"center\"><i>How are embedded systems\r\ndifferent than regular computers?</i></p>\r\n<p class=\"western\" align=\"justify\" style=\"font-style: normal\">When a\r\ncustomer buys a regular computer system, they go shopping for a\r\ncomputer. They talk to the salesperson about Gigabytes, Megahertz and\r\noperating systems. They treat it as a computer and expect it to\r\nbehave like a computer (including shutting it down properly and\r\noccasionally having file system problems or needing upgrades).</p>\r\n<p class=\"western\" align=\"justify\" style=\"font-style: normal\">When\r\nthey buy a fancy sewing machine, it probably has an embedded file\r\nsystem controlling it. The customer went shopping for a sewing\r\nmachine and bought a computer that they don\'t even know about. They\r\ndon\'t treat it like a computer, but like a sewing machine; they\r\ncertainly do not expect it to have file system problems.</p>\r\n<h4 class=\"western\">How people treat computers differently from\r\nembedded systems</h4>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"85*\">\r\n	<col width=\"85*\">\r\n	<col width=\"85*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\"><b>Issue</b></font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\"><b>Computer</b></font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\"><b>Embedded\r\n			system</b></font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Shut\r\n			down</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">User\r\n			expects to do a clean shut down.</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">User\r\n			just unplugs device.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Reinstalling\r\n			software</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Users\r\n			expect to have to deal with corruption and reinstall software\r\n			occasionally.</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Users\r\n			do not expect to deal with upgrades or data loss or corruption.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" height=\"11\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Software\r\n			Upgrade Failure</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Annoying</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Can\r\n			be devastating</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Attitude\r\n			to data loss</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Annoying,\r\n			but expected</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">System\r\n			has failed.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Cost\r\n			of failure</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Relatively\r\n			minor</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Can\r\n			shut down factory or even cause injury/death.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Delayed\r\n			boot due to file system recovery</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Annoying,\r\n			but expected.</font></p>\r\n		</td>\r\n		<td width=\"33%\" 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\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">This\r\n			is as bad as a failure.</font></p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\" align=\"left\" style=\"font-style: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"justify\">So people have different attitudes\r\nto computers and embedded systems. As a result, embedded systems need\r\nto be designed differently from computers. That is particularly\r\nimportant with reliability issues.</p>\r\n<p class=\"western\" align=\"center\" style=\"margin-bottom: 0.01cm\"><i><b>Data\r\ncorruption is a leading cause of embedded system failure, </b></i>\r\n</p>\r\n<p class=\"western\" align=\"center\" style=\"margin-bottom: 0.01cm\"><i><b>product\r\nreturns and warranty costs.</b></i> \r\n</p>\r\n<p class=\"western\" align=\"center\" style=\"margin-bottom: 0.01cm\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"justify\">The differences outlined above\r\nshow some of the reasons why embedded systems must perform\r\ndifferently to regular computers, particularly in the way data\r\nstorage is handled. These examples allow us to identify some very\r\nimportant product-level criteria for embedded file systems:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">High resilience against data\r\n	corruption, particularly in the event of power loss.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Prompt file system recovery\r\n	after power loss - no excessive time penalty</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Simple data integrity model to\r\n	ensure data is not compromised.</p>\r\n</ul>\r\n<p class=\"western\" align=\"left\">Of course we also want the embedded\r\nfile system to have some other very useful features:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">High read/write performance\r\n	with low latency.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Familiar programming models to\r\n	facilitate development.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Proven track record to reduce\r\n	risk.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Full source code access to aid\r\n	development.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Portability to provide a\r\n	future-proof solution for new products.</p>\r\n</ul>\r\n<p class=\"western\" align=\"center\"><i><b>Selecting an appropriate file\r\nsystem is crucial to product success.</b></i></p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Why does power\r\nfailure corrupt data?</h1>\r\n<p class=\"western\">Most power fail data loss in a File System is\r\ncaused through two mechanisms:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Corruption of allocation tables \r\n	</p>\r\n	<li/>\r\n<p class=\"western\">Loss of cached data that was not yet\r\n	written to the flash.</p>\r\n</ul>\r\n<h2 class=\"western\">Corruption of allocation tables and similar\r\nstructures.</h2>\r\n<p class=\"western\">Most file systems have allocation tables, bitmaps\r\nor similar structures which hold pointers showing which parts of the\r\nfile storage medium are being used and which parts of which file are\r\nstored there. These tables are critical to looking up files and data\r\nin the file system. If they are corrupted, then files and data become\r\ncorrupted. In the most dramatic cases, table corruption can destroy\r\nthe whole system.  \r\n</p>\r\n<p class=\"western\">Some file systems make these tables more robust by\r\nkeeping two copies, or by using journaling (which keeps a short log\r\nof changes, allowing the tables to be fixed up if the table changing\r\ngets interrupted) but this causes extra writes to the media, making\r\nthe file system slower.</p>\r\n<p class=\"western\">These tables are typically updated many times\r\nduring writing any file, so there are multiple opportunities for the\r\ntables to be corrupted or left in an inconsistent state due to a\r\npower loss.</p>\r\n<p class=\"western\">If power is interrupted at a critical point, then\r\nsome restoration (such as Microsoft chkdsk or booting in <span style=\"font-style: normal\">safe\r\nmode</span>) is often required to try to restore the tables. This may\r\nbe automatic, but then system start-up is delayed.</p>\r\n<p class=\"western\">Yaffs is very different; it is a log structured\r\nfile system which writes tagged data to the flash, and does not store\r\nallocation tables or such.</p>\r\n<p class=\"western\" align=\"center\"><i><b>If it isn\'t even stored, it\r\ncan\'t be corrupted!</b></i></p>\r\n<p class=\"western\">This has three dramatic effects:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Yaffs has no tables, so is immune to these\r\n	failure modes.</p>\r\n	<li/>\r\n<p class=\"western\">There are no extra tables to be written, so\r\n	Yaffs does not have to resort to caching to achieve good\r\n	performance.</p>\r\n	<li/>\r\n<p class=\"western\">Less flash writes means less flash wear,\r\n	improving product life and reducing power consumption.</p>\r\n</ul>\r\n<p class=\"western\">When a Yaffs file system is booted, the normal\r\nboot up sequence takes care of building up system state. There is\r\nthus no need for any special restoration code to be run. A boot up\r\nafter a power failure is not a special recovery condition, it is just\r\na normal boot up.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs does not have, or need,\r\nspecial recovery handling.</b></i></p>\r\n<h2 class=\"western\" style=\"page-break-after: avoid\"><font face=\"Liberation Sans, sans-serif\"><i><b>Trade-off\r\nin cached data</b></i></font></h2>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">File\r\nsystems tend to be inefficient in the way they write data.  Writing\r\njust one file requires many changes to the allocation tables; writing\r\nmany files requires far more changes, often to those same tables. By\r\ndelaying those writes and holding data in RAM briefly the file system\r\ncan do fewer writes to achieve the same set of changes. This can\r\nimprove write speed, at a price.</font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">Data\r\nwhich has not been written but just cached in RAM is vulnerable while\r\nit is there; it can all be lost if power fails, even including some\r\nthat the FS had apparently written already.</font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">Most\r\nfile systems support functions to reduce this inefficiency and force\r\nthe cache to be written out, but this may take many seconds, leaving\r\na significant period of vulnerability, and delaying system\r\noperations.  Excessive use of these functions to improve reliability\r\nwill typically impair write performance.</font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">A\r\nparticlarly serious example of critical data loss can occur if power\r\nor communication fails during a firmware upgrade.  Such a failure\r\ncripples the product, which must be returned for servicing.  Yaffs\r\nhas caching policies and data integrity models which make it easier\r\nto avoid this kind of fatal failure, and which have been tested very\r\nextensively. </font></font>\r\n</p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">Since\r\nYaffs is inherently faster and simpler, it does not need deep\r\ncaching. The Yaffs cache is small and used only for data alignment\r\npurposes and improving the throughput of very small reads and writes.\r\nYaffs files are always flushed from the cache when they are closed.\r\nYaffs also provides its own cache-flushing functions, but these are\r\nvery fast because the cache is small.</font></font></p>\r\n<p class=\"western\" align=\"center\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\"><i><b>By\r\nthe time Yaffs closes a file, all the data is guaranteed to be safe\r\non the flash.</b></i></font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">This\r\nsimple caching policy makes it very easy for programmers to write\r\nsoftware that is robust against power loss and avoids obscure failure\r\nmodes.  The simplicity confers more reliable operation, faster\r\nproduct development and huge savings in development and maintenance\r\ncosts.</font></font></p>\r\n<p class=\"western\" align=\"center\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\"><i><b>Reliable\r\nfile systems pay for themselves many times over.</b></i></font></font></p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Product risk\r\nreduction</h1>\r\n<p class=\"western\">At first glance, a file system seems like it\r\nshould be a simple body of code: just a few functions that read,\r\nwrite data and look things up by name. However, the reality is much\r\nmore complex than that.</p>\r\n<p class=\"western\">One of the most challenging aspects of file\r\nsystems is that errors are stored and incremental. Unlike most\r\nsoftware errors which can be cleared by a reset, storage errors are\r\npersistent.</p>\r\n<p class=\"western\" align=\"center\"><i><b>A reboot will typically not\r\nfix file-system errors.</b></i></p>\r\n<p class=\"western\">Customers might tolerate a product that needs to\r\nbe reset once in a while, but file system failures are often fatal.\r\nAs a result, file system issues can be very damaging to long-term\r\nproduct reliability.</p>\r\n<p class=\"western\">This is further complicated by flash memory. NAND\r\nflash is the only type of semiconductor hardware which leaves the\r\nfactory with known variable errors, expecting the file system\r\nsoftware to handle the problems.</p>\r\n<p class=\"western\">Flash, NAND in particular, has its own failure\r\nmodes and these are best handled by a file system specifically\r\ndesigned for NAND.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs was specifically\r\ndesigned to use with NAND and NOR flash chips.</b></i></p>\r\n<p class=\"western\">Flash memory chip errors may only show up after\r\nthe product has been used a while, or in a fraction of the flash\r\nparts. Typical testing during development (e.g. bench testing) will\r\noften fail to expose all types of flash chip error, and others will\r\nonly be exposed during pilot- or early-production. These put release\r\ndates at risk, which can cause huge revenue losses.</p>\r\n<p class=\"western\">We have a few clients who only determined that\r\nthey had file system issues when they did a pilot run. That prompted\r\nthem to try Yaffs and get their products shipping. While we are glad \r\nthey ended up with a good product, unfortunately they lost revenue\r\nand customer goodwill.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Finding problems late in\r\ndevelopment creates business risk.</b></i></p>\r\n<p class=\"western\">It is thus not surprising that much of our\r\nbusiness is repeat business. \r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Yaffs testing</h1>\r\n<p class=\"western\">Testing on its own does not create good software\r\nbut it does help to verify that the software is working correctly.</p>\r\n<p class=\"western\">Yaffs has many automated tests that are run on a\r\nregular basis. Automated tests allow the testing to be run without\r\nhuman intervention, thus allowing more testing to be done.</p>\r\n<p class=\"western\">The tests are too numerous to discuss completely\r\n(see the Further Information below). W<span style=\"font-weight: normal\">e</span>\r\nhighlight one: the power-fail stress test.</p>\r\n<p class=\"western\">The power-fail stress test is a test harness that\r\nuses software simulations of flash devices and some software and\r\nscripts to simulate the effects of removing power from a Yaffs-based\r\nsystem <span style=\"font-weight: normal\">while it is writing</span>\r\nto flash. This test is normally run for 100,0000 to 1 million\r\npower-fail simulation cycles, taking many days.</p>\r\n<p class=\"western\">This particular test suite was originally\r\ndeveloped in 2008 during the development of some new features. The\r\ntests are very rigorous. In the beginning, this test suite would find\r\na problem after less than 100 power fail iterations. As we identified\r\nand fixed the bugs, this number crept up and we now run millions of\r\ncycles without seeing a single problem.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs survives millions of\r\npower failures in simulation test benches.</b></i></p>\r\n<p class=\"western\">In addition, many of our clients have also run\r\nhardware power failure tests, using a relay and a micro-controller to\r\nkill power to the device under test.  They have been very satisfied\r\nwith the results.</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><font size=\"4\" style=\"font-size: 16pt\"><b>Licensing</b></font></p>\r\n<p class=\"western\">Yaffs is available under GNU Public License V2,\r\nGPL2, from our git repository at <a href=\"http://www.yaffs.net/\">www.yaffs.net</a>.\r\nYou may use that code for testing free of charge and for as long as\r\nyou want.</p>\r\n<p class=\"western\" align=\"left\" style=\"font-weight: normal\"><i>You\r\nwill be using it under the conditions of GPL2 with the obligation to\r\nrelease your associated source code when you start to sell or\r\ndistribute a product.</i></p>\r\n<p class=\"western\" align=\"left\" style=\"font-weight: normal\"><i>We can\r\nthen sell you a Licence to use Yaffs which removes that obligation\r\nand protects your intellectual property.</i></p>\r\n<p class=\"western\" align=\"center\"><i><b>With Yaffs you can try before\r\nyou buy!</b></i></p>\r\n<h1 class=\"western\">Conclusions</h1>\r\n<p class=\"western\">Selecting a robust flash file system is key to :</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">building a successful product.</p>\r\n	<li/>\r\n<p class=\"western\">reducing risk, warranty costs and\r\n	liability.</p>\r\n	<li/>\r\n<p class=\"western\">reducing development costs.</p>\r\n</ul>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs has proven itself and\r\ncan pay for itself many times over.</b></i></p>\r\n<h1 class=\"western\">Further information</h1>\r\n<p class=\"western\">This document is intentionally brief. There are\r\nmany documents at <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a>\r\nfor those that want more information, including:</p>\r\n<p class=\"western\"><b>How Yaffs Works:</b> detailed description of\r\ninternal design.</p>\r\n<p class=\"western\"><b>Yaffs Robustness and Testing:</b> how  we know\r\nYaffs handles various flash failure scenarios.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">For further information please contact\r\n<a href=\"mailto:info@yaffs.net\">info@yaffs.net</a> or access\r\n<a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a></p>','Failures in an embedded File System in a product are much more serious to the user than failures in an office computer.&nbsp; Power failures and failures to cache data properly can be avoided by choosing a FFS specifically designed for reliability from the ground up.','raw_html'),