提交 7b76fb6e 编写于 作者: B bernard.xiong@gmail.com

add UFFS 1.3.2-4 (http://sourceforge.net/projects/uffs)

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@888 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 a3ca8e33
Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
CMAKE_MINIMUM_REQUIRED(VERSION 2.6 )
PROJECT( uffs )
ADD_SUBDIRECTORY( src )
\ No newline at end of file
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
# Doxyfile 1.4.1-KDevelop
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = uffs-doc
PROJECT_NUMBER = 0.1
OUTPUT_DIRECTORY = doc/doxygen-doc
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH = ./
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = YES
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = YES
SORT_BY_SCOPE_NAME = YES
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ./src
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.mm \
*.dox \
*.C \
*.CC \
*.C++ \
*.II \
*.I++ \
*.H \
*.HH \
*.H++ \
*.CS \
*.PHP \
*.PHP3 \
*.M \
*.MM \
*.C \
*.H \
*.tlh \
*.diff \
*.patch \
*.moc \
*.xpm \
*.dox
RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = YES
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE = uffs.tag
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
UFFS: Ultra-low-cost Flash File System
Project: http://uffs.sf.net/
Blog: http://all-about-uffs.blogspot.com/
Q/A: http://groups.google.com/group/uffs/
Author: Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
INTRODUCTION
------------
UFFS is a nand flash file system designed for embedded system.
UFFS have some unique and advanced features:
* Low cost: e.g. it needs only 41K bytes RAM for 64MB NAND flash (page size 2048).
* Fast booting: it reads only a few spares from each block, typically
mounting a fully filled file system (Gbits) within one second.
* Superb Reliability:
- The file system is designed for the embedded system which may
frequently lost power/reset without care.
- Journal file system, the file system will automatically rollback
to the last state when lost power on the middle of flash programing.
- When 'write' return without error, the data is guarenteed been
saved on flash.
* Fast file create/read/write/seek.
* Bad-block tolerant, ECC enable and good ware-leveling.
* There is no garbage collection needed for UFFS.
* Support multiple NAND flash class in one system.
* Support bare flash hardware, no operating system needed.
* Support static memory allocation (works without 'malloc').
* Fully simulated on PC (Windows/Linux) platform.
Disadvantage:
* space inefficency for small files: UFFS use at least one
'block'(the minial erase unit for NAND flash, e.g. 16K ) for a file.
* maximum supported blocks: 2^16 = 65535
Memory consuming example:
For page size = 512:
[VARY]Tree nodes: 16 * total_blocks
[CONST]Page Bufs: MAX_CACHED_BUFFERS(10) * (40 + pageSize(512)) = 5.4K
[CONST]Block Info caches: (24 + 14 * pages_per_block (32)) * MAX_CACHED_BLOCK_INFO (10) = 4.6K
Example 1: 128M bytes NAND, 8192 blocks, total memory cost:
(16 * 8192)128K + 5.4K + 4.6K = 138K bytes.
Example 2: 32M Bytes NAND, 2048 blocks, total memory cost:
(16 * 2048)32K + 5.4K + 4.6K = 42K bytes.
Example 3: 16M bytes NAND, 1024 blocks, total memory cost:
(16 * 1024)16K + 5.4K + 4.6K = 26K bytes.
For page size = 2048:
[VARY]Tree nodes: 16 * total_blocks
[CONST]Page Bufs: MAX_CACHED_BUFFERS(10) * (40 + pageSize(2048)) = 20.4K
[CONST]Block Info caches: (24 + 14 * pages_per_block (32)) * MAX_CACHED_BLOCK_INFO (10) = 4.6K
Example 1: 512M bytes NAND, 8192 blocks, total memory cost:
(16 * 8192)128K + 20.4K + 4.6K = 153K bytes.
Example 2: 128M Bytes NAND, 2048 blocks, total memory cost:
(16 * 2048)32K + 20.4K + 4.6K = 57K bytes.
Example 3: 64M bytes NAND, 1024 blocks, total memory cost:
(16 * 1024)16K + 20.4K + 4.6K = 41K bytes.
BUILD SIMULATOR REQUIREMENT
---------------------------
From V1.2.0, build uffs simulator requires 'cmake'.
'cmake' can be downloaded from: http://www.cmake.org/
or, under Debian/Ubuntu:
sudo apt-get install cmake
BUILD SIMULATOR ON LINUX
------------------------
1) create a 'build' dir along with uffs source dir, for example:
/+
+--build/
+--uffs-1.2.0/
|
2) create Makefiles and build:
cd build
cmake ../uffs-1.2.0
make
5) run simulator (interactive mode):
src/utils/mkuffs
BUILD SIMULATOR ON WINDOWS
--------------------------
1) create a 'build' dir along with uffs source dir,
/+
+--build/
+--uffs-1.2.0/
|
2) Create VC project files:
cd build
cmake ../uffs-1.2.0
3) Open uffs.dsw (or uffs.sln for VC > 6 ), compile & run.
LATEST SOURCE CODE
------------------
You can get the latest source code from git repository:
git clone git://uffs.git.sourceforge.net/gitroot/uffs/uffs
CURRENT STATUS
--------------
UFFS 0.1.x is a working version on PC simulator, also has been ported to
uBase embedded OS as a 'real world' product for thousands of copies,
it works fine so far.
UFFS 0.2.0 implementes full directory.
UFFS 1.0.0 is the first stable release at sf.net.
UFFS 1.1.0: support NAND flash with large page size (up to 2K).
UFFS 1.1.1: bug fixes. a tool for making uffs disk image.
UFFS 1.1.2: bug fixes. add more Flash Class. change Licence from GNU GPLv2 to GNU LGPLv2
UFFS 1.2.0:
- eliminate 'current path' and relatives. Now you should use absolute path in all
uffs APIs. For dir, the fullname should end with '/'.
- allow using static memory allocation, 'malloc' is no longer needed.
- using cmake for building simulator.
- bug fixes & minor changes.
UFFS 1.2.1:
- improve bad block management
- bug fixes
- change Licence to modified GNU GPLv2.
UFFS 1.3.0:
- improved flash interface
- support hardware ECC
- support user defined spare layout (for customized NAND flash controller)
- support 4K page size
- no partial page program required, support MLC NAND flash
- reduced buffer flushes by grouping buffers
- structual improvments and bug fixes
UFFS v1.3.1:
- Tidy up three memory allocators: static, native and system.
- Fix bugs in flash interface example.
- Fix memory allocation bugs when using static memory allocator.
- Add flash driver interface 'WriteFullPage()'.
- Fix compilation errors for BlackFin DSP compiler.
UFFS v1.3.2:
- Add POSIX like file system APIs.
- Bug fixes.
LICENCE
-------
From v1.2.1, UFFS is released under a midified GNU GPLv2. (the same as eCos Licence)
The full licence text can be found in the header of source files:
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
ACKNOWLEDGMENT
---------------
Special thanks for your contributions to:
(list in no particular order)
* Chen Jun <chj@nlscan.com>
* Michail <digiolog@mail.ru>
* Sjpu <sjpu@163.com>
* RobertGray <xennex@hotmail.com>
* Dongbo <dongbo@ftsafe.com>
* Cag <seucag@hotmail.com>
* Sergey <s_sazonov@m2m-t.ru>
* Chris Conrad <chris.conrad@halliburton.com>
* Vladimir <decoder@rambler.ru>
* Thien Pham <thienpham2008@yahoo.com>
* Emmanuel Blot <eblot.ml@gmail.com>
* Michael <yowong2@gmail.com>
TODO list for v1.3:
* New API: int uffs_SkipObject(uffs_Object *obj, int size);
* Introduce buffer group
* Interface to Linux MTD
ADD_SUBDIRECTORY(emu)
ADD_SUBDIRECTORY(uffs)
ADD_SUBDIRECTORY(utils)
ADD_SUBDIRECTORY(example)
SET(libemu_SRCS cmdline.c cmdline.h helper_cmds.c uffs_fileem.c uffs_fileem.h uffs_os_posix.c test_cmds.c)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
ADD_LIBRARY(emu STATIC ${libemu_SRCS} )
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file cmdline.c
* \brief command line test interface
* \author Ricky Zheng, created in 22th Feb, 2007
*/
#include <string.h>
#include <stdio.h>
//#include <conio.h>
#include "cmdline.h"
#include "uffs/uffs_fs.h"
#define PROMPT "UFFS>"
static BOOL m_exit = FALSE;
static struct cli_commandset cmdset[200] = {0};
static int m_cmdCount = 0;
static char str_buf[128];
const char * cli_getparam(const char *tail, const char **next)
{
char *p;
if (tail == NULL)
return NULL;
strcpy(str_buf, tail);
p = str_buf;
while (*tail != ' ' && *tail != 0) {
tail++; p++;
}
if (*tail == ' ') {
*p = 0;
while(*tail == ' ')
tail++;
}
if(next)
*next = (char *)(*tail ? tail : NULL);
return str_buf;
}
static BOOL cmdExit(const char *tail)
{
m_exit = TRUE;
return TRUE;
}
static BOOL cmdHelp(const char *tail);
static struct cli_commandset default_cmdset[] =
{
{ cmdHelp, "help|?", "[<command>]", "Show commands or help on one command" },
{ cmdExit, "exit", NULL, "exit command line" },
{ NULL, NULL, NULL, NULL }
};
static BOOL match_cmd(const char *src, int start, int end, const char *des)
{
while (src[start] == ' ' && start < end)
start++;
while (src[end] == ' ' && start < end)
end--;
if ((int)strlen(des) == (end - start + 1)) {
if (memcmp(src + start, des, end - start + 1) == 0) {
return TRUE;
}
}
return FALSE;
}
static BOOL check_cmd(const char *cmds, const char *cmd)
{
int start, end;
for (start = end = 0; cmds[end] != 0 && cmds[end] != '|'; end++);
while (end > start) {
if (match_cmd(cmds, start, end - 1, cmd) == TRUE)
return TRUE;
if (cmds[end] == 0)
break;
if (cmds[end] == '|') {
end++;
for (start = end; cmds[end] != 0 && cmds[end] != '|'; end++);
}
}
return FALSE;
}
static int cmdFind(const char *cmd)
{
int icmd;
for (icmd = 0; cmdset[icmd].cmd != NULL; icmd++) {
//printf("cmdFind: Check cmd: %s with %s\n", cmd, cmdset[icmd].cmd);
if (check_cmd(cmdset[icmd].cmd, cmd) == TRUE)
return icmd;
}
return -1;
}
static BOOL cmdHelp(const char *tail)
{
int icmd;
if (tail == NULL) {
printf("Available commands:\n");
for (icmd = 0; cmdset[icmd].cmd != NULL; icmd++) {
int i;
printf("%s", cmdset[icmd].cmd);
for (i = strlen(cmdset[icmd].cmd); i%10; i++,printf(" "));
//if ((icmd & 7) == 7 || cmdset[icmd+1].cmd == NULL) printf("\n");
}
printf("\n");
}
else {
icmd = cmdFind(tail);
if (icmd < 0) {
printf("No such command\n");
}
else {
printf("%s: %s\n", cmdset[icmd].cmd, cmdset[icmd].descr);
printf("Usage: %s %s\n", cmdset[icmd].cmd, cmdset[icmd].args);
}
}
return TRUE;
}
void cliInterpret(const char *line)
{
char cmd[64];
const char *tail;
const char *psep;
int icmd;
psep = strchr(line, ' ');
cmd[0] = 0;
if (psep == NULL) {
strncat(cmd, line, sizeof(cmd) - 1);
tail = NULL;
}
else {
strncat(cmd, line, psep - line);
for (tail = psep; *tail == ' '; ++tail);
if (*tail == 0)
tail = NULL;
}
icmd = cmdFind(cmd);
if (icmd < 0) {
printf("Unknown command - try help\n");
return;
}
else {
//printf("Command idx: %d\n", icmd);
if (!cmdset[icmd].handler(tail)) {
cmdHelp(cmd);
}
}
}
void cli_add_commandset(struct cli_commandset *cmds)
{
int icmd;
for (icmd = 0; cmds[icmd].cmd != NULL; icmd++) {
memcpy(&(cmdset[m_cmdCount++]), &(cmds[icmd]), sizeof(struct cli_commandset));
}
}
void cliMain()
{
char line[80];
int linelen = 0;
printf("$ ");
cli_add_commandset(default_cmdset);
while (!m_exit) {
char ch;
ch = getc(stdin);
switch (ch) {
case 8:
case 127:
if (linelen > 0) {
--linelen;
printf("\x08 \x08");
}
break;
case '\r':
case '\n':
//printf("\r\n");
if (linelen > 0) {
line[linelen] = 0;
cliInterpret(line);
}
linelen = 0;
printf("$ ");
break;
case 21:
while (linelen > 0) {
--linelen;
printf("\x08 \x08");
}
break;
default:
if (ch >= ' ' && ch < 127 && linelen < sizeof(line) - 1) {
line[linelen++] = ch;
//printf("%c", ch);
}
}
}
}
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
#ifndef _UFFS_CLI_H_
#define _UFFS_CLI_H_
#ifndef BOOL
#define BOOL int
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef BOOL command_t(const char *tail);
struct cli_commandset {
command_t *handler;
const char *cmd;
const char *args;
const char *descr;
};
const char * cli_getparam(const char *tail, const char **next);
void cli_add_commandset(struct cli_commandset *cmds);
void cliInterpret(const char *line);
void cliMain();
#endif
此差异已折叠。
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file test_cmds.c
* \brief commands for test uffs
* \author Ricky Zheng
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uffs/uffs_config.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_mtb.h"
#include "uffs/uffs_find.h"
#include "uffs/uffs_badblock.h"
#include "cmdline.h"
#define PFX "test:"
static BOOL cmdTestPageReadWrite(const char *tail)
{
TreeNode *node;
uffs_Device *dev;
uffs_Tags local_tag;
uffs_Tags *tag = &local_tag;
int ret;
u16 block;
u16 page;
uffs_Buf *buf;
u32 i;
dev = uffs_GetDeviceFromMountPoint("/");
if (!dev)
goto ext;
buf = uffs_BufClone(dev, NULL);
if (!buf)
goto ext;
node = uffs_TreeGetErasedNode(dev);
if (!node) {
uffs_Perror(UFFS_ERR_SERIOUS, "no free block ?");
goto ext;
}
for (i = 0; i < dev->com.pg_data_size; i++) {
buf->data[i] = i & 0xFF;
}
block = node->u.list.block;
page = 1;
TAG_DATA_LEN(tag) = dev->com.pg_data_size;
TAG_TYPE(tag) = UFFS_TYPE_DATA;
TAG_PAGE_ID(tag) = 3;
TAG_PARENT(tag) = 100;
TAG_SERIAL(tag) = 10;
TAG_BLOCK_TS(tag) = 1;
ret = uffs_FlashWritePageCombine(dev, block, page, buf, tag);
if (UFFS_FLASH_HAVE_ERR(ret)) {
uffs_Perror(UFFS_ERR_SERIOUS, "Write page error: %d", ret);
goto ext;
}
ret = uffs_FlashReadPage(dev, block, page, buf);
if (UFFS_FLASH_HAVE_ERR(ret)) {
uffs_Perror(UFFS_ERR_SERIOUS, "Read page error: %d", ret);
goto ext;
}
for (i = 0; i < dev->com.pg_data_size; i++) {
if (buf->data[i] != (i & 0xFF)) {
uffs_Perror(UFFS_ERR_SERIOUS, "Data verify fail at: %d", i);
goto ext;
}
}
ret = uffs_FlashReadPageSpare(dev, block, page, tag, NULL);
if (UFFS_FLASH_HAVE_ERR(ret)) {
uffs_Perror(UFFS_ERR_SERIOUS, "Read tag (page spare) error: %d", ret);
goto ext;
}
// verify tag:
if (!TAG_IS_DIRTY(tag)) {
uffs_Perror(UFFS_ERR_SERIOUS, "not dirty ? Tag verify fail!");
goto ext;
}
if (!TAG_IS_VALID(tag)) {
uffs_Perror(UFFS_ERR_SERIOUS, "not valid ? Tag verify fail!");
goto ext;
}
if (TAG_DATA_LEN(tag) != dev->com.pg_data_size ||
TAG_TYPE(tag) != UFFS_TYPE_DATA ||
TAG_PAGE_ID(tag) != 3 ||
TAG_PARENT(tag) != 100 ||
TAG_SERIAL(tag) != 10 ||
TAG_BLOCK_TS(tag) != 1) {
uffs_Perror(UFFS_ERR_SERIOUS, "Tag verify fail!");
goto ext;
}
uffs_Perror(UFFS_ERR_SERIOUS, "Page read/write test succ.");
ext:
if (node) {
uffs_FlashEraseBlock(dev, node->u.list.block);
if (HAVE_BADBLOCK(dev))
uffs_BadBlockProcess(dev, node);
else
uffs_InsertToErasedListHead(dev, node);
}
if (dev)
uffs_PutDevice(dev);
if (buf)
uffs_BufFreeClone(dev, buf);
return TRUE;
}
static struct cli_commandset cmdset[] =
{
{ cmdTestPageReadWrite, "t_pgrw", NULL, "test page read/write" },
{ NULL, NULL, NULL, NULL }
};
struct cli_commandset * get_test_cmds()
{
return cmdset;
};
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fileem.c
* \brief emulate uffs file system
* \author Ricky Zheng, created 9th May, 2005
*/
#include <sys/types.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "uffs/uffs_device.h"
#include "uffs_fileem.h"
#define PFX "femu: "
#define MAXWRITETIME_PAGE 1
#define MAXWRITETIME_SPARE 1
#define FEMU_MAX_SPARE_SIZE UFFS_MAX_SPARE_SIZE
static u8 em_page_buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE];
static URET emu_initDevice(uffs_Device *dev);
static URET CheckInit(uffs_Device *dev)
{
int i;
int fSize;
int written;
u8 * p = em_page_buf;
uffs_FileEmu *emu;
int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size;
pg_size = dev->attr->page_data_size + dev->attr->spare_size;
pgd_size = dev->attr->page_data_size;
sp_size = dev->attr->spare_size;
blk_pgs = dev->attr->pages_per_block;
blks = dev->attr->total_blocks;
blk_size = dev->attr->page_data_size * dev->attr->pages_per_block;
emu = (uffs_FileEmu *)(dev->attr->_private);
if (emu->initCount > 0) {
emu->initCount++;
return U_SUCC;
}
if (dev->attr->ecc_opt != UFFS_ECC_NONE &&
dev->attr->ecc_opt != UFFS_ECC_SOFT) {
return U_FAIL; //!< file emulator don't support HW ECC.
}
emu->em_monitor_page = (u8 *) malloc(dev->attr->total_blocks * dev->attr->pages_per_block);
if (!emu->em_monitor_page)
return U_FAIL;
emu->em_monitor_spare = (u8 *) malloc(dev->attr->total_blocks * dev->attr->pages_per_block);
if (!emu->em_monitor_spare)
return U_FAIL;
//clear monitor
memset(emu->em_monitor_page, 0, blks * blk_pgs);
memset(emu->em_monitor_spare, 0, blks * blk_pgs);
emu->fp = fopen(emu->emu_filename, "rb");
if (emu->fp == NULL) {
emu->fp = fopen(emu->emu_filename, "ab+");
if (emu->fp == NULL) {
printf(PFX"Failed to create uffs emulation file.");
return U_FAIL;
}
fseek(emu->fp, 0, SEEK_END);
fSize = ftell(emu->fp);
if (fSize < blk_size * blks) {
printf("Creating uffs emulation file\n");
fseek(emu->fp, 0, SEEK_SET);
memset(p, 0xff, pgd_size + sp_size);
for (i = 0; i < blk_pgs * blks; i++) {
written = fwrite(p, 1, pgd_size + sp_size, emu->fp);
if (written != pgd_size + sp_size) {
printf("Write failed\n");
fclose(emu->fp);
emu->fp = NULL;
return U_FAIL;
}
}
}
}
fflush(emu->fp);
fclose(emu->fp);
emu->fp = fopen(emu->emu_filename, "rb+");
if (emu->fp == NULL) {
printf(PFX"Can't open emulation file.\n");
return U_FAIL;
}
emu->initCount++;
return U_SUCC;
}
static int femu_WritePageData(uffs_Device *dev, u32 block, u32 page_num, const u8 *data, int len, u8 *ecc)
{
int written;
int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size;
uffs_FileEmu *emu;
emu = (uffs_FileEmu *)(dev->attr->_private);
if (!emu || !(emu->fp))
goto err;
pg_size = dev->attr->page_data_size + dev->attr->spare_size;
pgd_size = dev->attr->page_data_size;
sp_size = dev->attr->spare_size;
blk_pgs = dev->attr->pages_per_block;
blks = dev->attr->total_blocks;
blk_size = dev->attr->page_data_size * dev->attr->pages_per_block;
if (len > pgd_size) {
printf("femu: write page data out of range!\n");
goto err;
}
emu->em_monitor_page[block * blk_pgs + page_num]++;
if (emu->em_monitor_page[block * blk_pgs + page_num] > MAXWRITETIME_PAGE) {
printf("Warrning: block %d page %d exceed it's maximum write time!\r\n", block, page_num);
goto err;
}
if (data) {
fseek(emu->fp,
(block * blk_pgs + page_num) *
(pgd_size + sp_size), SEEK_SET);
written = fwrite(data, 1, len, emu->fp);
if (written != len) {
printf("femu: write page I/O error ?\n");
goto err;
}
}
dev->st.page_write_count++;
return UFFS_FLASH_NO_ERR;
err:
return UFFS_FLASH_IO_ERR;
}
static int femu_WritePageSpare(uffs_Device *dev, u32 block, u32 page_num, const u8 *spare, int ofs, int len, UBOOL eod)
{
int written;
int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size;
uffs_FileEmu *emu;
emu = (uffs_FileEmu *)(dev->attr->_private);
if (!emu || !(emu->fp))
goto err;
pg_size = dev->attr->page_data_size + dev->attr->spare_size;
pgd_size = dev->attr->page_data_size;
sp_size = dev->attr->spare_size;
blk_pgs = dev->attr->pages_per_block;
blks = dev->attr->total_blocks;
blk_size = dev->attr->page_data_size * dev->attr->pages_per_block;
// printf("WS: %d/%d, size %d\n", block, page_num, len);
if (len > sp_size) {
printf("femu: write page data out of range!\n");
goto err;
}
emu->em_monitor_spare[block*blk_pgs + page_num]++;
if (emu->em_monitor_spare[block*blk_pgs + page_num] > MAXWRITETIME_SPARE) {
printf("Warrning: block %d page %d (spare) exceed it's maximum write time!\r\n", block, page_num);
goto err;
}
if (spare) {
// simulate power lost ! produce an unclean page.
if (0 && block == 3 && page_num == 2) {
fflush(emu->fp);
exit(1);
}
fseek(emu->fp, (block*blk_pgs + page_num) * (pgd_size + sp_size) + dev->attr->page_data_size + ofs, SEEK_SET);
written = fwrite(spare, 1, len, emu->fp);
if (written != len) {
printf("femu: write spare I/O error ?\n");
goto err;
}
}
if (eod == U_TRUE) {
// eod: U_TRUE -- single write cycle
// eod: U_FALSE -- this is the write after page data
}
fflush(emu->fp);
dev->st.spare_write_count++;
return UFFS_FLASH_NO_ERR;
err:
return UFFS_FLASH_IO_ERR;
}
static URET femu_ReadPageData(uffs_Device *dev, u32 block, u32 page_num, u8 *data, int len, u8 *ecc)
{
int nread;
int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size;
uffs_FileEmu *emu;
emu = (uffs_FileEmu *)(dev->attr->_private);
if (!emu || !(emu->fp))
goto err;
pg_size = dev->attr->page_data_size + dev->attr->spare_size;
pgd_size = dev->attr->page_data_size;
sp_size = dev->attr->spare_size;
blk_pgs = dev->attr->pages_per_block;
blks = dev->attr->total_blocks;
blk_size = dev->attr->page_data_size * dev->attr->pages_per_block;
if (len > pgd_size) {
printf("femu: read page data out of range!\n");
goto err;
}
if (data) {
fseek(emu->fp, (block*blk_pgs + page_num) * (pgd_size + sp_size), SEEK_SET);
nread = fread(data, 1, len, emu->fp);
// for ECC testing.
if (1 && block == 2 && page_num == 3 && len > 13) {
printf("--- ECC error inject to block %d page %d ---\n", block, page_num);
data[13] = (data[13] & ~0x40) | (~(data[13] & 0x40) & 0x40) ;
}
if (nread != len) {
printf("femu: read page I/O error ?\n");
goto err;
}
}
dev->st.page_read_count++;
return UFFS_FLASH_NO_ERR;
err:
return UFFS_FLASH_IO_ERR;
}
static URET femu_ReadPageSpare(uffs_Device *dev, u32 block, u32 page_num, u8 *spare, int ofs, int len)
{
int nread;
int pos;
int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size;
uffs_FileEmu *emu;
emu = (uffs_FileEmu *)(dev->attr->_private);
if (!emu || !(emu->fp))
goto err;
pg_size = dev->attr->page_data_size + dev->attr->spare_size;
pgd_size = dev->attr->page_data_size;
sp_size = dev->attr->spare_size;
blk_pgs = dev->attr->pages_per_block;
blks = dev->attr->total_blocks;
blk_size = dev->attr->page_data_size * dev->attr->pages_per_block;
// printf("RS: %d/%d, size %d\n", block, page_num, len);
if (len > sp_size) {
printf("femu: read page spare out of range!\n");
goto err;
}
if (spare) {
pos = (block*blk_pgs + page_num) * (pgd_size + sp_size) + dev->attr->page_data_size + ofs;
if (fseek(emu->fp, pos, SEEK_SET) != 0) {
printf("femu: seek to %d fail!\n", pos);
goto err;
}
nread= fread(spare, 1, len, emu->fp);
if (nread != len) {
printf("femu: read spare I/O error ?\n");
goto err;
}
}
dev->st.spare_read_count++;
return UFFS_FLASH_NO_ERR;
err:
return UFFS_FLASH_IO_ERR;
}
static URET femu_EraseBlock(uffs_Device *dev, u32 blockNumber)
{
int i;
u8 * pg = em_page_buf;
int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size;
uffs_FileEmu *emu;
emu = (uffs_FileEmu *)(dev->attr->_private);
if (!emu || !(emu->fp))
goto err;
pg_size = dev->attr->page_data_size + dev->attr->spare_size;
pgd_size = dev->attr->page_data_size;
sp_size = dev->attr->spare_size;
blk_pgs = dev->attr->pages_per_block;
blks = dev->attr->total_blocks;
blk_size = dev->attr->page_data_size * dev->attr->pages_per_block;
printf("femu: erase block %d\n", blockNumber);
if ((int)blockNumber >= blks) {
printf("Attempt to erase non-existant block %d\n",blockNumber);
goto err;
}
else {
//clear this block monitors
memset(emu->em_monitor_page + (blockNumber * blk_pgs),
0,
blk_pgs * sizeof(u8));
memset(emu->em_monitor_spare + (blockNumber * blk_pgs),
0,
blk_pgs * sizeof(u8));
if (1 && (blockNumber == 5)) { // simulate bad block
return UFFS_FLASH_BAD_BLK;
}
memset(pg, 0xff, (pgd_size + sp_size));
fseek(emu->fp, blockNumber * blk_pgs * (pgd_size + sp_size), SEEK_SET);
for (i = 0; i < blk_pgs; i++) {
fwrite(pg, 1, (pgd_size + sp_size), emu->fp);
}
fflush(emu->fp);
dev->st.block_erase_count++;
}
return UFFS_FLASH_NO_ERR;
err:
return UFFS_FLASH_IO_ERR;
}
/////////////////////////////////////////////////////////////////////////////////
#if GCC
static uffs_FlashOps emu_flash_ops = {
.ReadPageData = femu_ReadPageData,
.ReadPageSpare = femu_ReadPageSpare,
.ReadPageSpareLayout = NULL,
.WritePageData = femu_WritePageData,
.WritePageSpare = femu_WritePageSpare,
.WritePageSpareLayout = NULL,
.IsBadBlock = NULL,
.MarkBadBlock = NULL,
.EraseBlock = femu_EraseBlock,
};
#else
static uffs_FlashOps emu_flash_ops = {
femu_ReadPageData,
femu_ReadPageSpare,
NULL, //!< ReadPageSpareLayout, let UFFS do layout
femu_WritePageData,
femu_WritePageSpare,
NULL, //!< WritePageSpareLayout, let UFFS do layout
NULL, //!< IsBadBlock(), let UFFS take care of it.
NULL, //!< MarkBadBlock(), let UFFS take care of it.
femu_EraseBlock,
};
#endif
static URET femu_initDevice(uffs_Device *dev)
{
uffs_Perror(UFFS_ERR_NORMAL, "femu device init.");
dev->ops = &emu_flash_ops; /* EMU device operations */
CheckInit(dev);
return U_SUCC;
}
static URET femu_releaseDevice(uffs_Device *dev)
{
uffs_FileEmu *emu;
uffs_Perror(UFFS_ERR_NORMAL, "femu device release.");
emu = (uffs_FileEmu *)(dev->attr->_private);
emu->initCount--;
if (emu->initCount == 0) {
if (emu->fp) {
fclose(emu->fp);
emu->fp = NULL;
}
memset(emu, 0, sizeof(uffs_FileEmu));
if (emu->em_monitor_page)
free(emu->em_monitor_page);
if (emu->em_monitor_spare)
free(emu->em_monitor_spare);
emu->em_monitor_page = NULL;
emu->em_monitor_spare = NULL;
}
return U_SUCC;
}
void uffs_fileem_setup_device(uffs_Device *dev)
{
dev->Init = femu_initDevice;
dev->Release = femu_releaseDevice;
}
/////////////////////////////////////////////////////////////////////////////////
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fileem.h
* \brief Emulate NAND flash with host file.
* \author Ricky Zheng
*/
#ifndef _UFFS_FILEEM_H_
#define _UFFS_FILEEM_H_
#include "uffs/uffs_device.h"
typedef struct uffs_FileEmuSt {
int initCount;
FILE *fp;
u8 *em_monitor_page;
u8 * em_monitor_spare;
const char *emu_filename;
} uffs_FileEmu;
void uffs_fileem_setup_device(uffs_Device *dev);
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_os_linux.c
* \brief emulation on linux host
* \author Ricky Zheng
*/
#include "uffs/uffs_os.h"
#include "uffs/uffs_public.h"
#include <memory.h>
#include <stdlib.h>
#include <time.h>
#define PFX "linuxemu:"
int uffs_SemCreate(int n)
{
//TODO: ... create semaphore, return semaphore handler (rather then return n) ...
return n;
}
int uffs_SemWait(int sem)
{
if (sem) {
//TODO: ... wait semaphore available ...
}
return 0;
}
int uffs_SemSignal(int sem)
{
if (sem) {
//TODO: ... release semaphore ...
}
return 0;
}
int uffs_SemDelete(int sem)
{
if (sem) {
//TODO: ... delete semaphore ...
}
return 0;
}
int uffs_OSGetTaskId(void)
{
//TODO: ... return current task ID ...
return 0;
}
void uffs_CriticalEnter(void)
{
//TODO: enter critical section (for example, disable IRQ?)
return;
}
void uffs_CriticalExit(void)
{
//TODO: exit from critical section (for example, enable IRQ?)
return;
}
unsigned int uffs_GetCurDateTime(void)
{
// FIXME: return system time, please modify this for your platform !
// or just return 0 if you don't care about file time.
time_t tvalue;
tvalue = time(NULL);
return (unsigned int)tvalue;
}
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc)
INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu)
LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/emu)
LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/uffs)
SET(static_mem_SRCS static-mem-allocate.c)
SET(flash_if_SRCS flash-interface-example.c)
ADD_EXECUTABLE(static-mem-example ${static_mem_SRCS})
ADD_EXECUTABLE(flash-if-example ${flash_if_SRCS})
TARGET_LINK_LIBRARIES(static-mem-example emu uffs emu)
TARGET_LINK_LIBRARIES(flash-if-example emu uffs emu)
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.my_application_main_entry
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file flash-interface-example.c
* \brief example for using flash driver and multiple partitions, with static memory allocator.
* \author Ricky Zheng, created at 27 Nov, 2007
*/
#include <string.h>
#include "uffs/uffs_device.h"
#include "uffs/uffs_flash.h"
#include "uffs/uffs_mtb.h"
#include "uffs/uffs_fs.h"
#define PFX "nand-drv:"
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
int main()
{
uffs_Perror(UFFS_ERR_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1");
return 0;
}
#else
#define USE_SINGLE_WRITE_FUN
#ifdef USE_SINGLE_WRITE_FUN
static int nand_write_full_page(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, const u8 *tag, int tag_len, const u8 *ecc);
#else
static int nand_write_page_data(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, u8 *ecc);
static int nand_write_page_spare(uffs_Device *dev, u32 block, u32 pageNum, const u8 *spare, int ofs, int len, UBOOL eod);
#endif
static int nand_read_page_data(uffs_Device *dev, u32 block, u32 pageNum, u8 *page, int len, u8 *ecc);
static int nand_read_page_spare(uffs_Device *dev, u32 block, u32 pageNum, u8 *spare, int ofs, int len);
static int nand_erase_block(uffs_Device *dev, u32 blockNumber);
static URET nand_init_device(uffs_Device *dev);
#ifdef USE_SINGLE_WRITE_FUN
// if you want to optimize nand flash driver, or use special nand hardware controller,
// or use other NAND driver (for example, eCos NAND lib), you shoud do layout in nand driver.
static int nand_write_full_page(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, const u8 *tag, int tag_len, const u8 *ecc)
{
#define SPOOL(dev) &((dev)->mem.spare_pool)
u8 *spare_buf = NULL;
spare_buf = (u8 *) uffs_PoolGet(SPOOL(dev)); // alloc a spare buffer
// ... START WRITE COMMAND ...
// ...
if (page) {
// WRITE page data
// ....
if (dev->attr->ecc_opt == UFFS_ECC_HW) {
// read ECC from hardware controller to ecc buf,
// ...
}
}
if (tag && tag_len > 0) {
// now, you can use UFFS's layout function
uffs_FlashMakeSpare(dev, (uffs_TagStore *)tag, ecc, spare_buf);
// or, do your own layout
// ....
// WRITE spare_buf to page spare ...
// ...
}
// FINISH write command ...
// ...
// read program status ...
// ...
if (page)
dev->st.page_write_count++;
if (tag)
dev->st.spare_write_count++;
if (spare_buf)
uffs_PoolPut(SPOOL(dev), spare_buf); // release spare buffer
return UFFS_FLASH_NO_ERR;
}
#else
static int nand_write_page_data(uffs_Device *dev, u32 block, u32 pageNum, const u8 *page, int len, u8 *ecc)
{
// send WRITE command
// ... transfer data ...
dev->st.page_write_count++;
return UFFS_FLASH_NO_ERR;
}
static int nand_write_page_spare(uffs_Device *dev, u32 block, u32 pageNum, const u8 *spare, int ofs, int len, UBOOL eod)
{
if (eod == U_FALSE) {
// send WRITE command
}
else {
// do not need to send WRITE command if eod == U_FALSE because 'nand_write_page_data' is called before.
}
// ... transfer data ...
// send COMMIT command
// read STATUS
dev->st.spare_write_count++;
return UFFS_FLASH_NO_ERR;
}
#endif
static int nand_read_page_data(uffs_Device *dev, u32 block, u32 pageNum, u8 *page, int len, u8 *ecc)
{
// send READ command
// ... transfer data ...
// read STATUS
dev->st.page_read_count++;
return UFFS_FLASH_NO_ERR;
}
static int nand_read_page_spare(uffs_Device *dev, u32 block, u32 pageNum, u8 *spare, int ofs, int len)
{
// send READ command
// ... transfer data ...
// read STATUS
dev->st.spare_read_count++;
return UFFS_FLASH_NO_ERR;
}
static int nand_erase_block(uffs_Device *dev, u32 blockNumber)
{
// insert your nand driver codes here ...
dev->st.block_erase_count++;
return UFFS_FLASH_NO_ERR;
}
/////////////////////////////////////////////////////////////////////////////////
static struct uffs_FlashOpsSt my_nand_driver_ops = {
nand_read_page_data, //ReadPageData
nand_read_page_spare, //ReadPageSpare
NULL, //ReadPageSpareWithLayout
#ifdef USE_SINGLE_WRITE_FUN
NULL,
NULL,
nand_write_full_page, //WriteFullPages
#else
nand_write_page_data, //WritePageData
nand_write_page_spare, //WritePageSpare
NULL,
#endif
NULL, //IsBadBlock
NULL, //MarkBadBlock
nand_erase_block, //EraseBlock
};
// change these parameters to fit your nand flash specification
#define MAN_ID MAN_ID_SAMSUNG // simulate Samsung's NAND flash
#define TOTAL_BLOCKS 1024
#define PAGE_DATA_SIZE 512
#define PAGE_SPARE_SIZE 16
#define PAGES_PER_BLOCK 32
#define PAGE_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE * PAGES_PER_BLOCK)
#define NR_PARTITION 2 /* total partitions */
#define PAR_1_BLOCKS 100 /* partition 1 */
#define PAR_2_BLOCKS (TOTAL_BLOCKS - PAR_1_BLOCKS) /* partition 2 */
static struct uffs_StorageAttrSt flash_storage = {0};
/* static alloc the memory for each partition */
static int static_buffer_par1[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_1_BLOCKS) / sizeof(int)];
static int static_buffer_par2[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_2_BLOCKS) / sizeof(int)];;
static void setup_flash_storage(struct uffs_StorageAttrSt *attr)
{
memset(attr, 0, sizeof(struct uffs_StorageAttrSt));
attr->total_blocks = TOTAL_BLOCKS; /* total blocks */
attr->page_data_size = PAGE_DATA_SIZE; /* page data size */
attr->pages_per_block = PAGES_PER_BLOCK; /* pages per block */
attr->spare_size = PAGE_SPARE_SIZE; /* page spare size */
attr->block_status_offs = 4; /* block status offset is 5th byte in spare */
attr->ecc_opt = UFFS_ECC_SOFT; /* ecc option */
attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
}
static URET my_initDevice(uffs_Device *dev)
{
dev->ops = &my_nand_driver_ops;
return U_SUCC;
}
static URET my_releaseDevice(uffs_Device *dev)
{
return U_SUCC;
}
/* define mount table */
static uffs_Device demo_device_1 = {0};
static uffs_Device demo_device_2 = {0};
static uffs_MountTable demo_mount_table[] = {
{ &demo_device_1, 0, PAR_1_BLOCKS - 1, "/data/" },
{ &demo_device_2, PAR_1_BLOCKS, PAR_1_BLOCKS + PAR_2_BLOCKS - 1, "/" },
{ NULL, 0, 0, NULL }
};
static int my_init_filesystem(void)
{
uffs_MountTable *mtbl = &(demo_mount_table[0]);
/* setup nand storage attributes */
setup_flash_storage(&flash_storage);
/* setup memory allocator */
uffs_MemSetupStaticAllocator(&demo_device_1.mem, static_buffer_par1, sizeof(static_buffer_par1));
uffs_MemSetupStaticAllocator(&demo_device_2.mem, static_buffer_par2, sizeof(static_buffer_par2));
/* register mount table */
while(mtbl->dev) {
mtbl->dev->Init = my_initDevice;
mtbl->dev->Release = my_releaseDevice;
mtbl->dev->attr = &flash_storage;
uffs_RegisterMountTable(mtbl);
mtbl++;
}
return uffs_InitMountTable() == U_SUCC ? 0 : -1;
}
/* application entry */
int main()
{
my_init_filesystem();
// ... my application codes ....
// read/write/create/delete files ...
uffs_ReleaseMountTable();
return 0;
}
#endif
/////////////////////////////////////////////////////////////////////////////////
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file static-mem-allocate.c
* \brief demostrate how to use static memory allocation. This example use
* file emulated NAND flash.
* \author Ricky Zheng
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "uffs/uffs_config.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs_utils.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_mtb.h"
#include "cmdline.h"
#include "uffs_fileem.h"
#define PFX "static-example: "
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0
int main()
{
uffs_Perror(UFFS_ERR_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1");
return 0;
}
#else
extern struct cli_commandset * get_helper_cmds(void);
#define DEFAULT_EMU_FILENAME "uffsemfile.bin"
#define PAGE_DATA_SIZE 512
#define PAGE_SPARE_SIZE 16
#define PAGES_PER_BLOCK 32
#define TOTAL_BLOCKS 128
#define PAGE_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
#define BLOCK_DATA_SIZE (PAGES_PER_BLOCK * PAGE_DATA_SIZE)
#define TOTAL_DATA_SIZE (TOTAL_BLOCKS * BLOCK_DATA_SIZE)
#define BLOCK_SIZE (PAGES_PER_BLOCK * PAGE_SIZE)
#define TOTAL_SIZE (BLOCK_SIZE * TOTAL_BLOCKS)
#define MAX_MOUNT_TABLES 10
#define MAX_MOUNT_POINT_NAME 32
static uffs_Device demo_device = {0};
static struct uffs_MountTableEntrySt demo_mount = {
&demo_device,
0, /* start from block 0 */
-1, /* use whole chip */
"/", /* mount point */
NULL
};
static struct uffs_StorageAttrSt emu_storage = {0};
static struct uffs_FileEmuSt emu_private = {0};
/* static alloc the memory */
static int static_buffer_pool[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, TOTAL_BLOCKS) / sizeof(int)];
static void setup_emu_storage(struct uffs_StorageAttrSt *attr)
{
attr->total_blocks = TOTAL_BLOCKS; /* total blocks */
attr->page_data_size = PAGE_DATA_SIZE; /* page data size */
attr->spare_size = PAGE_SPARE_SIZE; /* page spare size */
attr->pages_per_block = PAGES_PER_BLOCK; /* pages per block */
attr->block_status_offs = 4; /* block status offset is 5th byte in spare */
attr->ecc_opt = UFFS_ECC_SOFT; /* ecc option */
attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
}
static void setup_emu_private(uffs_FileEmu *emu)
{
memset(emu, 0, sizeof(uffs_FileEmu));
emu->emu_filename = DEFAULT_EMU_FILENAME;
}
static int init_uffs_fs(void)
{
struct uffs_MountTableEntrySt *mtbl = &demo_mount;
/* setup emu storage */
setup_emu_storage(&emu_storage);
setup_emu_private(&emu_private);
emu_storage._private = &emu_private;
mtbl->dev->attr = &emu_storage;
/* setup memory allocator */
uffs_MemSetupStaticAllocator(&mtbl->dev->mem, static_buffer_pool, sizeof(static_buffer_pool));
/* setup device */
uffs_fileem_setup_device(mtbl->dev);
/* register mount table */
uffs_RegisterMountTable(mtbl);
return uffs_InitMountTable() == U_SUCC ? 0 : -1;
}
static int release_uffs_fs(void)
{
return uffs_ReleaseMountTable();
}
int main(int argc, char *argv[])
{
int ret;
ret = init_uffs_fs();
if (ret != 0) {
printf ("Init file system fail: %d\n", ret);
return -1;
}
cli_add_commandset(get_helper_cmds());
cliMain();
release_uffs_fs();
return 0;
}
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs.h
* \brief uffs basic defines
* \author Ricky Zheng
*/
#ifndef _UFFS_H_
#define _UFFS_H_
#include "uffs/uffs_types.h"
#ifdef __cplusplus
extern "C"{
#endif
#define UO_RDONLY 0x0000 /** read only */
#define UO_WRONLY 0x0001 /** write only */
#define UO_RDWR 0x0002 /** read and write */
#define UO_APPEND 0x0008 /** append */
#define UO_BINARY 0x0000 /** no used in uffs */
#define UO_CREATE 0x0100
#define UO_TRUNC 0x0200
#define UO_EXCL 0x0400
#define UO_DIR 0x1000 /** open a directory */
#define UENOERR 0 /** no error */
#define UEACCES 1 /** Tried to open read-only file
for writing, or files sharing mode
does not allow specified operations,
or given path is directory */
#define UEEXIST 2 /** _O_CREAT and _O_EXCL flags specified,
but filename already exists */
#define UEINVAL 3 /** Invalid oflag or pmode argument */
#define UEMFILE 4 /** No more file handles available
(too many open files) */
#define UENOENT 5 /** file or path not found */
#define UETIME 6 /** can't set file time */
#define UEBADF 9 /** invalid file handle */
#define UENOMEM 10 /** no enough memory */
#define UEIOERR 11 /** I/O error from lower level flash operation */
#define UENOTDIR 12 /** Not a directory */
#define UEISDIR 13 /** Is a directory */
#define UEUNKNOWN 100 /** unknown error */
#define _SEEK_CUR 0 /** seek from current position */
#define _SEEK_SET 1 /** seek from beginning of file */
#define _SEEK_END 2 /** seek from end of file */
#define USEEK_CUR _SEEK_CUR
#define USEEK_SET _SEEK_SET
#define USEEK_END _SEEK_END
/**
* \def MAX_FILENAME_LENGTH
* \note Be careful: it's part of the physical format (see: uffs_FileInfoSt.name)
* !!DO NOT CHANGE IT AFTER FILE SYSTEM IS FORMATED!!
*/
#define MAX_FILENAME_LENGTH 32
/** \note 8-bits attr goes to uffs_dirent::d_type */
#define FILE_ATTR_DIR (1 << 7) //!< attribute for directory
#define FILE_ATTR_WRITE (1 << 0) //!< writable
/**
* \structure uffs_FileInfoSt
* \brief file/dir entry info in physical storage format
*/
struct uffs_FileInfoSt {
u32 attr; //!< file/dir attribute
u32 create_time;
u32 last_modify;
u32 access;
u32 reserved;
u32 name_len; //!< length of file/dir name
char name[MAX_FILENAME_LENGTH];
};
typedef struct uffs_FileInfoSt uffs_FileInfo;
/**
* \struct uffs_ObjectInfoSt
* \brief object info
*/
typedef struct uffs_ObjectInfoSt {
uffs_FileInfo info;
u32 len; //!< length of file
u16 serial; //!< object serial num
} uffs_ObjectInfo;
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_badblock.h
* \brief bad block management
* \author Ricky Zheng
*/
#ifndef _UFFS_BADBLOCK_H_
#define _UFFS_BADBLOCK_H_
#include "uffs/uffs_public.h"
#include "uffs/uffs_device.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define HAVE_BADBLOCK(dev) (dev->bad.block != UFFS_INVALID_BLOCK)
/** initialize bad block management data structures for uffs device */
void uffs_BadBlockInit(uffs_Device *dev);
/** processing bad block: erase bad block, mark it as 'bad' and put it to bad block list */
void uffs_BadBlockProcess(uffs_Device *dev, TreeNode *node);
/** try to recover data from a new discovered bad block */
void uffs_BadBlockRecover(uffs_Device *dev);
/** put a new block to the bad block waiting list */
void uffs_BadBlockAdd(uffs_Device *dev, int block);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_blockinfo.h
* \brief data structure for operating block information
* \author Ricky Zheng
*/
#ifndef _UFFS_BLOCKINFO_H_
#define _UFFS_BLOCKINFO_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs_public.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
/**
* \struct uffs_PageSpareSt
* \brief this structure is for storing uffs tag and more.
*/
struct uffs_PageSpareSt {
uffs_Tags tag; //!< page tag
u8 expired:1;
};
/**
* \struct uffs_BlockInfoSt
* \brief block information data. Block info is frequently accessed,
UFFS use a cache system to speed up block info access.
*/
struct uffs_BlockInfoSt {
struct uffs_BlockInfoSt *next;
struct uffs_BlockInfoSt *prev;
u16 block; //!< block number
struct uffs_PageSpareSt *spares; //!< page spare info array
int expired_count; //!< how many pages expired in this block ?
int ref_count; //!< reference counter, it's safe to reuse this block memory when the counter is 0.
};
/** get tag from block info */
#define GET_TAG(bc, page) (&(bc)->spares[page].tag)
/** initialize block info caches */
URET uffs_BlockInfoInitCache(uffs_Device *dev, int maxCachedBlocks);
/** release block info caches */
URET uffs_BlockInfoReleaseCache(uffs_Device *dev);
/** load page spare to block info cache */
URET uffs_BlockInfoLoad(uffs_Device *dev, uffs_BlockInfo *work, int page);
/** find block info cache */
uffs_BlockInfo * uffs_BlockInfoFindInCache(uffs_Device *dev, int block);
/** get block info cache, load it on demand */
uffs_BlockInfo * uffs_BlockInfoGet(uffs_Device *dev, int block);
/** put info cache back to pool, should be called with #uffs_BlockInfoGet in pairs. */
void uffs_BlockInfoPut(uffs_Device *dev, uffs_BlockInfo *p);
/** explicitly expire a block info cache */
void uffs_BlockInfoExpire(uffs_Device *dev, uffs_BlockInfo *p, int page);
/** no one hold any block info cache ? safe to release block info caches */
UBOOL uffs_BlockInfoIsAllFree(uffs_Device *dev);
/** explicitly expire all block info caches */
void uffs_BlockInfoExpireAll(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_buf.h
* \brief page buffers
* \author Ricky Zheng
*/
#ifndef UFFS_BUF_H
#define UFFS_BUF_H
#include "uffs/uffs_types.h"
#include "uffs/uffs_device.h"
#include "uffs/uffs_tree.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define CLONE_BUF_MARK 0xffff //!< set uffs_BufSt::ref_count to this for a 'cloned' buffer
/** for uffs_BufSt::mark */
#define UFFS_BUF_EMPTY 0 //!< buffer is empty
#define UFFS_BUF_VALID 1 //!< buffer is holding valid data
#define UFFS_BUF_DIRTY 2 //!< buffer data is modified
/** for uffs_BufSt::ext_mark */
#define UFFS_BUF_EXT_MARK_TRUNC_TAIL 1 //!<
/** uffs page buffer */
struct uffs_BufSt{
struct uffs_BufSt *next; //!< link to next buffer
struct uffs_BufSt *prev; //!< link to previous buffer
struct uffs_BufSt *next_dirty; //!< link to next dirty buffer
struct uffs_BufSt *prev_dirty; //!< link to previous dirty buffer
u8 type; //!< #UFFS_TYPE_DIR or #UFFS_TYPE_FILE or #UFFS_TYPE_DATA
u16 parent; //!< parent serial
u16 serial; //!< serial
u16 page_id; //!< page id
u16 mark; //!< #UFFS_BUF_EMPTY or #UFFS_BUF_VALID, or #UFFS_BUF_DIRTY ?
u16 ref_count; //!< reference counter, or #CLONE_BUF_MARK for a cloned buffer
u16 data_len; //!< length of data
u16 check_sum; //!< checksum field
u8 * data; //!< data buffer
u8 * header; //!< header
int ext_mark; //!< extension mark.
};
#define uffs_BufIsFree(buf) (buf->ref_count == 0 ? U_TRUE : U_FALSE)
/** initialize page buffers */
URET uffs_BufInit(struct uffs_DeviceSt *dev, int buf_max, int dirty_buf_max);
/** release page buffers */
URET uffs_BufReleaseAll(struct uffs_DeviceSt *dev);
/** find the page buffer, move to link list head if found */
uffs_Buf * uffs_BufGet(struct uffs_DeviceSt *dev, u16 parent, u16 serial, u16 page_id);
uffs_Buf *uffs_BufGetEx(struct uffs_DeviceSt *dev, u8 type, TreeNode *node, u16 page_id);
/** alloc a new page buffer */
uffs_Buf *uffs_BufNew(struct uffs_DeviceSt *dev, u8 type, u16 parent, u16 serial, u16 page_id);
/** find the page buffer (not affect the reference counter) */
uffs_Buf * uffs_BufFind(uffs_Device *dev, u16 parent, u16 serial, u16 page_id);
/** put page buffer back to pool, called in pair with #uffs_Get,#uffs_GetEx or #uffs_BufNew */
URET uffs_BufPut(uffs_Device *dev, uffs_Buf *buf);
/** increase buffer references */
void uffs_BufIncRef(uffs_Buf *buf);
/** decrease buffer references */
void uffs_BufDecRef(uffs_Buf *buf);
/** write data to a page buffer */
URET uffs_BufWrite(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
/** read data from a page buffer */
URET uffs_BufRead(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len);
/** mark buffer as #UFFS_BUF_EMPTY if ref_count == 0, and discard all data it holds */
void uffs_BufMarkEmpty(uffs_Device *dev, uffs_Buf *buf);
/** if there is no free dirty group slot, flush the most dirty group */
URET uffs_BufFlush(struct uffs_DeviceSt *dev);
URET uffs_BufFlushEx(struct uffs_DeviceSt *dev, UBOOL force_block_recover);
/** flush dirty group */
URET uffs_BufFlushGroup(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
URET uffs_BufFlushGroupEx(struct uffs_DeviceSt *dev, u16 parent, u16 serial, UBOOL force_block_recover);
/** find free dirty group slot */
int uffs_BufFindFreeGroupSlot(struct uffs_DeviceSt *dev);
/** find the dirty group slot */
int uffs_BufFindGroupSlot(struct uffs_DeviceSt *dev, u16 parent, u16 serial);
/** lock dirty group */
URET uffs_BufLockGroup(struct uffs_DeviceSt *dev, int slot);
/** unlock dirty group */
URET uffs_BufUnLockGroup(struct uffs_DeviceSt *dev, int slot);
/** flush most dirty group */
URET uffs_BufFlushMostDirtyGroup(struct uffs_DeviceSt *dev);
/** flush all groups under the same parent number */
URET uffs_BufFlushGroupMatchParent(struct uffs_DeviceSt *dev, u16 parent);
/** flush all page buffers */
URET uffs_BufFlushAll(struct uffs_DeviceSt *dev);
/** no one holding any page buffer ? safe to release page buffers */
UBOOL uffs_BufIsAllFree(struct uffs_DeviceSt *dev);
/** are all page buffer marked with #UFFS_BUF_EMPTY ? */
UBOOL uffs_BufIsAllEmpty(struct uffs_DeviceSt *dev);
/** mark all page buffer as #UFFS_BUF_EMPTY */
URET uffs_BufSetAllEmpty(struct uffs_DeviceSt *dev);
/** clone a page buffer */
uffs_Buf * uffs_BufClone(struct uffs_DeviceSt *dev, uffs_Buf *buf);
/** release a cloned page buffer, call in pair with #uffs_BufClone */
URET uffs_BufFreeClone(uffs_Device *dev, uffs_Buf *buf);
/** load physical storage data to page buffer */
URET uffs_BufLoadPhyData(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
/** load physical storage data to page buffer withouth checking ECC */
URET uffs_LoadPhyDataToBufEccUnCare(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page);
/** showing page buffers info, for debug only */
void uffs_BufInspect(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_config.h
* \brief basic configuration of uffs
* \author Ricky Zheng
*/
#ifndef _UFFS_CONFIG_H_
#define _UFFS_CONFIG_H_
/**
* \def UFFS_MAX_PAGE_SIZE
* \note maximum page size UFFS support
*/
#define UFFS_MAX_PAGE_SIZE 2048
/**
* \def UFFS_MAX_SPARE_SIZE
*/
#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8)
/**
* \def MAX_CACHED_BLOCK_INFO
* \note uffs cache the block info for opened directories and files,
* a practical value is 5 ~ MAX_OBJECT_HANDLE
*/
#define MAX_CACHED_BLOCK_INFO 10
/**
* \def MAX_PAGE_BUFFERS
* \note the bigger value will bring better read/write performance.
* but few writing performance will be improved when this
* value is become larger than 'max pages per block'
*/
#define MAX_PAGE_BUFFERS 10
/**
* \def CLONE_BUFFER_THRESHOLD
* \note reserve buffers for clone. 1 or 2 should be enough.
*/
#define CLONE_BUFFERS_THRESHOLD 2
/**
* \def MAX_SPARE_BUFFERS
* \note spare buffers are used for lower level flash operations, 5 should be enough.
*/
#define MAX_SPARE_BUFFERS 5
/**
* \def MAX_DIRTY_PAGES_IN_A_BLOCK
* \note this value should be between '2' and the lesser of 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1).
* the smaller the value the frequently the buffer will be flushed.
*/
#define MAX_DIRTY_PAGES_IN_A_BLOCK 7
/**
* \def MAX_DIRTY_BUF_GROUPS
*/
#define MAX_DIRTY_BUF_GROUPS 3
/**
* \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR
* \note uffs will use static memory allocator if this is defined.
* to use static memory allocator, you need to provide memory
* buffer when creating uffs_Device.
*
* use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size.
*/
#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0
/**
* \def CONFIG_USE_NATIVE_MEMORY_ALLOCATOR
* \note the native memory allocator should only be used for
* tracking memory leak bugs or tracking memory consuming.
* In your final product, you either disable the native memory
* allocator or use the system heap as the memory pool for the
* native memory allocator.
*/
#define CONFIG_USE_NATIVE_MEMORY_ALLOCATOR 0
/**
* \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR
* \note using system platform's 'malloc' and 'free'.
*/
#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1
/**
* \def CONFIG_FLUSH_BUF_AFTER_WRITE
* \note UFFS will write all data directly into flash in
* each 'write' call if you enable this option.
* (which means lesser data lost when power failue but
* pooer writing performance).
* It's not recommented to open this define for normal applications.
*/
//#define CONFIG_FLUSH_BUF_AFTER_WRITE
/**
* \def CONFIG_TREE_NODE_USE_DOUBLE_LINK
* \note: enable double link tree node will speed up insert/delete operation,
*/
#define CONFIG_TREE_NODE_USE_DOUBLE_LINK
/**
* \def MAX_OBJECT_HANDLE
* maximum number of object handle
*/
#define MAX_OBJECT_HANDLE 10
/**
* \def MAX_DIR_HANDLE
* maximum number of uffs_DIR
*/
#define MAX_DIR_HANDLE 5
/**
* \def MINIMUN_ERASED_BLOCK
* UFFS will not allow appending or creating new files when the free/erased block
* is lower then MINIMUN_ERASED_BLOCK.
*/
#define MINIMUN_ERASED_BLOCK 2
/**
* \def CONFIG_CHANGE_MODIFY_TIME
* \note If defined, closing a file which is opened for writing/appending will
* update the file's modify time as well. Disable this feature will save a
* lot of writing activities if you frequently open files for write and close it.
*/
//#define CONFIG_CHANGE_MODIFY_TIME
/**
* \def CONFIG_ENABLE_BAD_BLOCK_VERIFY
* \note allow erase and verify block marked as 'bad' when format UFFS partition.
* it's not recommented for most NAND flash.
*/
#define CONFIG_ENABLE_BAD_BLOCK_VERIFY
/**
* \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
* \note erase block again before mark bad block
*/
#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD
/**
* \def CONFIG_PAGE_WRITE_VERIFY
* \note verify page data after write, for extra safe data storage.
*/
#define CONFIG_PAGE_WRITE_VERIFY
/**
* \def CONFIG_BAD_BLOCK_POLICY_STRICT
* \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found;
* otherwise, UFFS report bad block only when ECC failed or reported by low level flash driver.
*
* \note Enable this will ensure your data always be stored on completly good blocks.
*/
#define CONFIG_BAD_BLOCK_POLICY_STRICT
/** micros for calculating buffer sizes */
/**
* \def UFFS_BLOCK_INFO_BUFFER_SIZE
* \brief calculate memory bytes for block info caches
*/
#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) \
( \
( \
sizeof(uffs_BlockInfo) + \
sizeof(uffs_PageSpare) * n_pages_per_block \
) * MAX_CACHED_BLOCK_INFO \
)
/**
* \def UFFS_PAGE_BUFFER_SIZE
* \brief calculate memory bytes for page buffers
*/
#define UFFS_PAGE_BUFFER_SIZE(n_page_size) \
( \
( \
sizeof(uffs_Buf) + n_page_size \
) * MAX_PAGE_BUFFERS \
)
/**
* \def UFFS_TREE_BUFFER_SIZE
* \brief calculate memory bytes for tree nodes
*/
#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks)
#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE)
/**
* \def UFFS_STATIC_BUFF_SIZE
* \brief calculate total memory usage of uffs system
*/
#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \
( \
UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \
UFFS_PAGE_BUFFER_SIZE(n_page_size) + \
UFFS_TREE_BUFFER_SIZE(n_blocks) + \
UFFS_SPARE_BUFFER_SIZE \
)
/* config check */
#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3
#error "MAX_PAGE_BUFFERS is too small"
#endif
#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2)
#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2"
#endif
#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK)
#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)"
#endif
#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2)
#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled."
#endif
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_NATIVE_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1
#error "Please enable ONLY one memory allocator"
#endif
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_NATIVE_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0
#error "Please enable ONE of memory allocators"
#endif
#ifdef WIN32
# pragma warning(disable : 4996)
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
#ifndef _UFFS_CORE_H_
#define _UFFS_CORE_H_
#ifdef __cplusplus
extern "C"{
#endif
/** \typedef uffs_Device */
typedef struct uffs_DeviceSt uffs_Device;
/** \typedef uffs_FlashOps */
typedef struct uffs_FlashOpsSt uffs_FlashOps;
typedef struct uffs_BlockInfoSt uffs_BlockInfo;
typedef struct uffs_PageSpareSt uffs_PageSpare;
typedef struct uffs_TagsSt uffs_Tags; //!< UFFS page tags
typedef struct uffs_TagStoreSt uffs_TagStore; //!< UFFS page tags physical store structure
typedef struct uffs_BufSt uffs_Buf;
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_device.h
* \brief uffs device structures definition
* \author Ricky Zheng
*/
#ifndef UFFS_DEVICE_H
#define UFFS_DEVICE_H
#include "uffs/uffs_types.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_buf.h"
#include "uffs/uffs_blockinfo.h"
#include "uffs/uffs_pool.h"
#include "uffs/uffs_tree.h"
#include "uffs/uffs_mem.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_flash.h"
#ifdef __cplusplus
extern "C"{
#endif
/**
* \struct uffs_BlockInfoCacheSt
* \brief block information structure, used to manager block information caches
*/
struct uffs_BlockInfoCacheSt {
uffs_BlockInfo *head; //!< buffer head of block info(spares)
uffs_BlockInfo *tail; //!< buffer tail
void *mem_pool; //!< internal memory pool, used for release whole buffer
};
/**
* \struct uffs_PartitionSt
* \brief partition basic information
*/
struct uffs_PartitionSt {
u16 start; //!< start block number of partition
u16 end; //!< end block number of partiton
};
/**
* \struct uffs_LockSt
* \brief lock stuffs
*/
struct uffs_LockSt {
int sem;
int task_id;
int counter;
};
/**
* \struct uffs_DirtyGroupSt
* \brief manager dirty page buffers
*/
struct uffs_DirtyGroupSt {
int count; //!< dirty buffers count
int lock; //!< dirty group lock (0: unlocked, >0: locked)
uffs_Buf *dirty; //!< dirty buffer list
};
/**
* \struct uffs_PageBufDescSt
* \brief uffs page buffers descriptor
*/
struct uffs_PageBufDescSt {
uffs_Buf *head; //!< head of buffers
uffs_Buf *tail; //!< tail of buffers
struct uffs_DirtyGroupSt dirtyGroup[MAX_DIRTY_BUF_GROUPS]; //!< dirty buffer groups
int buf_max; //!< maximum buffers
int dirty_buf_max; //!< maximum dirty buffer allowed
void *pool; //!< memory pool for buffers
};
/**
* \struct uffs_PageCommInfoSt
* \brief common data for device, should be initialized at early
* \note it is possible that pg_size is smaller than physical page size, but normally they are the same.
* \note page data layout: [HEADER] + [DATA]
*/
struct uffs_PageCommInfoSt {
u16 pg_data_size; //!< page data size
u16 header_size; //!< header size
u16 pg_size; //!< page size
};
/**
* \struct uffs_NewBadBlockSt
* \brief holding new discovered bad block
*/
struct uffs_NewBadBlockSt {
u16 block; //!< bad block, FIX ME to process more than one bad block
};
/**
* \struct uffs_FlashStatSt
* \typedef uffs_FlashStat
* \brief statistic data of flash read/write/erase activities
*/
typedef struct uffs_FlashStatSt {
int block_erase_count;
int page_write_count;
int page_read_count;
int page_header_read_count;
int spare_write_count;
int spare_read_count;
} uffs_FlashStat;
/**
* \struct uffs_DeviceSt
* \brief The core data structure of UFFS, all information needed by manipulate UFFS object
* \note one partition corresponding one uffs device.
*/
struct uffs_DeviceSt {
URET (*Init)(uffs_Device *dev); //!< low level initialization
URET (*Release)(uffs_Device *dev); //!< low level release
void *_private; //!< private data for device
struct uffs_StorageAttrSt *attr; //!< storage attribute
struct uffs_PartitionSt par; //!< partition information
struct uffs_FlashOpsSt *ops; //!< flash operations
struct uffs_BlockInfoCacheSt bc; //!< block info cache
struct uffs_LockSt lock; //!< lock data structure
struct uffs_PageBufDescSt buf; //!< page buffers
struct uffs_PageCommInfoSt com; //!< common information
struct uffs_TreeSt tree; //!< tree list of block
struct uffs_NewBadBlockSt bad; //!< new discovered bad block
struct uffs_FlashStatSt st; //!< statistic (counters)
struct uffs_memAllocatorSt mem; //!< uffs native memory allocator
u32 ref_count; //!< device reference count
int dev_num; //!< device number (partition number)
};
/** create the lock for uffs device */
URET uffs_DeviceInitLock(uffs_Device *dev);
/** delete the lock of uffs device */
URET uffs_DeviceReleaseLock(uffs_Device *dev);
/** lock uffs device */
URET uffs_DeviceLock(uffs_Device *dev);
/** unlock uffs device */
URET uffs_DeviceUnLock(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_ecc.h
* \brief file handle operations
* \author Ricky Zheng, created 8th Jun, 2005
*/
#ifndef _UFFS_ECC_H_
#define _UFFS_ECC_H_
#include <string.h>
#include "uffs/uffs_fs.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#ifdef __cplusplus
extern "C"{
#endif
#define MAX_ECC_LENGTH 24 //!< 2K page ecc length is 24 bytes.
/**
* calculate ECC
* \return length of generated ECC. (3 bytes ECC per 256 data)
*/
int uffs_EccMake(void *data, int data_len, void *ecc);
/**
* correct data by ECC.
*
* return: 0 -- no error
* -1 -- can not be corrected
* >0 -- how many bits are corrected
*/
int uffs_EccCorrect(void *data, int data_len, void *read_ecc, const void *test_ecc);
/**
* generate 12 bit ecc for maximum 8 bytes data
*/
u16 uffs_EccMake8(void *data, int data_len);
/**
* correct maximum 8 bytes data from 12 bits ECC
*
* return: 0 -- no error
* -1 -- can not be corrected
* >0 -- how many bits are corrected
*/
int uffs_EccCorrect8(void *data, u16 read_ecc, u16 test_ecc, int errtop);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_fd.h
* \brief PISIX like file operations
* \author Ricky Zheng, created 8th Jun, 2005
*/
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_fs.h"
#include "uffs/uffs.h"
#include "uffs/uffs_find.h"
#include <string.h>
/**
* \brief definitions for uffs_stat::st_mode
*/
#define US_IFMT 0xF000 /* file type make */
#define US_IFREG 0x8000 /* regular */
#define US_IFLNK 0xA000 /* symbolic link */
#define US_IFDIR 0x4000 /* directory */
#define US_IREAD 00400 /* read permission */
#define US_IWRITE 00200 /* write permission */
#define US_IRWXU 00700 /* RWX owner */
#define US_IRUSR 00400 /* R owner */
#define US_IWUSR 00200 /* W owner */
#define US_IXUSR 00100 /* X owner */
#define US_IRWXG 00070 /* RWX group */
#define US_IRGRP 00040 /* R group */
#define US_IWGRP 00020 /* W group */
#define US_IXGRP 00010 /* X group */
#define US_IRWXO 00007 /* RWX other */
#define US_IROTH 00004 /* R other */
#define US_IWOTH 00002 /* W other */
#define US_IXOTH 00001 /* X other */
/**
* \brief POSIX dirent
*/
struct uffs_dirent {
int d_ino; /* inode number (serial number or this record) */
char d_name[MAX_FILENAME_LENGTH]; /* name of this record */
int d_off; /* offset to this dirent */
unsigned short int d_reclen; /* length of this uffs_dirent */
unsigned short int d_namelen; /* length of this d_name */
unsigned char d_type; /* type of this record */
};
/**
* \brief POSIX DIR
*/
typedef struct uffs_dirSt {
struct uffs_ObjectSt *obj; /* dir object */
struct uffs_FindInfoSt f; /* find info */
struct uffs_ObjectInfoSt info; /* object info */
struct uffs_dirent dirent; /* dir entry */
} uffs_DIR;
/**
* \brief POSIX stat
*/
struct uffs_stat {
int st_dev; /* ID of device containing file */
int st_ino; /* inode number */
int st_mode; /* protection */
int st_nlink; /* number of hard links */
int st_uid; /* user ID of owner */
int st_gid; /* group ID of owner */
int st_rdev; /* device ID (if special file) */
long st_size; /* total size, in bytes */
int st_blksize; /* blocksize for filesystem I/O */
int st_blocks; /* number of blocks allocated */
u32 st_atime; /* time of last access */
u32 st_mtime; /* time of last modification */
u32 st_ctime; /* time of last status change */
};
URET uffs_InitDirEntryBuf(void);
URET uffs_ReleaseDirEntryBuf(void);
uffs_Pool * uffs_GetDirEntryBufPool(void);
/* POSIX compliant file system APIs */
int uffs_open(const char *name, int oflag, ...);
int uffs_close(int fd);
int uffs_read(int fd, void *data, int len);
int uffs_write(int fd, void *data, int len);
long uffs_seek(int fd, long offset, int origin);
long uffs_tell(int fd);
int uffs_eof(int fd);
int uffs_flush(int fd);
int uffs_rename(const char *old_name, const char *new_name);
int uffs_remove(const char *name);
int uffs_truncate(int fd, long remain);
int uffs_mkdir(const char *name, ...);
int uffs_rmdir(const char *name);
int uffs_stat(const char *name, struct uffs_stat *buf);
int uffs_lstat(const char *name, struct uffs_stat *buf);
int uffs_fstat(int fd, struct uffs_stat *buf);
int uffs_closedir(uffs_DIR *dirp);
uffs_DIR * uffs_opendir(const char *path);
struct uffs_dirent * uffs_readdir(uffs_DIR *dirp);
void uffs_rewinddir(uffs_DIR *dirp);
#if 0
void uffs_seekdir(uffs_DIR *dirp, long loc);
long uffs_telldir(uffs_DIR *dirp);
#endif
int uffs_get_error(void);
int uffs_set_error(int err);
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_find.h
* \brief find objects under dir
* \author Ricky Zheng
*/
#ifndef _UFFS_FIND_H_
#define _UFFS_FIND_H_
#include "uffs/uffs_fs.h"
#ifdef __cplusplus
extern "C"{
#endif
typedef struct uffs_FindInfoSt {
uffs_Device *dev; //!< the device to be searched
u16 serial; //!< the dir serial number
int step; //!< step: 0 - working on dir entries, 1 - working on file entries, 2 - stoped.
int hash; //!< hash entry, internal used
TreeNode *work; //!< working node, internal used.
int pos; //!< current position
} uffs_FindInfo;
URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err);
URET uffs_FindObjectOpen(uffs_FindInfo *find_handle, uffs_Object *dir);
URET uffs_FindObjectOpenEx(uffs_FindInfo *f, uffs_Device *dev, int dir);
URET uffs_FindObjectFirst(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
URET uffs_FindObjectNext(uffs_ObjectInfo *info, uffs_FindInfo *find_handle);
URET uffs_FindObjectRewind(uffs_FindInfo *find_handle);
URET uffs_FindObjectClose(uffs_FindInfo * find_handle);
#ifdef __cplusplus
}
#endif
#endif
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
/**
* \file uffs_public.h
* \brief flash interface for UFFS
* \author Ricky Zheng
*/
#ifndef _UFFS_FLASH_H_
#define _UFFS_FLASH_H_
#include "uffs/uffs_types.h"
#include "uffs/uffs_config.h"
#include "uffs/uffs_core.h"
#include "uffs/uffs_device.h"
#ifdef __cplusplus
extern "C"{
#endif
/** ECC options (uffs_StorageAttrSt.ecc_opt) */
#define UFFS_ECC_NONE 0 //!< do not use ECC
#define UFFS_ECC_SOFT 1 //!< UFFS calculate the ECC
#define UFFS_ECC_HW 2 //!< Flash driver(or by hardware) calculate the ECC
#define UFFS_ECC_HW_AUTO 3 //!< Hardware calculate the ECC and automatically write to spare.
/** spare layout options (uffs_StorageAttrSt.layout_opt) */
#define UFFS_LAYOUT_UFFS 0 //!< do layout by dev->attr information
#define UFFS_LAYOUT_FLASH 1 //!< flash driver do the layout
#define UFFS_SPARE_LAYOUT_SIZE 6 //!< maximum spare layout array size, 2 segments
/** flash operation return code */
#define UFFS_FLASH_NO_ERR 0 //!< no error
#define UFFS_FLASH_ECC_OK 1 //!< bit-flip found, but corrected by ECC
#define UFFS_FLASH_IO_ERR -1 //!< I/O error
#define UFFS_FLASH_ECC_FAIL -2 //!< ECC failed
#define UFFS_FLASH_BAD_BLK -3 //!< bad block
#define UFFS_FLASH_UNKNOWN_ERR -100 //!< unkown error?
#define UFFS_FLASH_HAVE_ERR(e) ((e) < 0)
#if defined(CONFIG_BAD_BLOCK_POLICY_STRICT)
# define UFFS_FLASH_IS_BAD_BLOCK(e) ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_ECC_OK || (e) == UFFS_FLASH_BAD_BLK)
#else
# define UFFS_FLASH_IS_BAD_BLOCK(e) ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_BAD_BLK)
#endif
/** defines for page info (data length and data sum) */
#define UFFS_PAGE_INFO_CLEAN 0xFFFFFFFF
#define UFFS_PAGE_INFO_IOERR 0xDEADFFFF
#define UFFS_PAGE_GET_LEN(info) (info & 0xFFFF)
#define UFFS_PAGE_GET_DSUM(info) (info >> 16)
#define UFFS_PAGE_MAKE_INFO(d_len, d_sum) ((d_sum << 16) | d_len)
/**
* \struct uffs_StorageAttrSt
* \brief uffs device storage attribute, provide by nand specific file
*/
struct uffs_StorageAttrSt {
u32 total_blocks; //!< total blocks in this chip
u16 page_data_size; //!< page data size (physical page data size, e.g. 512)
u16 pages_per_block; //!< pages per block
u8 spare_size; //!< page spare size (physical page spare size, e.g. 16)
u8 block_status_offs; //!< block status byte offset in spare
int ecc_opt; //!< ecc option ( #UFFS_ECC_[NONE|SOFT|HW|HW_AUTO] )
int layout_opt; //!< layout option (#UFFS_LAYOUT_UFFS or #UFFS_LAYOUT_FLASH)
const u8 *ecc_layout; //!< page data ECC layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
const u8 *data_layout; //!< spare data layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0]
u8 _uffs_ecc_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare ecc layout
u8 _uffs_data_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare data layout
void *_private; //!< private data for storage attribute
};
/**
* \struct uffs_FlashOpsSt
* \brief low level flash operations, should be implement in flash driver
*/
struct uffs_FlashOpsSt {
/**
* Read page data.
*
* if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return ecc (if ecc != NULL).
*
* if ecc_opt is UFFS_ECC_HW_AUTO, flash driver do ecc correction aganist ecc in spare area.
*
* \return #UFFS_FLASH_NO_ERR: success and/or has no flip bits.
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_ECC_FAIL: page data has flip bits and ecc correct failed.
* #UFFS_FLASH_ECC_OK: page data has flip bits and corrected by ecc.
*
* \note pad 0xFF for calculating ECC if len < page_data_size
*/
int (*ReadPageData)(uffs_Device *dev, u32 block, u32 page, u8 *data, int len, u8 *ecc);
/**
* Read page spare [len] bytes from [ofs].
*
* \note flash driver must privide this function.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
*
* \note flash driver DO NOT need to do ecc correction for spare data,
* UFFS will take care of spare data ecc.
*/
int (*ReadPageSpare)(uffs_Device *dev, u32 block, u32 page, u8 *spare, int ofs, int len);
/**
* Read page spare, unload to tag and ecc.
*
* \note flash driver must provide this function if layout_opt is UFFS_LAYOUT_FLASH.
* UFFS will use this function (if exist) prio to 'ReadPageSpare()'
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
*
* \note flash driver DO NOT need to do ecc correction for spare data,
* UFFS will take care of spare data ecc.
*/
int (*ReadPageSpareWithLayout)(uffs_Device *dev, u32 block, u32 page, u8 *tag, int len, u8 *ecc);
/**
* Write page data.
*
* if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return the ecc.
* if ecc_opt is UFFS_ECC_HW_AUTO, do not need to return ecc.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*
* \note pad 0xFF for calculating ECC if len < page_data_size
*/
int (*WritePageData)(uffs_Device *dev, u32 block, u32 page, const u8 *data, int len, u8 *ecc);
/**
* Write [len] bytes to page spare from [ofs].
*
* \note flash driver must privide this function.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*WritePageSpare)(uffs_Device *dev, u32 block, u32 page, const u8 *spare, int ofs, int len, UBOOL eod);
/**
* Write full page, include page data and spare.
*
* you need to pack spare within nand driver.
*
* \note if layout_opt is UFFS_LAYOUT_FLASH, flash driver must implement this function.
* UFFS will use this function (if provided) prio to 'WritePageData() + WritePageSpare()'
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*WriteFullPage)(uffs_Device *dev, u32 block, u32 page, const u8* data, int len, const u8 *ts, int ts_len, const u8 *ecc);
/**
* check block status.
*
* \note flash driver may maintain a bad block table to speed up bad block checking or
* it will require one or two read spare I/O to check block status.
*
* \note if this function is not provided, UFFS check the block_status byte in spare.
*
* \return 1 if it's a bad block, 0 if it's not.
*/
int (*IsBadBlock)(uffs_Device *dev, u32 block);
/**
* Mark a new bad block.
*
* \return 0 if success, otherwise return -1.
*/
int (*MarkBadBlock)(uffs_Device *dev, u32 block);
/**
* Erase a block.
*
* \return #UFFS_FLASH_NO_ERR: success
* #UFFS_FLASH_IO_ERR: I/O error, expect retry ?
* #UFFS_FLASH_BAD_BLK: a bad block detected.
*/
int (*EraseBlock)(uffs_Device *dev, u32 block);
};
/** make spare from tag store and ecc */
void uffs_FlashMakeSpare(uffs_Device *dev, uffs_TagStore *ts, const u8 *ecc, u8* spare);
/** read page spare, fill tag and ECC */
int uffs_FlashReadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag, u8 *ecc);
/** read page data to page buf and do ECC correct */
int uffs_FlashReadPage(uffs_Device *dev, int block, int page, uffs_Buf *buf);
/** write page data and spare */
int uffs_FlashWritePageCombine(uffs_Device *dev, int block, int page, uffs_Buf *buf, uffs_Tags *tag);
/** Mark this block as bad block */
int uffs_FlashMarkBadBlock(uffs_Device *dev, int block);
/** Is this block a bad block ? */
UBOOL uffs_FlashIsBadBlock(uffs_Device *dev, int block);
/** Erase flash block */
int uffs_FlashEraseBlock(uffs_Device *dev, int block);
/* mark a clean page as 'dirty' (and 'invalid') */
int uffs_FlashMarkDirtyPage(uffs_Device *dev, int block, int page);
/**
* get page head info
*
* \return #UFFS_PAGE_INFO_IOERR if I/O error, otherwise return page info
*/
u32 uffs_FlashGetPageInfo(uffs_Device *dev, int block, int page);
/** load uffs_FileInfo from flash storage */
URET uffs_FlashReadFileinfoPhy(uffs_Device *dev, int block, int page, uffs_FileInfo *info);
/**
* Initialize UFFS flash interface
*/
URET uffs_FlashInterfaceInit(uffs_Device *dev);
/**
* Release UFFS flash interface
*/
URET uffs_FlashInterfaceRelease(uffs_Device *dev);
#ifdef __cplusplus
}
#endif
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
This file is part of UFFS, the Ultra-low-cost Flash File System.
Copyright (C) 2005-2009 Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
UFFS is free software; you can redistribute it and/or modify it under
the GNU Library General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any
later version.
UFFS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
or GNU Library General Public License, as applicable, for more details.
You should have received a copy of the GNU General Public License
and GNU Library General Public License along with UFFS; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
As a special exception, if other files instantiate templates or use
macros or inline functions from this file, or you compile this file
and link it with other works to produce a work based on this file,
this file does not by itself cause the resulting work to be covered
by the GNU General Public License. However the source code for this
file must still be made available in accordance with section (3) of
the GNU General Public License v2.
This exception does not invalidate any other reasons why a work based
on this file might be covered by the GNU General Public License.
*/
#ifndef UFFS_OS_H
#define UFFS_OS_H
#ifdef __cplusplus
extern "C"{
#endif
#include "uffs/uffs_device.h"
#include "uffs/uffs_core.h"
#define UFFS_TASK_ID_NOT_EXIST -1
typedef int OSSEM;
/* OS specific functions */
int uffs_SemCreate(int n);
int uffs_SemWait(int sem);
int uffs_SemSignal(int sem);
int uffs_SemDelete(int sem);
void uffs_CriticalEnter(void);
void uffs_CriticalExit(void);
int uffs_OSGetTaskId(void); //get current task id
unsigned int uffs_GetCurDateTime(void);
#ifdef __cplusplus
}
#endif
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册