('values:node:420','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:22:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"605\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1496873154\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"420\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:5:\"paper\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"c3d49866-ddb0-41b9-9505-630fed1d93f4\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:28:\"YAFFS Robustness and Testing\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"6\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1339119318\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496873154\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:61826:\"\r\n\r\n	<p class=\"western\">Many embedded systems need to store critical\r\n	data, making reliable file systems an important part of modern\r\n	embedded system design. That robustness is not achieved through\r\n	chance. Robustness is only achieved through design and extensive\r\n	testing to verify that the file system functions correctly and is\r\n	resistant to power failure.</p>\r\n	<p class=\"western\">This document describes some of the important\r\n	design criteria and design features used to achieve a robust design.</p>\r\n	\r\n<p class=\"western\" style=\"page-break-before: always\"><h1 class=\"western\">1 Background</h1>\r\n<p class=\"western\">Cheaper CPUs and flash have driven up embedded\r\nsystem functionality. These increased functions often require file\r\nsystem storage.</p>\r\n<p class=\"western\">The original flash file storage mechanisms were\r\nthe use of a flash translation layer (FTL) – a driver model which\r\nmakes flash memory appear as a disk drive – in conjunction with a\r\ndisk-oriented file system such as FAT. This storage methodology has\r\nvarious performance and robustness limitations, leading to the\r\ndevelopment of file systems designed specifically for flash memory.\r\nThese are known as flash file systems.</p>\r\n<p class=\"western\">Flash memory has various limitations when compared\r\nwith a disk. For example, flash memory pages cannot be individually\r\nre-written but instead the whole block must be  erased and rewritten\r\nwith the modified page. Typical FTL achieve this with various logical\r\nto physical mapping schemes. Thus emulating disk-like behaviour on\r\nflash memory adds an extra layer of software which slows down write\r\nperformance. Worse still, it adds extra state which is prone to\r\ncorruption due to power failure.</p>\r\n<p class=\"western\">A typical FTL-based solution will use a file\r\nsystem such as FAT. FAT always stores tables in the same disk blocks\r\nand must thus change the same blocks often. Since flash memory blocks\r\ncan endure a limited number of write/erasure cycles, the FTL must\r\nmove the physical location of the block around to prevent  the high\r\ntraffic blocks from wearing out. This requires wear levelling – a\r\nfurther burden.</p>\r\n<p class=\"western\">Some systems try to mitigate against the\r\nperformance penalties by caching a lot of data to reduce writes.\r\nWhile this can go some way towards reducing the apparent write time,\r\nit does make the solution prone to data loss in the event of a power\r\nfailure.</p>\r\n<p class=\"western\">As well as limitations, flash memory also has\r\ncertain advantages when compared to rotating media. There is no spin\r\nup time, making it more responsive. There is no read head so there is\r\nno read penalty if data is fragmented. Flash file systems can be\r\ndesigned to exploit these advantages.</p>\r\n<p class=\"western\">True flash file systems<a class=\"sdfootnoteanc\" name=\"sdfootnote1anc\" href=\"#sdfootnote1sym\"><sup>1</sup></a>,\r\non the other hand, are a single code body designed to take the\r\nfeatures and limitations of flash into consideration. Flash file\r\nsystems can thus be far more “flash friendly”. Well designed\r\nflash file systems will avoid using “flash unfriendly” techniques\r\nsuch as allocation tables and in-place rewriting.</p>\r\n<p class=\"western\">Yaffs is a flash file system, originally designed\r\nspecifically for NAND flash though also used with great success on\r\nNOR flash too. Yaffs development started in 2001 when 32Mbytes of\r\nflash was considered large. Since then, Yaffs has been expanded to\r\nwork properly with different flash types and far larger memory arrays\r\n(many GBytes).</p>\r\n<p class=\"western\">Yaffs was originally deployed in Linux, but was\r\nwritten in an OS neutral way, mainly to facilitate modular\r\ndevelopment and testing. This turned out to be useful when we had\r\nrequests to port Yaffs to other operating systems. Since then, Yaffs\r\nhas been used in many different products in a wide variety of\r\napplications from consumer products such as cell phones and sewing\r\nmachines to aerospace, industrial and medical applications including\r\nprocess control, building management, communications infrastructure\r\nand many others.</p>\r\n<p class=\"western\">Yaffs is not tied to any endian ordering and has\r\nbeen used on a wide variety of architectures including ARM, MIPS,\r\nPowerPC, x86, some DSPs. Yaffs has been deployed using a wide variety\r\nof compilers from many different vendors.</p>\r\n<p class=\"western\">Nor is Yaffs tied to any particular operating\r\nsystem. Yaffs has been used with Linux, eCOS, Windows Embedded\r\nCompact (previously Windows CE), VxWorks and others.</p>\r\n<h1 class=\"western\">2 Flash File System considerations</h1>\r\n<p class=\"western\">There are many criteria that are important when\r\nselecting a flash file system. These are some that out customers have\r\nfound to be most important:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Robustness: It really is not worth having a\r\n	file system that loses or corrupts data and prevents the system from\r\n	working properly. Some flash file systems are only robust when\r\n	synced (flushed) after files have been written. That requires extra\r\n	code, slows the system and leaves the file system in a\r\n	non-deterministic state until the sync has been completed. Some file\r\n	systems need to perform disk repair operations (eg. check disk) in\r\n	the event of a power failure. This can add considerable time to the\r\n	start up, preventing the system from being operational.</p>\r\n	<li/>\r\n<p class=\"western\">Performance: In many embedded system\r\n	designs, slow read/write performance can delay tasks and cause\r\n	system degradation or even failure. It is thus important that\r\n	read/write performance be acceptable. Note that many flash file\r\n	systems need to perform extra actions such as garbage collection. In\r\n	some cases these actions can cause the file system to stall for a\r\n	long time. It is thus important that these factors be taken into\r\n	consideration. Performance can sometimes be improved by adding a\r\n	write caching layer. These caching layers make the file system calls\r\n	(write etc) proceed quickly, without actually writing the data to\r\n	flash. This is a two-edged sword as data in the cache will be lost\r\n	on a power failure and syncing the file system will take a long\r\n	time. Thus, most flash file systems offer either speed or robustness\r\n	– not both.</p>\r\n	<li/>\r\n<p class=\"western\">Proven: It is very easy for a file system\r\n	vendor to provide a list of claims saying “100% power safe” or\r\n	similar, but what evidence do they have to back this up? All file\r\n	systems, including flash file systems, are complex bodies of\r\n	software with extremely complex state. They need very significant\r\n	testing to prove that they work correctly.</p>\r\n	<li/>\r\n<p class=\"western\">Portable: Software is a huge investment and\r\n	it is increasingly important to be able to port the software between\r\n	OSs and CPU architectures. Most flash file systems are limited to a\r\n	single operating system which makes it difficult to migrate software\r\n	between different platforms. In Yaffs\' case portability extends to\r\n	being able to seamlessly migrate the core Yaffs code into a test\r\n	framework which enhances testing.</p>\r\n</ul>\r\n<h1 class=\"western\">3 How Yaffs achieves robustness and performance</h1>\r\n<p class=\"western\">Yaffs was designed from the ground up specifically\r\nto work well with NAND flash. The author had already developed\r\nanother flash file system, so was already familiar with the  design\r\nchallenges of flash.</p>\r\n<p class=\"western\">As Yaffs is not just adapting a disk-oriented file\r\nsystem to work with flash it is not surprising that Yaffs is very\r\ndifferent in design to most other file systems. The key difference is\r\nthat Yaffs is a log-structured. file system<a class=\"sdfootnoteanc\" name=\"sdfootnote2anc\" href=\"#sdfootnote2sym\"><sup>2</sup></a>.</p>\r\n<p class=\"western\">In essence, a log structured file system writes\r\nfile system changes as a sequential log.  The log structure is\r\nparticularly suitable for various reasons including:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">All writes are at the end of the log. When\r\n	a file is modified, there is no need to erase and rewrite a part of\r\n	the flash. Changes are just appended to the log. Thus there is no\r\n	need to erase and copy old data just to change some existing pages\r\n	in a file. This tends to make writes much faster. There is no need\r\n	to do a lot of caching to achieve performance. Data can be written\r\n	to the log immediately meaning that sync time is very low. Data\r\n	robustness is improved dramatically.</p>\r\n	<li/>\r\n<p class=\"western\">There are no allocation tables or similar.\r\n	This reduces the amount of data being written to the flash, and that\r\n	there are no tables to corrupt.</p>\r\n	<li/>\r\n<p class=\"western\">Since all writes are to the end of the log\r\n	there are no “high traffic” blocks. This means Yaffs only needs\r\n	a simpler wear leveling strategy.</p>\r\n	<li/>\r\n<p class=\"western\">In the event of a power failure, the file\r\n	system state is easily re-created from the log. This means there is\r\n	no need to perform disk repair operations to correct for an unclean\r\n	shutdown.</p>\r\n</ul>\r\n<p class=\"western\">So why don\'t we see many log structured file\r\nsystems for disk file systems? The answer to this is that log file\r\nsystems tend to spread the writes around on the media. That is\r\ntypically very problematic for mechanical storage which must\r\nphysically move the read/write head from one location to another\r\nmaking the access time very slow. Of course that does not apply for\r\nflash memory. By designing specifically for flash, Yaffs can ignore\r\nthis issue and write fast.</p>\r\n<p class=\"western\">Many flash file systems need make a compromise\r\nbetween robustness against performance. Thanks to the log structure,\r\nYaffs does not need to. Yaffs can provide high performance without\r\ngiving up on robustness.</p>\r\n<p class=\"western\">Those familiar with log structured file system\r\ndesign will know that some log structured file systems have problems\r\nwith garbage collection<a class=\"sdfootnoteanc\" name=\"sdfootnote3anc\" href=\"#sdfootnote3sym\"><sup>3</sup></a>.\r\nGarbage collection is used to clean up the log and make more free\r\nspace available. Some log structured file system designs did not pay\r\nenough attention to garbage collection and can stall for a\r\nconsiderable time while garbage collection happens. Yaffs was\r\ndesigned differently. The potential impact of garbage collection was\r\nconsidered throughout the Yaffs design process. As a result, Yaffs\r\nhas a very simple garbage collection model that allows a lot of\r\nflexibility in garbage collection scheduling. This prevents the\r\ngarbage collection from making the file system unresponsive.</p>\r\n<p class=\"western\">Most file systems are developed within the\r\ncontext, and framework of, a single operating system. This typically\r\nmakes the code difficult to explore, debug and port. Yaffs on the\r\nother hand was developed from the start inside a portable\r\ndevelopment/testing framework. Yaffs is then ported to various\r\noperating systems through the addition of glue code.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 38784 characters]\" name=\"Object1\" align=\"left\" width=\"552\" height=\"524\"/>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">There are many benefits to this approach:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">A development framework runs in user space\r\n	which provides a richer development environment than inside an OS\r\n	kernel. It is much easier to attach debuggers and perform logging\r\n	and create reproducible testing.</p>\r\n	<li/>\r\n<p class=\"western\">The code is structured to be portable. That\r\n	makes it relatively easy to port to a new OS or RTOS with a high\r\n	level of confidence.</p>\r\n	<li/>\r\n<p class=\"western\">There is a choice of porting interfaces\r\n	allowing more flexibility to determine which porting method will be\r\n	simpler. For example, the Linux wrapper accesses the Yaffs core\r\n	directly while the Windows CE wrapper access the Yaffs Direct\r\n	Interface<a class=\"sdfootnoteanc\" name=\"sdfootnote4anc\" href=\"#sdfootnote4sym\"><sup>4</sup></a>.</p>\r\n	<li/>\r\n<p class=\"western\">Each different environment provides\r\n	different test tools. For example, Linux provides a raft of file\r\n	system test tools that do different kinds of testing to the power\r\n	fail test harness. Since the vast majority of the code is in the\r\n	portable Yaffs core, that code gets the advantage of all test\r\n	methods combined. The many millions of Android phone users that use\r\n	Yaffs-based devices are helping test the core code that is also used\r\n	on a wide variety of different operating systems and a wide range of\r\n	different device types.</p>\r\n	<li/>\r\n<p class=\"western\">Its Open Source status means any interested\r\n	person can take a version from git and test it to make sure that it\r\n	meets their needs.</p>\r\n</ul>\r\n<h1 class=\"western\">4 Testing</h1>\r\n<p class=\"western\">It is all very well to design software to be\r\nrobust, but it needs thorough testing to build confidence in the\r\nsoftware and in the code authors and supplier.</p>\r\n<p class=\"western\">File systems have incredibly complex state so it\r\nis not at all surprising that operating system designers find file\r\nsystems some of the most challenging code to test.</p>\r\n<p class=\"western\">There is no single test methodology that can test\r\nall cases, and exhaustive state testing is impossible. The best we\r\ncan do is to have a suite of test methodologies that combine to\r\nprovide thorough testing.</p>\r\n<p class=\"western\">Approximately 60% of Yaffs development effort is\r\ndirected towards testing and improving the test environment. We are\r\nconstantly researching new methodologies.</p>\r\n<p class=\"western\">The following are descriptions of the most\r\nimportant test strategies used in Yaffs.</p>\r\n<h2 class=\"western\">4.1 Power Fail Stress Testing</h2>\r\n<p class=\"western\">By far the most important consideration in Yaffs\r\ntesting is that it is robust to corruptions caused by power failure.\r\nWe want Yaffs to provide the basis for reliable products in typical\r\nembedded system environments.</p>\r\n<p class=\"western\">The first power fail testing was done by companies\r\nintegrating Yaffs into their products. Some of these built test jigs\r\nwhich would automatically interrupt power while running a real\r\nhardware device. This approach is better than nothing, but has some\r\nlimitations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">It is relatively costly to set up. Flash\r\n	has a limited lifetime meaning that test devices wear out with time\r\n	and must be replaced.</p>\r\n	<li/>\r\n<p class=\"western\">It is relatively slow since each cycle\r\n	takes many seconds to boot, run the application for a while and then\r\n	reboot.</p>\r\n	<li/>\r\n<p class=\"western\">Many, and perhaps most, of the power\r\n	interruptions will happen at times when the file system is inactive\r\n	and thus be wasted cycles.</p>\r\n</ul>\r\n<p class=\"western\">In 2008 we developed a simulated power-fail-test\r\nenvironment. This simulates power failures using simulated flash\r\nmemory while running various consistency checks.</p>\r\n<p class=\"western\">The benefits of a software-based test harness are\r\nnumerous:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The test harness controls the point at\r\n	which the simulated power failures happen. That means every test\r\n	cycle counts.</p>\r\n	<li/>\r\n<p class=\"western\">No special hardware is required.</p>\r\n	<li/>\r\n<p class=\"western\">Test loops run faster. A quad-core computer\r\n	can simulate ten to twenty power failures per second. That means\r\n	about a million power failure simulations per day.</p>\r\n</ul>\r\n<p class=\"western\">The effectiveness of the new software based\r\ntesting is dramatic.. A few times we have tested some user-suggested\r\nchanges that had passed a week or more of real-world power fail\r\ntesting only to have problems caught by the software simulation in a\r\nmatter of minutes.</p>\r\n<p class=\"western\">We regularly run the power fail simulation test\r\nover a weekend, testing millions of power fail cycles.</p>\r\n<h2 class=\"western\">4.2 Testing the Yaffs Direct Interface API</h2>\r\n<p class=\"western\">Yaffs Direct Interface (YDI) is a POSIX-like\r\nwrapper around the Yaffs core. This provides a set of function calls,\r\nyaffs_open(), yaffs_write() and the like.</p>\r\n<p class=\"western\">Each function can return numerous error codes and\r\nhas to handle numerous different parameters.</p>\r\n<p class=\"western\">Although there were already significant tests for\r\nthe YDI, an extensive test harness was developed in 2010 to\r\ncomprehensively test each of the error paths and generate all of the\r\nrequired errors.</p>\r\n<p class=\"western\">This provides a high level of confidence that the\r\ntest interfaces do what they should and that POSIX-like functionality\r\nprovides relatively clean porting of existing code.</p>\r\n<h2 class=\"western\">4.3 Linux Testing</h2>\r\n<p class=\"western\">The main purpose of the Linux testing is to test\r\nthe Linux wrapper code. It does, however, still exercise the Yaffs\r\ncore code differently to other testing and thus adds to the test\r\nfabric.</p>\r\n<p class=\"western\">The Linux testing does not do power fail testing\r\nbut instead tests other aspects such as clean shutdowns, cache\r\nintegrity and write performance. This gives a useful way to assess\r\nthe effects of modifications.</p>\r\n<p class=\"western\">Linux testing is done on both real hardware and on\r\nsimulated hardware using the Linux mtd nand simulator.</p>\r\n<p class=\"western\">As with the Power Fail Stress Testing described\r\nabove, the simulated testing is done using a scrippted environment\r\nwhich is typically run for a few days at a time.</p>\r\n<h2 class=\"western\">4.4 Fuzz Testing</h2>\r\n<p class=\"western\">Fuzz testing deliberately corrupts the flash image\r\nand ensures that Yaffs still mounts. This is done to ensure that\r\nYaffs does not crash on corrupted data.</p>\r\n<p class=\"western\">Clearly fuzz testing can corrupt the contents of\r\nindividual files (that\'s its job), but the file system integrity\r\nshould not be compromised. \r\n</p>\r\n<h2 class=\"western\">4.5 Software checking</h2>\r\n<p class=\"western\">Although code checking is  not actual testing per\r\nse, it does help to verify code changes.</p>\r\n<p class=\"western\">The Yaffs code has been checked with Coverity<a class=\"sdfootnoteanc\" name=\"sdfootnote5anc\" href=\"#sdfootnote5sym\"><sup>5</sup></a>\r\n– a market leader in code checking.</p>\r\n<p class=\"western\">We are investigating the use of KLEE and other\r\ntools.</p>\r\n<h2 class=\"western\">4.6 Open Source Usage</h2>\r\n<p class=\"western\">Open Source usage of Yaffs opens it up to testing\r\nby the many different projects. Many of these participate in some way\r\nwith the Yaffs mailing list, helping to uncover issues and generally\r\nprovide feedback.</p>\r\n<p class=\"western\">Each different project uses Yaffs in a different\r\nway, meaning that a wider range of operation sequences are tested.</p>\r\n<h2 class=\"western\">4.7 Universities</h2>\r\n<p class=\"western\">Over its lifetime, Yaffs has been used as a\r\nteaching framework for various university course in many different\r\ncounties around the world.</p>\r\n<p class=\"western\">For example, Oregon State and Utah State\r\nUniversities have used Yaffs as a test bench for their post-graduate\r\nsoftware testing courses. They essentially test the test tools by\r\ninjecting errors into the Yaffs code and seeing if these are\r\ndiscovered by the test tools they are testing. Of course this has the\r\nside effect of running these tests over the original Yaffs code too. \r\n</p>\r\n<p class=\"western\">Those interested in test methods are encouraged to\r\nread some of the university papers in the references of this\r\ndocument.</p>\r\n<p class=\"western\">We expect to adopt and extend some of the Oregon\r\nState ideas and use these to extend our in-house test suite.</p>\r\n<h1 class=\"western\">5 Conclusions</h1>\r\n<p class=\"western\">Software development is an iterative process of\r\ndesign and testing. Robust software solutions are only possible with\r\nextensive testing.</p>\r\n<p class=\"western\">Embedded systems increasingly need to store data\r\nin file systems as a critical part of their operation. It is thus\r\nimportant to have a file system that is predictable and robust to\r\npower failure and similar interruptions.</p>\r\n<p class=\"western\">Yaffs has been designed from scratch to be robust\r\nto power failure and that robustness has been verified with a\r\nmulti-pronged test strategy that is continuously being improved.</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">6References</h1>\r\n<p class=\"western\" align=\"left\">Charles Manning, “How Yaffs\r\nWorks”.<br/>\r\n<a href=\"http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf\">http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\">A. Groce et al, “Swarm Testing”\r\nfrom Oregon State University, School of EE and Computer Science and\r\nUtah State University, School of Computing,\r\n2011.<br/>\r\n<a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">http://</a><a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">www.ct.utah.edu/~regehr/papers/swarm12.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\"><em>Wu CH, “Efficient\r\nInitialization and Crash Recovery</em> for. <em>Log</em>-<em>based\r\nFile Systems</em> over Flash Memory” from National Taiwan\r\nUniversity, Dept of Computer Science,<span style=\"font-style: normal\">\r\n2006.<br/>\r\nhttp://</span><cite>www.cis.nctu.edu.tw/~lpchang/papers/SAC_wu_sac06.pdf</cite></p>\r\n<p class=\"western\" align=\"left\" style=\"font-style: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<div id=\"sdfootnote1\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote1sym\" href=\"#sdfootnote1anc\">1</a>Note\r\n	that flash translation layers (FTLs) are erroneously refered to as\r\n	flash file systems. For example, despite the name, M-Systems TrueFFS\r\n	is not a flash file system but a flash translation layer (FTL).</p>\r\n</div>\r\n<div id=\"sdfootnote2\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote2sym\" href=\"#sdfootnote2anc\">2</a>This\r\n	document only provides a brief overview of the Yaffs architecture\r\n	and design. The “How Yaffs Works” document provides an in-depth\r\n	explanation of the Yaffs design and architecture.</p>\r\n</div>\r\n<div id=\"sdfootnote3\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote3sym\" href=\"#sdfootnote3anc\">3</a>Refer\r\n	to the “How Yaffs Works” document to understand the need for\r\n	garbage collection and how Yaffs does garbage collection.</p>\r\n</div>\r\n<div id=\"sdfootnote4\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote4sym\" href=\"#sdfootnote4anc\">4</a>For\r\n	more information on Yaffs Direct Interface, please read the various\r\n	documents on the subject.</p>\r\n</div>\r\n<div id=\"sdfootnote5\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote5sym\" href=\"#sdfootnote5anc\">5</a>http://www.coverity.com</p>\r\n</div>\r\n\";s:7:\"summary\";s:241:\"<p>This document describes some of the important design criteria and design features used to achieve a robust design suitable for modern embedded systems which need to store critical data.&nbsp; The test methodologies are also described.</p>\";s:6:\"format\";s:8:\"raw_html\";}}}s:19:\"field_document_type\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:9:\"target_id\";s:3:\"345\";}}}s:6:\"upload\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:9:\"target_id\";s:2:\"78\";s:7:\"display\";s:1:\"1\";s:11:\"description\";s:0:\"\";}}}s:18:\"field_teaser_image\";a:1:{s:9:\"x-default\";a:1:{i:0;a:5:{s:9:\"target_id\";s:2:\"79\";s:3:\"alt\";s:40:\"Preview of YaffsRobustnessAndTesting.pdf\";s:5:\"title\";N;s:5:\"width\";N;s:6:\"height\";N;}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:5:\"paper\";s:2:\"id\";s:3:\"420\";s:8:\"revision\";s:3:\"605\";s:4:\"uuid\";s:36:\"c3d49866-ddb0-41b9-9505-630fed1d93f4\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:28:\"YAFFS Robustness and Testing\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"6\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"605\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105490.001,1,'entity_field_info node_values','814'),('values:node:435','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:20:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"436\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1344942371\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"4\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"435\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:27:\"what_is_special_about_yaffs\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"c27bc1aa-c1b5-47a6-bad6-53fbab401cc4\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:47:\"Highly configurable - matches your Flash memory\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1341567095\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1494888515\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:367:\"<p>Yaffs is adaptable to suit the Flash geometries, caching options, Error Correction strategies and other features that you need.</p><p>Details of the configuration options can be found in the Linux menuconfig compile options tool, and in&nbsp; <a href=\"http://www.yaffs.net/yaffs-tuning-and-configuration\">http://www.yaffs.net/yaffs-tuning-and-configuration</a></p>\";s:7:\"summary\";s:149:\"Yaffs is highly configurable, making it possible to work with various Flash geometries, Error Correction and caching options according to your needs.\";s:6:\"format\";s:9:\"full_html\";}}}s:15:\"field_icon_text\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:5:\"value\";s:15:\"fa-check-square\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:27:\"what_is_special_about_yaffs\";s:2:\"id\";s:3:\"435\";s:8:\"revision\";s:3:\"436\";s:4:\"uuid\";s:36:\"c27bc1aa-c1b5-47a6-bad6-53fbab401cc4\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:47:\"Highly configurable - matches your Flash memory\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"436\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105486.999,1,'entity_field_info node_values','814'),('values:node:436','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:20:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"437\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1341567314\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"436\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:27:\"what_is_special_about_yaffs\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"e4ffc5ce-460f-498f-9f3b-86bdef504158\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:19:\"Simple to integrate\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1341567314\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1495711914\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:339:\"<p>Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required. Yaffs also includes a POSIX interface. It has been used with Android, VXWorks, Windows, Linux, bare metal, and more; on ARM (32 and 64), x86 (32 and 64), Atmel, and more. </p><p>You can find details in the Yaffs Direct guide.</p>\";s:7:\"summary\";s:278:\"Yaffs Direct Interface is simple to integrate in a system &ndash; only a few interface functions are required. Yaffs also includes a POSIX interface. It has been used with Android, VXWorks, Windows, Linux, bare metal, and more; on ARM (32 & 64), x86 (32 & 64), Atmel, and more. \";s:6:\"format\";s:9:\"full_html\";}}}s:15:\"field_icon_text\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:5:\"value\";s:15:\"fa-puzzle-piece\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:27:\"what_is_special_about_yaffs\";s:2:\"id\";s:3:\"436\";s:8:\"revision\";s:3:\"437\";s:4:\"uuid\";s:36:\"e4ffc5ce-460f-498f-9f3b-86bdef504158\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:19:\"Simple to integrate\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"437\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105487.075,1,'entity_field_info node_values','814'),('values:node:448','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:20:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"584\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1496408204\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"448\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:5:\"paper\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"8ddb805d-cf10-4a08-9c47-6561a522a436\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:3:\"FAQ\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1341786644\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496408204\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:6835:\"<h3><em>What Operating System (OS) can you use with Yaffs?</em></h3>\r\n\r\n<p>Yaffs is agnostic about the OS it is used with; it has been used with many different OSs, including Linux, eCos, Windows CE, ThreadX, pSOS and vXworks. It is POSIX-compliant, so commands in an application calling POSIX functions will usually work.</p>\r\n\r\n<p>Windows CE uses the Microsoft file handling model and is not POSIX-like. The difference is handled in the Windows CE wrapper.&nbsp; Contact us for more information.</p>\r\n\r\n<p>Work on closer integration of Yaffs into the Linux kernel started in 2010 and the goal is to have Yaffs merged into the mainline Linux kernel.</p>\r\n\r\n<p>The Yaffs Direct Interface, YDI, is the heart of Yaffs and usually stands between the Application, on one side, and the Flash chips, and any OS, on the other side:-</p>\r\n\r\n<h3><em>What CPU can you use with Yaffs?</em></h3>\r\n\r\n<p>Yaffs has been used with many 32-bit and 64-bit CPUs including MIPS, 68000, ColdFire, PowerPC, x86 variants and many ARM-cored CPUs. It should work with 16-bit CPUs but has not been tested.</p>\r\n\r\n<h3><em>Does Yaffs care Which-Endian the CPU is?</em></h3>\r\n\r\n<p>No, Yaffs works with Big-Endian and Little-Endian CPUs</p>\r\n\r\n<h3><em>How big can the whole file system be, and how big can individual files be?</em></h3>\r\n\r\n<p>Yaffs2, which is now standard, can handle a File System (FS) of many Gigabytes total storage; some people are using it with 6GB satisfactorily.&nbsp;<em>Individual</em>&nbsp;files are currently limited to 2GB. The basic Yaffs architecture can handle larger single files and some changes would be required to support individual files greater than 2G bytes. There is an upper limit of around 32GB with the present 2k bytes granularity of \'chunks\' or page size, and the limit of about 16 million chunks per file.</p>\r\n\r\n<p>A coarser granularity of larger chunks can probably be obtained, with knock-on effects in other parameters like RAM usage.</p>\r\n\r\n<h3><em>How many files can there be?</em></h3>\r\n\r\n<p>There is no hard limit. Available flash and RAM will limit this.</p>\r\n\r\n<h3><em>What about directories etc?</em></h3>\r\n\r\n<p>Yaffs supports many different objects including: directories, regular files, hard links, symbolic links and device nodes.</p>\r\n\r\n<p>Yaffs supports long file names, attributes, extended attributes and Unicode.</p>\r\n\r\n<h3><em>How much RAM does it need?</em></h3>\r\n\r\n<p>This depends particularly on the number of tnodes, which in turn depends on the file size, and is therefore a dynamic variable.</p>\r\n\r\n<p>However, Yaffs compares favourably with other similar systems specialised for Flash, and includes robust error handling.</p>\r\n\r\n<h4><em>How are errors handled?</em></h4>\r\n\r\n<p>Error Correction Code (ECC) is used to correct for single-bit errors.</p>\r\n\r\n<p>ECC may use built-in code or that provided from other sources (flash controllers, ECC libraries etc).</p>\r\n\r\n<p>Yaffs is frequently tested on a \"fuzzer\" test harness. This randomly corrupts bits of the file system image to check that the file system still mounts and loads correctly.</p>\r\n\r\n<h3><em>What about Multi-level cell (MLC) chips?</em></h3>\r\n\r\n<p>Because a bit is represented by a smaller amount of charge in the MLC chip compared to a SLC chip, MLC chips are more prone to corruption than SLC.</p>\r\n\r\n<p>MLC also has various write restrictions, which are obeyed by Yaffs2.</p>\r\n\r\n<p>Yaffs2 has some features such as block refreshing to help alleviate the problems associated with MLC.</p>\r\n\r\n<p>MLC generally requires multi-bit ECC. Hardware ECC is preferred since it is faster and requires less computation than software multi-bit correction..</p>\r\n\r\n<h3><em>How robust is Yaffs ?</em></h3>\r\n\r\n<p>Yaffs is designed specifically to take account of manufacturing faults in, and of accumulated wear in, individual cells, and also to handle power failures during use.</p>\r\n\r\n<p>Yaffs allocates flash blocks in a way that gives statistical or implicit wear levelling; when a block is freed up it is released into a&nbsp;<em>free pool</em>&nbsp;and the next allocation comes from this&nbsp;<em>free pool.&nbsp;</em>This randomness tends to spread the blocks in use, giving some wear levelling, rather than one part of the file always being worked intensively.</p>\r\n\r\n<p>Accelerated lifetime testing has been carried out to seek evidence for excessive wear. For example on one professional PDA-style device used by surveyors in the field we determined that extreme lifetime usage would be:</p>\r\n\r\n<ul>\r\n	<li>20MB per day.</li>\r\n	<li>200 days per year</li>\r\n	<li>10 year lifetime</li>\r\n	<li>Total 40Gbytes lifetime write.</li>\r\n</ul>\r\n\r\n<p>We then ran well over 200Gbytes of writing through a specially designed File System Exerciser, a multi-threaded application that writes, reads, verifies, then deletes, repeatedly. There was no sign of a single bit of corruption at the end of the test.</p>\r\n\r\n<p>Another test applied randomly timed power failures repeatedly while running test code. Millions of cycles have been executed without any errors being observed.</p>\r\n\r\n<p>Yaffs is used (under GPL) in the Android mobile phones sold by Google and others. Extensive use in the field like this helps to ensure its robustness.</p>\r\n\r\n<h3><em>How big is its code?</em></h3>\r\n\r\n<p>That depends on how much of it you need; it is modular in organisation. The innermost or core part is about 11k lines of code, the the Yaffs Direct Interface giving file handle access and a Posix-like interface is around 2k lines.</p>\r\n\r\n<h3>Glossary and useful links.</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>Big-endian and Little-endian</p>\r\n			</td>\r\n			<td>\r\n			<p>Big-endian is when the most significant data chunk is listed first. Little-endian is when the least significant&nbsp;data chunk&nbsp;is listed first.</p>\r\n\r\n			<p><em>http://en.wikipedia.org/wiki/Endianness</em></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>tnodes</p>\r\n			</td>\r\n			<td>\r\n			<p>Tnodes are yaffs data structures used to build trees that map from a file to the file data chunks stored in flash. A large file will have multiple data chunks scattered throughout the flash and will need a larger tnode tree.</p>\r\n\r\n			<p>See the HowYaffs Works document for more information.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>ECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Error correction codes, See the&nbsp;<em>Yaffs Error mitigation</em>&nbsp;document.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>MLC</p>\r\n			</td>\r\n			<td>\r\n			<p>Multi-level cell, allows more than one bit state to be stored in a memory cell. MLC Flash often allows four state (ie. 2 bits) to be stored in one cell.&nbsp;<em>http://en.wikipedia.org/wiki/Multi-level_cell</em></p>\r\n\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n\";s:7:\"summary\";s:53:\"<p>Common questions about Yaffs technical issues.</p>\";s:6:\"format\";s:10:\"basic_html\";}}}s:19:\"field_document_type\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:9:\"target_id\";s:3:\"343\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:5:\"paper\";s:2:\"id\";s:3:\"448\";s:8:\"revision\";s:3:\"584\";s:4:\"uuid\";s:36:\"8ddb805d-cf10-4a08-9c47-6561a522a436\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:3:\"FAQ\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"584\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105490.073,1,'entity_field_info node_values','814'),('values:node:453','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:22:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"606\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1496875984\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"453\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:5:\"paper\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"4682c2f9-e73c-487f-9ed4-67796f6f0d82\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:22:\"Yaffs Direct Interface\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1343000234\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496875984\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:150878:\"	<p class=\"western\" align=\"justify\">This document describes the Yaffs\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\";s:7:\"summary\";s:159:\"<p>This describes the Yaffs Direct Interface (YDI), which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS.</p><p>&nbsp;</p>\";s:6:\"format\";s:8:\"raw_html\";}}}s:19:\"field_document_type\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:9:\"target_id\";s:3:\"344\";}}}s:6:\"upload\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:9:\"target_id\";s:2:\"80\";s:7:\"display\";s:1:\"1\";s:11:\"description\";s:0:\"\";}}}s:18:\"field_teaser_image\";a:1:{s:9:\"x-default\";a:1:{i:0;a:5:{s:9:\"target_id\";s:2:\"81\";s:3:\"alt\";s:26:\"Preview of YaffsDirect.pdf\";s:5:\"title\";N;s:5:\"width\";N;s:6:\"height\";N;}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:5:\"paper\";s:2:\"id\";s:3:\"453\";s:8:\"revision\";s:3:\"606\";s:4:\"uuid\";s:36:\"4682c2f9-e73c-487f-9ed4-67796f6f0d82\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:22:\"Yaffs Direct Interface\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"606\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105490.122,1,'entity_field_info node_values','814'),('values:node:454','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:21:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"607\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1496922769\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"454\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:7:\"article\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"adc93566-7e69-422e-bbc6-a8e0157794d1\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:26:\"Running Yaffs Direct Tests\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1343001796\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496922769\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:1796:\"<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\";s:7:\"summary\";s:259:\"<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>\";s:6:\"format\";s:9:\"full_html\";}}}s:19:\"field_document_type\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:9:\"target_id\";s:3:\"345\";}}}s:6:\"upload\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:9:\"target_id\";s:2:\"82\";s:7:\"display\";s:1:\"1\";s:11:\"description\";s:0:\"\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:7:\"article\";s:2:\"id\";s:3:\"454\";s:8:\"revision\";s:3:\"607\";s:4:\"uuid\";s:36:\"adc93566-7e69-422e-bbc6-a8e0157794d1\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:26:\"Running Yaffs Direct Tests\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"607\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498107621.470,1,'entity_field_info node_values','814'),('values:node:455','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:22:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"608\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1496923141\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"455\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:5:\"paper\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"c6cde019-a48b-43e3-a51f-4e698c671336\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:35:\"Yaffs NAND flash failure mitigation\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1343003341\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496923141\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:22283:\"<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\";s:7:\"summary\";s:275:\"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.\";s:6:\"format\";s:9:\"full_html\";}}}s:19:\"field_document_type\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:9:\"target_id\";s:3:\"345\";}}}s:6:\"upload\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:9:\"target_id\";s:2:\"83\";s:7:\"display\";s:1:\"1\";s:11:\"description\";s:0:\"\";}}}s:18:\"field_teaser_image\";a:1:{s:9:\"x-default\";a:1:{i:0;a:5:{s:9:\"target_id\";s:2:\"84\";s:3:\"alt\";s:41:\"Preview of YaffsNandFailureMitigation.pdf\";s:5:\"title\";N;s:5:\"width\";N;s:6:\"height\";N;}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:5:\"paper\";s:2:\"id\";s:3:\"455\";s:8:\"revision\";s:3:\"608\";s:4:\"uuid\";s:36:\"c6cde019-a48b-43e3-a51f-4e698c671336\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:35:\"Yaffs NAND flash failure mitigation\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"608\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105490.449,1,'entity_field_info node_values','814'),('values:node:457','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:21:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"475\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1345044728\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"457\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:15:\"yaffs_user_logo\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"2ffb5739-49f5-4d7f-9fa6-67a49b203a97\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:14:\"Google Android\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1345044409\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496410129\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:454:\"<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\";s:7:\"summary\";s:123:\"Google Android and all the phone manufacturers who use it, use Yaffs as the default filesystem in some versions of Android.\";s:6:\"format\";s:10:\"basic_html\";}}}s:15:\"field_logo_link\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:3:\"uri\";s:23:\"http://www.android.com/\";s:5:\"title\";s:14:\"Google Android\";s:7:\"options\";a:0:{}}}}s:21:\"field_yaffs_user_logo\";a:1:{s:9:\"x-default\";a:1:{i:0;a:5:{s:9:\"target_id\";s:2:\"48\";s:3:\"alt\";s:0:\"\";s:5:\"title\";s:0:\"\";s:5:\"width\";s:3:\"170\";s:6:\"height\";s:2:\"71\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:15:\"yaffs_user_logo\";s:2:\"id\";s:3:\"457\";s:8:\"revision\";s:3:\"475\";s:4:\"uuid\";s:36:\"2ffb5739-49f5-4d7f-9fa6-67a49b203a97\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:14:\"Google Android\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"475\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105484.818,1,'entity_field_info node_values','814'),('values:node:460','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:21:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"478\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1345477881\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"460\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:15:\"yaffs_user_logo\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"3d819054-b1c7-4aa6-9279-0ab0d6af19e3\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:16:\"Leica Geosystems\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1345477881\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496410357\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:371:\"<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\";s:7:\"summary\";s:307:\"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.\";s:6:\"format\";s:10:\"basic_html\";}}}s:15:\"field_logo_link\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:3:\"uri\";s:32:\"http://www.leica-geosystems.com/\";s:5:\"title\";s:16:\"Leica Geosystems\";s:7:\"options\";a:0:{}}}}s:21:\"field_yaffs_user_logo\";a:1:{s:9:\"x-default\";a:1:{i:0;a:5:{s:9:\"target_id\";s:2:\"44\";s:3:\"alt\";s:0:\"\";s:5:\"title\";s:0:\"\";s:5:\"width\";s:3:\"351\";s:6:\"height\";s:3:\"228\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:15:\"yaffs_user_logo\";s:2:\"id\";s:3:\"460\";s:8:\"revision\";s:3:\"478\";s:4:\"uuid\";s:36:\"3d819054-b1c7-4aa6-9279-0ab0d6af19e3\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:16:\"Leica Geosystems\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"478\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105484.851,1,'entity_field_info node_values','814'),('values:node:462','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:20:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"590\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1496410536\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"462\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:4:\"page\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"082d641d-2d02-45da-9553-a8bc4bf912cc\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:37:\"Licences - more background and detail\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"4\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1352909131\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496410536\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:5976:\"<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\";s:7:\"summary\";s:63:\"<p>More on the details and background of Licences for Yaffs</p>\";s:6:\"format\";s:10:\"basic_html\";}}}s:19:\"field_document_type\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:9:\"target_id\";s:3:\"343\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:4:\"page\";s:2:\"id\";s:3:\"462\";s:8:\"revision\";s:3:\"590\";s:4:\"uuid\";s:36:\"082d641d-2d02-45da-9553-a8bc4bf912cc\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:37:\"Licences - more background and detail\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"4\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"590\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498107603.483,1,'entity_field_info node_values','814'),('values:node:466','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:22:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"611\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1496924936\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"466\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:5:\"paper\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"c75f1175-eb9e-4081-89ae-53bfad24a474\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:46:\"Considerations in Choosing a Flash File System\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"4\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1401281609\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1496924936\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:26383:\"	<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>\";s:7:\"summary\";s:267:\"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.\";s:6:\"format\";s:8:\"raw_html\";}}}s:19:\"field_document_type\";a:1:{s:9:\"x-default\";a:1:{i:0;a:1:{s:9:\"target_id\";s:3:\"343\";}}}s:6:\"upload\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:9:\"target_id\";s:2:\"77\";s:7:\"display\";s:1:\"1\";s:11:\"description\";s:0:\"\";}}}s:18:\"field_teaser_image\";a:1:{s:9:\"x-default\";a:1:{i:0;a:5:{s:9:\"target_id\";s:2:\"88\";s:3:\"alt\";s:55:\"Preview of ConsiderationsInChoosingAFlashFileSystem.pdf\";s:5:\"title\";N;s:5:\"width\";N;s:6:\"height\";N;}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:5:\"paper\";s:2:\"id\";s:3:\"466\";s:8:\"revision\";s:3:\"611\";s:4:\"uuid\";s:36:\"c75f1175-eb9e-4081-89ae-53bfad24a474\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:46:\"Considerations in Choosing a Flash File System\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"4\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"611\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105490.532,1,'entity_field_info node_values','814'),('values:node:487','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:19:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:3:\"620\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1497460821\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:3:\"487\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:4:\"page\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"2b05bc65-3329-47e8-9fd0-39ae05a035ed\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:31:\"Robust Flash Storage Since 2002\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1493124112\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1497460913\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:350:\"<p>Yaffs (Yet Another Flash File System) is an open-source file system specifically designed to be fast, robust and suitable for embedded use with NAND and NOR Flash. It is widely used with Linux, RTOSs, or no OS at all, in consumer devices. It is available under GNU Public License, GPL, or on commercial terms from Aleph One.</p>\r\n\r\n<p>&nbsp;</p>\r\n\";s:7:\"summary\";s:0:\"\";s:6:\"format\";s:9:\"full_html\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:2:\"en\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:4:\"page\";s:2:\"id\";s:3:\"487\";s:8:\"revision\";s:3:\"620\";s:4:\"uuid\";s:36:\"2b05bc65-3329-47e8-9fd0-39ae05a035ed\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:31:\"Robust Flash Storage Since 2002\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:3:\"620\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105428.772,1,'entity_field_info node_values','814'),('values:node:73','O:23:\"Drupal\\node\\Entity\\Node\":25:{s:10:\"in_preview\";N;s:9:\"\0*\0values\";a:19:{s:3:\"vid\";a:1:{s:9:\"x-default\";s:2:\"73\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:18:\"revision_timestamp\";a:1:{s:9:\"x-default\";s:10:\"1453818953\";}s:12:\"revision_uid\";a:1:{s:9:\"x-default\";s:1:\"4\";}s:12:\"revision_log\";a:1:{s:9:\"x-default\";N;}s:3:\"nid\";a:1:{s:9:\"x-default\";s:2:\"73\";}s:4:\"type\";a:1:{s:9:\"x-default\";s:4:\"page\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"ffbcfa43-17ae-4152-8d86-4e063dd0a022\";}s:17:\"isDefaultRevision\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:7:\"Contact\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1119480717\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1453818953\";}s:7:\"promote\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:6:\"sticky\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:29:\"revision_translation_affected\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"body\";a:1:{s:9:\"x-default\";a:1:{i:0;a:3:{s:5:\"value\";s:3221:\"<p><img alt=\"The Old Courthouse\" class=\"image _original\" src=\"/sites/yaffs.net/files/images/OldCrt.jpg\" style=\"text-align: right; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; float: right; width: 400px; height: 300px; \" title=\"The Old Courthouse\"></p><dl><dt><strong style=\"text-align: left; \">Telephone</strong></dt><dd style=\"text-align: left; \">+44 (0)1223 811679</dd><dt style=\"text-align: left; \">&nbsp;</dt><dt style=\"text-align: left; \"><strong>Email</strong> -<a href=\"mailto:info@aleph1.co.uk\"> info@aleph1.co.uk</a></dt><dt style=\"text-align: left; \"><strong>Post</strong></dt><dd style=\"text-align: left; \">The Old Courthouse<br>123 High Street<br>Bottisham<br>Cambridge<br>CB25 9BA<br>United Kingdom.</dd></dl><p style=\"text-align: -webkit-auto;\">&nbsp;</p><h2 style=\"text-align: left;\">Public Transport - Buses</h2><p style=\"text-align: left;\">You can reach us by bus from the bus station on Drummer Street in the centre of Cambridge, in 20 minutes. Buses run two or three times an hour much of the day. Click for <a href=\"http://www.stagecoachbus.com/cambridge\" target=\"_self\" title=\"Bus Times\"> timetables </a> and under Bus Timetable Lookup enter 10 or 11 in the Service No. box.<br>Look at the map below</p><p style=\"text-align: left;\">&nbsp;The Number 10 bus enters the village from the East end and passes Westwards along the High Street. Get off at the bus shelter on the South side of the High Street about 500 metres after leaving the main (A1303) road to enter the village. The Courthouse is a further 100 metres West and on the other (North) side of the road.</p><p style=\"text-align: left;\">The Number 10 buses leave Drummer Street at the hour and half hour and take 20 minutes.<br><br>The Number 11 bus leaves at 15 and 45 minutes past each hour and travels along the main A1303 road to Newmarket (and them Bury St Edmunds), passing the East end of Bottisham.&nbsp; Get off at the bus shelter on the main road, and walk back past First Copy, (the former White Swan pub) on the High Street; continue about 450 metres West along the High Street towards the centre of Bottisham. The Courthouse is on the North side of the High Street.</p><p style=\"text-align: left;\"><strong>If coming to visit please make an appointment before setting out.</strong></p><p style=\"text-align: left;\"><a href=\"?q=node/323\">Click here for a page with only these maps, for printing out</a>.</p><p style=\"text-align: left;\">This shows the location of Aleph One within Bottisham. Park in the layby on the South side of the road. We are opposite in a large building with three arched windows. There are doors on either side of the building, and you may need to try both to get a response.</p><center><img alt=\"Bottisham map\" src=\"/sites/yaffs.net/files/images/Bottisham.jpg\" style=\"border: 0;\" title=\"Bottisham map\" border=\"0\"></center><p>&nbsp;</p><p>Map below shows where we are in relation to Cambridge and the surrounding roads.</p><center><img alt=\"How to get to Aleph One\" src=\"/sites/yaffs.net/files/images/Cambridge.jpg\" style=\"border: 0;\" title=\"How to get to Aleph One\" border=\"0\"></center>\";s:7:\"summary\";s:51:\"Everything needed to get in touch with us or visit.\";s:6:\"format\";s:9:\"full_html\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:3:\"und\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";s:1:\"1\";s:13:\"\0*\0entityKeys\";a:4:{s:6:\"bundle\";s:4:\"page\";s:2:\"id\";s:2:\"73\";s:8:\"revision\";s:2:\"73\";s:4:\"uuid\";s:36:\"ffbcfa43-17ae-4152-8d86-4e063dd0a022\";}s:25:\"\0*\0translatableEntityKeys\";a:6:{s:5:\"label\";a:1:{s:9:\"x-default\";s:7:\"Contact\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:3:\"und\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:9:\"published\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";s:2:\"73\";s:15:\"\0*\0entityTypeId\";s:4:\"node\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498106001.899,1,'entity_field_info node_values','814'),('values:shortcut:1','O:31:\"Drupal\\shortcut\\Entity\\Shortcut\":24:{s:9:\"\0*\0values\";a:8:{s:2:\"id\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:12:\"shortcut_set\";a:1:{s:9:\"x-default\";s:7:\"default\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"5c1bebfa-f579-4311-b175-8389588943f2\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:5:\"title\";a:1:{s:9:\"x-default\";s:11:\"Add content\";}s:6:\"weight\";a:1:{s:9:\"x-default\";s:3:\"-20\";}s:4:\"link\";a:1:{s:9:\"x-default\";a:3:{s:3:\"uri\";s:18:\"internal:/node/add\";s:5:\"title\";N;s:7:\"options\";s:6:\"a:0:{}\";}}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:2:\"en\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";b:1;s:13:\"\0*\0entityKeys\";a:3:{s:6:\"bundle\";s:7:\"default\";s:2:\"id\";s:1:\"1\";s:4:\"uuid\";s:36:\"5c1bebfa-f579-4311-b175-8389588943f2\";}s:25:\"\0*\0translatableEntityKeys\";a:3:{s:5:\"label\";a:1:{s:9:\"x-default\";s:11:\"Add content\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";N;s:15:\"\0*\0entityTypeId\";s:8:\"shortcut\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498105469.456,1,'entity_field_info shortcut_values','814'),('values:user:0','O:23:\"Drupal\\user\\Entity\\User\":24:{s:9:\"\0*\0values\";a:16:{s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"a7de68c1-3719-4405-8acc-5fd1cf81cf5c\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:18:\"preferred_langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:24:\"preferred_admin_langcode\";a:1:{s:9:\"x-default\";N;}s:4:\"name\";a:1:{s:9:\"x-default\";s:0:\"\";}s:4:\"pass\";a:1:{s:9:\"x-default\";N;}s:4:\"mail\";a:1:{s:9:\"x-default\";N;}s:8:\"timezone\";a:1:{s:9:\"x-default\";s:0:\"\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1489529271\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1489529271\";}s:6:\"access\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:5:\"login\";a:1:{s:9:\"x-default\";s:1:\"0\";}s:4:\"init\";a:1:{s:9:\"x-default\";N;}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:2:\"en\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";b:1;s:13:\"\0*\0entityKeys\";a:3:{s:6:\"bundle\";s:4:\"user\";s:2:\"id\";s:1:\"0\";s:4:\"uuid\";s:36:\"a7de68c1-3719-4405-8acc-5fd1cf81cf5c\";}s:25:\"\0*\0translatableEntityKeys\";a:2:{s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";N;s:15:\"\0*\0entityTypeId\";s:4:\"user\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498106001.375,1,'entity_field_info user_values','814'),('values:user:1','O:23:\"Drupal\\user\\Entity\\User\":24:{s:9:\"\0*\0values\";a:17:{s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"370858b2-375f-4eac-be4c-65400a485ba0\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:18:\"preferred_langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:24:\"preferred_admin_langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:4:\"name\";a:1:{s:9:\"x-default\";s:5:\"Admin\";}s:4:\"pass\";a:1:{s:9:\"x-default\";s:55:\"$S$EOZf4osRQ2i/zDh81co1XNG6MTOGA5WfYg.JyqP5E5kso3BzJfe7\";}s:4:\"mail\";a:1:{s:9:\"x-default\";s:22:\"jeff.veit@tanasity.com\";}s:8:\"timezone\";a:1:{s:9:\"x-default\";s:13:\"Europe/London\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1116435302\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1491844207\";}s:6:\"access\";a:1:{s:9:\"x-default\";s:10:\"1498108213\";}s:5:\"login\";a:1:{s:9:\"x-default\";s:10:\"1498051487\";}s:4:\"init\";a:1:{s:9:\"x-default\";s:22:\"jeff.veit@tanasity.com\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"roles\";a:1:{s:9:\"x-default\";a:2:{i:0;a:1:{s:9:\"target_id\";s:14:\"administrators\";}i:1;a:1:{s:9:\"target_id\";s:13:\"administrator\";}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:2:\"en\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";b:1;s:13:\"\0*\0entityKeys\";a:3:{s:6:\"bundle\";s:4:\"user\";s:2:\"id\";s:1:\"1\";s:4:\"uuid\";s:36:\"370858b2-375f-4eac-be4c-65400a485ba0\";}s:25:\"\0*\0translatableEntityKeys\";a:2:{s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";N;s:15:\"\0*\0entityTypeId\";s:4:\"user\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498108242.340,1,'entity_field_info user_values','814'),('values:user:4','O:23:\"Drupal\\user\\Entity\\User\":24:{s:9:\"\0*\0values\";a:20:{s:3:\"uid\";a:1:{s:9:\"x-default\";s:1:\"4\";}s:4:\"uuid\";a:1:{s:9:\"x-default\";s:36:\"8a148983-c270-4ba3-9bd4-d6e553a26327\";}s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:18:\"preferred_langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:24:\"preferred_admin_langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:4:\"name\";a:1:{s:9:\"x-default\";s:6:\"Laurie\";}s:4:\"pass\";a:1:{s:9:\"x-default\";s:56:\"U$S$EKL.aSzX4fGz6sHgWeXd8MAfJZ0YoRUbtywqIND8bq//Fy/bjQsZ\";}s:4:\"mail\";a:1:{s:9:\"x-default\";s:19:\"laurie@aleph1.co.uk\";}s:8:\"timezone\";a:1:{s:9:\"x-default\";s:13:\"Europe/London\";}s:6:\"status\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:7:\"created\";a:1:{s:9:\"x-default\";s:10:\"1131713367\";}s:7:\"changed\";a:1:{s:9:\"x-default\";s:10:\"1489536906\";}s:6:\"access\";a:1:{s:9:\"x-default\";s:10:\"1482140678\";}s:5:\"login\";a:1:{s:9:\"x-default\";s:10:\"1482140678\";}s:4:\"init\";a:1:{s:9:\"x-default\";s:19:\"laurie@aleph1.co.uk\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}s:5:\"roles\";a:1:{s:9:\"x-default\";a:2:{i:0;a:1:{s:9:\"target_id\";s:14:\"administrators\";}i:1;a:1:{s:9:\"target_id\";s:13:\"administrator\";}}}s:23:\"profile_employee_detail\";a:1:{s:9:\"x-default\";a:1:{i:0;a:2:{s:5:\"value\";s:164:\"Laurie started Aleph One in 1971 to sell computer related hardware. Nowdays Yaffs is the main product. Laurie lives in a lovely village just North of Cambridge, UK.\";s:6:\"format\";N;}}}s:26:\"profile_employee_job_title\";a:1:{s:9:\"x-default\";a:1:{i:0;a:2:{s:5:\"value\";s:17:\"Managing Director\";s:6:\"format\";N;}}}s:21:\"profile_employee_name\";a:1:{s:9:\"x-default\";a:1:{i:0;a:2:{s:5:\"value\";s:18:\"Laurie van Someren\";s:6:\"format\";N;}}}}s:9:\"\0*\0fields\";a:0:{}s:19:\"\0*\0fieldDefinitions\";N;s:12:\"\0*\0languages\";N;s:14:\"\0*\0langcodeKey\";s:8:\"langcode\";s:21:\"\0*\0defaultLangcodeKey\";s:16:\"default_langcode\";s:17:\"\0*\0activeLangcode\";s:9:\"x-default\";s:18:\"\0*\0defaultLangcode\";s:2:\"en\";s:15:\"\0*\0translations\";a:1:{s:9:\"x-default\";a:1:{s:6:\"status\";i:1;}}s:24:\"\0*\0translationInitialize\";b:0;s:14:\"\0*\0newRevision\";b:0;s:20:\"\0*\0isDefaultRevision\";b:1;s:13:\"\0*\0entityKeys\";a:3:{s:6:\"bundle\";s:4:\"user\";s:2:\"id\";s:1:\"4\";s:4:\"uuid\";s:36:\"8a148983-c270-4ba3-9bd4-d6e553a26327\";}s:25:\"\0*\0translatableEntityKeys\";a:2:{s:8:\"langcode\";a:1:{s:9:\"x-default\";s:2:\"en\";}s:16:\"default_langcode\";a:1:{s:9:\"x-default\";s:1:\"1\";}}s:12:\"\0*\0validated\";b:0;s:21:\"\0*\0validationRequired\";b:0;s:19:\"\0*\0loadedRevisionId\";N;s:15:\"\0*\0entityTypeId\";s:4:\"user\";s:15:\"\0*\0enforceIsNew\";N;s:12:\"\0*\0typedData\";N;s:16:\"\0*\0cacheContexts\";a:0:{}s:12:\"\0*\0cacheTags\";a:0:{}s:14:\"\0*\0cacheMaxAge\";i:-1;s:14:\"\0*\0_serviceIds\";a:0:{}}',-1,1498108007.204,1,'entity_field_info user_values','814');
commit;

--
