mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-20 00:45:22 +08:00
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2014 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
@@ -1 +0,0 @@
|
||||
Ricky Zheng <ricky_gz_zheng@yahoo.co.nz>
|
||||
@@ -1,3 +0,0 @@
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6 )
|
||||
PROJECT( uffs )
|
||||
ADD_SUBDIRECTORY( src )
|
||||
@@ -1,339 +0,0 @@
|
||||
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.
|
||||
@@ -1,275 +0,0 @@
|
||||
# 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
|
||||
@@ -1,213 +0,0 @@
|
||||
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>
|
||||
@@ -1,5 +0,0 @@
|
||||
TODO list for v1.3:
|
||||
|
||||
* New API: int uffs_SkipObject(uffs_Object *obj, int size);
|
||||
* Introduce buffer group
|
||||
* Interface to Linux MTD
|
||||
@@ -1,298 +0,0 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
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 nand flash interface example
|
||||
* \brief example for using nand flash driver and multiple partitions, with system memory allocator.
|
||||
* \author Ricky Zheng, created at 27 Nov, 2007
|
||||
* \modify amsl, at 17 Jan, 2010 iamyhw@gmail.com
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <stdio.h>
|
||||
#include <dfs_fs.h>
|
||||
#include "uffs/uffs_device.h"
|
||||
#include "uffs/uffs_flash.h"
|
||||
#include "uffs/uffs_mtb.h"
|
||||
#include "uffs/uffs_fs.h"
|
||||
#include "uffs/uffs_utils.h"
|
||||
#include "uffs/uffs_find.h"
|
||||
#include "uffs/uffs_fd.h"
|
||||
#include "uffs_ext.h"
|
||||
|
||||
#include "k9f2g08.h"
|
||||
|
||||
#define PFX "nand-drv:"
|
||||
|
||||
/*
|
||||
* Note: all=0,read manufacturer id and device id only.
|
||||
* all=1,read all bytes,comprise additional ids.
|
||||
*/
|
||||
static void nand_read_chip_ids(u8* buf, UBOOL all)
|
||||
{
|
||||
K9F2G08_ReadChipID(buf, all);
|
||||
}
|
||||
|
||||
static int nand_write_page_data(uffs_Device *dev, u32 block, u32 page, const u8 *buffer, int len, u8 *ecc)
|
||||
{
|
||||
K9F2G08_WritePage(block,page,buffer,len,ecc);
|
||||
|
||||
dev->st.page_write_count++;
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
}
|
||||
|
||||
|
||||
static int nand_write_page_spare(uffs_Device *dev, u32 block, u32 page, const u8 *spare, int ofs, int len, UBOOL eod)
|
||||
{
|
||||
K9F2G08_WriteTags(block,page,spare,ofs,len);
|
||||
|
||||
dev->st.spare_write_count++;
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
}
|
||||
|
||||
static int nand_read_page_data(uffs_Device *dev, u32 block, u32 page, u8 *buffer, int len, u8 *ecc)
|
||||
{
|
||||
K9F2G08_ReadPage(block,page,buffer,len,ecc);
|
||||
|
||||
dev->st.page_read_count++;
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
}
|
||||
|
||||
static int nand_read_page_spare(uffs_Device *dev, u32 block, u32 page, u8 *spare, int ofs, int len)
|
||||
{
|
||||
K9F2G08_ReadTags(block,page,spare,ofs,len);
|
||||
|
||||
dev->st.spare_read_count++;
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
}
|
||||
|
||||
static int nand_erase_block(uffs_Device *dev, u32 block)
|
||||
{
|
||||
K9F2G08_EraseBlock(block);
|
||||
|
||||
dev->st.block_erase_count++;
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
}
|
||||
|
||||
static int nand_mark_badblock(uffs_Device *dev,u32 block)
|
||||
{
|
||||
return K9F2G08_Mark_badblk(block);
|
||||
}
|
||||
|
||||
static int nand_is_badblock(uffs_Device *dev,u32 block)
|
||||
{
|
||||
return K9F2G08_Check_badblk(block);
|
||||
}
|
||||
|
||||
/* The only uffs v1.3.2-4 can used. */
|
||||
static uffs_FlashOps nand_driver_ops =
|
||||
{
|
||||
nand_read_page_data, /* ReadPageData */
|
||||
nand_read_page_spare, /* ReadPageSpare */
|
||||
NULL, /* ReadPageSpareWithLayout */
|
||||
nand_write_page_data, /* WritePageData */
|
||||
nand_write_page_spare, /* WritePageSpare */
|
||||
NULL, /* WriteFullPage */
|
||||
nand_is_badblock, /* IsBadBlock */
|
||||
nand_mark_badblock, /* MarkBadBlock */
|
||||
nand_erase_block, /* EraseBlock */
|
||||
};
|
||||
|
||||
static struct uffs_StorageAttrSt flash_storage = {0};
|
||||
|
||||
static int initDevice(uffs_Device *dev)
|
||||
{
|
||||
dev->ops = &nand_driver_ops;
|
||||
return U_SUCC;
|
||||
}
|
||||
|
||||
static int releaseDevice(uffs_Device *dev)
|
||||
{
|
||||
return U_SUCC;
|
||||
}
|
||||
|
||||
#include <dfs_uffs.h>
|
||||
|
||||
static uffs_Device uffs_device = {0};
|
||||
|
||||
/*
|
||||
* define mount table,UFFS FS private data
|
||||
* it is absolute accessing for uffs.
|
||||
* set struct data on the RT-Thread device
|
||||
*/
|
||||
static uffs_MountTable uffs_mount_table =
|
||||
{
|
||||
&uffs_device,
|
||||
0,
|
||||
TOTAL_BLOCKS-1,
|
||||
"/" ,
|
||||
NULL,
|
||||
};
|
||||
|
||||
#include "nand.h"
|
||||
extern struct nand_flash_dev nand_flash_ids[];
|
||||
extern struct nand_manufacturers nand_manuf_ids[];
|
||||
|
||||
struct nand_flash_dev* nand_init(u8* buf)
|
||||
{
|
||||
struct nand_flash_dev* type=RT_NULL;
|
||||
int i, dev_id,maf_id;
|
||||
|
||||
K9F2G08_Reset();
|
||||
rt_kprintf("nand: ");
|
||||
|
||||
nand_read_chip_ids(buf,0);
|
||||
maf_id= buf[0];
|
||||
/* Try to identify manufacturer */
|
||||
for (i = 0; nand_manuf_ids[i].id != 0x0; i++)
|
||||
{
|
||||
if (nand_manuf_ids[i].id == maf_id)
|
||||
{
|
||||
rt_kprintf("%s ",nand_manuf_ids[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(nand_manuf_ids[i].id == 0x0)
|
||||
{
|
||||
rt_kprintf("%s\n",nand_manuf_ids[i].name);
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
dev_id = buf[1];
|
||||
/* Lookup the flash id */
|
||||
for(i = 0; nand_flash_ids[i].name != RT_NULL; i++)
|
||||
{
|
||||
if(dev_id == nand_flash_ids[i].id)
|
||||
{
|
||||
type = &nand_flash_ids[i];
|
||||
rt_kprintf("%s\n",nand_flash_ids[i].name);
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* RT-Thread Device Driver Interface
|
||||
* UFFS FileSystem NandFlash InterFace
|
||||
* we don't use entity, let uffs autarky
|
||||
*/
|
||||
|
||||
struct rt_device nand_device;
|
||||
|
||||
static rt_err_t rt_nand_init(rt_device_t dev)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_nand_open(rt_device_t dev, u16 oflag)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_nand_close(rt_device_t dev)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t rt_nand_control(rt_device_t dev, u8 cmd, void *args)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_size_t rt_nand_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_size_t rt_nand_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
void rt_hw_nand_init(void)
|
||||
{
|
||||
struct nand_flash_dev *type = RT_NULL;
|
||||
u8 buf[5];
|
||||
if((type = nand_init(buf)) != RT_NULL)
|
||||
{
|
||||
uffs_MountTable *entry;
|
||||
struct uffs_StorageAttrSt *chip = &flash_storage;
|
||||
|
||||
rt_device_t dev = &nand_device;
|
||||
/* fill in NandFlash device struct */
|
||||
dev->type = RT_Device_Class_Block;
|
||||
dev->init = rt_nand_init;
|
||||
dev->open = rt_nand_open;
|
||||
dev->close = rt_nand_close;
|
||||
dev->read = rt_nand_read;
|
||||
dev->write = rt_nand_write;
|
||||
dev->control = rt_nand_control;
|
||||
dev->user_data = &uffs_mount_table;
|
||||
/* register nandfalsh device */
|
||||
rt_device_register(&nand_device, "nand0",
|
||||
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
||||
|
||||
/* about uffs codes */
|
||||
entry = &uffs_mount_table;
|
||||
/* entry->lock = rt_sem_create("sem_nand0", 1, RT_IPC_FLAG_FIFO); */ /* it's lonely!how to do? */
|
||||
|
||||
uffs_MemSetupSystemAllocator(&(entry->dev->mem));
|
||||
entry->dev->Init = initDevice;
|
||||
entry->dev->Release = releaseDevice;
|
||||
entry->dev->attr = chip;
|
||||
uffs_RegisterMountTable(entry);
|
||||
|
||||
/* Newer devices have all the information in additional id bytes */
|
||||
if(!type->pagesize)
|
||||
{
|
||||
int extid;
|
||||
nand_read_chip_ids(buf,1);//reread chip ids,the all and the one.
|
||||
|
||||
/* The 3rd id byte holds MLC / multichip data,untapped */
|
||||
/* The 4th id byte is the important one */
|
||||
extid = buf[3];
|
||||
/* Calc pagesize */
|
||||
chip->page_data_size = 1024 << (extid & 0x3);
|
||||
extid >>= 2;
|
||||
/* Calc oobsize */
|
||||
chip->spare_size = (8<<(extid & 0x01))*(chip->page_data_size>>9);
|
||||
extid >>= 2;
|
||||
/* Calc blocksize. Blocksize is multiples of 64KiB */
|
||||
chip->pages_per_block = ((64*1024)<<(extid & 0x03))/(chip->page_data_size);
|
||||
/* The 5th id byte,it is no use */
|
||||
chip->total_blocks = (type->chipsize*1024*1024) /
|
||||
chip->page_data_size / chip->pages_per_block;
|
||||
|
||||
}
|
||||
else
|
||||
{ /* Old devices have chip data hardcoded in the device id table */
|
||||
chip->page_data_size = type->pagesize;
|
||||
chip->pages_per_block = type->blocksize / type->pagesize;
|
||||
chip->spare_size = chip->page_data_size / 32;
|
||||
chip->total_blocks = (type->chipsize*1024*1024) / type->blocksize;
|
||||
}
|
||||
if(type->options & NAND_SAMSUNG_LP_OPTIONS)
|
||||
chip->block_status_offs = NAND_LARGE_BADBLOCK_POS;
|
||||
else
|
||||
chip->block_status_offs = NAND_SMALL_BADBLOCK_POS;
|
||||
chip->ecc_opt = UFFS_ECC_SOFT; /* ecc option, do not use ECC,debug */
|
||||
chip->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
|
||||
#if (0) /* DEBUG trace facility */
|
||||
rt_kprintf("page_data_size = %d\n",chip->page_data_size);
|
||||
rt_kprintf("pages_per_block = %d\n",chip->pages_per_block);
|
||||
rt_kprintf("spare_size = %d\n",chip->spare_size);
|
||||
rt_kprintf("total_blocks = %d\n",chip->total_blocks);
|
||||
rt_kprintf("block_stat_offs = %d\n",chip->block_status_offs);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* end of file */
|
||||
|
||||
@@ -1,355 +0,0 @@
|
||||
#include <rtthread.h>
|
||||
#include <dfs_def.h>
|
||||
#include <dfs_fs.h>
|
||||
#include "uffs/uffs_fs.h"
|
||||
#include "uffs/uffs_mtb.h"
|
||||
#include "uffs/uffs_fd.h"
|
||||
#include "uffs_ext.h"
|
||||
|
||||
/* mount and unmount file system */
|
||||
int dfs_uffs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
|
||||
{
|
||||
return ((uffs_InitMountTable() == U_SUCC) ? 0 : -1);
|
||||
}
|
||||
|
||||
int dfs_uffs_unmount(struct dfs_filesystem* fs)
|
||||
{
|
||||
uffs_ReleaseObjectBuf();
|
||||
return uffs_ReleaseMountTable();
|
||||
}
|
||||
|
||||
int dfs_uffs_mkfs(const char* device_name)
|
||||
{
|
||||
return uffs_format(NULL);
|
||||
}
|
||||
|
||||
int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf)
|
||||
{
|
||||
int ret = U_SUCC;
|
||||
uffs_MountTable *entry = (uffs_MountTable*)(fs->dev_id->user_data);
|
||||
struct uffs_StorageAttrSt *attr = entry->dev->attr;
|
||||
|
||||
buf->f_bsize = attr->page_data_size * attr->pages_per_block;
|
||||
buf->f_blocks = attr->total_blocks;
|
||||
buf->f_bfree = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfs_uffs_open(struct dfs_fd* fd)
|
||||
{
|
||||
if (fd->flags & DFS_O_DIRECTORY)
|
||||
{ /* directory */
|
||||
uffs_DIR* dirp;
|
||||
int oflag = UO_DIR;
|
||||
|
||||
if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE;
|
||||
if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY;
|
||||
if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY;
|
||||
|
||||
if (oflag & UO_CREATE)
|
||||
{ /* create directory right now */
|
||||
uffs_Object* fp = uffs_GetObject();
|
||||
if(fp == NULL)
|
||||
{
|
||||
uffs_set_error(-UEMFILE);
|
||||
return U_FAIL;
|
||||
}
|
||||
|
||||
if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC)
|
||||
{
|
||||
return U_FAIL;
|
||||
}
|
||||
/* release object hander */
|
||||
uffs_PutObject(fp);
|
||||
}
|
||||
|
||||
/* use directory handler */
|
||||
dirp = uffs_opendir(fd->path);
|
||||
if(dirp == NULL)
|
||||
{
|
||||
uffs_set_error(-UEMFILE);
|
||||
return U_FAIL;
|
||||
}
|
||||
fd->data = dirp;
|
||||
|
||||
return U_SUCC;
|
||||
}
|
||||
else
|
||||
{/* file */
|
||||
uffs_Object *fp;
|
||||
|
||||
int mode = UO_RDONLY;
|
||||
|
||||
if (fd->flags & DFS_O_WRONLY) mode |= UO_WRONLY;
|
||||
if ((fd->flags & DFS_O_ACCMODE) & DFS_O_RDWR) mode |= UO_WRONLY;
|
||||
/* Opens the file, if it is existing. If not, a new file is created. */
|
||||
if (fd->flags & DFS_O_CREAT) mode |= UO_CREATE;
|
||||
/* Creates a new file. If the file is existing, it is truncated and overwritten. */
|
||||
if (fd->flags & DFS_O_TRUNC) mode |= UO_TRUNC;
|
||||
/* Creates a new file. The function fails if the file is already existing. */
|
||||
if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL;
|
||||
|
||||
/* get an object hander */
|
||||
fp = uffs_GetObject();
|
||||
if(fp == NULL)
|
||||
{
|
||||
uffs_set_error(-UEMFILE);
|
||||
return U_FAIL;
|
||||
}
|
||||
|
||||
if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC)
|
||||
{
|
||||
struct uffs_stat stat_buf;
|
||||
|
||||
uffs_stat(fd->path, &stat_buf);
|
||||
|
||||
fd->pos = fp->pos;
|
||||
fd->size = stat_buf.st_size;
|
||||
fd->data = fp;
|
||||
|
||||
if(fd->flags & DFS_O_APPEND)
|
||||
{
|
||||
fd->pos = uffs_SeekObject(fp, 0, USEEK_END);
|
||||
}
|
||||
return U_SUCC;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* open failed, return */
|
||||
uffs_set_error(-uffs_GetObjectErr(fp));
|
||||
/* release object hander */
|
||||
uffs_PutObject(fp);
|
||||
return U_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dfs_uffs_close(struct dfs_fd* fd)
|
||||
{
|
||||
int ret=U_SUCC;
|
||||
|
||||
if (fd->type == FT_DIRECTORY)
|
||||
{
|
||||
uffs_DIR* dirp;
|
||||
dirp = (uffs_DIR*)(fd->data);
|
||||
RT_ASSERT(dirp != RT_NULL);
|
||||
|
||||
ret = uffs_closedir(dirp);
|
||||
}
|
||||
else if (fd->type == FT_REGULAR)
|
||||
{
|
||||
uffs_Object* fp = (uffs_Object*)(fd->data);
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
ret = uffs_CloseObject(fp);
|
||||
/* release object hander */
|
||||
uffs_PutObject(fp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfs_uffs_ioctl(struct dfs_fd* fd, int cmd, void *args)
|
||||
{
|
||||
return -DFS_STATUS_ENOSYS;
|
||||
}
|
||||
|
||||
int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count)
|
||||
{
|
||||
uffs_Object* fp;
|
||||
uffs_DIR* dirp;
|
||||
|
||||
if (fd->type == FT_DIRECTORY)
|
||||
{
|
||||
dirp = (uffs_DIR*)(fd->data);
|
||||
fp = dirp->obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = (uffs_Object*)(fd->data);
|
||||
}
|
||||
|
||||
RT_ASSERT(fd != RT_NULL);
|
||||
|
||||
/* update position */
|
||||
fd->pos = fp->pos;
|
||||
|
||||
return uffs_ReadObject(fp, buf, count);
|
||||
}
|
||||
|
||||
int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count)
|
||||
{
|
||||
uffs_Object* fp;
|
||||
u32 byte_write;
|
||||
struct uffs_stat stat_buf;
|
||||
rt_kprintf("count=%d\n",count);
|
||||
if(fd->type == FT_DIRECTORY)
|
||||
{
|
||||
return -DFS_STATUS_EISDIR;
|
||||
}
|
||||
|
||||
fp = (uffs_Object*)(fd->data);
|
||||
RT_ASSERT(fp != RT_NULL);
|
||||
|
||||
byte_write = uffs_WriteObject(fp, buf, count);
|
||||
|
||||
/* update position and file size */
|
||||
fd->pos = fp->pos;
|
||||
|
||||
uffs_stat(fp->name, &stat_buf);
|
||||
fd->size = stat_buf.st_size;
|
||||
|
||||
return byte_write;
|
||||
}
|
||||
|
||||
int dfs_uffs_flush(struct dfs_fd* fd)
|
||||
{
|
||||
uffs_Object* fp;
|
||||
|
||||
fp = (uffs_Object*)(fd->data);
|
||||
RT_ASSERT(fp != RT_NULL);
|
||||
|
||||
return uffs_FlushObject(fp);
|
||||
}
|
||||
|
||||
int dfs_uffs_lseek(struct dfs_fd* fd, rt_off_t offset)
|
||||
{
|
||||
uffs_Object* fp;
|
||||
|
||||
fp = (uffs_Object*)(fd->data);
|
||||
RT_ASSERT(fp != RT_NULL);
|
||||
|
||||
return uffs_SeekObject(fp, offset, USEEK_SET);
|
||||
}
|
||||
|
||||
int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count)
|
||||
{
|
||||
uffs_DIR* dirp;
|
||||
struct uffs_dirent *ent;
|
||||
rt_uint32_t index;
|
||||
struct dirent* d;
|
||||
|
||||
if(fd->type != FT_DIRECTORY)
|
||||
{
|
||||
return -DFS_STATUS_EISDIR;
|
||||
}
|
||||
|
||||
dirp = (uffs_DIR*)(fd->data);
|
||||
RT_ASSERT(dirp != RT_NULL);
|
||||
|
||||
/* make integer count */
|
||||
count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
||||
if ( count == 0 ) return -DFS_STATUS_EINVAL;
|
||||
|
||||
index = 0;
|
||||
while (1)
|
||||
{
|
||||
d = dir + index;
|
||||
|
||||
ent = uffs_readdir(dirp);
|
||||
if(ent == RT_NULL)break;
|
||||
|
||||
|
||||
d->d_type = DFS_DT_DIR;
|
||||
|
||||
d->d_namlen = ent->d_namelen;
|
||||
d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||||
rt_strncpy(d->d_name, ent->d_name, rt_strlen(ent->d_name) + 1);
|
||||
|
||||
index ++;
|
||||
if ( index * sizeof(struct dirent) >= count )
|
||||
break;
|
||||
}
|
||||
return index * sizeof(struct dirent);
|
||||
}
|
||||
|
||||
//Delete a File or Directory
|
||||
int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path)
|
||||
{
|
||||
int ret;
|
||||
int err = 0;
|
||||
|
||||
ret = uffs_DeleteObject(path, &err);
|
||||
uffs_set_error(-err);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st)
|
||||
{
|
||||
int ret=U_SUCC;
|
||||
struct uffs_stat stat_buf;
|
||||
|
||||
ret = uffs_stat(path, &stat_buf);
|
||||
|
||||
if (ret == U_SUCC)
|
||||
{
|
||||
rt_uint32_t mode=0;
|
||||
st->st_dev = 0;
|
||||
|
||||
if(stat_buf.st_mode & US_IFREG) mode |= DFS_S_IFREG;
|
||||
if(stat_buf.st_mode & US_IFDIR) mode |= DFS_S_IFDIR;
|
||||
if(stat_buf.st_mode & US_IRWXU) mode |= DFS_S_IRWXU;
|
||||
if(stat_buf.st_mode & US_IRUSR) mode |= DFS_S_IRUSR;
|
||||
if(stat_buf.st_mode & US_IWUSR) mode |= DFS_S_IWUSR;
|
||||
if(stat_buf.st_mode & US_IXUSR) mode |= DFS_S_IXUSR;
|
||||
if(stat_buf.st_mode & US_IRWXG) mode |= DFS_S_IRWXG;
|
||||
if(stat_buf.st_mode & US_IRGRP) mode |= DFS_S_IRGRP;
|
||||
if(stat_buf.st_mode & US_IWGRP) mode |= DFS_S_IWGRP;
|
||||
if(stat_buf.st_mode & US_IXGRP) mode |= DFS_S_IXGRP;
|
||||
if(stat_buf.st_mode & US_IRWXO) mode |= DFS_S_IRWXO;
|
||||
if(stat_buf.st_mode & US_IROTH) mode |= DFS_S_IROTH;
|
||||
if(stat_buf.st_mode & US_IWOTH) mode |= DFS_S_IWOTH;
|
||||
if(stat_buf.st_mode & US_IXOTH) mode |= DFS_S_IXOTH;
|
||||
|
||||
st->st_mode = mode;
|
||||
st->st_size = stat_buf.st_size;
|
||||
st->st_mtime= stat_buf.st_mtime;
|
||||
st->st_blksize= stat_buf.st_blksize;
|
||||
|
||||
return U_SUCC;
|
||||
}
|
||||
|
||||
return U_FAIL;
|
||||
}
|
||||
|
||||
int dfs_uffs_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
|
||||
{
|
||||
int ret;
|
||||
int err = 0;
|
||||
|
||||
ret = uffs_RenameObject(oldpath, newpath, &err);
|
||||
uffs_set_error(-err);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct dfs_filesystem_operation _uffs =
|
||||
{
|
||||
"uffs",
|
||||
DFS_FS_FLAG_DEFAULT,
|
||||
dfs_uffs_mount,
|
||||
dfs_uffs_unmount,
|
||||
dfs_uffs_mkfs,
|
||||
dfs_uffs_statfs,
|
||||
dfs_uffs_open,
|
||||
dfs_uffs_close,
|
||||
dfs_uffs_ioctl,
|
||||
dfs_uffs_read,
|
||||
dfs_uffs_write,
|
||||
dfs_uffs_flush,
|
||||
dfs_uffs_lseek,
|
||||
dfs_uffs_getdents,
|
||||
dfs_uffs_unlink,
|
||||
dfs_uffs_stat,
|
||||
dfs_uffs_rename,
|
||||
};
|
||||
|
||||
int dfs_uffs_init(void)
|
||||
{
|
||||
/* register UFFS file system */
|
||||
return dfs_register(&_uffs);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
+------------------------------------------------------------------------------
|
||||
| Project : Device Filesystem
|
||||
+------------------------------------------------------------------------------
|
||||
| Copyright 2010
|
||||
| All rights reserved.
|
||||
|------------------------------------------------------------------------------
|
||||
| File : dfs_uffs.h
|
||||
|------------------------------------------------------------------------------
|
||||
| Chang Logs:
|
||||
| Date Author Notes
|
||||
| 2010-09-02 Bernard The first version.
|
||||
| 2010-12-24 amsl Add dfs_uffs_init function declaration
|
||||
+------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __DFS_UFFS_H__
|
||||
#define __DFS_UFFS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int dfs_uffs_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB |
@@ -1,28 +0,0 @@
|
||||
#ifndef __K9F2G08_H__
|
||||
#define __K9F2G08_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
#include <s3c24x0.h>
|
||||
#include <nand.h>
|
||||
|
||||
void K9F2G08_Program(u32 blockIndex, u32 srcAddress, u32 fileSize);
|
||||
|
||||
//*************** H/W dependent functions ***************
|
||||
void K9F2G08_ReadChipID(u8* buf, UBOOL all);
|
||||
|
||||
int K9F2G08_Check_badblk(u32 block);
|
||||
int K9F2G08_EraseBlock (u32 block);
|
||||
int K9F2G08_Mark_badblk (u32 block);
|
||||
int K9F2G08_ReadPage (u32 block, u32 page, u8 *buffer, int len, u8 *ecc);
|
||||
int K9F2G08_WritePage (u32 block, u32 page, const u8 *buffer, int len, const u8 *ecc);
|
||||
int K9F2G08_ReadTags (u32 block, u32 page, u8 *spare, int ofs, int len);
|
||||
int K9F2G08_WriteTags (u32 block, u32 page, const u8 *spare, int ofs, int len);
|
||||
|
||||
void K9F2G08_Reset(void);
|
||||
|
||||
void K9F2G08_Init(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
* uffs/flash/k9f2g08.c
|
||||
*
|
||||
* COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rt-thread.org/license/LICENSE
|
||||
*
|
||||
* Info:
|
||||
* Low hardware driver for samsung nandflash.
|
||||
*/
|
||||
|
||||
/* XXX UFFS XXX */
|
||||
#include <uffs/uffs_types.h>
|
||||
|
||||
#include <nand.h>
|
||||
#include "s3c24x0.h"
|
||||
#include <k9f2g08.h>
|
||||
|
||||
#define nand_write_cmd(cmd) (NFCMD = (cmd))
|
||||
#define nand_write_addr(addr) (NFADDR = (addr))
|
||||
#define nand_cs_en() (NFCONT &= ~(1<<1))
|
||||
#define nand_cs_ds() (NFCONT |= (1<<1))
|
||||
#define nand_Init_ECC() (NFCONT |= (1<<4))
|
||||
#define nand_read() (NFDATA8)
|
||||
#define nand_write(data) (NFDATA8 = (data))
|
||||
|
||||
#define nand_wait() {while(!(NFSTAT&(1<<0)));} //wait tWB and check F_RNB pin.
|
||||
|
||||
/*
|
||||
*************************************************
|
||||
** H/W dependent functions **
|
||||
*************************************************
|
||||
*/
|
||||
|
||||
/* HCLK=100Mhz */
|
||||
#define TACLS 1 /* 1clk(0ns) */
|
||||
#define TWRPH0 4 /* 3clk(25ns) */
|
||||
#define TWRPH1 0 /* 1clk(10ns) */ /* TACLS+TWRPH0+TWRPH1>=50ns */
|
||||
|
||||
int read_nand_stats(void) /* R/B is fixed? */
|
||||
{
|
||||
u8 stat;
|
||||
|
||||
nand_write_cmd(NAND_CMD_STATUS);
|
||||
|
||||
stat = nand_read();/* read byte */
|
||||
|
||||
if(stat&1) return 1; /* I/O0=1 successful */
|
||||
else return 0; /* I/O0=0 unsuccessful */
|
||||
}
|
||||
|
||||
/*
|
||||
*erase a block
|
||||
*return 0,successful
|
||||
*return 1,error
|
||||
*/
|
||||
int K9F2G08_EraseBlock(u32 block)
|
||||
{
|
||||
int stat;
|
||||
u32 _page = block*PAGES_PER_BLOCK;
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_ERASE1); /* Erase one block 1st command */
|
||||
|
||||
nand_write_addr(_page&0xff); /* Page number=0 */
|
||||
nand_write_addr((_page>>8)&0xff);
|
||||
nand_write_addr((_page>>16)&0xff);
|
||||
|
||||
nand_write_cmd(NAND_CMD_ERASE2); /* Erase one blcok 2nd command */
|
||||
|
||||
nand_wait(); /* Wait tBERS max 3ms. */
|
||||
|
||||
stat = read_nand_stats();
|
||||
nand_cs_ds();
|
||||
return stat;
|
||||
}
|
||||
|
||||
/*
|
||||
* check block is bad?
|
||||
* return 1 if it's a bad block, 0 if it's good.
|
||||
*/
|
||||
int K9F2G08_Check_badblk(u32 block)
|
||||
{
|
||||
u8 data;
|
||||
u32 _page;/* frist page in block */
|
||||
|
||||
_page = block*PAGES_PER_BLOCK; /* For 2'nd cycle I/O[7:5] */
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_READ0); /* Spare array read command */
|
||||
nand_write_addr(PAGE_DATA_SIZE&0xff); /* Read the mark of bad block in spare array(M addr=5) */
|
||||
nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
|
||||
nand_write_addr(_page&0xff); /* The mark of bad block is in 0 page */
|
||||
nand_write_addr((_page>>8)&0xff); /* For block number A[24:17] */
|
||||
nand_write_addr((_page>>16)&0xff); /* For block number A[25] */
|
||||
nand_write_cmd(NAND_CMD_READSTART);
|
||||
|
||||
nand_wait(); /* Wait tR(max 12us) */
|
||||
|
||||
data=nand_read();
|
||||
nand_cs_ds();
|
||||
if(data==0x00)
|
||||
return 1;/* bad */
|
||||
else
|
||||
return 0;/* good */
|
||||
}
|
||||
/*
|
||||
* mark a block is bad
|
||||
* return 0 if ok, 1:fail
|
||||
*/
|
||||
int K9F2G08_Mark_badblk(u32 block)
|
||||
{
|
||||
u8 stat;
|
||||
u32 _page = block*PAGES_PER_BLOCK;
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_SEQIN); /* Write 1st command */
|
||||
|
||||
nand_write_addr(PAGE_DATA_SIZE & 0xff);/* The mark of bad block */
|
||||
nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
|
||||
nand_write_addr(_page&0xff); /* marked 1th spare array */
|
||||
nand_write_addr((_page>>8)&0xff); /* in the 1st page. */
|
||||
nand_write_addr((_page>>16)&0xff);
|
||||
|
||||
nand_write(0x00); /* 0x00 is commendatory make of the bad block. */
|
||||
|
||||
nand_write_cmd(NAND_CMD_PAGEPROG); /* Write 2nd command */
|
||||
|
||||
nand_wait(); /* Wait tPROG(200~500us) */
|
||||
stat = read_nand_stats();
|
||||
nand_cs_ds();
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
int K9F2G08_ReadPage(u32 block, u32 page, u8 *buffer, int len, u8 *ecc)
|
||||
{
|
||||
int i;
|
||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||
|
||||
/* NF_RSTECC(); */ /* Initialize ECC*/
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_READ0); /* Read command */
|
||||
nand_write_addr(0x00); /* Column = 0 */
|
||||
nand_write_addr(0x00);
|
||||
nand_write_addr(_page&0xff);
|
||||
nand_write_addr((_page>>8)&0xff);
|
||||
nand_write_addr((_page>>16)&0xff);
|
||||
|
||||
nand_write_cmd(NAND_CMD_READSTART);
|
||||
|
||||
nand_wait(); /* Wait tR(max 12us) */
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
buffer[i] = nand_read(); /* Read one page */
|
||||
}
|
||||
|
||||
nand_cs_ds();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int K9F2G08_ReadTags(u32 block, u32 page, u8 *spare, int ofs, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||
|
||||
/* NF_RSTECC(); */ /* Initialize ECC */
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_READ0);
|
||||
nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
|
||||
nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
|
||||
nand_write_addr(_page&0xff);
|
||||
nand_write_addr((_page>>8)&0xff);
|
||||
nand_write_addr((_page>>16)&0xff);
|
||||
|
||||
nand_write_cmd(NAND_CMD_READSTART);
|
||||
|
||||
nand_wait(); /* Wait tR(max 12us) */
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
spare[i] = nand_read(); /* Read one page */
|
||||
}
|
||||
|
||||
nand_cs_ds();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* write one page data
|
||||
* return 0,successful
|
||||
* return 1,error
|
||||
*/
|
||||
int K9F2G08_WritePage(u32 block, u32 page, const u8 *buffer, int len, const u8 *ecc)
|
||||
{
|
||||
int i,stat;
|
||||
|
||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||
|
||||
/* nand_Init_ECC(); */ /* nitialize ECC */
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_SEQIN);
|
||||
for(i=0;i<10;i++);
|
||||
nand_write_addr(0x00); /* Column 0 */
|
||||
nand_write_addr(0x00);
|
||||
nand_write_addr(_page&0xff);
|
||||
nand_write_addr((_page>>8)&0xff);
|
||||
nand_write_addr((_page>>16)&0xff);
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
nand_write(*buffer++);
|
||||
}
|
||||
nand_write_cmd(NAND_CMD_PAGEPROG);
|
||||
|
||||
nand_wait(); /* wait tPROG 200~500us; */
|
||||
|
||||
stat = read_nand_stats();
|
||||
nand_cs_ds();
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
int K9F2G08_WriteTags(u32 block, u32 page, const u8 *spare, int ofs, int len)
|
||||
{
|
||||
int i,stat;
|
||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||
|
||||
/* nand_Init_ECC(); */ /* Initialize ECC */
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_SEQIN);
|
||||
for(i=0;i<10;i++);
|
||||
nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
|
||||
nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
|
||||
nand_write_addr(_page&0xff);
|
||||
nand_write_addr((_page>>8)&0xff);
|
||||
nand_write_addr((_page>>16)&0xff);
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
nand_write(*spare++);
|
||||
}
|
||||
|
||||
nand_write_cmd(NAND_CMD_PAGEPROG);
|
||||
|
||||
nand_wait(); /* wait tPROG 200~500us; */
|
||||
|
||||
stat = read_nand_stats();
|
||||
if(!stat) /* Page write error */
|
||||
{
|
||||
nand_cs_ds();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
nand_cs_ds();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* when all is true,read all byte */
|
||||
void K9F2G08_ReadChipID(u8* buf, UBOOL all)
|
||||
{
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_READID);
|
||||
nand_write_addr(NAND_CMD_READ0);
|
||||
|
||||
buf[0] = nand_read();/* manufacturer ID */
|
||||
buf[1] = nand_read();/* physical chip ID */
|
||||
if(all)
|
||||
{
|
||||
buf[2] = nand_read();
|
||||
buf[3] = nand_read();
|
||||
/* buf[4] = nand_read(); */ /* Some chips have no 5th byte */
|
||||
}
|
||||
|
||||
nand_cs_ds();
|
||||
}
|
||||
|
||||
void K9F2G08_Init(void)
|
||||
{
|
||||
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
|
||||
NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
|
||||
NFSTAT = 0;
|
||||
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
|
||||
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
|
||||
}
|
||||
|
||||
void K9F2G08_Reset(void)
|
||||
{
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(0xFF); /* reset command */
|
||||
|
||||
nand_wait(); /* wait 200~500us */
|
||||
nand_cs_ds();
|
||||
|
||||
K9F2G08_Init();
|
||||
}
|
||||
|
||||
#if (0)
|
||||
int K9F2G08_ReadChunk(u32 chunk, u8 *data, u8 *tags)
|
||||
{
|
||||
int i;
|
||||
|
||||
nand_cs_en();
|
||||
|
||||
nand_write_cmd(NAND_CMD_READ0);
|
||||
nand_write_addr(0x00);
|
||||
nand_write_addr(0x00);
|
||||
nand_write_addr(chunk & 0xff);
|
||||
nand_write_addr((chunk >> 8) & 0xff);
|
||||
nand_write_addr((chunk >> 16) & 0xff); //
|
||||
/* nand_Init_ECC(); */
|
||||
nand_write_cmd(NAND_CMD_READ30);
|
||||
|
||||
nand_wait(); /* Wait tR(max 12us) */
|
||||
|
||||
for(i = 0; i < PAGE_DATA_SIZE; i++)
|
||||
{
|
||||
data[i] = nand_read(); /* Read page data */
|
||||
}
|
||||
for(i = 0; i < PAGE_SPARE_SIZE; i++)
|
||||
{
|
||||
tags[i] = nand_read(); /* Read spare array */
|
||||
}
|
||||
|
||||
nand_cs_ds();
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* uffs/flash/nand.h
|
||||
*
|
||||
* COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rt-thread.org/license/LICENSE
|
||||
*
|
||||
* Info:
|
||||
* Contains standard defines and IDs for NAND flash devices
|
||||
*/
|
||||
#ifndef __RTT_DFS_NAND_H__
|
||||
#define __RTT_DFS_NAND_H__
|
||||
|
||||
/*
|
||||
* Standard NAND flash commands
|
||||
*/
|
||||
#define NAND_CMD_READ0 0 /* Read0 */
|
||||
#define NAND_CMD_READ1 1 /* Read1 */
|
||||
#define NAND_CMD_RNDOUT 5 /* Random data output */
|
||||
#define NAND_CMD_PAGEPROG 0x10 /* Write phase 2 */
|
||||
#define NAND_CMD_READOOB 0x50 /* Read oob */
|
||||
#define NAND_CMD_ERASE1 0x60 /* Erase phase 1 */
|
||||
#define NAND_CMD_STATUS 0x70 /* Status read */
|
||||
#define NAND_CMD_STATUS_MULTI 0x71
|
||||
#define NAND_CMD_SEQIN 0x80 /* Write phase 1 */
|
||||
#define NAND_CMD_RNDIN 0x85 /* Random data input */
|
||||
#define NAND_CMD_READID 0x90 /* ReadID,all-purpose command */
|
||||
#define NAND_CMD_ERASE2 0xd0 /* Erase phase 2 */
|
||||
#define NAND_CMD_RESET 0xff /* Reset */
|
||||
|
||||
/* Extended commands for large page devices */
|
||||
#define NAND_CMD_READSTART 0x30
|
||||
#define NAND_CMD_RNDOUTSTART 0xE0
|
||||
#define NAND_CMD_CACHEDPROG 0x15
|
||||
#define NAND_CMD_READ_EDC 0x7b
|
||||
|
||||
/* define low accessing value */
|
||||
#define TOTAL_BLOCKS 2048 /* total block of whole chip */
|
||||
#define PAGE_DATA_SIZE 2048 /* max size of page data */
|
||||
#define PAGE_SPARE_SIZE 64 /* max size of extended partition */
|
||||
#define PAGES_PER_BLOCK 64 /* max pages per block' */
|
||||
#define PAGE_SIZE (PAGE_DATA_SIZE+PAGE_SPARE_SIZE)/* max size per whole page */
|
||||
#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE*PAGES_PER_BLOCK)/* max size per block' */
|
||||
|
||||
/* bad flags offset in the oob area. */
|
||||
#define NAND_SMALL_BADBLOCK_POS 5 /* small page FLASH */
|
||||
#define NAND_LARGE_BADBLOCK_POS 0 /* large page FLASH */
|
||||
|
||||
/* Option constants for bizarre disfunctionality and real
|
||||
* features
|
||||
*/
|
||||
/* Chip can not auto increment pages */
|
||||
#define NAND_NO_AUTOINCR 0x00000001
|
||||
/* Buswitdh is 16 bit */
|
||||
#define NAND_BUSWIDTH_16 0x00000002
|
||||
/* Device supports partial programming without padding */
|
||||
#define NAND_NO_PADDING 0x00000004
|
||||
/* Chip has cache program function */
|
||||
#define NAND_CACHEPRG 0x00000008
|
||||
/* Chip has copy back function */
|
||||
#define NAND_COPYBACK 0x00000010
|
||||
/* AND Chip which has 4 banks and a confusing page / block
|
||||
* assignment. See Renesas datasheet for further information */
|
||||
#define NAND_IS_AND 0x00000020
|
||||
/* Chip has a array of 4 pages which can be read without
|
||||
* additional ready /busy waits */
|
||||
#define NAND_4PAGE_ARRAY 0x00000040
|
||||
|
||||
/* Options valid for Samsung large page devices */
|
||||
#define NAND_SAMSUNG_LP_OPTIONS \
|
||||
(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
|
||||
|
||||
struct nand_flash_dev
|
||||
{
|
||||
char *name; /* chip name */
|
||||
int id; /* chip ID */
|
||||
unsigned long pagesize; /* max pages */
|
||||
unsigned long chipsize; /* size of whole chip iMB */
|
||||
unsigned long blocksize;/* size of block */
|
||||
unsigned long options; /* option */
|
||||
};
|
||||
|
||||
struct nand_manufacturers
|
||||
{
|
||||
int id;
|
||||
char * name;
|
||||
};
|
||||
|
||||
#endif /*__RTT_DFS_NAND_H__*/
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* drivers/mtd/nandids.c
|
||||
*
|
||||
* Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
|
||||
*
|
||||
* $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#include "flash/nand.h"
|
||||
|
||||
/*
|
||||
* Chip ID list
|
||||
*
|
||||
* name, ID, pagesize, chipsize in MegaByte, eraseblock size,options
|
||||
*
|
||||
* if 0, get this information from the extended chip ID
|
||||
*/
|
||||
struct nand_flash_dev nand_flash_ids[] =
|
||||
{
|
||||
{"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
|
||||
{"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0},
|
||||
{"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0},
|
||||
{"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0},
|
||||
{"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0},
|
||||
{"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0},
|
||||
{"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0},
|
||||
{"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
|
||||
{"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
|
||||
{"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
|
||||
|
||||
{"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
|
||||
{"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
|
||||
{"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
|
||||
{"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
|
||||
|
||||
{"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
|
||||
{"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
|
||||
{"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
|
||||
{"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
|
||||
|
||||
{"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
|
||||
{"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
|
||||
{"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
|
||||
{"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
|
||||
|
||||
{"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
|
||||
{"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
|
||||
{"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
|
||||
{"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
|
||||
|
||||
{"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
|
||||
{"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
|
||||
{"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16},
|
||||
{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
|
||||
|
||||
{"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
|
||||
|
||||
/* {"NAND 512MiB 3,3V 8-bit", 0xDC, 512, 512, 0x4000, 0}, */
|
||||
{"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, 0},
|
||||
|
||||
/* These are the new chips with large page size. The pagesize
|
||||
* and the erasesize is determined from the extended id bytes
|
||||
*/
|
||||
/* 1 Gigabit */
|
||||
{"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
{"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
|
||||
/* 2 Gigabit */
|
||||
{"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
{"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
|
||||
/* 4 Gigabit */
|
||||
{"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
{"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
|
||||
/* 8 Gigabit */
|
||||
{"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
{"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
|
||||
/* 16 Gigabit */
|
||||
{"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
|
||||
{"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
{"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
|
||||
|
||||
/* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
|
||||
* The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
|
||||
* 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
|
||||
* Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
|
||||
* There are more speed improvements for reads and writes possible, but not implemented now
|
||||
*/
|
||||
{"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY},
|
||||
|
||||
{RT_NULL,}
|
||||
};
|
||||
|
||||
/*
|
||||
* NAND Flash 生产厂家代码
|
||||
*/
|
||||
#define NAND_MFR_TOSHIBA 0x98
|
||||
#define NAND_MFR_SAMSUNG 0xec
|
||||
#define NAND_MFR_FUJITSU 0x04
|
||||
#define NAND_MFR_NATIONAL 0x8f
|
||||
#define NAND_MFR_RENESAS 0x07
|
||||
#define NAND_MFR_STMICRO 0x20
|
||||
|
||||
/* 制造商ID列表 */
|
||||
struct nand_manufacturers nand_manuf_ids[] =
|
||||
{
|
||||
{NAND_MFR_TOSHIBA, "Toshiba"},
|
||||
{NAND_MFR_SAMSUNG, "Samsung"},
|
||||
{NAND_MFR_FUJITSU, "Fujitsu"},
|
||||
{NAND_MFR_NATIONAL,"National"},
|
||||
{NAND_MFR_RENESAS, "Renesas"},
|
||||
{NAND_MFR_STMICRO, "ST Micro"},
|
||||
{0x0, "Unknown"}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
ADD_SUBDIRECTORY(emu)
|
||||
ADD_SUBDIRECTORY(uffs)
|
||||
ADD_SUBDIRECTORY(utils)
|
||||
ADD_SUBDIRECTORY(example)
|
||||
@@ -1,5 +0,0 @@
|
||||
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} )
|
||||
|
||||
@@ -1,265 +0,0 @@
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
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(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
};
|
||||
@@ -1,475 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
This file is part of UFFS, the Ultra-low-cost Flash File System.
|
||||
|
||||
Copyright (C) 2005-2010 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_ecc_hw.c
|
||||
* \brief emulate uffs file system for hardware ECC.
|
||||
*
|
||||
* In this emulator, we call 'uffs_FlashMakeSpare()' to do the layout job
|
||||
* and call 'uffs_EccMake()' to calculate ECC.
|
||||
*
|
||||
* \author Ricky Zheng @ Oct, 2010
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uffs/uffs_device.h"
|
||||
#include "uffs_fileem.h"
|
||||
#include "uffs/uffs_ecc.h"
|
||||
|
||||
#define PFX "femu: "
|
||||
#define MSG(msg,...) uffs_PerrorRaw(UFFS_ERR_NORMAL, msg, ## __VA_ARGS__)
|
||||
#define MSGLN(msg,...) uffs_Perror(UFFS_ERR_NORMAL, msg, ## __VA_ARGS__)
|
||||
|
||||
static int femu_hw_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page,
|
||||
const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts)
|
||||
{
|
||||
int written;
|
||||
int abs_page;
|
||||
int full_page_size;
|
||||
uffs_FileEmu *emu;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
u8 spare[UFFS_MAX_SPARE_SIZE];
|
||||
u8 ecc_buf[UFFS_MAX_ECC_SIZE];
|
||||
int spare_len;
|
||||
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
if (!emu || !(emu->fp)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
abs_page = attr->pages_per_block * block + page;
|
||||
full_page_size = attr->page_data_size + attr->spare_size;
|
||||
|
||||
if (data && data_len > 0) {
|
||||
if (data_len > attr->page_data_size)
|
||||
goto err;
|
||||
|
||||
emu->em_monitor_page[abs_page]++;
|
||||
if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) {
|
||||
MSG("Warrning: block %d page %d exceed it's maximum write time!", block, page);
|
||||
goto err;
|
||||
}
|
||||
|
||||
fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
|
||||
|
||||
written = fwrite(data, 1, data_len, emu->fp);
|
||||
|
||||
if (written != data_len) {
|
||||
MSG("write page I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev->st.page_write_count++;
|
||||
dev->st.io_write += written;
|
||||
|
||||
}
|
||||
|
||||
if (ts) {
|
||||
|
||||
emu->em_monitor_spare[abs_page]++;
|
||||
if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) {
|
||||
MSG("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page);
|
||||
goto err;
|
||||
}
|
||||
|
||||
uffs_Assert(data != NULL, "BUG: Write spare without data ?");
|
||||
uffs_EccMake(data, data_len, ecc_buf);
|
||||
uffs_FlashMakeSpare(dev, ts, ecc_buf, spare);
|
||||
spare_len = dev->mem.spare_data_size;
|
||||
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
|
||||
written = fwrite(spare, 1, spare_len, emu->fp);
|
||||
if (written != spare_len) {
|
||||
MSG("write spare I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev->st.spare_write_count++;
|
||||
dev->st.io_write += written;
|
||||
}
|
||||
|
||||
if (data == NULL && ts == NULL) {
|
||||
// mark bad block
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
|
||||
written = fwrite("\0", 1, 1, emu->fp);
|
||||
if (written != 1) {
|
||||
MSG("write bad block mark I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
dev->st.io_write++;
|
||||
}
|
||||
|
||||
fflush(emu->fp);
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
err:
|
||||
fflush(emu->fp);
|
||||
return UFFS_FLASH_IO_ERR;
|
||||
}
|
||||
|
||||
|
||||
static URET femu_hw_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,
|
||||
uffs_TagStore *ts, u8 *ecc_store)
|
||||
{
|
||||
int nread;
|
||||
uffs_FileEmu *emu;
|
||||
int abs_page;
|
||||
int full_page_size;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
unsigned char status;
|
||||
u8 spare[UFFS_MAX_SPARE_SIZE];
|
||||
int spare_len;
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
if (!emu || !(emu->fp)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
abs_page = attr->pages_per_block * block + page;
|
||||
full_page_size = attr->page_data_size + attr->spare_size;
|
||||
|
||||
if (data && data_len > 0) {
|
||||
if (data_len > attr->page_data_size)
|
||||
goto err;
|
||||
|
||||
fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
|
||||
nread = fread(data, 1, data_len, emu->fp);
|
||||
|
||||
if (nread != data_len) {
|
||||
MSG("read page I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
dev->st.io_read += nread;
|
||||
dev->st.page_read_count++;
|
||||
|
||||
if (ecc) {
|
||||
// calculate ECC for data
|
||||
uffs_EccMake(data, data_len, ecc);
|
||||
}
|
||||
}
|
||||
|
||||
if (ts) {
|
||||
|
||||
spare_len = dev->mem.spare_data_size;
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
|
||||
nread = fread(spare, 1, spare_len, emu->fp);
|
||||
|
||||
if (nread != spare_len) {
|
||||
MSG("read page spare I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
|
||||
// unload ts and ecc from spare
|
||||
uffs_FlashUnloadSpare(dev, spare, ts, ecc_store);
|
||||
|
||||
dev->st.io_read += nread;
|
||||
dev->st.spare_read_count++;
|
||||
}
|
||||
|
||||
if (data == NULL && ts == NULL) {
|
||||
// read bad block mark
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
|
||||
nread = fread(&status, 1, 1, emu->fp);
|
||||
|
||||
if (nread != 1) {
|
||||
MSG("read badblock mark I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
dev->st.io_read++;
|
||||
|
||||
return status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK;
|
||||
}
|
||||
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
err:
|
||||
return UFFS_FLASH_IO_ERR;
|
||||
}
|
||||
|
||||
|
||||
uffs_FlashOps g_femu_ops_ecc_hw = {
|
||||
femu_InitFlash, // InitFlash()
|
||||
femu_ReleaseFlash, // ReleaseFlash()
|
||||
NULL, // ReadPage()
|
||||
femu_hw_ReadPageWithLayout, // ReadPageWithLayout()
|
||||
NULL, // WritePage()
|
||||
femu_hw_WritePageWithLayout,// WritePageWithLayout()
|
||||
NULL, // IsBadBlock(), let UFFS take care of it.
|
||||
NULL, // MarkBadBlock(), let UFFS take care of it.
|
||||
femu_EraseBlock, // EraseBlock()
|
||||
};
|
||||
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
This file is part of UFFS, the Ultra-low-cost Flash File System.
|
||||
|
||||
Copyright (C) 2005-2010 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_ecc_hw_auto.c
|
||||
*
|
||||
* \brief Emulate uffs file system for auto hardware ECC or RS error collection.
|
||||
*
|
||||
* This emulator emulate LPC32x0 MLC NAND controller which generate 10 bytes
|
||||
* Reed-Solomon error correction code (RS-ECC) for every 518 bytes data.
|
||||
*
|
||||
* For small page MLC have 16 bytes spare area leves only 6 bytes for 'meta-data',
|
||||
* no enough room for UFFS's 8 bytes tag and bad block mark. For this reason,
|
||||
* we adjust page data/spare boundary to 508/20.
|
||||
*
|
||||
* This emulator does not calculate real RS-ECC code, instead, we use software ECC
|
||||
* to calculate 6 bytes ECC code, so this solution does not have the same error
|
||||
* correcting cabability of RS-ECC.
|
||||
*
|
||||
* Note: the MLC controller strictly require sequencial access to serial data buffer.
|
||||
*
|
||||
* \author Ricky Zheng @ Oct, 2010
|
||||
*/
|
||||
|
||||
#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 MSG(msg,...) uffs_PerrorRaw(UFFS_ERR_NORMAL, msg, ## __VA_ARGS__)
|
||||
#define MSGLN(msg,...) uffs_Perror(UFFS_ERR_NORMAL, msg, ## __VA_ARGS__)
|
||||
|
||||
#define RS_ECC_SIZE 10
|
||||
#define PAGE_DATA_SIZE 508
|
||||
#define PAGE_SPARE_SIZE 20
|
||||
#define PAGE_FULL_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
|
||||
static u8 g_sdata_buf[PAGE_FULL_SIZE]; // emulating LPC32x0's 528-bytes serial data buffer
|
||||
|
||||
static int g_sdata_buf_pointer = 0;
|
||||
|
||||
static void start_sdata_access()
|
||||
{
|
||||
g_sdata_buf_pointer = 0;
|
||||
}
|
||||
|
||||
static void feed_sdata(const u8 *data, int len)
|
||||
{
|
||||
uffs_Assert(g_sdata_buf_pointer + len <= sizeof(g_sdata_buf), "BUG: Serial Data Buffer overflow !!");
|
||||
if (data)
|
||||
memcpy(g_sdata_buf + g_sdata_buf_pointer, data, len);
|
||||
g_sdata_buf_pointer += len;
|
||||
}
|
||||
|
||||
static void feed_sdata_constant(u8 val, int num)
|
||||
{
|
||||
uffs_Assert(g_sdata_buf_pointer + num <= sizeof(g_sdata_buf), "BUG: Serial Data Buffer overflow !!");
|
||||
memset(g_sdata_buf + g_sdata_buf_pointer, val, num);
|
||||
g_sdata_buf_pointer += num;
|
||||
}
|
||||
|
||||
static void drain_sdata(u8 *data, int len)
|
||||
{
|
||||
uffs_Assert(sizeof(g_sdata_buf) - g_sdata_buf_pointer >= len, "BUG: Serial Data Buffer overdrain !!");
|
||||
if (data)
|
||||
memcpy(data, g_sdata_buf + g_sdata_buf_pointer, len);
|
||||
g_sdata_buf_pointer += len;
|
||||
}
|
||||
|
||||
static int load_sdata(uffs_Device *dev, int block, int page)
|
||||
{
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
int abs_page;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
int nread;
|
||||
int ret;
|
||||
u8 ecc_buf[RS_ECC_SIZE];
|
||||
u8 *ecc_store;
|
||||
|
||||
abs_page = attr->pages_per_block * block + page;
|
||||
|
||||
fseek(emu->fp, abs_page * PAGE_FULL_SIZE, SEEK_SET);
|
||||
nread = fread(g_sdata_buf, 1, PAGE_FULL_SIZE, emu->fp);
|
||||
g_sdata_buf_pointer = 0;
|
||||
|
||||
ret = ((nread == PAGE_FULL_SIZE) ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR);
|
||||
|
||||
if (ret == UFFS_FLASH_NO_ERR) {
|
||||
|
||||
// Perform ECC check & correction
|
||||
// In the real world, this is done by MLC controller hardware
|
||||
memset(ecc_buf, 0xFF, RS_ECC_SIZE);
|
||||
uffs_EccMake(g_sdata_buf, attr->page_data_size, ecc_buf);
|
||||
|
||||
ecc_store = g_sdata_buf + PAGE_FULL_SIZE - RS_ECC_SIZE;
|
||||
|
||||
ret = uffs_EccCorrect(g_sdata_buf, attr->page_data_size, ecc_store, ecc_buf);
|
||||
|
||||
ret = (ret < 0 ? UFFS_FLASH_ECC_FAIL :
|
||||
(ret > 0 ? UFFS_FLASH_ECC_OK : UFFS_FLASH_NO_ERR));
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int program_sdata(uffs_Device *dev, int block, int page)
|
||||
{
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
int abs_page;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
u8 ecc_buf[RS_ECC_SIZE];
|
||||
int writtern;
|
||||
|
||||
// In the real world, MLC controller will generate RS-ECC code in serial data buffer
|
||||
// and might start auto programing NAND flash. Here, we use software ECC to emulate RS-ECC.
|
||||
memset(ecc_buf, 0xFF, sizeof(ecc_buf));
|
||||
uffs_EccMake(g_sdata_buf, attr->page_data_size, ecc_buf);
|
||||
feed_sdata(ecc_buf, RS_ECC_SIZE);
|
||||
|
||||
uffs_Assert(g_sdata_buf_pointer == PAGE_FULL_SIZE, "Serial Data Buffer is not fully filled !!");
|
||||
|
||||
abs_page = attr->pages_per_block * block + page;
|
||||
|
||||
fseek(emu->fp, abs_page * PAGE_FULL_SIZE, SEEK_SET);
|
||||
writtern = fwrite(g_sdata_buf, 1, PAGE_FULL_SIZE, emu->fp);
|
||||
|
||||
return (writtern == PAGE_FULL_SIZE) ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR;
|
||||
}
|
||||
|
||||
|
||||
static int femu_hw_auto_InitFlash(uffs_Device *dev)
|
||||
{
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
|
||||
// now this is a good chance to adjust page data/spare boundary
|
||||
if (attr->page_data_size + attr->spare_size != PAGE_FULL_SIZE) {
|
||||
MSGLN("This emulator emulates only for page size %d bytes !", PAGE_FULL_SIZE);
|
||||
return -1;
|
||||
}
|
||||
if (attr->spare_size < PAGE_SPARE_SIZE) {
|
||||
attr->page_data_size -= (PAGE_SPARE_SIZE - attr->spare_size);
|
||||
attr->spare_size = PAGE_SPARE_SIZE;
|
||||
MSGLN("Adjust page data/spare boundary to %d/%d", attr->page_data_size, attr->spare_size);
|
||||
}
|
||||
|
||||
// and fix ECC size
|
||||
attr->ecc_size = RS_ECC_SIZE;
|
||||
MSGLN("Adjust ECC size to %d bytes", attr->ecc_size);
|
||||
|
||||
return femu_InitFlash(dev);
|
||||
}
|
||||
|
||||
|
||||
static int femu_hw_auto_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page,
|
||||
const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts)
|
||||
{
|
||||
int abs_page;
|
||||
uffs_FileEmu *emu;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
u8 spare[PAGE_SPARE_SIZE];
|
||||
int ret = UFFS_FLASH_IO_ERR;
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
if (!emu || !(emu->fp)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
abs_page = attr->pages_per_block * block + page;
|
||||
|
||||
start_sdata_access();
|
||||
|
||||
dev->st.page_write_count++;
|
||||
dev->st.spare_write_count++;
|
||||
dev->st.io_write += PAGE_FULL_SIZE;
|
||||
|
||||
if (data || ts) {
|
||||
// normal page write
|
||||
if (data && data_len > 0) {
|
||||
if (data_len > attr->page_data_size)
|
||||
goto err;
|
||||
|
||||
emu->em_monitor_page[abs_page]++;
|
||||
if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) {
|
||||
MSGLN("Warrning: block %d page %d exceed it's maximum write time!", block, page);
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Copy data to serial data buffer
|
||||
feed_sdata(data, data_len);
|
||||
|
||||
// Pad the rest data as 0xFF
|
||||
feed_sdata_constant(0xFF, attr->page_data_size - data_len);
|
||||
|
||||
}
|
||||
else {
|
||||
// We still need to feed data to serial data buffer to make MLC controller happy
|
||||
// The current UFFS won't write ts only, so we'll never run to here.
|
||||
feed_sdata_constant(0xFF, attr->page_data_size);
|
||||
}
|
||||
|
||||
if (ts) {
|
||||
|
||||
emu->em_monitor_spare[abs_page]++;
|
||||
if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) {
|
||||
MSGLN("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page);
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(spare, 0xFF, sizeof(spare));
|
||||
uffs_FlashMakeSpare(dev, ts, NULL, spare); // do not pack ECC, as MLC controller will
|
||||
// automatically write RS-ECC to the latest 10 bytes.
|
||||
|
||||
// feed spare data to serial data buffer
|
||||
feed_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// mark bad block
|
||||
|
||||
// feed data to serial data buffer to make MLC controller happy
|
||||
feed_sdata_constant(0xFF, attr->page_data_size);
|
||||
|
||||
memset(spare, 0xFF, sizeof(spare));
|
||||
spare[attr->block_status_offs] = 0;
|
||||
|
||||
// feed spare data to serial data buffer
|
||||
feed_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE);
|
||||
|
||||
dev->st.io_write++;
|
||||
}
|
||||
|
||||
// now, program serial data buffer to NAND flash
|
||||
ret = program_sdata(dev, block, page);
|
||||
|
||||
fflush(emu->fp);
|
||||
return ret;
|
||||
err:
|
||||
fflush(emu->fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static URET femu_hw_auto_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc,
|
||||
uffs_TagStore *ts, u8 *ecc_store)
|
||||
{
|
||||
uffs_FileEmu *emu;
|
||||
int abs_page;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
unsigned char status;
|
||||
int spare_len;
|
||||
u8 spare[PAGE_SPARE_SIZE];
|
||||
u8 ecc_buf[RS_ECC_SIZE];
|
||||
int ret = UFFS_FLASH_IO_ERR;
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
if (!emu || !(emu->fp)) {
|
||||
goto ext;
|
||||
}
|
||||
|
||||
abs_page = attr->pages_per_block * block + page;
|
||||
|
||||
// now load full page to serial data buffer
|
||||
ret = load_sdata(dev, block, page);
|
||||
if (ret != UFFS_FLASH_NO_ERR)
|
||||
goto ext;
|
||||
|
||||
start_sdata_access();
|
||||
|
||||
dev->st.io_read += PAGE_FULL_SIZE;
|
||||
dev->st.page_read_count++;
|
||||
dev->st.spare_read_count++;
|
||||
|
||||
if (data || ts) {
|
||||
|
||||
if (data && data_len > 0) {
|
||||
if (data_len > attr->page_data_size)
|
||||
goto ext;
|
||||
|
||||
drain_sdata(data, data_len);
|
||||
}
|
||||
|
||||
if (ts) {
|
||||
if (g_sdata_buf_pointer < attr->page_data_size)
|
||||
drain_sdata(NULL, attr->page_data_size - g_sdata_buf_pointer);
|
||||
|
||||
drain_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE);
|
||||
|
||||
// unload ts from spare
|
||||
uffs_FlashUnloadSpare(dev, spare, ts, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// read bad block mark
|
||||
drain_sdata(NULL, attr->page_data_size + attr->block_status_offs - 1);
|
||||
drain_sdata(&status, 1);
|
||||
|
||||
ret = (status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);
|
||||
}
|
||||
|
||||
ext:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uffs_FlashOps g_femu_ops_ecc_hw_auto = {
|
||||
femu_hw_auto_InitFlash, // InitFlash()
|
||||
femu_ReleaseFlash, // ReleaseFlash()
|
||||
NULL, // ReadPage()
|
||||
femu_hw_auto_ReadPageWithLayout, // ReadPageWithLayout()
|
||||
NULL, // WritePage()
|
||||
femu_hw_auto_WritePageWithLayout, // WirtePageWithLayout()
|
||||
NULL, // IsBadBlock(), let UFFS take care of it.
|
||||
NULL, // MarkBadBlock(), let UFFS take care of it.
|
||||
femu_EraseBlock, // EraseBlock()
|
||||
};
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
This file is part of UFFS, the Ultra-low-cost Flash File System.
|
||||
|
||||
Copyright (C) 2005-2010 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_ecc_soft.c
|
||||
* \brief emulate uffs file system for software ECC
|
||||
* \author Ricky Zheng @ Oct, 2010
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "uffs/uffs_device.h"
|
||||
#include "uffs/uffs_flash.h"
|
||||
#include "uffs_fileem.h"
|
||||
|
||||
#define PFX "femu: "
|
||||
#define MSG(msg,...) uffs_PerrorRaw(UFFS_ERR_NORMAL, msg, ## __VA_ARGS__)
|
||||
#define MSGLN(msg,...) uffs_Perror(UFFS_ERR_NORMAL, msg, ## __VA_ARGS__)
|
||||
|
||||
static int femu_WritePage(uffs_Device *dev, u32 block, u32 page_num,
|
||||
const u8 *data, int data_len, const u8 *spare, int spare_len)
|
||||
{
|
||||
int written;
|
||||
int abs_page;
|
||||
int full_page_size;
|
||||
uffs_FileEmu *emu;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
if (!emu || !(emu->fp)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
abs_page = attr->pages_per_block * block + page_num;
|
||||
full_page_size = attr->page_data_size + attr->spare_size;
|
||||
|
||||
if (data && data_len > 0) {
|
||||
if (data_len > attr->page_data_size)
|
||||
goto err;
|
||||
|
||||
emu->em_monitor_page[abs_page]++;
|
||||
if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) {
|
||||
MSGLN("Warrning: block %d page %d exceed it's maximum write time!", block, page_num);
|
||||
goto err;
|
||||
}
|
||||
|
||||
fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
|
||||
|
||||
written = fwrite(data, 1, data_len, emu->fp);
|
||||
|
||||
if (written != data_len) {
|
||||
MSGLN("write page I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev->st.page_write_count++;
|
||||
dev->st.io_write += written;
|
||||
}
|
||||
|
||||
if (spare && spare_len > 0) {
|
||||
if (spare_len > attr->spare_size)
|
||||
goto err;
|
||||
|
||||
emu->em_monitor_spare[abs_page]++;
|
||||
if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) {
|
||||
MSGLN("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page_num);
|
||||
goto err;
|
||||
}
|
||||
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
|
||||
written = fwrite(spare, 1, spare_len, emu->fp);
|
||||
if (written != spare_len) {
|
||||
MSGLN("write spare I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev->st.spare_write_count++;
|
||||
dev->st.io_write += written;
|
||||
}
|
||||
|
||||
if (data == NULL && spare == NULL) {
|
||||
// mark bad block
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
|
||||
written = fwrite("\0", 1, 1, emu->fp);
|
||||
if (written != 1) {
|
||||
MSGLN("write bad block mark I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
dev->st.io_write++;
|
||||
}
|
||||
|
||||
fflush(emu->fp);
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
err:
|
||||
fflush(emu->fp);
|
||||
return UFFS_FLASH_IO_ERR;
|
||||
}
|
||||
|
||||
|
||||
static URET femu_ReadPage(uffs_Device *dev, u32 block, u32 page_num, u8 *data, int data_len, u8 *ecc,
|
||||
u8 *spare, int spare_len)
|
||||
{
|
||||
int nread;
|
||||
uffs_FileEmu *emu;
|
||||
int abs_page;
|
||||
int full_page_size;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
unsigned char status;
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
if (!emu || !(emu->fp)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
abs_page = attr->pages_per_block * block + page_num;
|
||||
full_page_size = attr->page_data_size + attr->spare_size;
|
||||
|
||||
if (data && data_len > 0) {
|
||||
if (data_len > attr->page_data_size)
|
||||
goto err;
|
||||
|
||||
fseek(emu->fp, abs_page * full_page_size, SEEK_SET);
|
||||
nread = fread(data, 1, data_len, emu->fp);
|
||||
|
||||
if (nread != data_len) {
|
||||
MSGLN("read page I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
dev->st.io_read += nread;
|
||||
dev->st.page_read_count++;
|
||||
}
|
||||
|
||||
if (spare && spare_len > 0) {
|
||||
if (spare_len > attr->spare_size)
|
||||
goto err;
|
||||
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET);
|
||||
nread = fread(spare, 1, spare_len, emu->fp);
|
||||
|
||||
if (nread != spare_len) {
|
||||
MSGLN("read page spare I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
dev->st.io_read += nread;
|
||||
dev->st.spare_read_count++;
|
||||
}
|
||||
|
||||
if (data == NULL && spare == NULL) {
|
||||
// read bad block mark
|
||||
fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET);
|
||||
nread = fread(&status, 1, 1, emu->fp);
|
||||
|
||||
if (nread != 1) {
|
||||
MSGLN("read badblock mark I/O error ?");
|
||||
goto err;
|
||||
}
|
||||
dev->st.io_read++;
|
||||
|
||||
return status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK;
|
||||
}
|
||||
|
||||
return UFFS_FLASH_NO_ERR;
|
||||
err:
|
||||
return UFFS_FLASH_IO_ERR;
|
||||
}
|
||||
|
||||
|
||||
uffs_FlashOps g_femu_ops_ecc_soft = {
|
||||
femu_InitFlash, // InitFlash()
|
||||
femu_ReleaseFlash, // ReleaseFlash()
|
||||
femu_ReadPage, // ReadPage()
|
||||
NULL, // ReadPageWithLayout
|
||||
femu_WritePage, // WritePage()
|
||||
NULL, // WirtePageWithLayout
|
||||
NULL, // IsBadBlock(), let UFFS take care of it.
|
||||
NULL, // MarkBadBlock(), let UFFS take care of it.
|
||||
femu_EraseBlock, // EraseBlock()
|
||||
};
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
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_share.c
|
||||
* \brief emulate uffs file system, shared functions
|
||||
* \author Ricky Zheng, created Nov, 2010
|
||||
*/
|
||||
|
||||
|
||||
#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: "
|
||||
|
||||
/****************************************************************/
|
||||
/* Shared flash driver functions: */
|
||||
/* */
|
||||
/* femu_InitFlash(), femu_ReleaseFlash(), femu_EraseBlock() */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
static u8 g_page_buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE];
|
||||
|
||||
/*
|
||||
* Create emulator disk, initialise monitors, inject manufacture bad blocks, etc.
|
||||
*
|
||||
*/
|
||||
int femu_InitFlash(uffs_Device *dev)
|
||||
{
|
||||
int i;
|
||||
int fSize;
|
||||
int written;
|
||||
u8 * p = g_page_buf;
|
||||
uffs_FileEmu *emu;
|
||||
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
|
||||
int full_page_size = attr->page_data_size + attr->spare_size;
|
||||
int blk_size = full_page_size * attr->pages_per_block;
|
||||
int total_pages = attr->total_blocks * attr->pages_per_block;
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
if (emu->initCount > 0) {
|
||||
emu->initCount++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (emu->emu_filename == NULL)
|
||||
emu->emu_filename = UFFS_FEMU_FILE_NAME;
|
||||
|
||||
uffs_Perror(UFFS_ERR_NORMAL, "femu device init.");
|
||||
|
||||
emu->em_monitor_page = (u8 *) malloc(total_pages);
|
||||
if (!emu->em_monitor_page)
|
||||
return -1;
|
||||
emu->em_monitor_spare = (u8 *) malloc(total_pages);
|
||||
if (!emu->em_monitor_spare)
|
||||
return -1;
|
||||
|
||||
|
||||
//clear monitor
|
||||
memset(emu->em_monitor_page, 0, total_pages);
|
||||
memset(emu->em_monitor_spare, 0, total_pages);
|
||||
|
||||
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 -1;
|
||||
}
|
||||
|
||||
fseek(emu->fp, 0, SEEK_END);
|
||||
fSize = ftell(emu->fp);
|
||||
|
||||
if (fSize < total_pages * full_page_size) {
|
||||
printf("Creating uffs emulation file\n");
|
||||
fseek(emu->fp, 0, SEEK_SET);
|
||||
memset(p, 0xff, full_page_size);
|
||||
for (i = 0; i < total_pages; i++) {
|
||||
written = fwrite(p, 1, full_page_size, emu->fp);
|
||||
if (written != full_page_size) {
|
||||
printf("Write failed\n");
|
||||
fclose(emu->fp);
|
||||
emu->fp = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 -1;
|
||||
}
|
||||
|
||||
emu->initCount++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release resources
|
||||
*/
|
||||
int femu_ReleaseFlash(uffs_Device *dev)
|
||||
{
|
||||
uffs_FileEmu *emu;
|
||||
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
emu->initCount--;
|
||||
|
||||
if (emu->initCount == 0) {
|
||||
|
||||
uffs_Perror(UFFS_ERR_NORMAL, "femu device release.");
|
||||
|
||||
if (emu->fp) {
|
||||
fclose(emu->fp);
|
||||
emu->fp = NULL;
|
||||
}
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
||||
int femu_EraseBlock(uffs_Device *dev, u32 blockNumber)
|
||||
{
|
||||
|
||||
int i;
|
||||
u8 * pg = g_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));
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
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_wrap.c
|
||||
*
|
||||
* \brief file emulator wrapper functions for injecting bad blocks or ECC errors.
|
||||
*
|
||||
* \author Ricky Zheng, created Nov, 2010
|
||||
*/
|
||||
|
||||
#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: "
|
||||
|
||||
#ifdef UFFS_FEMU_ENABLE_INJECTION
|
||||
|
||||
struct uffs_FileEmuBitFlip {
|
||||
int block;
|
||||
int page;
|
||||
int offset;
|
||||
u8 mask;
|
||||
};
|
||||
|
||||
/* simulate bad blocks */
|
||||
#define FILEEMU_STOCK_BAD_BLOCKS {5, 18} // bad block come from manufacture
|
||||
#define FILEEMU_ERASE_BAD_BLOCKS {10, 15} // new bad block discovered when erasing
|
||||
|
||||
/* simulating bit flip */
|
||||
#define FILEEMU_WRITE_BIT_FLIP \
|
||||
{ \
|
||||
{2, 2, 10, 1 << 4}, /* block 2, page 2, offset 10, bit 4 */ \
|
||||
{2, 4, -3, 1 << 2}, /* block 2, page 4, spare offset 3, bit 2*/ \
|
||||
{6, 1, 5, 1 << 3}, /* block 6, page 1, offset 5, bit 3 */ \
|
||||
{6, 1, 15, 1 << 7}, /* block 6, page 1, offset 300, bit 7 */ \
|
||||
{8, 2, 2, 1 << 1}, /* block 8, page 2, offset 2, bit 1 */ \
|
||||
{8, 2, 100, 1 << 5},/* block 8, page 2, offset 100, bit 5 */ \
|
||||
}
|
||||
|
||||
|
||||
static int femu_InitFlash_wrap(uffs_Device *dev);
|
||||
|
||||
static int femu_ReadPage_wrap(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
|
||||
u8 *spare, int spare_len);
|
||||
static int femu_WritePage_wrap(uffs_Device *dev, u32 block, u32 page,
|
||||
const u8 *data, int data_len, const u8 *spare, int spare_len);
|
||||
static int femu_WritePageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, const u8* data, int data_len, const u8 *ecc,
|
||||
const uffs_TagStore *ts);
|
||||
static int femu_EraseBlock_wrap(uffs_Device *dev, u32 blockNumber);
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void femu_setup_wrapper_functions(uffs_Device *dev)
|
||||
{
|
||||
uffs_FileEmu *emu;
|
||||
emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
// setup wrap functions, for inject ECC errors, etc.
|
||||
|
||||
memcpy(&emu->ops_orig, dev->ops, sizeof(struct uffs_FlashOpsSt));
|
||||
|
||||
if (dev->ops->InitFlash)
|
||||
dev->ops->InitFlash = femu_InitFlash_wrap;
|
||||
if (dev->ops->EraseBlock)
|
||||
dev->ops->EraseBlock = femu_EraseBlock_wrap;
|
||||
if (dev->ops->ReadPage)
|
||||
dev->ops->ReadPage = femu_ReadPage_wrap;
|
||||
//if (dev->ops->ReadPageWithLayout)
|
||||
// dev->ops->ReadPageWithLayout = femu_ReadPageWithLayout_wrap;
|
||||
if (dev->ops->WritePage)
|
||||
dev->ops->WritePage = femu_WritePage_wrap;
|
||||
if (dev->ops->WritePageWithLayout)
|
||||
dev->ops->WritePageWithLayout = femu_WritePageWithLayout_wrap;
|
||||
}
|
||||
|
||||
static int femu_InitFlash_wrap(uffs_Device *dev)
|
||||
{
|
||||
int ret;
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
#ifdef FILEEMU_STOCK_BAD_BLOCKS
|
||||
int bad_blocks[] = FILEEMU_STOCK_BAD_BLOCKS;
|
||||
int j;
|
||||
u8 x = 0;
|
||||
struct uffs_StorageAttrSt *attr = dev->attr;
|
||||
int full_page_size = attr->page_data_size + attr->spare_size;
|
||||
int blk_size = full_page_size * attr->pages_per_block;
|
||||
#endif
|
||||
|
||||
if (emu->initCount == 0) {
|
||||
ret = emu->ops_orig.InitFlash(dev);
|
||||
#ifdef FILEEMU_STOCK_BAD_BLOCKS
|
||||
if (ret >= 0) {
|
||||
for (j = 0; j < ARRAY_SIZE(bad_blocks); j++) {
|
||||
if (bad_blocks[j] < dev->attr->total_blocks) {
|
||||
printf(" --- manufacture bad block %d ---\n", bad_blocks[j]);
|
||||
fseek(emu->fp, bad_blocks[j] * blk_size + attr->page_data_size + dev->attr->block_status_offs, SEEK_SET);
|
||||
fwrite(&x, 1, 1, emu->fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
ret = emu->ops_orig.InitFlash(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int femu_ReadPage_wrap(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
|
||||
u8 *spare, int spare_len)
|
||||
{
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
//printf("femu: Read block %d page %d data %d spare %d\n", block, page, data_len, spare_len);
|
||||
|
||||
return emu->ops_orig.ReadPage(dev, block, page, data, data_len, ecc, spare, spare_len);
|
||||
}
|
||||
|
||||
////////////////////// wraper functions ///////////////////////////
|
||||
|
||||
static void InjectBitFlip(uffs_Device *dev, u32 block, u32 page)
|
||||
{
|
||||
#ifdef FILEEMU_WRITE_BIT_FLIP
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
struct uffs_FileEmuBitFlip flips[] = FILEEMU_WRITE_BIT_FLIP;
|
||||
struct uffs_FileEmuBitFlip *x;
|
||||
u8 buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE];
|
||||
u8 *data = buf;
|
||||
u8 *spare = buf + dev->attr->page_data_size;
|
||||
int full_page_size = dev->attr->page_data_size + dev->attr->spare_size;
|
||||
int blk_size = full_page_size * dev->attr->pages_per_block;
|
||||
int page_offset = block * blk_size + full_page_size * page;
|
||||
|
||||
int i;
|
||||
u8 *p;
|
||||
|
||||
fseek(emu->fp, page_offset, SEEK_SET);
|
||||
fread(buf, 1, full_page_size, emu->fp);
|
||||
|
||||
p = NULL;
|
||||
for (i = 0; i < ARRAY_SIZE(flips); i++) {
|
||||
x = &flips[i];
|
||||
if (x->block == block && x->page == page) {
|
||||
if (x->offset >= 0) {
|
||||
printf(" --- Inject data bit flip at block%d, page%d, offset%d, mask%d --- \n", block, page, x->offset, x->mask);
|
||||
p = (u8 *)(data + x->offset);
|
||||
}
|
||||
else {
|
||||
printf(" --- Inject spare bit flip at block%d, page%d, offset%d, mask%d --- \n", block, page, -x->offset, x->mask);
|
||||
p = (u8 *)(spare - x->offset);
|
||||
}
|
||||
*p = (*p & ~x->mask) | (~(*p & x->mask) & x->mask);
|
||||
}
|
||||
}
|
||||
|
||||
if (p) {
|
||||
fseek(emu->fp, page_offset, SEEK_SET);
|
||||
fwrite(buf, 1, full_page_size, emu->fp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int femu_WritePage_wrap(uffs_Device *dev, u32 block, u32 page,
|
||||
const u8 *data, int data_len, const u8 *spare, int spare_len)
|
||||
{
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
int ret;
|
||||
|
||||
//printf("femu: Write block %d page %d data %d spare %d\n", block, page, data_len, spare_len);
|
||||
|
||||
ret = emu->ops_orig.WritePage(dev, block, page, data, data_len, spare, spare_len);
|
||||
|
||||
InjectBitFlip(dev, block, page);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int femu_WritePageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, const u8* data, int data_len, const u8 *ecc,
|
||||
const uffs_TagStore *ts)
|
||||
{
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
int ret;
|
||||
|
||||
//printf("femu: Write block %d page %d data %d spare %d\n", block, page, data_len, spare_len);
|
||||
|
||||
ret = emu->ops_orig.WritePageWithLayout(dev, block, page, data, data_len, ecc, ts);
|
||||
|
||||
InjectBitFlip(dev, block, page);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int femu_EraseBlock_wrap(uffs_Device *dev, u32 blockNumber)
|
||||
{
|
||||
uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private);
|
||||
|
||||
#ifdef FILEEMU_ERASE_BAD_BLOCKS
|
||||
int blocks[] = FILEEMU_ERASE_BAD_BLOCKS;
|
||||
int i;
|
||||
URET ret;
|
||||
ret = emu->ops_orig.EraseBlock(dev, blockNumber);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(blocks); i++) {
|
||||
if (blockNumber == blocks[i]) {
|
||||
printf(" --- Inject bad block%d when erasing --- \n", blockNumber);
|
||||
ret = UFFS_FLASH_BAD_BLK;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
#else
|
||||
|
||||
return emu->ops_orig.EraseBlock(dev, blockNumber);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // UFFS_FEMU_ENABLE_INJECTION
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
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 = 0;//time(NULL);
|
||||
|
||||
return (unsigned int)tvalue;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
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)
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
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:"
|
||||
|
||||
struct my_nand_chip {
|
||||
void *IOR_ADDR;
|
||||
void *IOW_ADDR;
|
||||
UBOOL inited;
|
||||
// ...
|
||||
};
|
||||
|
||||
/*
|
||||
* Standard NAND flash commands
|
||||
*/
|
||||
#define NAND_CMD_READ0 0
|
||||
#define NAND_CMD_READ1 1
|
||||
#define NAND_CMD_RNDOUT 5
|
||||
#define NAND_CMD_PAGEPROG 0x10
|
||||
#define NAND_CMD_READOOB 0x50
|
||||
#define NAND_CMD_ERASE1 0x60
|
||||
#define NAND_CMD_STATUS 0x70
|
||||
#define NAND_CMD_STATUS_MULTI 0x71
|
||||
#define NAND_CMD_SEQIN 0x80
|
||||
#define NAND_CMD_RNDIN 0x85
|
||||
#define NAND_CMD_READID 0x90
|
||||
#define NAND_CMD_ERASE2 0xd0
|
||||
#define NAND_CMD_RESET 0xff
|
||||
|
||||
|
||||
/* impelent the following functions for your NAND flash */
|
||||
#define CHIP_SET_CLE(chip) {}
|
||||
#define CHIP_CLR_CLE(chip) {}
|
||||
#define CHIP_SET_ALE(chip) {}
|
||||
#define CHIP_CLR_ALE(chip) {}
|
||||
#define CHIP_SET_NCS(chip) {}
|
||||
#define CHIP_CLR_NCS(chip) {}
|
||||
#define CHIP_BUSY(chip) {}
|
||||
#define CHIP_READY(chip) {}
|
||||
#define WRITE_COMMAND(chip, cmd) {}
|
||||
#define WRITE_DATA_ADDR(chip, block, page, offset) {}
|
||||
#define WRITE_ERASE_ADDR(chip, block) {}
|
||||
#define WRITE_DATA(chip, data, len) {}
|
||||
#define READ_DATA(chip, data, len) {}
|
||||
|
||||
#define PARSE_STATUS(v) (UFFS_FLASH_NO_ERR) // parse status to UFFS_FLASH_NO_ERR or UFFS_FLASH_BAD_BLK
|
||||
|
||||
|
||||
|
||||
#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
|
||||
|
||||
|
||||
static int nand_read_page(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc,
|
||||
u8 *spare, int spare_len)
|
||||
{
|
||||
u8 val = 0;
|
||||
int ret = UFFS_FLASH_NO_ERR;
|
||||
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
|
||||
|
||||
CHIP_CLR_NCS(chip);
|
||||
if (data && data_len > 0) {
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_READ0);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_SET_ALE(chip);
|
||||
WRITE_DATA_ADDR(chip, block, page, 0);
|
||||
CHIP_CLR_ALE(chip);
|
||||
READ_DATA(chip, data, data_len);
|
||||
|
||||
// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
|
||||
memset(data, 0xFF, data_len);
|
||||
}
|
||||
|
||||
if (spare && spare_len > 0) {
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_READOOB);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_SET_ALE(chip);
|
||||
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
|
||||
CHIP_CLR_ALE(chip);
|
||||
READ_DATA(chip, spare, spare_len);
|
||||
|
||||
// for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver
|
||||
memset(spare, 0xFF, spare_len);
|
||||
}
|
||||
|
||||
if (data == NULL && spare == NULL) {
|
||||
// read bad block mark
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_READOOB);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_SET_ALE(chip);
|
||||
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
|
||||
CHIP_CLR_ALE(chip);
|
||||
READ_DATA(chip, &val, 1);
|
||||
ret = (val == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK);
|
||||
|
||||
// for now, we return UFFS_FLASH_NO_ERR to pass UFFS mount, you should remove this at your driver
|
||||
ret = UFFS_FLASH_NO_ERR;
|
||||
}
|
||||
|
||||
CHIP_SET_NCS(chip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nand_write_page(uffs_Device *dev, u32 block, u32 page,
|
||||
const u8 *data, int data_len, const u8 *spare, int spare_len)
|
||||
{
|
||||
u8 val = 0;
|
||||
int ret = UFFS_FLASH_NO_ERR;
|
||||
UBOOL fall_through = FALSE;
|
||||
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
|
||||
|
||||
CHIP_CLR_NCS(chip);
|
||||
|
||||
if (data && data_len > 0) {
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_READ0);
|
||||
WRITE_COMMAND(chip, NAND_CMD_SEQIN);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_SET_ALE(chip);
|
||||
WRITE_DATA_ADDR(chip, block, page, 0);
|
||||
CHIP_CLR_ALE(chip);
|
||||
CHIP_BUSY(chip);
|
||||
WRITE_DATA(chip, data, data_len);
|
||||
if (data_len == dev->attr->page_data_size)
|
||||
fall_through = U_TRUE;
|
||||
else {
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
|
||||
WRITE_COMMAND(chip, NAND_CMD_STATUS);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_READY(chip);
|
||||
READ_DATA(chip, &val, 1);
|
||||
ret = PARSE_STATUS(val);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != UFFS_FLASH_NO_ERR)
|
||||
goto ext;
|
||||
|
||||
if (spare && spare_len > 0) {
|
||||
if (!fall_through) {
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_READOOB);
|
||||
WRITE_COMMAND(chip, NAND_CMD_SEQIN);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_SET_ALE(chip);
|
||||
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size);
|
||||
CHIP_CLR_ALE(chip);
|
||||
CHIP_BUSY(chip);
|
||||
}
|
||||
WRITE_DATA(chip, spare, spare_len);
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
|
||||
WRITE_COMMAND(chip, NAND_CMD_STATUS);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_READY(chip);
|
||||
READ_DATA(chip, &val, 1);
|
||||
ret = PARSE_STATUS(val);
|
||||
}
|
||||
|
||||
if (data == NULL && spare == NULL) {
|
||||
// mark bad block
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_READOOB);
|
||||
WRITE_COMMAND(chip, NAND_CMD_SEQIN);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_SET_ALE(chip);
|
||||
WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs);
|
||||
CHIP_CLR_ALE(chip);
|
||||
CHIP_BUSY(chip);
|
||||
val = 0;
|
||||
WRITE_DATA(chip, &val, 1);
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_PAGEPROG);
|
||||
WRITE_COMMAND(chip, NAND_CMD_STATUS);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_READY(chip);
|
||||
READ_DATA(chip, &val, 1);
|
||||
ret = PARSE_STATUS(val);
|
||||
}
|
||||
|
||||
ext:
|
||||
CHIP_SET_NCS(chip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nand_erase_block(uffs_Device *dev, u32 block)
|
||||
{
|
||||
u8 val;
|
||||
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
|
||||
|
||||
CHIP_CLR_NCS(chip);
|
||||
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_ERASE1);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_SET_ALE(chip);
|
||||
WRITE_ERASE_ADDR(chip, blcok);
|
||||
CHIP_CLR_ALE(chip);
|
||||
CHIP_SET_CLE(chip);
|
||||
WRITE_COMMAND(chip, NAND_CMD_ERASE2);
|
||||
WRITE_COMMAND(chip, NAND_CMD_STATUS);
|
||||
CHIP_CLR_CLE(chip);
|
||||
CHIP_READY(chip);
|
||||
READ_DATA(chip, &val, 1);
|
||||
|
||||
CHIP_SET_NCS(chip);
|
||||
|
||||
return PARSE_STATUS(val);
|
||||
}
|
||||
|
||||
|
||||
static int nand_init_flash(uffs_Device *dev)
|
||||
{
|
||||
// initialize your hardware here ...
|
||||
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
|
||||
|
||||
if (!chip->inited) {
|
||||
// setup chip I/O address, setup NAND flash controller ... etc.
|
||||
// chip->IOR_ADDR = 0xF0000000
|
||||
// chip->IOW_ADDR = 0xF0000000
|
||||
chip->inited = U_TRUE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nand_release_flash(uffs_Device *dev)
|
||||
{
|
||||
// release your hardware here
|
||||
struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uffs_FlashOps g_my_nand_ops = {
|
||||
nand_init_flash, // InitFlash()
|
||||
nand_release_flash, // ReleaseFlash()
|
||||
nand_read_page, // ReadPage()
|
||||
NULL, // ReadPageWithLayout
|
||||
nand_write_page, // WritePage()
|
||||
NULL, // WirtePageWithLayout
|
||||
NULL, // IsBadBlock(), let UFFS take care of it.
|
||||
NULL, // MarkBadBlock(), let UFFS take care of it.
|
||||
nand_erase_block, // EraseBlock()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// change these parameters to fit your nand flash specification
|
||||
|
||||
#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 */
|
||||
|
||||
struct my_nand_chip g_nand_chip = {0};
|
||||
static struct uffs_StorageAttrSt g_my_flash_storage = {0};
|
||||
|
||||
/* 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 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 init_nand_chip(struct my_nand_chip *chip)
|
||||
{
|
||||
// init chip IO address, etc.
|
||||
}
|
||||
|
||||
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->attr = &g_my_flash_storage;
|
||||
dev->attr->_private = (void *) &g_nand_chip; // hook nand_chip data structure to attr->_private
|
||||
dev->ops = &g_my_nand_ops;
|
||||
|
||||
return U_SUCC;
|
||||
}
|
||||
|
||||
static URET my_ReleaseDevice(uffs_Device *dev)
|
||||
{
|
||||
return U_SUCC;
|
||||
}
|
||||
|
||||
|
||||
static int my_init_filesystem(void)
|
||||
{
|
||||
uffs_MountTable *mtbl = &(demo_mount_table[0]);
|
||||
|
||||
/* setup nand storage attributes */
|
||||
setup_flash_storage(&g_my_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) {
|
||||
// setup device init/release entry
|
||||
mtbl->dev->Init = my_InitDevice;
|
||||
mtbl->dev->Release = my_ReleaseDevice;
|
||||
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
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
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, one partition only.
|
||||
* \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 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 alloc the memory */
|
||||
static int static_buffer_pool[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, TOTAL_BLOCKS) / sizeof(int)];
|
||||
|
||||
|
||||
static void setup_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; /* use UFFS software ecc */
|
||||
attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
|
||||
}
|
||||
|
||||
static void setup_device(uffs_Device *dev)
|
||||
{
|
||||
// using file emulator device
|
||||
dev->Init = femu_InitDevice;
|
||||
dev->Release = femu_ReleaseDevice;
|
||||
dev->attr = femu_GetStorage();
|
||||
}
|
||||
|
||||
static int init_uffs_fs(void)
|
||||
{
|
||||
struct uffs_MountTableEntrySt *mtbl = &demo_mount;
|
||||
|
||||
/* setup flash storage attributes */
|
||||
setup_storage(femu_GetStorage());
|
||||
|
||||
/* setup memory allocator */
|
||||
uffs_MemSetupStaticAllocator(&mtbl->dev->mem, static_buffer_pool, sizeof(static_buffer_pool));
|
||||
|
||||
/* setup device: init, release, attr */
|
||||
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());
|
||||
cli_add_commandset(get_test_cmds());
|
||||
cliMain();
|
||||
|
||||
release_uffs_fs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
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 <rtthread.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
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,277 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
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 */
|
||||
u16 d_reclen; /* length of this uffs_dirent */
|
||||
u16 d_namelen; /* length of this d_name */
|
||||
u32 d_type; /* type of this record ,ÒªÓëinfo.attrµÄÀàÐͱ£³ÖÒ»ÖÂ*/
|
||||
};
|
||||
|
||||
/**
|
||||
* \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 */
|
||||
};
|
||||
|
||||
|
||||
int uffs_InitDirEntryBuf(void);
|
||||
int 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);
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
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_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
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
|
||||
@@ -1,274 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
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_fs.h
|
||||
* \brief uffs basic file operations
|
||||
* \author Ricky Zheng
|
||||
*/
|
||||
|
||||
#ifndef _UFFS_FS_H_
|
||||
#define _UFFS_FS_H_
|
||||
|
||||
#include "uffs/uffs_types.h"
|
||||
#include "uffs/uffs.h"
|
||||
#include "uffs/uffs_public.h"
|
||||
#include "uffs/uffs_core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
|
||||
/** file object */
|
||||
struct uffs_ObjectSt {
|
||||
/******* objects manager ********/
|
||||
int dev_lock_count;
|
||||
int dev_get_count;
|
||||
|
||||
/******** init level 0 ********/
|
||||
const char * name; //!< pointer to the start of name, for open or create
|
||||
u32 name_len; //!< name length
|
||||
u16 sum; //!< sum of name
|
||||
uffs_Device *dev; //!< uffs device
|
||||
u32 oflag;
|
||||
u8 type;
|
||||
u16 head_pages; //!< data pages on file head block
|
||||
u16 parent;
|
||||
|
||||
/******* init level 1 ********/
|
||||
TreeNode *node; //!< file entry node in tree
|
||||
u16 serial;
|
||||
|
||||
/******* output ******/
|
||||
int err; //!< error number
|
||||
|
||||
/******* current *******/
|
||||
u32 pos; //!< current position in file
|
||||
|
||||
/***** others *******/
|
||||
UBOOL attr_loaded; //!< attributes loaded ?
|
||||
UBOOL open_succ; //!< U_TRUE or U_FALSE
|
||||
|
||||
};
|
||||
|
||||
typedef struct uffs_ObjectSt uffs_Object;
|
||||
|
||||
|
||||
|
||||
#define uffs_GetObjectErr(obj) ((obj)->err)
|
||||
#define uffs_ClearObjectErr(obj) do { (obj)->err = UENOERR; } while (0)
|
||||
|
||||
uffs_Pool * uffs_GetObjectPool(void);
|
||||
|
||||
URET uffs_InitObjectBuf(void);
|
||||
URET uffs_ReleaseObjectBuf(void);
|
||||
uffs_Object * uffs_GetObject(void);
|
||||
void uffs_PutObject(uffs_Object *obj);
|
||||
int uffs_GetObjectIndex(uffs_Object *obj);
|
||||
uffs_Object * uffs_GetObjectByIndex(int idx);
|
||||
|
||||
|
||||
/**
|
||||
* Re-initialize an object.
|
||||
* should call this function if you want to re-use an object.
|
||||
*/
|
||||
URET uffs_ReInitObject(uffs_Object *obj);
|
||||
|
||||
URET uffs_ParseObject(uffs_Object *obj, const char *name);
|
||||
|
||||
URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev,
|
||||
int dir, const char *name, int name_len, int oflag);
|
||||
URET uffs_OpenObjectEx(uffs_Object *obj, uffs_Device *dev,
|
||||
int dir, const char *name, int name_len, int oflag);
|
||||
|
||||
URET uffs_OpenObject(uffs_Object *obj, const char *fullname, int oflag);
|
||||
URET uffs_TruncateObject(uffs_Object *obj, u32 remain);
|
||||
URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag);
|
||||
|
||||
URET uffs_CloseObject(uffs_Object *obj);
|
||||
int uffs_WriteObject(uffs_Object *obj, const void *data, int len);
|
||||
int uffs_ReadObject(uffs_Object *obj, void *data, int len);
|
||||
long uffs_SeekObject(uffs_Object *obj, long offset, int origin);
|
||||
int uffs_GetCurOffset(uffs_Object *obj);
|
||||
int uffs_EndOfFile(uffs_Object *obj);
|
||||
URET uffs_FlushObject(uffs_Object *obj);
|
||||
|
||||
URET uffs_RenameObject(const char *old_name, const char *new_name, int *err);
|
||||
URET uffs_DeleteObject(const char * name, int *err);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
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_MEM_H
|
||||
#define UFFS_MEM_H
|
||||
|
||||
#include "uffs/uffs_device.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#define MAX_ECC_SIZE (3 * UFFS_MAX_PAGE_SIZE / 256)
|
||||
#define MAX_SPARE_SIZE (8 * UFFS_MAX_PAGE_SIZE / 256)
|
||||
#define MAX_SPARE_BUF 10
|
||||
|
||||
|
||||
#if CONFIG_USE_NATIVE_MEMORY_ALLOCATOR > 0
|
||||
|
||||
#define HEAP_HASH_BIT 6 /* hash table bit */
|
||||
#define HEAP_HASH_SIZE (1 << (HEAP_HASH_BIT - 1)) /* hash table size */
|
||||
#define HEAP_HASH_MASK (HEAP_HASH_SIZE - 1) /* hash table mask */
|
||||
#define GET_HASH_INDEX(p) ((((unsigned long)(p)) >> 2) & HEAP_HASH_MASK)
|
||||
|
||||
/* memory alloc node */
|
||||
typedef struct HeapManagementNodeSt{
|
||||
int task_id; /* who alloc this block? it's the caller's task id */
|
||||
struct HeapManagementNodeSt * next; /* point to next node */
|
||||
void *p; /* point to allocated block */
|
||||
int size; /* block size */
|
||||
} HeapMm;
|
||||
|
||||
typedef HeapMm* HeapHashTable;
|
||||
|
||||
/** \note: uffs_MemInitHeap should be called before using native memory allocator on each device */
|
||||
void uffs_MemInitHeap(void *addr, int size);
|
||||
|
||||
URET uffs_MemInitNativeAllocator(uffs_Device *dev);
|
||||
int uffs_MemReleaseNativeAllocator(uffs_Device *dev);
|
||||
|
||||
#endif //CONFIG_USE_NATIVE_MEMORY_ALLOCATOR
|
||||
|
||||
|
||||
/** uffs native memory allocator */
|
||||
typedef struct uffs_memAllocatorSt {
|
||||
URET (*init)(struct uffs_DeviceSt *dev); /* init memory allocator, setup buffer sizes */
|
||||
URET (*release)(struct uffs_DeviceSt *dev); /* release memory allocator (for dynamic memory allocation) */
|
||||
|
||||
void * (*malloc)(struct uffs_DeviceSt *dev, unsigned int size); /* allocate memory (for dynamic memory allocation) */
|
||||
URET (*free)(struct uffs_DeviceSt *dev, void *p); /* free memory (for dynamic memory allocation) */
|
||||
|
||||
void * blockinfo_pool_buf; //!< block info cache buffers
|
||||
void * pagebuf_pool_buf; //!< page buffers
|
||||
void * tree_nodes_pool_buf; //!< tree nodes buffer
|
||||
void * spare_pool_buf; //!< spare buffers
|
||||
|
||||
int blockinfo_pool_size; //!< block info cache buffers size
|
||||
int pagebuf_pool_size; //!< page buffers size
|
||||
int tree_nodes_pool_size; //!< tree nodes buffer size
|
||||
int spare_pool_size; //!< spare buffer pool size
|
||||
|
||||
uffs_Pool tree_pool;
|
||||
uffs_Pool spare_pool;
|
||||
|
||||
int spare_data_size; //!< spare data size, calculated by UFFS.
|
||||
|
||||
|
||||
#if CONFIG_USE_NATIVE_MEMORY_ALLOCATOR > 0
|
||||
HeapHashTable tbl[HEAP_HASH_SIZE];
|
||||
int count;
|
||||
int maxused;
|
||||
#endif
|
||||
|
||||
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0
|
||||
char *buf_start;
|
||||
int buf_size;
|
||||
int pos;
|
||||
#endif
|
||||
|
||||
} uffs_MemAllocator;
|
||||
|
||||
|
||||
#if CONFIG_USE_NATIVE_MEMORY_ALLOCATOR > 0
|
||||
void uffs_MemSetupNativeAllocator(uffs_MemAllocator *allocator);
|
||||
#endif
|
||||
|
||||
#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0
|
||||
void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator);
|
||||
#endif
|
||||
|
||||
#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0
|
||||
void uffs_MemSetupStaticAllocator(uffs_MemAllocator *allocator, void *pool, int size);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
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_mtb.h
|
||||
* \brief mount table related stuff
|
||||
* \author Ricky Zheng
|
||||
*/
|
||||
|
||||
#ifndef UFFS_MTB_H
|
||||
#define UFFS_MTB_H
|
||||
|
||||
#include "uffs/uffs_types.h"
|
||||
#include "uffs/uffs_config.h"
|
||||
#include "uffs/uffs_core.h"
|
||||
#include "uffs/uffs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct uffs_MountTableEntrySt {
|
||||
uffs_Device *dev;
|
||||
int start_block;
|
||||
int end_block;
|
||||
const char *mount;
|
||||
struct uffs_MountTableEntrySt *next;
|
||||
} uffs_MountTable;
|
||||
|
||||
/** initialize registered mount table */
|
||||
URET uffs_InitMountTable(void);
|
||||
|
||||
/** release registered mount table */
|
||||
URET uffs_ReleaseMountTable(void);
|
||||
|
||||
/** get registered mount table */
|
||||
uffs_MountTable * uffs_GetMountTable(void);
|
||||
|
||||
/** register mount table */
|
||||
int uffs_RegisterMountTable(uffs_MountTable *mtab);
|
||||
|
||||
/** get matched mount point from absolute path */
|
||||
int uffs_GetMatchedMountPointSize(const char *path);
|
||||
|
||||
/** get uffs device from mount point */
|
||||
uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount);
|
||||
|
||||
/** get uffs device from mount point */
|
||||
uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len);
|
||||
|
||||
/** get mount point name from uffs device */
|
||||
const char * uffs_GetDeviceMountPoint(uffs_Device *dev);
|
||||
|
||||
/** down crease uffs device references by uffs_GetDeviceXXX() */
|
||||
void uffs_PutDevice(uffs_Device *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user