mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 09:38:32 -04:00
Update version numbers in preparation for new release.
This commit is contained in:
parent
b4c3d91aff
commit
99d4f2c454
1451 changed files with 31767 additions and 11220 deletions
|
@ -53,8 +53,8 @@
|
|||
|
||||
/* If the application writer needs to place the buffer used by the CLI at a
|
||||
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in
|
||||
FreeRTOSConfig.h, and provide then declare an array as follows with the
|
||||
following name and size in one of the application files:
|
||||
FreeRTOSConfig.h, then declare an array with the following name and size in
|
||||
one of the application files:
|
||||
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
|
||||
*/
|
||||
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer
|
||||
|
|
18
FreeRTOS-Plus/Source/Reliance-Edge/CREDITS.txt
Normal file
18
FreeRTOS-Plus/Source/Reliance-Edge/CREDITS.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
Reliance Edge Credits
|
||||
=====================
|
||||
|
||||
This is a list (or partial list) of people who have made non-trivial or
|
||||
noteworthy contributions to the Reliance Edge project. It is sorted by name.
|
||||
Entries are formatted as below:
|
||||
|
||||
Real Name (githubaccount)
|
||||
Short description of how Real Name contributed to Reliance Edge.
|
||||
|
||||
The real name may be withheld by request and the GitHub account name might be
|
||||
missing if the contributor does not use GitHub.
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
None yet! ;)
|
||||
|
340
FreeRTOS-Plus/Source/Reliance-Edge/LICENSE.txt
Normal file
340
FreeRTOS-Plus/Source/Reliance-Edge/LICENSE.txt
Normal file
|
@ -0,0 +1,340 @@
|
|||
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.
|
||||
|
115
FreeRTOS-Plus/Source/Reliance-Edge/README.md
Normal file
115
FreeRTOS-Plus/Source/Reliance-Edge/README.md
Normal file
|
@ -0,0 +1,115 @@
|
|||
# Reliance Edge
|
||||
|
||||
Reliance Edge is a small, portable, highly reliable power-fail safe file system
|
||||
for resource-constrained embedded systems like microcontrollers. It is written
|
||||
in C and provides a familiar POSIX-like file system API, making it easy to use
|
||||
in your application; or an alternate minimalist API if your application has
|
||||
simple storage needs. Reliance Edge is highly configurable and can be tuned to
|
||||
the precise needs of your application.
|
||||
|
||||
## Documentation
|
||||
|
||||
The complete documentation for Reliance Edge is distributed separately. It
|
||||
includes an API reference and detailed discussions of various aspects of using
|
||||
Reliance Edge, including porting, building, configuring, and testing. This
|
||||
complete documentation, called the _Developer's Guide_, can be obtained for free
|
||||
from here:
|
||||
|
||||
<http://www.datalight.com/reliance-edge>
|
||||
|
||||
In addition this README, see [doc/release_notes.md](doc/release_notes.md) for a
|
||||
list of updates to Reliance Edge and a list of known issues. There is also a
|
||||
quick-start guide in the doc/ directory that describes step-by-step how to
|
||||
compile and run Reliance Edge in a simulated Windows environment.
|
||||
|
||||
## Why Use Reliance Edge?
|
||||
|
||||
Reliance Edge is ideal for small embedded systems with data storage
|
||||
requirements, especially if there is a chance of sudden power loss or other
|
||||
system failures. Compared to "raw" disk access, using a file system like
|
||||
Reliance Edge removes the burden of tracking which sectors belong to which
|
||||
objects, and allows data to be updated more reliably. Compared to the FAT file
|
||||
system, using Reliance Edge eliminates the possibility that file system data
|
||||
will be left in an inconsistent state, corrupting the disk; Reliance Edge does
|
||||
not need a fsck/CHKDSK utility. Compared to journaling file systems, Reliance
|
||||
Edge has less overhead and results in less storage media wear for longer device
|
||||
lifetimes.
|
||||
|
||||
Reliance Edge uses a unique transactional model that not only prevents file
|
||||
system corruption but also allows a set of changes to be made in an atomic "all
|
||||
or nothing" fashion. This is very useful for applications that make sets of
|
||||
interrelated changes. By using the features of Reliance Edge, a set of changes
|
||||
can be incorporated into a single atomic transaction, which is committed in its
|
||||
entirety or not at all even if interrupted by power loss; this means the
|
||||
application does not need code to recover from partially-finished updates.
|
||||
|
||||
## Hardware
|
||||
|
||||
The typical hardware for Reliance Edge is a 32-bit microcontroller, but other
|
||||
targets are possible. In its typical configurations, Reliance Edge needs at
|
||||
least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the ROM or NOR flash),
|
||||
and 500 to 700 bytes of stack.
|
||||
|
||||
Reliance Edge is not designed for high-end embedded systems that run complicated
|
||||
operating systems like Linux or Windows Embedded Compact. Embedded systems of
|
||||
that variety are better served by other file systems, like Datalight's
|
||||
[Reliance Nitro](http://www.datalight.com/products/embedded-file-systems/reliance-nitro).
|
||||
|
||||
## Getting Reliance Edge Working
|
||||
|
||||
Before you can use Reliance Edge, it must be ported and configured. At a
|
||||
minimum, porting includes filling-in functions so that Reliance Edge can issue
|
||||
commands to your storage medium; depending on your needs, other functions may
|
||||
need to be filled in as well. These functions reside in a subdirectory in the
|
||||
os/ directory; see os/stub/ for a blank set of functions. Configuring includes
|
||||
creating a project directory (start by copying projects/newproj) and creating
|
||||
the two configuration files (redconf.h/redconf.c) using the Reliance Edge
|
||||
Configuration Utility (which can be downloaded from
|
||||
<http://www.datalight.com/reliance-edge>).
|
||||
|
||||
These topics are covered in much greater detail in the _Developer's Guide_,
|
||||
linked above.
|
||||
|
||||
## Using Reliance Edge
|
||||
|
||||
Using Reliance Edge is a simple matter of including the primary Reliance Edge
|
||||
application header in your application (either include/redposix.h or
|
||||
include/redfse.h) and compiling and linking against Reliance Edge binaries.
|
||||
The Reliance Edge driver must be initialized before it is used (via the
|
||||
red\_init() or RedFseInit() functions) and then volumes can be mounted and file
|
||||
and directory functions invoked. The Reliance Edge API is documented in the
|
||||
_Developer's Guide_ (linked above) and also via comments in the source code.
|
||||
|
||||
## Licensing
|
||||
|
||||
Reliance Edge is an open-source project licensed under the GNU General Public
|
||||
License v2 (GPLv2). Businesses and individuals that for commercial or other
|
||||
reasons cannot comply with the terms of the GPLv2 license may obtain a
|
||||
commercial license before incorporating Reliance Edge into proprietary software
|
||||
for distribution in any form. Visit <http://www.datalight.com/reliance-edge>
|
||||
for more information. The commercial distribution also includes extra tests and
|
||||
tools not distributed with the GPLv2 version.
|
||||
|
||||
See LICENSE.txt for the full license terms of this distribution of the product.
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you need assistance using Reliance Edge, and you have already consulted the
|
||||
_Developer's Guide_, contact <RelianceEdgeSupport@datalight.com>.
|
||||
|
||||
In the near future, a community forum or message board will be set up to
|
||||
facilitate discussion of Reliance Edge and allow users to get help from
|
||||
Datalight and from each other. In the meantime, please use the email address
|
||||
given above.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to Reliance Edge are welcome. Our policy is that Datalight must
|
||||
own the copyright of all code incorporated into Reliance Edge; if contributing a
|
||||
significant amount of code, you will be asked to file a copyright assignment
|
||||
agreement. See CONTRIBUTING.txt for further details and contribution
|
||||
guidelines.
|
||||
|
||||
To report bugs, please create a GitHub issue or contact
|
||||
<RelianceEdgeSupport@datalight.com>.
|
||||
|
131
FreeRTOS-Plus/Source/Reliance-Edge/README.txt
Normal file
131
FreeRTOS-Plus/Source/Reliance-Edge/README.txt
Normal file
|
@ -0,0 +1,131 @@
|
|||
|
||||
|
||||
RELIANCE EDGE
|
||||
|
||||
|
||||
Reliance Edge is a small, portable, highly reliable power-fail safe file
|
||||
system for resource-constrained embedded systems like microcontrollers.
|
||||
It is written in C and provides a familiar POSIX-like file system API,
|
||||
making it easy to use in your application; or an alternate minimalist
|
||||
API if your application has simple storage needs. Reliance Edge is
|
||||
highly configurable and can be tuned to the precise needs of your
|
||||
application.
|
||||
|
||||
|
||||
Documentation
|
||||
|
||||
The complete documentation for Reliance Edge is distributed separately.
|
||||
It includes an API reference and detailed discussions of various aspects
|
||||
of using Reliance Edge, including porting, building, configuring, and
|
||||
testing. This complete documentation, called the _Developer's Guide_,
|
||||
can be obtained for free from here:
|
||||
|
||||
http://www.datalight.com/reliance-edge
|
||||
|
||||
In addition this README, see doc/release_notes.md for a list of updates
|
||||
to Reliance Edge and a list of known issues. There is also a quick-start
|
||||
guide in the doc/ directory that describes step-by-step how to compile
|
||||
and run Reliance Edge in a simulated Windows environment.
|
||||
|
||||
|
||||
Why Use Reliance Edge?
|
||||
|
||||
Reliance Edge is ideal for small embedded systems with data storage
|
||||
requirements, especially if there is a chance of sudden power loss or
|
||||
other system failures. Compared to "raw" disk access, using a file
|
||||
system like Reliance Edge removes the burden of tracking which sectors
|
||||
belong to which objects, and allows data to be updated more reliably.
|
||||
Compared to the FAT file system, using Reliance Edge eliminates the
|
||||
possibility that file system data will be left in an inconsistent state,
|
||||
corrupting the disk; Reliance Edge does not need a fsck/CHKDSK utility.
|
||||
Compared to journaling file systems, Reliance Edge has less overhead and
|
||||
results in less storage media wear for longer device lifetimes.
|
||||
|
||||
Reliance Edge uses a unique transactional model that not only prevents
|
||||
file system corruption but also allows a set of changes to be made in an
|
||||
atomic "all or nothing" fashion. This is very useful for applications
|
||||
that make sets of interrelated changes. By using the features of
|
||||
Reliance Edge, a set of changes can be incorporated into a single atomic
|
||||
transaction, which is committed in its entirety or not at all even if
|
||||
interrupted by power loss; this means the application does not need code
|
||||
to recover from partially-finished updates.
|
||||
|
||||
|
||||
Hardware
|
||||
|
||||
The typical hardware for Reliance Edge is a 32-bit microcontroller, but
|
||||
other targets are possible. In its typical configurations, Reliance Edge
|
||||
needs at least 4 KB to 5 KB of RAM, 11 to 18 KB of code space (on the
|
||||
ROM or NOR flash), and 500 to 700 bytes of stack.
|
||||
|
||||
Reliance Edge is not designed for high-end embedded systems that run
|
||||
complicated operating systems like Linux or Windows Embedded Compact.
|
||||
Embedded systems of that variety are better served by other file
|
||||
systems, like Datalight's Reliance Nitro.
|
||||
|
||||
|
||||
Getting Reliance Edge Working
|
||||
|
||||
Before you can use Reliance Edge, it must be ported and configured. At a
|
||||
minimum, porting includes filling-in functions so that Reliance Edge can
|
||||
issue commands to your storage medium; depending on your needs, other
|
||||
functions may need to be filled in as well. These functions reside in a
|
||||
subdirectory in the os/ directory; see os/stub/ for a blank set of
|
||||
functions. Configuring includes creating a project directory (start by
|
||||
copying projects/newproj) and creating the two configuration files
|
||||
(redconf.h/redconf.c) using the Reliance Edge Configuration Utility
|
||||
(which can be downloaded from http://www.datalight.com/reliance-edge).
|
||||
|
||||
These topics are covered in much greater detail in the _Developer's
|
||||
Guide_, linked above.
|
||||
|
||||
|
||||
Using Reliance Edge
|
||||
|
||||
Using Reliance Edge is a simple matter of including the primary Reliance
|
||||
Edge application header in your application (either include/redposix.h
|
||||
or include/redfse.h) and compiling and linking against Reliance Edge
|
||||
binaries. The Reliance Edge driver must be initialized before it is used
|
||||
(via the red_init() or RedFseInit() functions) and then volumes can be
|
||||
mounted and file and directory functions invoked. The Reliance Edge API
|
||||
is documented in the _Developer's Guide_ (linked above) and also via
|
||||
comments in the source code.
|
||||
|
||||
|
||||
Licensing
|
||||
|
||||
Reliance Edge is an open-source project licensed under the GNU General
|
||||
Public License v2 (GPLv2). Businesses and individuals that for
|
||||
commercial or other reasons cannot comply with the terms of the GPLv2
|
||||
license may obtain a commercial license before incorporating Reliance
|
||||
Edge into proprietary software for distribution in any form. Visit
|
||||
http://www.datalight.com/reliance-edge for more information. The
|
||||
commercial distribution also includes extra tests and tools not
|
||||
distributed with the GPLv2 version.
|
||||
|
||||
See LICENSE.txt for the full license terms of this distribution of the
|
||||
product.
|
||||
|
||||
|
||||
Getting Help
|
||||
|
||||
If you need assistance using Reliance Edge, and you have already
|
||||
consulted the _Developer's Guide_, contact
|
||||
RelianceEdgeSupport@datalight.com.
|
||||
|
||||
In the near future, a community forum or message board will be set up to
|
||||
facilitate discussion of Reliance Edge and allow users to get help from
|
||||
Datalight and from each other. In the meantime, please use the email
|
||||
address given above.
|
||||
|
||||
|
||||
Contributing
|
||||
|
||||
Contributions to Reliance Edge are welcome. Our policy is that Datalight
|
||||
must own the copyright of all code incorporated into Reliance Edge; if
|
||||
contributing a significant amount of code, you will be asked to file a
|
||||
copyright assignment agreement. See CONTRIBUTING.txt for further details
|
||||
and contribution guidelines.
|
||||
|
||||
To report bugs, please create a GitHub issue or contact
|
||||
RelianceEdgeSupport@datalight.com.
|
164
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/blockio.c
Normal file
164
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/blockio.c
Normal file
|
@ -0,0 +1,164 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements block device I/O using logical blocks as the units.
|
||||
|
||||
The OS block device implementations operate on sectors. The core does I/O
|
||||
in terms of logical blocks: this module translates from logical blocks to
|
||||
sectors.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redcore.h>
|
||||
|
||||
|
||||
/** @brief Read a range of logical blocks.
|
||||
|
||||
@param bVolNum The volume whose block device is being read from.
|
||||
@param ulBlockStart The first block to read.
|
||||
@param ulBlockCount The number of blocks to read.
|
||||
@param pBuffer The buffer to populate with the data read.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_EINVAL Invalid parameters.
|
||||
*/
|
||||
REDSTATUS RedIoRead(
|
||||
uint8_t bVolNum,
|
||||
uint32_t ulBlockStart,
|
||||
uint32_t ulBlockCount,
|
||||
void *pBuffer)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( (bVolNum >= REDCONF_VOLUME_COUNT)
|
||||
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
|
||||
|| ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
|
||||
|| (ulBlockCount == 0U)
|
||||
|| (pBuffer == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
|
||||
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
|
||||
uint32_t ulSectorCount = ulBlockCount << bSectorShift;
|
||||
|
||||
REDASSERT(bSectorShift < 32U);
|
||||
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
|
||||
|
||||
ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
|
||||
}
|
||||
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Write a range of logical blocks.
|
||||
|
||||
@param bVolNum The volume whose block device is being written to.
|
||||
@param ulBlockStart The first block to write.
|
||||
@param ulBlockCount The number of blocks to write.
|
||||
@param pBuffer The buffer containing the data to write.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_EINVAL Invalid parameters.
|
||||
*/
|
||||
REDSTATUS RedIoWrite(
|
||||
uint8_t bVolNum,
|
||||
uint32_t ulBlockStart,
|
||||
uint32_t ulBlockCount,
|
||||
const void *pBuffer)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( (bVolNum >= REDCONF_VOLUME_COUNT)
|
||||
|| (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount)
|
||||
|| ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount)
|
||||
|| (ulBlockCount == 0U)
|
||||
|| (pBuffer == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift;
|
||||
uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift;
|
||||
uint32_t ulSectorCount = ulBlockCount << bSectorShift;
|
||||
|
||||
REDASSERT(bSectorShift < 32U);
|
||||
REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount);
|
||||
|
||||
ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer);
|
||||
}
|
||||
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Flush any caches beneath the file system.
|
||||
|
||||
@param bVolNum The volume number of the volume whose block device is being
|
||||
flushed.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedIoFlush(
|
||||
uint8_t bVolNum)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if(bVolNum >= REDCONF_VOLUME_COUNT)
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RedOsBDevFlush(bVolNum);
|
||||
}
|
||||
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* REDCONF_READ_ONLY == 0 */
|
||||
|
1212
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/buffer.c
Normal file
1212
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/buffer.c
Normal file
File diff suppressed because it is too large
Load diff
1921
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/core.c
Normal file
1921
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/core.c
Normal file
File diff suppressed because it is too large
Load diff
950
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/dir.c
Normal file
950
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/dir.c
Normal file
|
@ -0,0 +1,950 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements directory operations.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
|
||||
#include <redcore.h>
|
||||
|
||||
|
||||
#define DIR_INDEX_INVALID UINT32_MAX
|
||||
|
||||
#if (REDCONF_NAME_MAX % 4U) != 0U
|
||||
#define DIRENT_PADDING (4U - (REDCONF_NAME_MAX % 4U))
|
||||
#else
|
||||
#define DIRENT_PADDING (0U)
|
||||
#endif
|
||||
#define DIRENT_SIZE (4U + REDCONF_NAME_MAX + DIRENT_PADDING)
|
||||
#define DIRENTS_PER_BLOCK (REDCONF_BLOCK_SIZE / DIRENT_SIZE)
|
||||
#define DIRENTS_MAX (uint32_t)REDMIN(UINT32_MAX, UINT64_SUFFIX(1) * INODE_DATA_BLOCKS * DIRENTS_PER_BLOCK)
|
||||
|
||||
|
||||
/** @brief On-disk directory entry.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** The inode number that the directory entry points at. If the directory
|
||||
entry is available, this holds INODE_INVALID.
|
||||
*/
|
||||
uint32_t ulInode;
|
||||
|
||||
/** The name of the directory entry. For names shorter than
|
||||
REDCONF_NAME_MAX, unused bytes in the array are zeroed. For names of
|
||||
the maximum length, the string is not null terminated.
|
||||
*/
|
||||
char acName[REDCONF_NAME_MAX];
|
||||
|
||||
#if DIRENT_PADDING > 0U
|
||||
/** Unused padding so that ulInode is always aligned on a four-byte
|
||||
boundary.
|
||||
*/
|
||||
uint8_t abPadding[DIRENT_PADDING];
|
||||
#endif
|
||||
} DIRENT;
|
||||
|
||||
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
|
||||
static REDSTATUS DirCyclicRenameCheck(uint32_t ulSrcInode, const CINODE *pDstPInode);
|
||||
#endif
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
static REDSTATUS DirEntryWrite(CINODE *pPInode, uint32_t ulIdx, uint32_t ulInode, const char *pszName, uint32_t ulNameLen);
|
||||
static uint64_t DirEntryIndexToOffset(uint32_t ulIdx);
|
||||
#endif
|
||||
static uint32_t DirOffsetToEntryIndex(uint64_t ullOffset);
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Create a new entry in a directory.
|
||||
|
||||
@param pPInode A pointer to the cached inode structure of the directory
|
||||
to which the new entry will be added.
|
||||
@param pszName The name to be given to the new entry, terminated by a
|
||||
null or a path separator.
|
||||
@param ulInode The inode number the new name will point at.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOSPC There is not enough space on the volume to
|
||||
create the new directory entry; or the directory
|
||||
is full.
|
||||
@retval -RED_ENOTDIR @p pPInode is not a directory.
|
||||
@retval -RED_ENAMETOOLONG @p pszName is too long.
|
||||
@retval -RED_EEXIST @p pszName already exists in @p ulPInode.
|
||||
@retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode
|
||||
structure; or @p pszName is not a valid name.
|
||||
*/
|
||||
REDSTATUS RedDirEntryCreate(
|
||||
CINODE *pPInode,
|
||||
const char *pszName,
|
||||
uint32_t ulInode)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if(!CINODE_IS_DIRTY(pPInode) || (pszName == NULL) || !INODE_IS_VALID(ulInode))
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(!pPInode->fDirectory)
|
||||
{
|
||||
ret = -RED_ENOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulNameLen = RedNameLen(pszName);
|
||||
|
||||
if(ulNameLen == 0U)
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(ulNameLen > REDCONF_NAME_MAX)
|
||||
{
|
||||
ret = -RED_ENAMETOOLONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulEntryIdx;
|
||||
|
||||
ret = RedDirEntryLookup(pPInode, pszName, &ulEntryIdx, NULL);
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = -RED_EEXIST;
|
||||
}
|
||||
else if(ret == -RED_ENOENT)
|
||||
{
|
||||
if(ulEntryIdx == DIR_INDEX_INVALID)
|
||||
{
|
||||
ret = -RED_ENOSPC;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unexpected error, no action.
|
||||
*/
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = DirEntryWrite(pPInode, ulEntryIdx, ulInode, pszName, ulNameLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* REDCONF_READ_ONLY == 0 */
|
||||
|
||||
|
||||
#if DELETE_SUPPORTED
|
||||
/** @brief Delete an existing directory entry.
|
||||
|
||||
@param pPInode A pointer to the cached inode structure of the directory
|
||||
containing the entry to be deleted.
|
||||
@param ulDeleteIdx Position within the directory of the entry to be
|
||||
deleted.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOSPC The file system does not have enough space to modify
|
||||
the parent directory to perform the deletion.
|
||||
@retval -RED_ENOTDIR @p pPInode is not a directory.
|
||||
@retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode
|
||||
structure; or @p ulIdx is out of range.
|
||||
*/
|
||||
REDSTATUS RedDirEntryDelete(
|
||||
CINODE *pPInode,
|
||||
uint32_t ulDeleteIdx)
|
||||
{
|
||||
REDSTATUS ret = 0;
|
||||
|
||||
if(!CINODE_IS_DIRTY(pPInode) || (ulDeleteIdx >= DIRENTS_MAX))
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(!pPInode->fDirectory)
|
||||
{
|
||||
ret = -RED_ENOTDIR;
|
||||
}
|
||||
else if((DirEntryIndexToOffset(ulDeleteIdx) + DIRENT_SIZE) == pPInode->pInodeBuf->ullSize)
|
||||
{
|
||||
uint32_t ulTruncIdx = ulDeleteIdx;
|
||||
bool fDone = false;
|
||||
|
||||
/* We are deleting the last dirent in the directory, so search
|
||||
backwards to find the last populated dirent, allowing us to truncate
|
||||
the directory to that point.
|
||||
*/
|
||||
while((ret == 0) && (ulTruncIdx > 0U) && !fDone)
|
||||
{
|
||||
ret = RedInodeDataSeekAndRead(pPInode, ulTruncIdx / DIRENTS_PER_BLOCK);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
|
||||
uint32_t ulBlockIdx = (ulTruncIdx - 1U) % DIRENTS_PER_BLOCK;
|
||||
|
||||
do
|
||||
{
|
||||
if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)
|
||||
{
|
||||
fDone = true;
|
||||
break;
|
||||
}
|
||||
|
||||
ulTruncIdx--;
|
||||
ulBlockIdx--;
|
||||
} while(ulBlockIdx != UINT32_MAX);
|
||||
}
|
||||
else if(ret == -RED_ENODATA)
|
||||
{
|
||||
ret = 0;
|
||||
|
||||
REDASSERT((ulTruncIdx % DIRENTS_PER_BLOCK) == 0U);
|
||||
ulTruncIdx -= DIRENTS_PER_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unexpected error, loop will terminate; nothing else
|
||||
to be done.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/* Truncate the directory, deleting the requested entry and any empty
|
||||
dirents at the end of the directory.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedInodeDataTruncate(pPInode, DirEntryIndexToOffset(ulTruncIdx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The dirent to delete is not the last entry in the directory, so just
|
||||
zero it.
|
||||
*/
|
||||
ret = DirEntryWrite(pPInode, ulDeleteIdx, INODE_INVALID, "", 0U);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* DELETE_SUPPORTED */
|
||||
|
||||
|
||||
/** @brief Perform a case-sensitive search of a directory for a given name.
|
||||
|
||||
If found, then position of the entry within the directory and the inode
|
||||
number it points to are returned. As an optimization for directory entry
|
||||
creation, in the case where the requested entry does not exist, the position
|
||||
of the first available (unused) entry is returned.
|
||||
|
||||
@param pPInode A pointer to the cached inode structure of the directory
|
||||
to search.
|
||||
@param pszName The name of the desired entry, terminated by either a
|
||||
null or a path separator.
|
||||
@param pulEntryIdx On successful return, meaning that the desired entry
|
||||
exists, populated with the position of the entry. If
|
||||
returning an -RED_ENOENT error, populated with the
|
||||
position of the first available entry, or set to
|
||||
DIR_INDEX_INVALID if the directory is full. Optional.
|
||||
@param pulInode On successful return, populated with the inode number
|
||||
that the name points to. Optional; may be `NULL`.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOENT @p pszName does not name an existing file or
|
||||
directory.
|
||||
@retval -RED_ENOTDIR @p pPInode is not a directory.
|
||||
@retval -RED_EINVAL @p pPInode is not a mounted cached inode
|
||||
structure; or @p pszName is not a valid name; or
|
||||
@p pulEntryIdx is `NULL`.
|
||||
@retval -RED_ENAMETOOLONG @p pszName is too long.
|
||||
*/
|
||||
REDSTATUS RedDirEntryLookup(
|
||||
CINODE *pPInode,
|
||||
const char *pszName,
|
||||
uint32_t *pulEntryIdx,
|
||||
uint32_t *pulInode)
|
||||
{
|
||||
REDSTATUS ret = 0;
|
||||
|
||||
if(!CINODE_IS_MOUNTED(pPInode) || (pszName == NULL))
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(!pPInode->fDirectory)
|
||||
{
|
||||
ret = -RED_ENOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulNameLen = RedNameLen(pszName);
|
||||
|
||||
if(ulNameLen == 0U)
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(ulNameLen > REDCONF_NAME_MAX)
|
||||
{
|
||||
ret = -RED_ENAMETOOLONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulIdx = 0U;
|
||||
uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);
|
||||
uint32_t ulFreeIdx = DIR_INDEX_INVALID; /* Index of first free dirent. */
|
||||
|
||||
/* Loop over the directory blocks, searching each block for a
|
||||
dirent that matches the given name.
|
||||
*/
|
||||
while((ret == 0) && (ulIdx < ulDirentCount))
|
||||
{
|
||||
ret = RedInodeDataSeekAndRead(pPInode, ulIdx / DIRENTS_PER_BLOCK);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
|
||||
uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - ulIdx);
|
||||
uint32_t ulBlockIdx;
|
||||
|
||||
for(ulBlockIdx = 0U; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)
|
||||
{
|
||||
const DIRENT *pDirent = &pDirents[ulBlockIdx];
|
||||
|
||||
if(pDirent->ulInode != INODE_INVALID)
|
||||
{
|
||||
/* The name in the dirent will not be null
|
||||
terminated if it is of the maximum length, so
|
||||
use a bounded string compare and then make sure
|
||||
there is nothing more to the name.
|
||||
*/
|
||||
if( (RedStrNCmp(pDirent->acName, pszName, ulNameLen) == 0)
|
||||
&& ((ulNameLen == REDCONF_NAME_MAX) || (pDirent->acName[ulNameLen] == '\0')))
|
||||
{
|
||||
/* Found a matching dirent, stop and return its
|
||||
information.
|
||||
*/
|
||||
if(pulInode != NULL)
|
||||
{
|
||||
*pulInode = pDirent->ulInode;
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
*pulInode = RedRev32(*pulInode);
|
||||
#endif
|
||||
}
|
||||
|
||||
ulIdx += ulBlockIdx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(ulFreeIdx == DIR_INDEX_INVALID)
|
||||
{
|
||||
ulFreeIdx = ulIdx + ulBlockIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The directory entry is free, but we already found a free one, so there's
|
||||
nothing to do here.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if(ulBlockIdx < ulBlockLastIdx)
|
||||
{
|
||||
/* If we broke out of the for loop, we found a matching
|
||||
dirent and can stop the search.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
ulIdx += ulBlockLastIdx;
|
||||
}
|
||||
else if(ret == -RED_ENODATA)
|
||||
{
|
||||
if(ulFreeIdx == DIR_INDEX_INVALID)
|
||||
{
|
||||
ulFreeIdx = ulIdx;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
ulIdx += DIRENTS_PER_BLOCK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unexpected error, let the loop terminate, no action
|
||||
here.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
/* If we made it all the way to the end of the directory
|
||||
without stopping, then the given name does not exist in the
|
||||
directory.
|
||||
*/
|
||||
if(ulIdx == ulDirentCount)
|
||||
{
|
||||
/* If the directory had no sparse dirents, then the first
|
||||
free dirent is beyond the end of the directory. If the
|
||||
directory is already the maximum size, then there is no
|
||||
free dirent.
|
||||
*/
|
||||
if((ulFreeIdx == DIR_INDEX_INVALID) && (ulDirentCount < DIRENTS_MAX))
|
||||
{
|
||||
ulFreeIdx = ulDirentCount;
|
||||
}
|
||||
|
||||
ulIdx = ulFreeIdx;
|
||||
|
||||
ret = -RED_ENOENT;
|
||||
}
|
||||
|
||||
if(pulEntryIdx != NULL)
|
||||
{
|
||||
*pulEntryIdx = ulIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)
|
||||
/** @brief Read the next entry from a directory, given a starting index.
|
||||
|
||||
@param pInode A pointer to the cached inode structure of the directory to
|
||||
read from.
|
||||
@param pulIdx On entry, the directory index to start reading from. On
|
||||
successful return, populated with the directory index to use
|
||||
for subsequent reads. On -RED_ENOENT return, populated with
|
||||
the directory index immediately following the last valid
|
||||
one.
|
||||
@param pszName On successful return, populated with the name of the next
|
||||
directory entry. Buffer must be at least
|
||||
REDCONF_NAME_MAX + 1 in size, to store the maximum name
|
||||
length plus a null terminator.
|
||||
@param pulInode On successful return, populated with the inode number
|
||||
pointed at by the next directory entry.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOENT There are no more entries in the directory.
|
||||
@retval -RED_ENOTDIR @p pPInode is not a directory.
|
||||
@retval -RED_EINVAL @p pPInode is not a mounted cached inode structure;
|
||||
or @p pszName is `NULL`; or @p pulIdx is `NULL`; or
|
||||
@p pulInode is `NULL`.
|
||||
*/
|
||||
REDSTATUS RedDirEntryRead(
|
||||
CINODE *pPInode,
|
||||
uint32_t *pulIdx,
|
||||
char *pszName,
|
||||
uint32_t *pulInode)
|
||||
{
|
||||
REDSTATUS ret = 0;
|
||||
|
||||
if(!CINODE_IS_MOUNTED(pPInode) || (pulIdx == NULL) || (pszName == NULL) || (pulInode == NULL))
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(!pPInode->fDirectory)
|
||||
{
|
||||
ret = -RED_ENOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulIdx = *pulIdx;
|
||||
uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pInodeBuf->ullSize);
|
||||
|
||||
/* Starting either at the beginning of the directory or where we left
|
||||
off, loop over the directory blocks, searching each block for a
|
||||
non-sparse dirent to return as the next entry in the directory.
|
||||
*/
|
||||
while((ret == 0) && (ulIdx < ulDirentCount))
|
||||
{
|
||||
uint32_t ulBlockOffset = ulIdx / DIRENTS_PER_BLOCK;
|
||||
|
||||
ret = RedInodeDataSeekAndRead(pPInode, ulBlockOffset);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData);
|
||||
uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - (ulBlockOffset * DIRENTS_PER_BLOCK));
|
||||
uint32_t ulBlockIdx;
|
||||
|
||||
for(ulBlockIdx = ulIdx % DIRENTS_PER_BLOCK; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++)
|
||||
{
|
||||
if(pDirents[ulBlockIdx].ulInode != INODE_INVALID)
|
||||
{
|
||||
*pulIdx = ulIdx + 1U;
|
||||
RedStrNCpy(pszName, pDirents[ulBlockIdx].acName, REDCONF_NAME_MAX);
|
||||
pszName[REDCONF_NAME_MAX] = '\0';
|
||||
|
||||
*pulInode = pDirents[ulBlockIdx].ulInode;
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
*pulInode = RedRev32(*pulInode);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(ulBlockIdx < ulBlockLastIdx)
|
||||
{
|
||||
REDASSERT(ulIdx <= ulDirentCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(ret == -RED_ENODATA)
|
||||
{
|
||||
ulIdx += DIRENTS_PER_BLOCK - (ulIdx % DIRENTS_PER_BLOCK);
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unexpected error, loop will terminate; nothing else to do.
|
||||
*/
|
||||
}
|
||||
|
||||
REDASSERT(ulIdx <= ulDirentCount);
|
||||
}
|
||||
|
||||
if((ret == 0) && (ulIdx >= ulDirentCount))
|
||||
{
|
||||
*pulIdx = ulDirentCount;
|
||||
ret = -RED_ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
|
||||
/** Rename a directory entry.
|
||||
|
||||
@param pSrcPInode The inode of the directory containing @p pszSrcName.
|
||||
@param pszSrcName The name of the directory entry to be renamed.
|
||||
@param pSrcInode On successful return, populated with the inode of the
|
||||
source entry.
|
||||
@param pDstPInode The inode of the directory in which @p pszDstName will
|
||||
be created or replaced.
|
||||
@param pszDstName The name of the directory entry to be created or
|
||||
replaced.
|
||||
@param pDstInode On successful return, if the destination previously
|
||||
existed, populated with the inode previously pointed to
|
||||
by the destination. This may be the same as the source
|
||||
inode. If the destination did not exist, populated with
|
||||
INODE_INVALID.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EEXIST #REDCONF_RENAME_ATOMIC is false and the
|
||||
destination name exists.
|
||||
@retval -RED_EINVAL @p pSrcPInode is not a mounted dirty cached
|
||||
inode structure; or @p pSrcInode is `NULL`; or
|
||||
@p pszSrcName is not a valid name; or
|
||||
@p pDstPInode is not a mounted dirty cached
|
||||
inode structure; or @p pDstInode is `NULL`; or
|
||||
@p pszDstName is not a valid name.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_EISDIR The destination name exists and is a directory,
|
||||
and the source name is a non-directory.
|
||||
@retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer
|
||||
than #REDCONF_NAME_MAX.
|
||||
@retval -RED_ENOENT The source name is not an existing entry; or
|
||||
either @p pszSrcName or @p pszDstName point to
|
||||
an empty string.
|
||||
@retval -RED_ENOTDIR @p pSrcPInode is not a directory; or
|
||||
@p pDstPInode is not a directory; or the source
|
||||
name is a directory and the destination name is
|
||||
a file.
|
||||
@retval -RED_ENOTEMPTY The destination name is a directory which is not
|
||||
empty.
|
||||
@retval -RED_ENOSPC The file system does not have enough space to
|
||||
extend the @p ulDstPInode directory.
|
||||
@retval -RED_EROFS The directory to be removed resides on a
|
||||
read-only file system.
|
||||
*/
|
||||
REDSTATUS RedDirEntryRename(
|
||||
CINODE *pSrcPInode,
|
||||
const char *pszSrcName,
|
||||
CINODE *pSrcInode,
|
||||
CINODE *pDstPInode,
|
||||
const char *pszDstName,
|
||||
CINODE *pDstInode)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( !CINODE_IS_DIRTY(pSrcPInode)
|
||||
|| (pszSrcName == NULL)
|
||||
|| (pSrcInode == NULL)
|
||||
|| !CINODE_IS_DIRTY(pDstPInode)
|
||||
|| (pszDstName == NULL)
|
||||
|| (pDstInode == NULL))
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(!pSrcPInode->fDirectory || !pDstPInode->fDirectory)
|
||||
{
|
||||
ret = -RED_ENOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulDstIdx = 0U; /* Init'd to quiet warnings. */
|
||||
uint32_t ulSrcIdx;
|
||||
|
||||
/* Look up the source and destination names.
|
||||
*/
|
||||
ret = RedDirEntryLookup(pSrcPInode, pszSrcName, &ulSrcIdx, &pSrcInode->ulInode);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedDirEntryLookup(pDstPInode, pszDstName, &ulDstIdx, &pDstInode->ulInode);
|
||||
|
||||
if(ret == -RED_ENOENT)
|
||||
{
|
||||
if(ulDstIdx == DIR_INDEX_INVALID)
|
||||
{
|
||||
ret = -RED_ENOSPC;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if REDCONF_RENAME_ATOMIC == 1
|
||||
pDstInode->ulInode = INODE_INVALID;
|
||||
#endif
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#if REDCONF_RENAME_ATOMIC == 0
|
||||
else if(ret == 0)
|
||||
{
|
||||
ret = -RED_EEXIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do here, just propagate the error.
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if REDCONF_RENAME_ATOMIC == 1
|
||||
/* If both names point to the same inode, POSIX says to do nothing to
|
||||
either name.
|
||||
*/
|
||||
if((ret == 0) && (pSrcInode->ulInode != pDstInode->ulInode))
|
||||
#else
|
||||
if(ret == 0)
|
||||
#endif
|
||||
{
|
||||
ret = RedInodeMount(pSrcInode, FTYPE_EITHER, true);
|
||||
|
||||
#if REDCONF_RENAME_ATOMIC == 1
|
||||
if((ret == 0) && (pDstInode->ulInode != INODE_INVALID))
|
||||
{
|
||||
/* Source and destination must be the same type (file/dir).
|
||||
*/
|
||||
ret = RedInodeMount(pDstInode, pSrcInode->fDirectory ? FTYPE_DIR : FTYPE_FILE, true);
|
||||
|
||||
/* If renaming directories, the destination must be empty.
|
||||
*/
|
||||
if((ret == 0) && pDstInode->fDirectory && (pDstInode->pInodeBuf->ullSize > 0U))
|
||||
{
|
||||
ret = -RED_ENOTEMPTY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we are renaming a directory, make sure the rename isn't
|
||||
cyclic (e.g., renaming "foo" into "foo/bar").
|
||||
*/
|
||||
if((ret == 0) && pSrcInode->fDirectory)
|
||||
{
|
||||
ret = DirCyclicRenameCheck(pSrcInode->ulInode, pDstPInode);
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = DirEntryWrite(pDstPInode, ulDstIdx, pSrcInode->ulInode, pszDstName, RedNameLen(pszDstName));
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedDirEntryDelete(pSrcPInode, ulSrcIdx);
|
||||
|
||||
if(ret == -RED_ENOSPC)
|
||||
{
|
||||
REDSTATUS ret2;
|
||||
|
||||
/* If there was not enough space to branch the parent
|
||||
directory inode and data block containin the source
|
||||
entry, revert destination directory entry to its
|
||||
previous state.
|
||||
*/
|
||||
#if REDCONF_RENAME_ATOMIC == 1
|
||||
if(pDstInode->ulInode != INODE_INVALID)
|
||||
{
|
||||
ret2 = DirEntryWrite(pDstPInode, ulDstIdx, pDstInode->ulInode, pszDstName, RedNameLen(pszDstName));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ret2 = RedDirEntryDelete(pDstPInode, ulDstIdx);
|
||||
}
|
||||
|
||||
if(ret2 != 0)
|
||||
{
|
||||
ret = ret2;
|
||||
CRITICAL_ERROR();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
pSrcInode->pInodeBuf->ulPInode = pDstPInode->ulInode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Check for a cyclic rename.
|
||||
|
||||
A cyclic rename is renaming a directory into a subdirectory of itself. For
|
||||
example, renaming "a" into "a/b/c/d" is cyclic. These renames must not be
|
||||
allowed since they would corrupt the directory tree.
|
||||
|
||||
@param ulSrcInode The inode number of the directory being renamed.
|
||||
@param pDstPInode A pointer to the cached inode structure of the directory
|
||||
into which the source is being renamed.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_EINVAL The rename is cyclic; or invalid parameters.
|
||||
@retval -RED_ENOTDIR @p pDstPInode is not a directory.
|
||||
*/
|
||||
static REDSTATUS DirCyclicRenameCheck(
|
||||
uint32_t ulSrcInode,
|
||||
const CINODE *pDstPInode)
|
||||
{
|
||||
REDSTATUS ret = 0;
|
||||
|
||||
if(!INODE_IS_VALID(ulSrcInode) || !CINODE_IS_MOUNTED(pDstPInode))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(ulSrcInode == pDstPInode->ulInode)
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(!pDstPInode->fDirectory)
|
||||
{
|
||||
ret = -RED_ENOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
CINODE NextParent;
|
||||
/* Used to prevent infinite loop in case of corrupted directory
|
||||
structure.
|
||||
*/
|
||||
uint32_t ulIteration = 0U;
|
||||
|
||||
NextParent.ulInode = pDstPInode->pInodeBuf->ulPInode;
|
||||
|
||||
while( (NextParent.ulInode != ulSrcInode)
|
||||
&& (NextParent.ulInode != INODE_ROOTDIR)
|
||||
&& (NextParent.ulInode != INODE_INVALID)
|
||||
&& (ulIteration < gpRedVolConf->ulInodeCount))
|
||||
{
|
||||
ret = RedInodeMount(&NextParent, FTYPE_DIR, false);
|
||||
if(ret != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
NextParent.ulInode = NextParent.pInodeBuf->ulPInode;
|
||||
|
||||
RedInodePut(&NextParent, 0U);
|
||||
|
||||
ulIteration++;
|
||||
}
|
||||
|
||||
if((ret == 0) && (ulIteration == gpRedVolConf->ulInodeCount))
|
||||
{
|
||||
CRITICAL_ERROR();
|
||||
ret = -RED_EFUBAR;
|
||||
}
|
||||
|
||||
if((ret == 0) && (ulSrcInode == NextParent.ulInode))
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) */
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Update the contents of a directory entry.
|
||||
|
||||
@param pPInode A pointer to the cached inode structure of the directory
|
||||
whose entry is being written.
|
||||
@param ulIdx The index of the directory entry to write.
|
||||
@param ulInode The inode number the directory entry is to point at.
|
||||
@param pszName The name of the directory entry.
|
||||
@param ulNameLen The length of @p pszName.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOSPC There is not enough space on the volume to write the
|
||||
directory entry.
|
||||
@retval -RED_ENOTDIR @p pPInode is not a directory.
|
||||
@retval -RED_EINVAL Invalid parameters.
|
||||
*/
|
||||
static REDSTATUS DirEntryWrite(
|
||||
CINODE *pPInode,
|
||||
uint32_t ulIdx,
|
||||
uint32_t ulInode,
|
||||
const char *pszName,
|
||||
uint32_t ulNameLen)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( !CINODE_IS_DIRTY(pPInode)
|
||||
|| (ulIdx >= DIRENTS_MAX)
|
||||
|| (!INODE_IS_VALID(ulInode) && (ulInode != INODE_INVALID))
|
||||
|| (pszName == NULL)
|
||||
|| (ulNameLen > REDCONF_NAME_MAX)
|
||||
|| ((ulNameLen == 0U) != (ulInode == INODE_INVALID)))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(!pPInode->fDirectory)
|
||||
{
|
||||
ret = -RED_ENOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t ullOffset = DirEntryIndexToOffset(ulIdx);
|
||||
uint32_t ulLen = DIRENT_SIZE;
|
||||
static DIRENT de;
|
||||
|
||||
RedMemSet(&de, 0U, sizeof(de));
|
||||
|
||||
de.ulInode = ulInode;
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
de.ulInode = RedRev32(de.ulInode);
|
||||
#endif
|
||||
|
||||
RedStrNCpy(de.acName, pszName, ulNameLen);
|
||||
|
||||
ret = RedInodeDataWrite(pPInode, ullOffset, &ulLen, &de);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert a directory entry index to a byte offset.
|
||||
|
||||
@param ulIdx Directory entry index.
|
||||
|
||||
@return Byte offset in the directory corresponding with ulIdx.
|
||||
*/
|
||||
static uint64_t DirEntryIndexToOffset(
|
||||
uint32_t ulIdx)
|
||||
{
|
||||
uint32_t ulBlock = ulIdx / DIRENTS_PER_BLOCK;
|
||||
uint32_t ulOffsetInBlock = ulIdx % DIRENTS_PER_BLOCK;
|
||||
uint64_t ullOffset;
|
||||
|
||||
REDASSERT(ulIdx < DIRENTS_MAX);
|
||||
|
||||
ullOffset = (uint64_t)ulBlock << BLOCK_SIZE_P2;
|
||||
ullOffset += (uint64_t)ulOffsetInBlock * DIRENT_SIZE;
|
||||
|
||||
return ullOffset;
|
||||
}
|
||||
#endif /* REDCONF_READ_ONLY == 0 */
|
||||
|
||||
|
||||
/** @brief Convert a byte offset to a directory entry index.
|
||||
|
||||
@param ullOffset Byte offset in the directory.
|
||||
|
||||
@return Directory entry index corresponding with @p ullOffset.
|
||||
*/
|
||||
static uint32_t DirOffsetToEntryIndex(
|
||||
uint64_t ullOffset)
|
||||
{
|
||||
uint32_t ulIdx;
|
||||
|
||||
REDASSERT(ullOffset < INODE_SIZE_MAX);
|
||||
REDASSERT(((uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) % DIRENT_SIZE) == 0U);
|
||||
|
||||
/* Avoid doing any 64-bit divides.
|
||||
*/
|
||||
ulIdx = (uint32_t)(ullOffset >> BLOCK_SIZE_P2) * DIRENTS_PER_BLOCK;
|
||||
ulIdx += (uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) / DIRENT_SIZE;
|
||||
|
||||
return ulIdx;
|
||||
}
|
||||
|
||||
|
||||
#endif /* REDCONF_API_POSIX == 1 */
|
||||
|
235
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/format.c
Normal file
235
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/format.c
Normal file
|
@ -0,0 +1,235 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements the Reliance Edge file system formatter.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redcoreapi.h>
|
||||
#include <redcore.h>
|
||||
|
||||
#if FORMAT_SUPPORTED
|
||||
|
||||
|
||||
/** @brief Format a file system volume.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EBUSY Volume is mounted.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedVolFormat(void)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if(gpRedVolume->fMounted)
|
||||
{
|
||||
ret = -RED_EBUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR);
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
MASTERBLOCK *pMB;
|
||||
REDSTATUS ret2;
|
||||
|
||||
/* Overwrite the master block with zeroes, so that if formatting is
|
||||
interrupted, the volume will not be mountable.
|
||||
*/
|
||||
ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB));
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);
|
||||
|
||||
RedBufferDiscard(pMB);
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedIoFlush(gbRedVolNum);
|
||||
}
|
||||
|
||||
#if REDCONF_IMAP_EXTERNAL == 1
|
||||
if((ret == 0) && !gpRedCoreVol->fImapInline)
|
||||
{
|
||||
uint32_t ulImapBlock;
|
||||
uint32_t ulImapBlockLimit = gpRedCoreVol->ulImapStartBN + (gpRedCoreVol->ulImapNodeCount * 2U);
|
||||
uint16_t uImapFlags = (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY);
|
||||
|
||||
/* Technically it is only necessary to create one copy of each imap
|
||||
node (the copy the metaroot points at), but creating them both
|
||||
avoids headaches during disk image analysis from stale imaps
|
||||
left over from previous formats.
|
||||
*/
|
||||
for(ulImapBlock = gpRedCoreVol->ulImapStartBN; ulImapBlock < ulImapBlockLimit; ulImapBlock++)
|
||||
{
|
||||
IMAPNODE *pImap;
|
||||
|
||||
ret = RedBufferGet(ulImapBlock, uImapFlags, CAST_VOID_PTR_PTR(&pImap));
|
||||
if(ret != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
RedBufferPut(pImap);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the first metaroot.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR));
|
||||
|
||||
gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable;
|
||||
#if REDCONF_API_POSIX == 1
|
||||
gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount;
|
||||
#endif
|
||||
gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;
|
||||
|
||||
/* The branched flag is typically set automatically when bits in
|
||||
the imap change. It is set here explicitly because the imap has
|
||||
only been initialized, not changed.
|
||||
*/
|
||||
gpRedCoreVol->fBranched = true;
|
||||
|
||||
ret = RedVolTransact();
|
||||
}
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
/* Create the root directory.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
CINODE rootdir;
|
||||
|
||||
rootdir.ulInode = INODE_ROOTDIR;
|
||||
ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
RedInodePut(&rootdir, 0U);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if REDCONF_API_FSE == 1
|
||||
/* The FSE API does not support creating or deletes files, so all the
|
||||
inodes are created during setup.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
uint32_t ulInodeIdx;
|
||||
|
||||
for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++)
|
||||
{
|
||||
CINODE ino;
|
||||
|
||||
ino.ulInode = INODE_FIRST_FREE + ulInodeIdx;
|
||||
ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
RedInodePut(&ino, 0U);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the second metaroot.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedVolTransact();
|
||||
}
|
||||
|
||||
/* Populate and write out the master block.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedBufferGet(BLOCK_NUM_MASTER, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB));
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
pMB->ulVersion = RED_DISK_LAYOUT_VERSION;
|
||||
RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum));
|
||||
pMB->ulFormatTime = RedOsClockGetTime();
|
||||
pMB->ulInodeCount = gpRedVolConf->ulInodeCount;
|
||||
pMB->ulBlockCount = gpRedVolume->ulBlockCount;
|
||||
pMB->uMaxNameLen = REDCONF_NAME_MAX;
|
||||
pMB->uDirectPointers = REDCONF_DIRECT_POINTERS;
|
||||
pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS;
|
||||
pMB->bBlockSizeP2 = BLOCK_SIZE_P2;
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
pMB->bFlags |= MBFLAG_API_POSIX;
|
||||
#endif
|
||||
#if REDCONF_INODE_TIMESTAMPS == 1
|
||||
pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS;
|
||||
#endif
|
||||
#if REDCONF_INODE_BLOCKS == 1
|
||||
pMB->bFlags |= MBFLAG_INODE_BLOCKS;
|
||||
#endif
|
||||
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
|
||||
pMB->bFlags |= MBFLAG_INODE_NLINK;
|
||||
#endif
|
||||
|
||||
ret = RedBufferFlush(BLOCK_NUM_MASTER, 1U);
|
||||
|
||||
RedBufferPut(pMB);
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedIoFlush(gbRedVolNum);
|
||||
}
|
||||
|
||||
ret2 = RedOsBDevClose(gbRedVolNum);
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = ret2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Discard the buffers so a subsequent format will not run into blocks it
|
||||
does not expect.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* FORMAT_SUPPORTED */
|
||||
|
348
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imap.c
Normal file
348
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imap.c
Normal file
|
@ -0,0 +1,348 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements allocation routines.
|
||||
|
||||
This module implements routines for working with the imap, a bitmap which
|
||||
tracks which blocks are allocated or free. Some of the functionality is
|
||||
delegated to imapinline.c and imapextern.c.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redcore.h>
|
||||
|
||||
|
||||
/** @brief Get the allocation bit of a block from either metaroot.
|
||||
|
||||
Will pass the call down either to the inline imap or to the external imap
|
||||
implementation, whichever is appropriate for the current volume.
|
||||
|
||||
@param bMR The metaroot index: either 0 or 1.
|
||||
@param ulBlock The block number to query.
|
||||
@param pfAllocated On successful return, populated with the allocation bit
|
||||
of the block.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;
|
||||
or @p pfAllocated is `NULL`.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedImapBlockGet(
|
||||
uint8_t bMR,
|
||||
uint32_t ulBlock,
|
||||
bool *pfAllocated)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( (bMR > 1U)
|
||||
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|
||||
|| (ulBlock >= gpRedVolume->ulBlockCount)
|
||||
|| (pfAllocated == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)
|
||||
if(gpRedCoreVol->fImapInline)
|
||||
{
|
||||
ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);
|
||||
}
|
||||
#elif REDCONF_IMAP_INLINE == 1
|
||||
ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated);
|
||||
#else
|
||||
ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Set the allocation bit of a block in the working metaroot.
|
||||
|
||||
Will pass the call down either to the inline imap or to the external imap
|
||||
implementation, whichever is appropriate for the current volume.
|
||||
|
||||
@param ulBlock The block number to allocate or free.
|
||||
@param fAllocated Whether to allocate the block (true) or free it (false).
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p ulBlock is out of range; or @p ulBlock is allocable
|
||||
and @p fAllocated is 1.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedImapBlockSet(
|
||||
uint32_t ulBlock,
|
||||
bool fAllocated)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|
||||
|| (ulBlock >= gpRedVolume->ulBlockCount))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if( (ulBlock >= gpRedCoreVol->ulFirstAllocableBN)
|
||||
&& ( (fAllocated && (gpRedMR->ulFreeBlocks == 0U))
|
||||
|| ((!fAllocated) && (gpRedMR->ulFreeBlocks >= gpRedVolume->ulBlocksAllocable))))
|
||||
{
|
||||
/* Attempting either to free more blocks than are allocable, or
|
||||
allocate a block when there are none available. This could indicate
|
||||
metadata corruption.
|
||||
*/
|
||||
CRITICAL_ERROR();
|
||||
ret = -RED_EFUBAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1)
|
||||
if(gpRedCoreVol->fImapInline)
|
||||
{
|
||||
ret = RedImapIBlockSet(ulBlock, fAllocated);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RedImapEBlockSet(ulBlock, fAllocated);
|
||||
}
|
||||
#elif REDCONF_IMAP_INLINE == 1
|
||||
ret = RedImapIBlockSet(ulBlock, fAllocated);
|
||||
#else
|
||||
ret = RedImapEBlockSet(ulBlock, fAllocated);
|
||||
#endif
|
||||
|
||||
/* Any change to the allocation state of a block indicates that the
|
||||
volume is now branched.
|
||||
*/
|
||||
gpRedCoreVol->fBranched = true;
|
||||
}
|
||||
|
||||
/* If a block was marked as no longer in use, discard it from the buffers.
|
||||
*/
|
||||
if((ret == 0) && (!fAllocated))
|
||||
{
|
||||
ret = RedBufferDiscardRange(ulBlock, 1U);
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
}
|
||||
|
||||
/* Adjust the free/almost free block count if the block was allocable.
|
||||
*/
|
||||
if((ret == 0) && (ulBlock >= gpRedCoreVol->ulFirstAllocableBN))
|
||||
{
|
||||
if(fAllocated)
|
||||
{
|
||||
gpRedMR->ulFreeBlocks--;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool fWasAllocated;
|
||||
|
||||
/* Whether the block became free or almost free depends on its
|
||||
previous allocation state. If it was used, then it is now
|
||||
almost free. Otherwise, it was new and is now free.
|
||||
*/
|
||||
ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fWasAllocated);
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(fWasAllocated)
|
||||
{
|
||||
gpRedCoreVol->ulAlmostFreeBlocks++;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpRedMR->ulFreeBlocks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Allocate one block.
|
||||
|
||||
@param pulBlock On successful return, populated with the allocated block
|
||||
number.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p pulBlock is `NULL`.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOSPC Insufficient free space to perform the allocation.
|
||||
*/
|
||||
REDSTATUS RedImapAllocBlock(
|
||||
uint32_t *pulBlock)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if(pulBlock == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(gpRedMR->ulFreeBlocks == 0U)
|
||||
{
|
||||
ret = -RED_ENOSPC;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulStopBlock = gpRedMR->ulAllocNextBlock;
|
||||
bool fAllocated = false;
|
||||
|
||||
do
|
||||
{
|
||||
ALLOCSTATE state;
|
||||
|
||||
ret = RedImapBlockState(gpRedMR->ulAllocNextBlock, &state);
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(state == ALLOCSTATE_FREE)
|
||||
{
|
||||
ret = RedImapBlockSet(gpRedMR->ulAllocNextBlock, true);
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
|
||||
*pulBlock = gpRedMR->ulAllocNextBlock;
|
||||
fAllocated = true;
|
||||
}
|
||||
|
||||
/* Increment the next block number, wrapping it when the end of
|
||||
the volume is reached.
|
||||
*/
|
||||
gpRedMR->ulAllocNextBlock++;
|
||||
if(gpRedMR->ulAllocNextBlock == gpRedVolume->ulBlockCount)
|
||||
{
|
||||
gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN;
|
||||
}
|
||||
}
|
||||
}
|
||||
while((ret == 0) && !fAllocated && (gpRedMR->ulAllocNextBlock != ulStopBlock));
|
||||
|
||||
if((ret == 0) && !fAllocated)
|
||||
{
|
||||
/* The free block count was already determined to be non-zero, no
|
||||
error occurred while looking for free blocks, but no free blocks
|
||||
were found. This indicates metadata corruption.
|
||||
*/
|
||||
CRITICAL_ERROR();
|
||||
ret = -RED_EFUBAR;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* REDCONF_READ_ONLY == 0 */
|
||||
|
||||
|
||||
/** @brief Get the allocation state of a block.
|
||||
|
||||
Takes into account the allocation bits from both metaroots, and returns one
|
||||
of four possible allocation state values:
|
||||
|
||||
- ::ALLOCSTATE_FREE Free and may be allocated; writeable.
|
||||
- ::ALLOCSTATE_USED In-use and transacted; not writeable.
|
||||
- ::ALLOCSTATE_NEW In-use but not transacted; writeable.
|
||||
- ::ALLOCSTATE_AFREE Will become free after a transaction; not writeable.
|
||||
|
||||
@param ulBlock The block number to query.
|
||||
@param pState On successful return, populated with the state of the block.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p ulBlock is out of range; or @p pState is `NULL`.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedImapBlockState(
|
||||
uint32_t ulBlock,
|
||||
ALLOCSTATE *pState)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|
||||
|| (ulBlock >= gpRedVolume->ulBlockCount)
|
||||
|| (pState == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool fBitCurrent;
|
||||
|
||||
ret = RedImapBlockGet(gpRedCoreVol->bCurMR, ulBlock, &fBitCurrent);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
bool fBitOld;
|
||||
|
||||
ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fBitOld);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(fBitCurrent)
|
||||
{
|
||||
if(fBitOld)
|
||||
{
|
||||
*pState = ALLOCSTATE_USED;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pState = ALLOCSTATE_NEW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fBitOld)
|
||||
{
|
||||
*pState = ALLOCSTATE_AFREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pState = ALLOCSTATE_FREE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
316
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapextern.c
Normal file
316
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapextern.c
Normal file
|
@ -0,0 +1,316 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements routines for the external imap.
|
||||
|
||||
The external imap is used on volumes that are too big for the imap bitmap
|
||||
to be stored entirely in the metaroot, so instead the bitmap is stored in
|
||||
imap nodes on disk, and the metaroot bitmap is used to toggle between imap
|
||||
nodes.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_IMAP_EXTERNAL == 1
|
||||
|
||||
#include <redcore.h>
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
static REDSTATUS ImapNodeBranch(uint32_t ulImapNode, IMAPNODE **ppImap);
|
||||
static bool ImapNodeIsBranched(uint32_t ulImapNode);
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Get the allocation bit of a block from the imap as it exists in
|
||||
either metaroot.
|
||||
|
||||
@param bMR The metaroot index: either 0 or 1.
|
||||
@param ulBlock The block number to query.
|
||||
@param pfAllocated On successful exit, populated with the allocation bit
|
||||
of the block.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;
|
||||
or @p pfAllocated is `NULL`.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedImapEBlockGet(
|
||||
uint8_t bMR,
|
||||
uint32_t ulBlock,
|
||||
bool *pfAllocated)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( gpRedCoreVol->fImapInline
|
||||
|| (bMR > 1U)
|
||||
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|
||||
|| (ulBlock >= gpRedVolume->ulBlockCount)
|
||||
|| (pfAllocated == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;
|
||||
uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;
|
||||
uint8_t bMRToRead = bMR;
|
||||
IMAPNODE *pImap;
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/* If the imap node is not branched, then both copies of the imap are
|
||||
identical. If the old metaroot copy is requested, use the current
|
||||
copy instead, since it is more likely to be buffered.
|
||||
*/
|
||||
if(bMR == (1U - gpRedCoreVol->bCurMR))
|
||||
{
|
||||
if(!ImapNodeIsBranched(ulImapNode))
|
||||
{
|
||||
bMRToRead = 1U - bMR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = RedBufferGet(RedImapNodeBlock(bMRToRead, ulImapNode), BFLAG_META_IMAP, CAST_VOID_PTR_PTR(&pImap));
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
*pfAllocated = RedBitGet(pImap->abEntries, ulOffset % IMAPNODE_ENTRIES);
|
||||
|
||||
RedBufferPut(pImap);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Set the allocation bit of a block in the working-state imap.
|
||||
|
||||
@param ulBlock The block number to allocate or free.
|
||||
@param fAllocated Whether to allocate the block (true) or free it (false).
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p ulBlock is out of range.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedImapEBlockSet(
|
||||
uint32_t ulBlock,
|
||||
bool fAllocated)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( gpRedCoreVol->fImapInline
|
||||
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|
||||
|| (ulBlock >= gpRedVolume->ulBlockCount))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;
|
||||
uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES;
|
||||
IMAPNODE *pImap;
|
||||
|
||||
ret = ImapNodeBranch(ulImapNode, &pImap);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
uint32_t ulImapEntry = ulOffset % IMAPNODE_ENTRIES;
|
||||
|
||||
if(RedBitGet(pImap->abEntries, ulImapEntry) == fAllocated)
|
||||
{
|
||||
/* The driver shouldn't ever set a bit in the imap to its
|
||||
current value. That shouldn't ever be needed, and it
|
||||
indicates that the driver is doing unnecessary I/O, or
|
||||
that the imap is corrupt.
|
||||
*/
|
||||
CRITICAL_ERROR();
|
||||
ret = -RED_EFUBAR;
|
||||
}
|
||||
else if(fAllocated)
|
||||
{
|
||||
RedBitSet(pImap->abEntries, ulImapEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedBitClear(pImap->abEntries, ulImapEntry);
|
||||
}
|
||||
|
||||
RedBufferPut(pImap);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Branch an imap node and get a buffer for it.
|
||||
|
||||
If the imap node is already branched, it can be overwritten in its current
|
||||
location, and this function just gets it buffered dirty. If the node is not
|
||||
already branched, the metaroot must be updated to toggle the imap node to
|
||||
its alternate location, thereby preserving the committed state copy of the
|
||||
imap node.
|
||||
|
||||
@param ulImapNode The imap node to branch and buffer.
|
||||
@param ppImap On successful return, populated with the imap node
|
||||
buffer, which will be marked dirty.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p ulImapNode is out of range; or @p ppImap is `NULL`.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
static REDSTATUS ImapNodeBranch(
|
||||
uint32_t ulImapNode,
|
||||
IMAPNODE **ppImap)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if((ulImapNode >= gpRedCoreVol->ulImapNodeCount) || (ppImap == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(ImapNodeIsBranched(ulImapNode))
|
||||
{
|
||||
/* Imap node is already branched, so just get it buffered dirty.
|
||||
*/
|
||||
ret = RedBufferGet(RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode), BFLAG_META_IMAP | BFLAG_DIRTY, CAST_VOID_PTR_PTR(ppImap));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulBlockCurrent;
|
||||
uint32_t ulBlockOld;
|
||||
|
||||
/* The metaroot currently points to the committed state imap node.
|
||||
Toggle the metaroot to point at the alternate, writeable location.
|
||||
*/
|
||||
if(RedBitGet(gpRedMR->abEntries, ulImapNode))
|
||||
{
|
||||
RedBitClear(gpRedMR->abEntries, ulImapNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedBitSet(gpRedMR->abEntries, ulImapNode);
|
||||
}
|
||||
|
||||
ulBlockCurrent = RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode);
|
||||
ulBlockOld = RedImapNodeBlock(1U - gpRedCoreVol->bCurMR, ulImapNode);
|
||||
|
||||
ret = RedBufferDiscardRange(ulBlockCurrent, 1U);
|
||||
|
||||
/* Buffer the committed copy then reassign the block number to the
|
||||
writeable location. This also dirties the buffer.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedBufferGet(ulBlockOld, BFLAG_META_IMAP, CAST_VOID_PTR_PTR(ppImap));
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
RedBufferBranch(*ppImap, ulBlockCurrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Determine whether an imap node is branched.
|
||||
|
||||
If the imap node is branched, it can be overwritten in its current location.
|
||||
|
||||
@param ulImapNode The imap node to examine.
|
||||
|
||||
@return Whether the imap node is branched.
|
||||
*/
|
||||
static bool ImapNodeIsBranched(
|
||||
uint32_t ulImapNode)
|
||||
{
|
||||
bool fNodeBitSetInMetaroot0 = RedBitGet(gpRedCoreVol->aMR[0U].abEntries, ulImapNode);
|
||||
bool fNodeBitSetInMetaroot1 = RedBitGet(gpRedCoreVol->aMR[1U].abEntries, ulImapNode);
|
||||
|
||||
/* If the imap node is not branched, both metaroots will point to the same
|
||||
copy of the node.
|
||||
*/
|
||||
return fNodeBitSetInMetaroot0 != fNodeBitSetInMetaroot1;
|
||||
}
|
||||
#endif /* REDCONF_READ_ONLY == 0 */
|
||||
|
||||
|
||||
/** @brief Calculate the block number of the imap node location indicated by the
|
||||
given metaroot.
|
||||
|
||||
An imap node has two locations on disk. A bit in the metaroot bitmap
|
||||
indicates which location is the valid one, according to that metaroot. This
|
||||
function returns the block number of the imap node which is valid in the
|
||||
given metaroot.
|
||||
|
||||
@param bMR Which metaroot to examine.
|
||||
@param ulImapNode The imap node for which to calculate the block number.
|
||||
|
||||
@return Block number of the imap node, as indicated by the given metaroot.
|
||||
*/
|
||||
uint32_t RedImapNodeBlock(
|
||||
uint8_t bMR,
|
||||
uint32_t ulImapNode)
|
||||
{
|
||||
uint32_t ulBlock;
|
||||
|
||||
REDASSERT(ulImapNode < gpRedCoreVol->ulImapNodeCount);
|
||||
|
||||
ulBlock = gpRedCoreVol->ulImapStartBN + (ulImapNode * 2U);
|
||||
|
||||
if(bMR > 1U)
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else if(RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulImapNode))
|
||||
{
|
||||
/* Bit is set, so point ulBlock at the second copy of the node.
|
||||
*/
|
||||
ulBlock++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ulBlock already points at the first copy of the node.
|
||||
*/
|
||||
}
|
||||
|
||||
return ulBlock;
|
||||
}
|
||||
|
||||
#endif /* REDCONF_IMAP_EXTERNAL == 1 */
|
||||
|
133
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapinline.c
Normal file
133
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/imapinline.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements routines for the inline imap.
|
||||
|
||||
The inline imap is used on volumes that are small enough for the imap bitmap
|
||||
to be entirely contained within the metaroot.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_IMAP_INLINE == 1
|
||||
|
||||
#include <redcore.h>
|
||||
|
||||
|
||||
/** @brief Get the allocation bit of a block from either metaroot.
|
||||
|
||||
@param bMR The metaroot index: either 0 or 1.
|
||||
@param ulBlock The block number to query.
|
||||
@param pfAllocated On successful return, populated with the allocation bit
|
||||
of the block.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range;
|
||||
@p pfAllocated is `NULL`; or the current volume does not
|
||||
use the inline imap.
|
||||
*/
|
||||
REDSTATUS RedImapIBlockGet(
|
||||
uint8_t bMR,
|
||||
uint32_t ulBlock,
|
||||
bool *pfAllocated)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( (!gpRedCoreVol->fImapInline)
|
||||
|| (bMR > 1U)
|
||||
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|
||||
|| (ulBlock >= gpRedVolume->ulBlockCount)
|
||||
|| (pfAllocated == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pfAllocated = RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulBlock - gpRedCoreVol->ulInodeTableStartBN);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Set the allocation bit of a block in the working metaroot.
|
||||
|
||||
@param ulBlock The block number to allocate or free.
|
||||
@param fAllocated Whether to allocate the block (true) or free it (false).
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p ulBlock is out of range; or the current volume does
|
||||
not use the inline imap.
|
||||
*/
|
||||
REDSTATUS RedImapIBlockSet(
|
||||
uint32_t ulBlock,
|
||||
bool fAllocated)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if( (!gpRedCoreVol->fImapInline)
|
||||
|| (ulBlock < gpRedCoreVol->ulInodeTableStartBN)
|
||||
|| (ulBlock >= gpRedVolume->ulBlockCount))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN;
|
||||
|
||||
if(RedBitGet(gpRedMR->abEntries, ulOffset) == fAllocated)
|
||||
{
|
||||
/* The driver shouldn't ever set a bit in the imap to its current
|
||||
value. This is more of a problem with the external imap, but it
|
||||
is checked here for consistency.
|
||||
*/
|
||||
CRITICAL_ERROR();
|
||||
ret = -RED_EFUBAR;
|
||||
}
|
||||
else if(fAllocated)
|
||||
{
|
||||
RedBitSet(gpRedMR->abEntries, ulOffset);
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RedBitClear(gpRedMR->abEntries, ulOffset);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* REDCONF_IMAP_INLINE == 1 */
|
||||
|
1120
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inode.c
Normal file
1120
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inode.c
Normal file
File diff suppressed because it is too large
Load diff
1917
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c
Normal file
1917
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/inodedata.c
Normal file
File diff suppressed because it is too large
Load diff
536
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/volume.c
Normal file
536
FreeRTOS-Plus/Source/Reliance-Edge/core/driver/volume.c
Normal file
|
@ -0,0 +1,536 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements core volume operations.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redcore.h>
|
||||
|
||||
|
||||
static bool MetarootIsValid(METAROOT *pMR, bool *pfSectorCRCIsValid);
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
static void MetaRootEndianSwap(METAROOT *pMetaRoot);
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Mount a file system volume.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO Volume not formatted, improperly formatted, or corrupt.
|
||||
*/
|
||||
REDSTATUS RedVolMount(void)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR);
|
||||
#else
|
||||
ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDONLY);
|
||||
#endif
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedVolMountMaster();
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedVolMountMetaroot();
|
||||
}
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
(void)RedOsBDevClose(gbRedVolNum);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Mount the master block.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO Master block missing, corrupt, or inconsistent with the
|
||||
compile-time driver settings.
|
||||
*/
|
||||
REDSTATUS RedVolMountMaster(void)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
MASTERBLOCK *pMB;
|
||||
|
||||
/* Read the master block, to ensure that the disk was formatted with
|
||||
Reliance Edge.
|
||||
*/
|
||||
ret = RedBufferGet(BLOCK_NUM_MASTER, BFLAG_META_MASTER, CAST_VOID_PTR_PTR(&pMB));
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
/* Verify that the driver was compiled with the same settings that
|
||||
the disk was formatted with. If not, the user has made a
|
||||
mistake: either the driver settings are wrong, or the disk needs
|
||||
to be reformatted.
|
||||
*/
|
||||
if( (pMB->ulVersion != RED_DISK_LAYOUT_VERSION)
|
||||
|| (pMB->ulInodeCount != gpRedVolConf->ulInodeCount)
|
||||
|| (pMB->ulBlockCount != gpRedVolume->ulBlockCount)
|
||||
|| (pMB->uMaxNameLen != REDCONF_NAME_MAX)
|
||||
|| (pMB->uDirectPointers != REDCONF_DIRECT_POINTERS)
|
||||
|| (pMB->uIndirectPointers != REDCONF_INDIRECT_POINTERS)
|
||||
|| (pMB->bBlockSizeP2 != BLOCK_SIZE_P2)
|
||||
|| (((pMB->bFlags & MBFLAG_API_POSIX) != 0U) != (REDCONF_API_POSIX == 1))
|
||||
|| (((pMB->bFlags & MBFLAG_INODE_TIMESTAMPS) != 0U) != (REDCONF_INODE_TIMESTAMPS == 1))
|
||||
|| (((pMB->bFlags & MBFLAG_INODE_BLOCKS) != 0U) != (REDCONF_INODE_BLOCKS == 1)))
|
||||
{
|
||||
ret = -RED_EIO;
|
||||
}
|
||||
#if REDCONF_API_POSIX == 1
|
||||
else if(((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U) != (REDCONF_API_POSIX_LINK == 1))
|
||||
{
|
||||
ret = -RED_EIO;
|
||||
}
|
||||
#else
|
||||
else if((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U)
|
||||
{
|
||||
ret = -RED_EIO;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
/* Master block configuration is valid.
|
||||
|
||||
Save the sequence number of the master block in the volume,
|
||||
since we need it later (see RedVolMountMetaroot()) and we do
|
||||
not want to re-buffer the master block.
|
||||
*/
|
||||
gpRedVolume->ullSequence = pMB->hdr.ullSequence;
|
||||
}
|
||||
|
||||
RedBufferPut(pMB);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Mount the latest metaroot.
|
||||
|
||||
This function also populates the volume contexts.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO Both metaroots are missing or corrupt.
|
||||
*/
|
||||
REDSTATUS RedVolMountMetaroot(void)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT, 1U, &gpRedCoreVol->aMR[0U]);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedIoRead(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + 1U, 1U, &gpRedCoreVol->aMR[1U]);
|
||||
}
|
||||
|
||||
/* Determine which metaroot is the most recent copy that was written
|
||||
completely.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
uint8_t bMR = UINT8_MAX;
|
||||
bool fSectorCRCIsValid;
|
||||
|
||||
if(MetarootIsValid(&gpRedCoreVol->aMR[0U], &fSectorCRCIsValid))
|
||||
{
|
||||
bMR = 0U;
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
MetaRootEndianSwap(&gpRedCoreVol->aMR[0U]);
|
||||
#endif
|
||||
}
|
||||
else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)
|
||||
{
|
||||
ret = -RED_EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Metaroot is not valid, so it is ignored and there's nothing
|
||||
to do here.
|
||||
*/
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(MetarootIsValid(&gpRedCoreVol->aMR[1U], &fSectorCRCIsValid))
|
||||
{
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
MetaRootEndianSwap(&gpRedCoreVol->aMR[1U]);
|
||||
#endif
|
||||
|
||||
if((bMR != 0U) || (gpRedCoreVol->aMR[1U].hdr.ullSequence > gpRedCoreVol->aMR[0U].hdr.ullSequence))
|
||||
{
|
||||
bMR = 1U;
|
||||
}
|
||||
}
|
||||
else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid)
|
||||
{
|
||||
ret = -RED_EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Metaroot is not valid, so it is ignored and there's nothing
|
||||
to do here.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(bMR == UINT8_MAX)
|
||||
{
|
||||
/* Neither metaroot was valid.
|
||||
*/
|
||||
ret = -RED_EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpRedCoreVol->bCurMR = bMR;
|
||||
gpRedMR = &gpRedCoreVol->aMR[bMR];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
/* Normally the metaroot contains the highest sequence number, but the
|
||||
master block is the last block written during format, so on a
|
||||
freshly formatted volume the master block sequence number (stored in
|
||||
gpRedVolume->ullSequence) will be higher than that in the metaroot.
|
||||
*/
|
||||
if(gpRedMR->hdr.ullSequence > gpRedVolume->ullSequence)
|
||||
{
|
||||
gpRedVolume->ullSequence = gpRedMR->hdr.ullSequence;
|
||||
}
|
||||
|
||||
/* gpRedVolume->ullSequence stores the *next* sequence number; to avoid
|
||||
giving the next node written to disk the same sequence number as the
|
||||
metaroot, increment it here.
|
||||
*/
|
||||
ret = RedVolSeqNumIncrement();
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
gpRedVolume->fMounted = true;
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
gpRedVolume->fReadOnly = false;
|
||||
#endif
|
||||
|
||||
#if RESERVED_BLOCKS > 0U
|
||||
gpRedCoreVol->fUseReservedBlocks = false;
|
||||
#endif
|
||||
gpRedCoreVol->ulAlmostFreeBlocks = 0U;
|
||||
|
||||
gpRedCoreVol->aMR[1U - gpRedCoreVol->bCurMR] = *gpRedMR;
|
||||
gpRedCoreVol->bCurMR = 1U - gpRedCoreVol->bCurMR;
|
||||
gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Determine whether the metaroot is valid.
|
||||
|
||||
@param pMR The metaroot buffer.
|
||||
@param pfSectorCRCIsValid Populated with whether the first sector of the
|
||||
metaroot buffer is valid.
|
||||
|
||||
@return Whether the metaroot is valid.
|
||||
|
||||
@retval true The metaroot buffer is valid.
|
||||
@retval false The metaroot buffer is invalid.
|
||||
*/
|
||||
static bool MetarootIsValid(
|
||||
METAROOT *pMR,
|
||||
bool *pfSectorCRCIsValid)
|
||||
{
|
||||
bool fRet = false;
|
||||
|
||||
if(pfSectorCRCIsValid == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else if(pMR == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
*pfSectorCRCIsValid = false;
|
||||
}
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
else if(RedRev32(pMR->hdr.ulSignature) != META_SIG_METAROOT)
|
||||
#else
|
||||
else if(pMR->hdr.ulSignature != META_SIG_METAROOT)
|
||||
#endif
|
||||
{
|
||||
*pfSectorCRCIsValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMR);
|
||||
uint32_t ulSectorCRC = pMR->ulSectorCRC;
|
||||
uint32_t ulCRC;
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
ulSectorCRC = RedRev32(ulSectorCRC);
|
||||
#endif
|
||||
|
||||
/* The sector CRC was zero when the CRC was computed during the
|
||||
transaction, so it must be zero here.
|
||||
*/
|
||||
pMR->ulSectorCRC = 0U;
|
||||
|
||||
ulCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U);
|
||||
|
||||
fRet = ulCRC == ulSectorCRC;
|
||||
*pfSectorCRCIsValid = fRet;
|
||||
|
||||
if(fRet)
|
||||
{
|
||||
if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE)
|
||||
{
|
||||
ulCRC = RedCrc32Update(ulCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize);
|
||||
}
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
ulCRC = RedRev32(ulCRC);
|
||||
#endif
|
||||
|
||||
fRet = ulCRC == pMR->hdr.ulCRC;
|
||||
}
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Commit a transaction point.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
REDSTATUS RedVolTransact(void)
|
||||
{
|
||||
REDSTATUS ret = 0;
|
||||
|
||||
REDASSERT(!gpRedVolume->fReadOnly); /* Should be checked by caller. */
|
||||
|
||||
if(gpRedCoreVol->fBranched)
|
||||
{
|
||||
gpRedMR->ulFreeBlocks += gpRedCoreVol->ulAlmostFreeBlocks;
|
||||
gpRedCoreVol->ulAlmostFreeBlocks = 0U;
|
||||
|
||||
ret = RedBufferFlush(0U, gpRedVolume->ulBlockCount);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
gpRedMR->hdr.ulSignature = META_SIG_METAROOT;
|
||||
gpRedMR->hdr.ullSequence = gpRedVolume->ullSequence;
|
||||
|
||||
ret = RedVolSeqNumIncrement();
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(gpRedMR);
|
||||
uint32_t ulSectorCRC;
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
MetaRootEndianSwap(gpRedMR);
|
||||
#endif
|
||||
|
||||
gpRedMR->ulSectorCRC = 0U;
|
||||
|
||||
ulSectorCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U);
|
||||
|
||||
if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE)
|
||||
{
|
||||
gpRedMR->hdr.ulCRC = RedCrc32Update(ulSectorCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpRedMR->hdr.ulCRC = ulSectorCRC;
|
||||
}
|
||||
|
||||
gpRedMR->ulSectorCRC = ulSectorCRC;
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
gpRedMR->hdr.ulCRC = RedRev32(gpRedMR->hdr.ulCRC);
|
||||
gpRedMR->ulSectorCRC = RedRev32(gpRedMR->ulSectorCRC);
|
||||
#endif
|
||||
|
||||
/* Flush the block device before writing the metaroot, so that all
|
||||
previously written blocks are guaranteed to be on the media before
|
||||
the metaroot is written. Otherwise, if the block device reorders
|
||||
the writes, the metaroot could reach the media before metadata it
|
||||
points at, creating a window for disk corruption if power is lost.
|
||||
*/
|
||||
ret = RedIoFlush(gbRedVolNum);
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedIoWrite(gbRedVolNum, BLOCK_NUM_FIRST_METAROOT + gpRedCoreVol->bCurMR, 1U, gpRedMR);
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
MetaRootEndianSwap(gpRedMR);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Flush the block device to force the metaroot write to the media. This
|
||||
guarantees the transaction point is really complete before we return.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedIoFlush(gbRedVolNum);
|
||||
}
|
||||
|
||||
/* Toggle to the other metaroot buffer. The working state and committed
|
||||
state metaroot buffers exchange places.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
uint8_t bNextMR = 1U - gpRedCoreVol->bCurMR;
|
||||
|
||||
gpRedCoreVol->aMR[bNextMR] = *gpRedMR;
|
||||
gpRedCoreVol->bCurMR = bNextMR;
|
||||
|
||||
gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR];
|
||||
|
||||
gpRedCoreVol->fBranched = false;
|
||||
}
|
||||
|
||||
CRITICAL_ASSERT(ret == 0);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
static void MetaRootEndianSwap(
|
||||
METAROOT *pMetaRoot)
|
||||
{
|
||||
if(pMetaRoot == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else
|
||||
{
|
||||
pMetaRoot->ulSectorCRC = RedRev32(pMetaRoot->ulSectorCRC);
|
||||
pMetaRoot->ulFreeBlocks = RedRev32(pMetaRoot->ulFreeBlocks);
|
||||
#if REDCONF_API_POSIX == 1
|
||||
pMetaRoot->ulFreeInodes = RedRev32(pMetaRoot->ulFreeInodes);
|
||||
#endif
|
||||
pMetaRoot->ulAllocNextBlock = RedRev32(pMetaRoot->ulAllocNextBlock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Process a critical file system error.
|
||||
|
||||
@param pszFileName The file in which the error occurred.
|
||||
@param ulLineNum The line number at which the error occurred.
|
||||
*/
|
||||
void RedVolCriticalError(
|
||||
const char *pszFileName,
|
||||
uint32_t ulLineNum)
|
||||
{
|
||||
#if REDCONF_OUTPUT == 1
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
if(!gpRedVolume->fReadOnly)
|
||||
{
|
||||
RedOsOutputString("Critical file system error in Reliance Edge, setting volume to READONLY\n");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
RedOsOutputString("Critical file system error in Reliance Edge (volume already READONLY)\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
gpRedVolume->fReadOnly = true;
|
||||
#endif
|
||||
|
||||
#if REDCONF_ASSERTS == 1
|
||||
RedOsAssertFail(pszFileName, ulLineNum);
|
||||
#else
|
||||
(void)pszFileName;
|
||||
(void)ulLineNum;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** @brief Increment the sequence number.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL Cannot increment sequence number: maximum value reached.
|
||||
This should not ever happen.
|
||||
*/
|
||||
REDSTATUS RedVolSeqNumIncrement(void)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if(gpRedVolume->ullSequence == UINT64_MAX)
|
||||
{
|
||||
/* In practice this should never, ever happen; to get here, there would
|
||||
need to be UINT64_MAX disk writes, which would take eons: longer
|
||||
than the lifetime of any product or storage media. If this assert
|
||||
fires and the current year is still written with four digits,
|
||||
suspect memory corruption.
|
||||
*/
|
||||
CRITICAL_ERROR();
|
||||
ret = -RED_EFUBAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpRedVolume->ullSequence++;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
257
FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcore.h
Normal file
257
FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcore.h
Normal file
|
@ -0,0 +1,257 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDCORE_H
|
||||
#define REDCORE_H
|
||||
|
||||
|
||||
#include <redstat.h>
|
||||
#include <redvolume.h>
|
||||
#include "rednodes.h"
|
||||
#include "redcoremacs.h"
|
||||
#include "redcorevol.h"
|
||||
|
||||
|
||||
#define META_SIG_MASTER (0x5453414DU) /* 'MAST' */
|
||||
#define META_SIG_METAROOT (0x4154454DU) /* 'META' */
|
||||
#define META_SIG_IMAP (0x50414D49U) /* 'IMAP' */
|
||||
#define META_SIG_INODE (0x444F4E49U) /* 'INOD' */
|
||||
#define META_SIG_DINDIR (0x494C4244U) /* 'DBLI' */
|
||||
#define META_SIG_INDIR (0x49444E49U) /* 'INDI' */
|
||||
|
||||
|
||||
REDSTATUS RedIoRead(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, void *pBuffer);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedIoWrite(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, const void *pBuffer);
|
||||
REDSTATUS RedIoFlush(uint8_t bVolNum);
|
||||
#endif
|
||||
|
||||
|
||||
/** Indicates a block buffer is dirty (its contents are different than the
|
||||
contents of the corresponding block on disk); or, when passed into
|
||||
RedBufferGet(), indicates that the buffer should be marked dirty.
|
||||
*/
|
||||
#define BFLAG_DIRTY ((uint16_t) 0x0001U)
|
||||
|
||||
/** Tells RedBufferGet() that the buffer is for a newly allocated block, and its
|
||||
contents should be zeroed instead of being read from disk. Always used in
|
||||
combination with BFLAG_DIRTY.
|
||||
*/
|
||||
#define BFLAG_NEW ((uint16_t) 0x0002U)
|
||||
|
||||
/** Indicates that a block buffer is a master block (MASTERBLOCK) metadata node.
|
||||
*/
|
||||
#define BFLAG_META_MASTER ((uint16_t)(0x0004U | BFLAG_META))
|
||||
|
||||
/** Indicates that a block buffer is an imap (IMAPNODE) metadata node.
|
||||
*/
|
||||
#define BFLAG_META_IMAP ((uint16_t)(0x0008U | BFLAG_META))
|
||||
|
||||
/** Indicates that a block buffer is an inode (INODE) metadata node.
|
||||
*/
|
||||
#define BFLAG_META_INODE ((uint16_t)(0x0010U | BFLAG_META))
|
||||
|
||||
/** Indicates that a block buffer is an indirect (INDIR) metadata node.
|
||||
*/
|
||||
#define BFLAG_META_INDIR ((uint16_t)(0x0020U | BFLAG_META))
|
||||
|
||||
/** Indicates that a block buffer is a double indirect (DINDIR) metadata node.
|
||||
*/
|
||||
#define BFLAG_META_DINDIR ((uint16_t)(0x0040U | BFLAG_META))
|
||||
|
||||
/** Indicates that a block buffer is a metadata node. Callers of RedBufferGet()
|
||||
should not use this flag; instead, use one of the BFLAG_META_* flags.
|
||||
*/
|
||||
#define BFLAG_META ((uint16_t) 0x8000U)
|
||||
|
||||
|
||||
void RedBufferInit(void);
|
||||
REDSTATUS RedBufferGet(uint32_t ulBlock, uint16_t uFlags, void **ppBuffer);
|
||||
void RedBufferPut(const void *pBuffer);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedBufferFlush(uint32_t ulBlockStart, uint32_t ulBlockCount);
|
||||
void RedBufferDirty(const void *pBuffer);
|
||||
void RedBufferBranch(const void *pBuffer, uint32_t ulBlockNew);
|
||||
#if (REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED
|
||||
void RedBufferDiscard(const void *pBuffer);
|
||||
#endif
|
||||
#endif
|
||||
REDSTATUS RedBufferDiscardRange(uint32_t ulBlockStart, uint32_t ulBlockCount);
|
||||
|
||||
|
||||
/** @brief Allocation state of a block.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */
|
||||
ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */
|
||||
ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */
|
||||
ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */
|
||||
} ALLOCSTATE;
|
||||
|
||||
REDSTATUS RedImapBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedImapBlockSet(uint32_t ulBlock, bool fAllocated);
|
||||
REDSTATUS RedImapAllocBlock(uint32_t *pulBlock);
|
||||
#endif
|
||||
REDSTATUS RedImapBlockState(uint32_t ulBlock, ALLOCSTATE *pState);
|
||||
|
||||
#if REDCONF_IMAP_INLINE == 1
|
||||
REDSTATUS RedImapIBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
|
||||
REDSTATUS RedImapIBlockSet(uint32_t ulBlock, bool fAllocated);
|
||||
#endif
|
||||
|
||||
#if REDCONF_IMAP_EXTERNAL == 1
|
||||
REDSTATUS RedImapEBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated);
|
||||
REDSTATUS RedImapEBlockSet(uint32_t ulBlock, bool fAllocated);
|
||||
uint32_t RedImapNodeBlock(uint8_t bMR, uint32_t ulImapNode);
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Cached inode structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ulInode; /**< The inode number of the cached inode. */
|
||||
#if REDCONF_API_POSIX == 1
|
||||
bool fDirectory; /**< True if the inode is a directory. */
|
||||
#endif
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
bool fBranched; /**< True if the inode is branched (writeable). */
|
||||
bool fDirty; /**< True if the inode buffer is dirty. */
|
||||
#endif
|
||||
bool fCoordInited; /**< True after the first seek. */
|
||||
|
||||
INODE *pInodeBuf; /**< Pointer to the inode buffer. */
|
||||
#if DINDIR_POINTERS > 0U
|
||||
DINDIR *pDindir; /**< Pointer to the double indirect node buffer. */
|
||||
#endif
|
||||
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
|
||||
INDIR *pIndir; /**< Pointer to the indirect node buffer. */
|
||||
#endif
|
||||
uint8_t *pbData; /**< Pointer to the data block buffer. */
|
||||
|
||||
/* All the members below this point are part of the seek coordinates; see
|
||||
RedInodeDataSeek().
|
||||
*/
|
||||
uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */
|
||||
#if DINDIR_POINTERS > 0U
|
||||
uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */
|
||||
#endif
|
||||
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
|
||||
uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */
|
||||
#endif
|
||||
uint32_t ulDataBlock; /**< Physical block number of the file data block. */
|
||||
|
||||
uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */
|
||||
#if DINDIR_POINTERS > 0U
|
||||
uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */
|
||||
#endif
|
||||
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
|
||||
uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */
|
||||
#endif
|
||||
} CINODE;
|
||||
|
||||
#define CINODE_IS_MOUNTED(pInode) (((pInode) != NULL) && INODE_IS_VALID((pInode)->ulInode) && ((pInode)->pInodeBuf != NULL))
|
||||
#define CINODE_IS_DIRTY(pInode) (CINODE_IS_MOUNTED(pInode) && (pInode)->fDirty)
|
||||
|
||||
|
||||
#define IPUT_UPDATE_ATIME (0x01U)
|
||||
#define IPUT_UPDATE_MTIME (0x02U)
|
||||
#define IPUT_UPDATE_CTIME (0x04U)
|
||||
#define IPUT_UPDATE_MASK (IPUT_UPDATE_ATIME|IPUT_UPDATE_MTIME|IPUT_UPDATE_CTIME)
|
||||
|
||||
|
||||
REDSTATUS RedInodeMount(CINODE *pInode, FTYPE type, bool fBranch);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedInodeBranch(CINODE *pInode);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)
|
||||
REDSTATUS RedInodeCreate(CINODE *pInode, uint32_t ulPInode, uint16_t uMode);
|
||||
#endif
|
||||
#if DELETE_SUPPORTED
|
||||
REDSTATUS RedInodeDelete(CINODE *pInode);
|
||||
REDSTATUS RedInodeLinkDec(CINODE *pInode);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)
|
||||
REDSTATUS RedInodeFree(CINODE *pInode);
|
||||
#endif
|
||||
void RedInodePut(CINODE *pInode, uint8_t bTimeFields);
|
||||
void RedInodePutCoord(CINODE *pInode);
|
||||
#if DINDIR_POINTERS > 0U
|
||||
void RedInodePutDindir(CINODE *pInode);
|
||||
#endif
|
||||
#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES
|
||||
void RedInodePutIndir(CINODE *pInode);
|
||||
#endif
|
||||
void RedInodePutData(CINODE *pInode);
|
||||
#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || FORMAT_SUPPORTED)) || (REDCONF_CHECKER == 1)
|
||||
REDSTATUS RedInodeIsFree(uint32_t ulInode, bool *pfFree);
|
||||
#endif
|
||||
REDSTATUS RedInodeBitGet(uint8_t bMR, uint32_t ulInode, uint8_t bWhich, bool *pfAllocated);
|
||||
|
||||
REDSTATUS RedInodeDataRead(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedInodeDataWrite(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);
|
||||
#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED
|
||||
REDSTATUS RedInodeDataTruncate(CINODE *pInode, uint64_t ullSize);
|
||||
#endif
|
||||
#endif
|
||||
REDSTATUS RedInodeDataSeekAndRead(CINODE *pInode, uint32_t ulBlock);
|
||||
REDSTATUS RedInodeDataSeek(CINODE *pInode, uint32_t ulBlock);
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedDirEntryCreate(CINODE *pPInode, const char *pszName, uint32_t ulInode);
|
||||
#endif
|
||||
#if DELETE_SUPPORTED
|
||||
REDSTATUS RedDirEntryDelete(CINODE *pPInode, uint32_t ulDeleteIdx);
|
||||
#endif
|
||||
REDSTATUS RedDirEntryLookup(CINODE *pPInode, const char *pszName, uint32_t *pulEntryIdx, uint32_t *pulInode);
|
||||
#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1)
|
||||
REDSTATUS RedDirEntryRead(CINODE *pPInode, uint32_t *pulIdx, char *pszName, uint32_t *pulInode);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
|
||||
REDSTATUS RedDirEntryRename(CINODE *pSrcPInode, const char *pszSrcName, CINODE *pSrcInode, CINODE *pDstPInode, const char *pszDstName, CINODE *pDstInode);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
REDSTATUS RedVolMount(void);
|
||||
REDSTATUS RedVolMountMaster(void);
|
||||
REDSTATUS RedVolMountMetaroot(void);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedVolTransact(void);
|
||||
#endif
|
||||
void RedVolCriticalError(const char *pszFileName, uint32_t ulLineNum);
|
||||
REDSTATUS RedVolSeqNumIncrement(void);
|
||||
|
||||
#if FORMAT_SUPPORTED
|
||||
REDSTATUS RedVolFormat(void);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDCOREMACS_H
|
||||
#define REDCOREMACS_H
|
||||
|
||||
|
||||
#define BLOCK_NUM_MASTER (0UL) /* Block number of the master block. */
|
||||
#define BLOCK_NUM_FIRST_METAROOT (1UL) /* Block number of the first metaroot. */
|
||||
|
||||
#define BLOCK_SPARSE (0U)
|
||||
|
||||
#define DINDIR_POINTERS ((INODE_ENTRIES - REDCONF_DIRECT_POINTERS) - REDCONF_INDIRECT_POINTERS)
|
||||
#define DINDIR_DATA_BLOCKS (INDIR_ENTRIES * INDIR_ENTRIES)
|
||||
|
||||
#define INODE_INDIR_BLOCKS (REDCONF_INDIRECT_POINTERS * INDIR_ENTRIES)
|
||||
#define INODE_DINDIR_BLOCKS (DINDIR_POINTERS * DINDIR_DATA_BLOCKS)
|
||||
#define INODE_DATA_BLOCKS (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS + INODE_DINDIR_BLOCKS)
|
||||
#define INODE_SIZE_MAX (UINT64_SUFFIX(1) * REDCONF_BLOCK_SIZE * INODE_DATA_BLOCKS)
|
||||
|
||||
|
||||
/* First inode number that can be allocated.
|
||||
*/
|
||||
#if REDCONF_API_POSIX == 1
|
||||
#define INODE_FIRST_FREE (INODE_FIRST_VALID + 1U)
|
||||
#else
|
||||
#define INODE_FIRST_FREE (INODE_FIRST_VALID)
|
||||
#endif
|
||||
|
||||
/** @brief Determine if an inode number is valid.
|
||||
*/
|
||||
#define INODE_IS_VALID(INODENUM) (((INODENUM) >= INODE_FIRST_VALID) && ((INODENUM) < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount)))
|
||||
|
||||
|
||||
/* The number of blocks reserved to allow a truncate or delete operation to
|
||||
complete when the disk is otherwise full.
|
||||
|
||||
The more expensive of the two operations is delete, which has to actually
|
||||
write to a file data block to remove the directory entry.
|
||||
*/
|
||||
#if REDCONF_READ_ONLY == 1
|
||||
#define RESERVED_BLOCKS 0U
|
||||
#elif (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))
|
||||
#if DINDIR_POINTERS > 0U
|
||||
#define RESERVED_BLOCKS 3U
|
||||
#elif REDCONF_INDIRECT_POINTERS > 0U
|
||||
#define RESERVED_BLOCKS 2U
|
||||
#else
|
||||
#define RESERVED_BLOCKS 1U
|
||||
#endif
|
||||
#elif ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))
|
||||
#if DINDIR_POINTERS > 0U
|
||||
#define RESERVED_BLOCKS 2U
|
||||
#elif REDCONF_INDIRECT_POINTERS > 0U
|
||||
#define RESERVED_BLOCKS 1U
|
||||
#else
|
||||
#define RESERVED_BLOCKS 0U
|
||||
#endif
|
||||
#else
|
||||
#define RESERVED_BLOCKS 0U
|
||||
#endif
|
||||
|
||||
|
||||
#define CRITICAL_ASSERT(EXP) ((EXP) ? (void)0 : CRITICAL_ERROR())
|
||||
#define CRITICAL_ERROR() RedVolCriticalError(__FILE__, __LINE__)
|
||||
|
||||
|
||||
#endif
|
||||
|
95
FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcorevol.h
Normal file
95
FreeRTOS-Plus/Source/Reliance-Edge/core/include/redcorevol.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDCOREVOL_H
|
||||
#define REDCOREVOL_H
|
||||
|
||||
|
||||
/** @brief Per-volume run-time data specific to the core.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Whether this volume uses the inline imap (true) or external imap
|
||||
(false). Computed at initialization time based on the block count.
|
||||
*/
|
||||
bool fImapInline;
|
||||
|
||||
#if REDCONF_IMAP_EXTERNAL == 1
|
||||
/** First block number of the on-disk imap. Valid only when fImapInline
|
||||
is false.
|
||||
*/
|
||||
uint32_t ulImapStartBN;
|
||||
|
||||
/** The number of double-allocated imap nodes that make up the imap.
|
||||
*/
|
||||
uint32_t ulImapNodeCount;
|
||||
#endif
|
||||
|
||||
/** Block number where the inode table starts.
|
||||
*/
|
||||
uint32_t ulInodeTableStartBN;
|
||||
|
||||
/** First block number that can be allocated.
|
||||
*/
|
||||
uint32_t ulFirstAllocableBN;
|
||||
|
||||
/** The two metaroot structures, committed and working state.
|
||||
*/
|
||||
METAROOT aMR[2U];
|
||||
|
||||
/** The index of the current metaroot; must be 0 or 1.
|
||||
*/
|
||||
uint8_t bCurMR;
|
||||
|
||||
/** Whether the volume has been branched or not.
|
||||
*/
|
||||
bool fBranched;
|
||||
|
||||
/** The number of blocks which will become free after the next transaction.
|
||||
*/
|
||||
uint32_t ulAlmostFreeBlocks;
|
||||
|
||||
#if RESERVED_BLOCKS > 0U
|
||||
/** Whether to use the blocks reserved for operations that create free
|
||||
space.
|
||||
*/
|
||||
bool fUseReservedBlocks;
|
||||
#endif
|
||||
} COREVOLUME;
|
||||
|
||||
/* Pointer to the core volume currently being accessed; populated during
|
||||
RedCoreVolSetCurrent().
|
||||
*/
|
||||
extern COREVOLUME * CONST_IF_ONE_VOLUME gpRedCoreVol;
|
||||
|
||||
/* Pointer to the metaroot currently being accessed; populated during
|
||||
RedCoreVolSetCurrent() and RedCoreVolTransact().
|
||||
*/
|
||||
extern METAROOT *gpRedMR;
|
||||
|
||||
|
||||
#endif
|
||||
|
195
FreeRTOS-Plus/Source/Reliance-Edge/core/include/rednodes.h
Normal file
195
FreeRTOS-Plus/Source/Reliance-Edge/core/include/rednodes.h
Normal file
|
@ -0,0 +1,195 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDNODES_H
|
||||
#define REDNODES_H
|
||||
|
||||
|
||||
#define NODEHEADER_SIZE (16U)
|
||||
#define NODEHEADER_OFFSET_SIG (0U)
|
||||
#define NODEHEADER_OFFSET_CRC (4U)
|
||||
#define NODEHEADER_OFFSET_SEQ (8U)
|
||||
|
||||
/** @brief Common header for all metadata nodes.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */
|
||||
uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */
|
||||
uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */
|
||||
} NODEHEADER;
|
||||
|
||||
|
||||
/** Flag set in the master block when REDCONF_API_POSIX == 1. */
|
||||
#define MBFLAG_API_POSIX (0x01U)
|
||||
|
||||
/** Flag set in the master block when REDCONF_INODE_TIMESTAMPS == 1. */
|
||||
#define MBFLAG_INODE_TIMESTAMPS (0x02U)
|
||||
|
||||
/** Flag set in the master block when REDCONF_INODE_BLOCKS == 1. */
|
||||
#define MBFLAG_INODE_BLOCKS (0x04U)
|
||||
|
||||
/** Flag set in the master block when (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1). */
|
||||
#define MBFLAG_INODE_NLINK (0x08U)
|
||||
|
||||
|
||||
/** @brief Node which identifies the volume and stores static volume information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
NODEHEADER hdr; /**< Common node header. */
|
||||
|
||||
uint32_t ulVersion; /**< On-disk layout version number. */
|
||||
char acBuildNum[8U]; /**< Build number of the product (not null terminated). */
|
||||
uint32_t ulFormatTime; /**< Date and time the volume was formatted. */
|
||||
uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */
|
||||
uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */
|
||||
uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */
|
||||
uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */
|
||||
uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */
|
||||
uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */
|
||||
uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */
|
||||
} MASTERBLOCK;
|
||||
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 16U) /* Size in bytes of the metaroot header fields. */
|
||||
#else
|
||||
#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 12U) /* Size in bytes of the metaroot header fields. */
|
||||
#endif
|
||||
#define METAROOT_ENTRY_BYTES (REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE) /* Number of bytes remaining in the metaroot block for entries. */
|
||||
#define METAROOT_ENTRIES (METAROOT_ENTRY_BYTES * 8U)
|
||||
|
||||
/** @brief Metadata root node; each volume has two.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
NODEHEADER hdr; /**< Common node header. */
|
||||
|
||||
uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */
|
||||
uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */
|
||||
#if REDCONF_API_POSIX == 1
|
||||
uint32_t ulFreeInodes; /**< Number of inode slots that are free. */
|
||||
#endif
|
||||
uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */
|
||||
|
||||
/** Imap bitmap. With inline imaps, this is the imap bitmap that indicates
|
||||
which inode blocks are used and which allocable blocks are used.
|
||||
Otherwise, this bitmap toggles nodes in the external imap between one
|
||||
of two possible block locations.
|
||||
*/
|
||||
uint8_t abEntries[METAROOT_ENTRY_BYTES];
|
||||
} METAROOT;
|
||||
|
||||
|
||||
#if REDCONF_IMAP_EXTERNAL == 1
|
||||
#define IMAPNODE_HEADER_SIZE (NODEHEADER_SIZE) /* Size in bytes of the imap node header fields. */
|
||||
#define IMAPNODE_ENTRY_BYTES (REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE) /* Number of bytes remaining in the imap node for entries. */
|
||||
#define IMAPNODE_ENTRIES (IMAPNODE_ENTRY_BYTES * 8U)
|
||||
|
||||
/** @brief One node of the external imap.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
NODEHEADER hdr; /**< Common node header. */
|
||||
|
||||
/** Bitmap which indicates which inode blocks are used and which allocable
|
||||
blocks are used.
|
||||
*/
|
||||
uint8_t abEntries[IMAPNODE_ENTRY_BYTES];
|
||||
} IMAPNODE;
|
||||
#endif
|
||||
|
||||
|
||||
#define INODE_HEADER_SIZE (NODEHEADER_SIZE + 8U + ((REDCONF_INODE_BLOCKS == 1) ? 4U : 0U) + \
|
||||
((REDCONF_INODE_TIMESTAMPS == 1) ? 12U : 0U) + 4U + ((REDCONF_API_POSIX == 1) ? 4U : 0U))
|
||||
#define INODE_ENTRIES ((REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE) / 4U)
|
||||
|
||||
#if (REDCONF_DIRECT_POINTERS < 0) || (REDCONF_DIRECT_POINTERS > (INODE_ENTRIES - REDCONF_INDIRECT_POINTERS))
|
||||
#error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS"
|
||||
#endif
|
||||
#if (REDCONF_INDIRECT_POINTERS < 0) || (REDCONF_INDIRECT_POINTERS > (INODE_ENTRIES - REDCONF_DIRECT_POINTERS))
|
||||
#error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS"
|
||||
#endif
|
||||
|
||||
/** @brief Stores metadata for a file or directory.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
NODEHEADER hdr; /**< Common node header. */
|
||||
|
||||
uint64_t ullSize; /**< Size of the inode, in bytes. */
|
||||
#if REDCONF_INODE_BLOCKS == 1
|
||||
uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */
|
||||
#endif
|
||||
#if REDCONF_INODE_TIMESTAMPS == 1
|
||||
uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */
|
||||
uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */
|
||||
uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */
|
||||
#endif
|
||||
uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */
|
||||
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
|
||||
uint16_t uNLink; /**< Link count, number of names pointing to the inode. */
|
||||
#else
|
||||
uint8_t abPadding[2]; /**< Padding to 32-bit align the next member. */
|
||||
#endif
|
||||
#if REDCONF_API_POSIX == 1
|
||||
uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */
|
||||
#endif
|
||||
|
||||
/** Block numbers for lower levels of the file metadata structure. Some
|
||||
fraction of these entries are for direct pointers (file data block
|
||||
numbers), some for indirect pointers, some for double-indirect
|
||||
pointers; the number allocated to each is static but user-configurable.
|
||||
For all types, an array slot is zero if the range is sparse or beyond
|
||||
the end of file.
|
||||
*/
|
||||
uint32_t aulEntries[INODE_ENTRIES];
|
||||
} INODE;
|
||||
|
||||
|
||||
#define INDIR_HEADER_SIZE (NODEHEADER_SIZE + 4U)
|
||||
#define INDIR_ENTRIES ((REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE) / 4U)
|
||||
|
||||
/** @brief Node for storing block pointers.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
NODEHEADER hdr; /**< Common node header. */
|
||||
|
||||
uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */
|
||||
|
||||
/** For indirect nodes, stores block numbers of file data. For double
|
||||
indirect nodes, stores block numbers of indirect nodes. An array
|
||||
slot is zero if the corresponding block or indirect range is beyond
|
||||
the end of file or entirely sparse.
|
||||
*/
|
||||
uint32_t aulEntries[INDIR_ENTRIES];
|
||||
} INDIR, DINDIR;
|
||||
|
||||
|
||||
#endif
|
||||
|
389
FreeRTOS-Plus/Source/Reliance-Edge/doc/coding_style.txt
Normal file
389
FreeRTOS-Plus/Source/Reliance-Edge/doc/coding_style.txt
Normal file
|
@ -0,0 +1,389 @@
|
|||
Datalight Coding Style
|
||||
======================
|
||||
|
||||
This is a description of the Datalight Coding Style intended for third parties
|
||||
who want to contribute code to Reliance Edge. This document is derived from the
|
||||
DDSS Coding Guidelines, but only contains a subset of the content which is most
|
||||
likely to be relevant to third party contributors.
|
||||
|
||||
Reliance Edge complies with the MISRA-C:2012 coding guidelines, which includes
|
||||
many rules that affect coding style. Unfortunately the MISRA-C:2012 document is
|
||||
not freely available, and is much too long to be effectively summarized, but if
|
||||
you are familiar with the rules, adhere to them. A few important rules of
|
||||
thumb: avoid the goto and continue keywords; avoid using more than one break
|
||||
in a loop; and avoid having more than one return from a function (single point
|
||||
of exit); default cases in every switch statement; avoid recursion; and make
|
||||
generous use of parentheses. Outside of the file system driver, in tests and
|
||||
host tools, the MISRA-C rules are relaxed.
|
||||
|
||||
Beyond MISRA-C, Datalight has a standard coding style. Most aspects of this
|
||||
style are matters of preference, but when contributing code to Datalight an
|
||||
effort should be made to use this style for the sake of consistency.
|
||||
|
||||
Below is an example function, which illustrates several key points of Datalight
|
||||
Coding Style:
|
||||
|
||||
/** @brief One-sentence description of what this function does.
|
||||
|
||||
Additional description.
|
||||
|
||||
@param ulFirstParameter Description of the parameter.
|
||||
@param pszPointer Description of the parameter.
|
||||
|
||||
@return Describe the return value.
|
||||
|
||||
@retval true Optional description of specific return value.
|
||||
@retval false Optional description of specific return value.
|
||||
*/
|
||||
bool ExampleFunction(
|
||||
uint32_t ulFirstParameter,
|
||||
char *pszPointer)
|
||||
{
|
||||
bool fStatus = true;
|
||||
|
||||
/* This is a single-line comment.
|
||||
*/
|
||||
if(ulFirstParameter > 0U)
|
||||
{
|
||||
/* This is a multi-line comment. Filler text: Lorem ipsum dolor sit
|
||||
amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
|
||||
ut labore et dolore magna aliqua.
|
||||
*/
|
||||
FunctionCall();
|
||||
|
||||
while(fStatus)
|
||||
{
|
||||
fStatus = AnotherFunction(ulFirstParameter, pszPointer);
|
||||
}
|
||||
}
|
||||
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
Tab Stop Conventions
|
||||
--------------------
|
||||
|
||||
In all C code (.c/.h), use a tab width of four spaces, and use soft tabs (in
|
||||
other words, tabs are expanded to spaces). In Makefiles, use hard tabs and a
|
||||
tab width of 8.
|
||||
|
||||
Naming
|
||||
------
|
||||
|
||||
Datalight uses CamelCase for functions and variables. Type names are generally
|
||||
UPPERCASE, except for standard types like uint32_t. Preprocessor macros are
|
||||
UPPERCASE, with words separated by underscores (for example, INODE_INVALID).
|
||||
|
||||
Doxygen Documentation
|
||||
---------------------
|
||||
|
||||
Doxygen is used to document functions (including static functions), along with
|
||||
types, structures, files, etc. For Doxygen tags, use '@' instead of a backslash
|
||||
(thus "@param" not "\param").
|
||||
|
||||
Function Declarations
|
||||
---------------------
|
||||
|
||||
Multi-line function declarations are preferred, as they tend to be more
|
||||
readable. Use the following form:
|
||||
|
||||
static bool ExampleFunctionDeclaration(
|
||||
uint32_t ulFirstParameter,
|
||||
char *pszPointer,
|
||||
uint8_t **ppbBuffer)
|
||||
{
|
||||
uint16_t uLocalVar; /* descriptive comment */
|
||||
uint8_t *pbBuffer = NULL; /* descriptive comment */
|
||||
|
||||
Function body...
|
||||
}
|
||||
|
||||
The following guidelines should be used:
|
||||
|
||||
- Align both the data-type and the variable names, for parameters and locals, at
|
||||
the same level if practical.
|
||||
- For pointer types, the '*' belongs to the variable name---it's not part of the
|
||||
data-type, so keep it with the variable name.
|
||||
- If useful, single line comments may be used to describe local variables (not
|
||||
a requirement).
|
||||
- For functions with no parameters, the "void" declaration does not need to be
|
||||
on a separate line.
|
||||
- Generally each variable should be declared on a separate line. This promotes
|
||||
readability, and facilitates having a comment for each variable.
|
||||
|
||||
Function declarations should be spaced apart by two blank lines between the
|
||||
closing brace which ends a function and the Doxygen comment which starts the
|
||||
next.
|
||||
|
||||
Curly Braces
|
||||
------------
|
||||
|
||||
Datalight lines up all curly braces vertically. As per MISRA-C, curly braces
|
||||
are never omitted, even if the braces contain only a single statement.
|
||||
|
||||
For consistency, even structure declarations and initializations should use the
|
||||
same style, with the curly braces lined up vertically. One exception is for
|
||||
structure initializations where both the opening and closing curly braces can
|
||||
fit on the same line. If so, do it.
|
||||
|
||||
Code Comments
|
||||
-------------
|
||||
|
||||
Datalight uses the standard C style /* comments */. C++ style comments (//) are
|
||||
never used. The Datalight standard comment style is shown below. This style
|
||||
applies to all general comments within the code.
|
||||
|
||||
/* This is a single-line comment.
|
||||
*/
|
||||
if(ulFirstParameter > 0U)
|
||||
{
|
||||
/* This is a multi-line comment. Filler text: Lorem ipsum dolor sit amet,
|
||||
consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
|
||||
et dolore magna aliqua.
|
||||
*/
|
||||
while(fStatus)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Note the characteristics:
|
||||
|
||||
- The /* and */ align with the natural 4 character indentation.
|
||||
- The comment text is exactly indented another 4 characters.
|
||||
- The comment text starts on the same line as the opening /*.
|
||||
- The terminating */ is on its own line.
|
||||
- There is usually a single blank line preceding the comment, however if the
|
||||
preceding line is an opening curly brace, then an extra blank line is not
|
||||
necessary.
|
||||
- There is usually no blank line after the comment, but rather the closing */
|
||||
"attaches" the comment to the code about which the comment refers.
|
||||
- These comments should always fit with the standard 80 character margin.
|
||||
|
||||
Comments where the /* and */ are on the same line may be used in a few places:
|
||||
|
||||
- For variable or parameter descriptions, where the comment fits on the same
|
||||
line as the declaration.
|
||||
- For structure member declarations, where the comment fits on the same line as
|
||||
the declaration.
|
||||
- For macros or preprocessor logic, where the comment fits on the same line.
|
||||
|
||||
It is OK for such comments to exceed the 80 character margin by a small amount,
|
||||
if necessary, as this sometimes promotes code readability.
|
||||
|
||||
Indentation Style
|
||||
-----------------
|
||||
|
||||
The general paradigm used in Datalight code is that curly braces line up
|
||||
vertically, and everything in between them is indented. This should include all
|
||||
comments, labels, and preprocessor symbols. The only things which are aligned
|
||||
at the left-most columns are:
|
||||
|
||||
- Symbols, variables, declarations, and preprocessor logic which are at the
|
||||
module-scope (outside of a function)
|
||||
- Comments which are outside of a function
|
||||
- Function declarations
|
||||
- Function open and closing curly braces
|
||||
|
||||
Typically comments are always lined up directly with the code to which they
|
||||
apply.
|
||||
|
||||
Labels (when used; gotos are disallowed in driver code) are lined up two
|
||||
characters to the left of the code they reside in, to make them stand out, while
|
||||
as the same time, still remaining subservient to the level of curly braces in
|
||||
which they reside. For example:
|
||||
|
||||
bool ExampleLabelUsage(void)
|
||||
{
|
||||
MutexLock();
|
||||
|
||||
Lots of complicated code...
|
||||
|
||||
Unlock:
|
||||
|
||||
MutexUnlock();
|
||||
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
Preprocessor logic, such as controlling features which are conditionally
|
||||
compiled in or out, should not disrupt the flow of the code, but rather should
|
||||
be indented in similar fashion to the code it controls, but positioned two
|
||||
characters to the left. For example, consider the following code snippet. The
|
||||
preprocessor conditions are both indented relative to the outer curly braces,
|
||||
but do not disrupt the normal code flow.
|
||||
|
||||
int32_t red_statvfs(
|
||||
const char *pszVolume,
|
||||
REDSTATFS *pStatvfs)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = PosixEnter();
|
||||
if(ret == 0)
|
||||
{
|
||||
uint8_t bVolNum;
|
||||
|
||||
ret = RedPathSplit(pszVolume, &bVolNum, NULL);
|
||||
|
||||
#if REDCONF_VOLUME_COUNT > 1U
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreVolSetCurrent(bVolNum);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreVolStat(pStatvfs);
|
||||
}
|
||||
|
||||
PosixLeave();
|
||||
}
|
||||
|
||||
return PosixReturn(ret);
|
||||
}
|
||||
|
||||
Note that, like anything else between curly brackets, the contents of a switch
|
||||
statement are indented:
|
||||
|
||||
switch(ulSignature)
|
||||
{
|
||||
case META_SIG_MASTER:
|
||||
fValid = (uFlags == BFLAG_META_MASTER);
|
||||
break;
|
||||
case META_SIG_IMAP:
|
||||
fValid = (uFlags == BFLAG_META_IMAP);
|
||||
break;
|
||||
case META_SIG_INODE:
|
||||
fValid = (uFlags == BFLAG_META_INODE);
|
||||
break;
|
||||
case META_SIG_DINDIR:
|
||||
fValid = (uFlags == BFLAG_META_DINDIR);
|
||||
break;
|
||||
case META_SIG_INDIR:
|
||||
fValid = (uFlags == BFLAG_META_INDIR);
|
||||
break;
|
||||
default:
|
||||
fValid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
Maximum Line Length
|
||||
-------------------
|
||||
|
||||
The maximum line length for code need not be rigidly limited to the traditional
|
||||
80 characters. Nevertheless the line lengths should be kept reasonable.
|
||||
Anything longer than 100 to 120 characters should probably be broken up. The
|
||||
most important consideration is readability---fitting on the screen is important
|
||||
for readability, but equally important is facilitating an easy understanding of
|
||||
the logical code flow.
|
||||
|
||||
There are a few exceptions on both sides of the issue. Generally comments
|
||||
should be limited to 80 characters always. Some lines of code may exceed the
|
||||
120 character length by a large margin, if it makes the code more understandable
|
||||
and maintainable. This is especially true when dealing with code that generates
|
||||
output which needs to be lined up.
|
||||
|
||||
Regardless of everything else, no lines should exceed 250 characters because
|
||||
some editors cannot handle anything larger.
|
||||
|
||||
Maximum Display Output Line Length
|
||||
----------------------------------
|
||||
|
||||
Any code which displays TTY style output, whether on a screen or a terminal,
|
||||
should be constructed so the output is readable and wraps properly on an 80
|
||||
character wide display. This primarily applies to the "standard" output from
|
||||
various tests and tools as well as syntax output for those tests and tools;
|
||||
debug output can violate this rule.
|
||||
|
||||
Preprocessor Notation
|
||||
---------------------
|
||||
|
||||
Don't use preprocessor notation where the # is separated from the keyword by one
|
||||
or more white spaces. For example, don't do:
|
||||
|
||||
#ifndef SYMBOL1
|
||||
# define SYMBOL1
|
||||
#endif
|
||||
|
||||
Instead, do:
|
||||
|
||||
#ifndef SYMBOL1
|
||||
#define SYMBOL1
|
||||
#endif
|
||||
|
||||
Hexadecimal Notation
|
||||
--------------------
|
||||
|
||||
Use uppercase for any alphabetic hexadecimal digits, and lower case for the
|
||||
notational element. For example:
|
||||
|
||||
#define HEXNUM 0x123abd /* Bad */
|
||||
#define HEXNUM 0X123ABD /* Bad */
|
||||
#define HEXNUM 0x123ABD /* Good */
|
||||
|
||||
Hungarian Notation
|
||||
------------------
|
||||
|
||||
Datalight uses Hungarian notation. The following type prefixes are used:
|
||||
|
||||
Type Prefix | Meaning
|
||||
----------- | -------
|
||||
c | char
|
||||
uc | unsigned char
|
||||
i | int
|
||||
n | unsigned int or size_t
|
||||
b | uint8_t
|
||||
u | uint16_t
|
||||
ul | uint32_t
|
||||
ull | uint64_t
|
||||
sz | array of char that will be null-terminated
|
||||
f | bool
|
||||
h | A handle
|
||||
fn | A function (always used with the "p" modifier)
|
||||
|
||||
There is no official Hungarian for int8_t, int16_t, int32_t, or int64_t,
|
||||
although some code uses unofficial variants (like "ll" for int64_t).
|
||||
|
||||
The following modifiers may be used in combination with the type prefixes
|
||||
defined above, or in combination with other types:
|
||||
|
||||
Modifier | Meaning
|
||||
-------- | -------
|
||||
a | An array
|
||||
p | A pointer
|
||||
g | A global variable
|
||||
|
||||
Notes:
|
||||
|
||||
- There is no standard Hungarian for structure declarations, however the use of
|
||||
the "a" and "p" modifiers is completely appropriate (and expected).
|
||||
- For those data types which do not have any standard defined Hungarian prefix,
|
||||
using none is preferable to misusing another prefix which would lead to
|
||||
confusion.
|
||||
- The "p" pointer modifier must be used such that a variable which is a pointer
|
||||
to a pointer uses multiple "p" prefixes. A general rule-of-thumb is that the
|
||||
variable name should have the same number of "p" prefixes as the declaration
|
||||
has asterisks. This allows pointer expressions to be easily decoded using
|
||||
cancellation.
|
||||
|
||||
Variable Scope
|
||||
--------------
|
||||
|
||||
Declare a variable in the narrowest scope in which it is meaningful.
|
||||
Unnecessarily declaring all variables at the beginning of a function, where they
|
||||
may be physically far from where they are actually used, makes the code harder
|
||||
to maintain.
|
||||
|
||||
When multiple blocks of code share a variable, but not its value, declare the
|
||||
variable separately for each code block.
|
||||
|
||||
For example, if two separate blocks contain loops indexed by a variable ulIndex
|
||||
declare it separately in each block rather than declaring it once in a wider
|
||||
scope and using it in both places.
|
||||
|
||||
Using distinct declarations in the two blocks allows the compiler to check for
|
||||
failure to initialize the variable in the second block. If there is a single
|
||||
declaration, the (now meaningless) value left over from the first block can be
|
||||
used erroneously in the second block.
|
||||
|
61
FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.md
Normal file
61
FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Reliance Edge Release Notes
|
||||
|
||||
This file contains a list of updates made to Reliance Edge over the course of
|
||||
recent releases and a list of known issues.
|
||||
|
||||
## Release History and Changes
|
||||
|
||||
### Reliance Edge v1.0, July 2015
|
||||
|
||||
#### Common Code Changes
|
||||
|
||||
- First release of commercial kit and MISRA C:2012 Design Assurance Package.
|
||||
The commercial kit includes many new tools and tests which were not previously
|
||||
available.
|
||||
- Overhauled parsing of command-line parameters to be consistent for all tools
|
||||
and tests. Command-line tools now use Unix-style short and long options (such
|
||||
as `-H` and `--help`) instead of DOS-style switches (such as `/?`).
|
||||
- Renamed all os/\*/include/ostypes.h headers to os/\*/include/redostypes.h, so
|
||||
that all headers use the product prefix. If you created a port using v0.9,
|
||||
this header needs to be renamed and its header guard (#ifndef OSTYPES_H etc.)
|
||||
should also be updated.
|
||||
- Add a new header for OS-specific MISRA C:2012 deviation macros, located at
|
||||
os/\*/include/redosdeviations.h. If you created a port using v0.9, copy the
|
||||
template from os/stub/include/redosdeviations.h into the include directory.
|
||||
- Eliminated support for sector sizes less than 256. If using a smaller sector
|
||||
size (say for a RAM disk), this must now be emulated in the implementation of
|
||||
the block device OS service.
|
||||
- Added RedFseFormat() as an optional FSE API, allowing FSE applications to
|
||||
format the volume at run-time.
|
||||
- This added a new macro to redconf.h: existing redconf.h files from v0.9 must
|
||||
be updated to work with v1.0. Open redconf.h with the configuration tool,
|
||||
ignore the warning about the missing macro, and save it.
|
||||
- Internal restructuring has renamed the macros for the string and memory
|
||||
functions used in redconf.h. An existing redconf.h file from v0.9 will need
|
||||
to be updated; for a file containing the old names, the new config tool will
|
||||
default to using the (slow) Reliance Edge string/memory functions; to use the
|
||||
C library or custom versions, this will need to be selected in the
|
||||
configuration utility.
|
||||
- Fix a bug which would result in an error when attempting to create a name with
|
||||
one or more trailing path separators (such as `red_mkdir("/foo/bar/")`).
|
||||
- Fix a bug where an open handle for an inode on one volume would prevent the
|
||||
same inode number from being deleted on a different volume.
|
||||
|
||||
#### FreeRTOS Port Changes
|
||||
|
||||
- The implementation of the timestamp OS service no longer requires that
|
||||
`configUSE_TIMERS` be set to `1`.
|
||||
|
||||
### Reliance Edge v0.9 (Beta), April 2015
|
||||
|
||||
First public release.
|
||||
|
||||
## Known Issues
|
||||
|
||||
### Visual Studio 2005
|
||||
|
||||
The Reliance Edge Win32 port (used for the host tools and the Win32 test
|
||||
project) cannot be compiled by Visual Studio 2005. This is not going to be
|
||||
fixed since VS2005 is an old toolset. Newer versions of Visual Studio, starting
|
||||
with Visual Studio 2008, work just fine.
|
||||
|
71
FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.txt
Normal file
71
FreeRTOS-Plus/Source/Reliance-Edge/doc/release_notes.txt
Normal file
|
@ -0,0 +1,71 @@
|
|||
|
||||
|
||||
RELIANCE EDGE RELEASE NOTES
|
||||
|
||||
|
||||
This file contains a list of updates made to Reliance Edge over the
|
||||
course of recent releases and a list of known issues.
|
||||
|
||||
|
||||
Release History and Changes
|
||||
|
||||
Reliance Edge v1.0, July 2015
|
||||
|
||||
Common Code Changes
|
||||
|
||||
- First release of commercial kit and MISRA C:2012 Design
|
||||
Assurance Package. The commercial kit includes many new tools and
|
||||
tests which were not previously available.
|
||||
- Overhauled parsing of command-line parameters to be consistent for
|
||||
all tools and tests. Command-line tools now use Unix-style short and
|
||||
long options (such as -H and --help) instead of DOS-style switches
|
||||
(such as /?).
|
||||
- Renamed all os/*/include/ostypes.h headers to
|
||||
os/*/include/redostypes.h, so that all headers use the
|
||||
product prefix. If you created a port using v0.9, this header needs
|
||||
to be renamed and its header guard (#ifndef OSTYPES_H etc.) should
|
||||
also be updated.
|
||||
- Add a new header for OS-specific MISRA C:2012 deviation macros,
|
||||
located at os/*/include/redosdeviations.h. If you created a port
|
||||
using v0.9, copy the template from os/stub/include/redosdeviations.h
|
||||
into the include directory.
|
||||
- Eliminated support for sector sizes less than 256. If using a
|
||||
smaller sector size (say for a RAM disk), this must now be emulated
|
||||
in the implementation of the block device OS service.
|
||||
- Added RedFseFormat() as an optional FSE API, allowing FSE
|
||||
applications to format the volume at run-time.
|
||||
- This added a new macro to redconf.h: existing redconf.h files from
|
||||
v0.9 must be updated to work with v1.0. Open redconf.h with the
|
||||
configuration tool, ignore the warning about the missing macro, and
|
||||
save it.
|
||||
- Internal restructuring has renamed the macros for the string and
|
||||
memory functions used in redconf.h. An existing redconf.h file from
|
||||
v0.9 will need to be updated; for a file containing the old names,
|
||||
the new config tool will default to using the (slow) Reliance Edge
|
||||
string/memory functions; to use the C library or custom versions,
|
||||
this will need to be selected in the configuration utility.
|
||||
- Fix a bug which would result in an error when attempting to create a
|
||||
name with one or more trailing path separators (such as
|
||||
red_mkdir("/foo/bar/")).
|
||||
- Fix a bug where an open handle for an inode on one volume would
|
||||
prevent the same inode number from being deleted on a
|
||||
different volume.
|
||||
|
||||
FreeRTOS Port Changes
|
||||
|
||||
- The implementation of the timestamp OS service no longer requires
|
||||
that configUSE_TIMERS be set to 1.
|
||||
|
||||
Reliance Edge v0.9 (Beta), April 2015
|
||||
|
||||
First public release.
|
||||
|
||||
|
||||
Known Issues
|
||||
|
||||
Visual Studio 2005
|
||||
|
||||
The Reliance Edge Win32 port (used for the host tools and the Win32 test
|
||||
project) cannot be compiled by Visual Studio 2005. This is not going to
|
||||
be fixed since VS2005 is an old toolset. Newer versions of Visual
|
||||
Studio, starting with Visual Studio 2008, work just fine.
|
690
FreeRTOS-Plus/Source/Reliance-Edge/fse/fse.c
Normal file
690
FreeRTOS-Plus/Source/Reliance-Edge/fse/fse.c
Normal file
|
@ -0,0 +1,690 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implementation of the Reliance Edge FSE API.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_API_FSE == 1
|
||||
|
||||
/** @defgroup red_group_fse The File System Essentials Interface
|
||||
@{
|
||||
*/
|
||||
|
||||
#include <redvolume.h>
|
||||
#include <redcoreapi.h>
|
||||
#include <redfse.h>
|
||||
|
||||
|
||||
static REDSTATUS FseEnter(uint8_t bVolNum);
|
||||
static void FseLeave(void);
|
||||
|
||||
|
||||
static bool gfFseInited; /* Whether driver is initialized. */
|
||||
|
||||
|
||||
/** @brief Initialize the Reliance Edge file system driver.
|
||||
|
||||
Prepares the Reliance Edge file system driver to be used. Must be the first
|
||||
Reliance Edge function to be invoked: no volumes can be mounted until the
|
||||
driver has been initialized.
|
||||
|
||||
If this function is called when the Reliance Edge driver is already
|
||||
initialized, it does nothing and returns success.
|
||||
|
||||
This function is not thread safe: attempting to initialize from multiple
|
||||
threads could leave things in a bad state.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
*/
|
||||
REDSTATUS RedFseInit(void)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if(gfFseInited)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RedCoreInit();
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
gfFseInited = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Uninitialize the Reliance Edge file system driver.
|
||||
|
||||
Tears down the Reliance Edge file system driver. Cannot be used until all
|
||||
Reliance Edge volumes are unmounted. A subsequent call to RedFseInit()
|
||||
will initialize the driver again.
|
||||
|
||||
If this function is called when the Reliance Edge driver is already
|
||||
uninitialized, it does nothing and returns success.
|
||||
|
||||
This function is not thread safe: attempting to uninitialize from multiple
|
||||
threads could leave things in a bad state.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EBUSY At least one volume is still mounted.
|
||||
*/
|
||||
REDSTATUS RedFseUninit(void)
|
||||
{
|
||||
REDSTATUS ret = 0;
|
||||
|
||||
if(!gfFseInited)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t bVolNum;
|
||||
|
||||
#if REDCONF_TASK_COUNT > 1U
|
||||
RedOsMutexAcquire();
|
||||
#endif
|
||||
|
||||
for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)
|
||||
{
|
||||
if(gaRedVolume[bVolNum].fMounted)
|
||||
{
|
||||
ret = -RED_EBUSY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
gfFseInited = false;
|
||||
}
|
||||
|
||||
#if REDCONF_TASK_COUNT > 1U
|
||||
RedOsMutexRelease();
|
||||
#endif
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreUninit();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Mount a file system volume.
|
||||
|
||||
Prepares the file system volume to be accessed. Mount will fail if the
|
||||
volume has never been formatted, or if the on-disk format is inconsistent
|
||||
with the compile-time configuration.
|
||||
|
||||
If the volume is already mounted, this function does nothing and returns
|
||||
success.
|
||||
|
||||
@param bVolNum The volume number of the volume to be mounted.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is
|
||||
uninitialized.
|
||||
@retval -RED_EIO Volume not formatted, improperly formatted, or corrupt.
|
||||
*/
|
||||
REDSTATUS RedFseMount(
|
||||
uint8_t bVolNum)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(!gpRedVolume->fMounted)
|
||||
{
|
||||
ret = RedCoreVolMount();
|
||||
}
|
||||
|
||||
FseLeave();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Unmount a file system volume.
|
||||
|
||||
This function discards the in-memory state for the file system and marks it
|
||||
as unmounted. Subsequent attempts to access the volume will fail until the
|
||||
volume is mounted again.
|
||||
|
||||
If unmount automatic transaction points are enabled, this function will
|
||||
commit a transaction point prior to unmounting. If unmount automatic
|
||||
transaction points are disabled, this function will unmount without
|
||||
transacting, effectively discarding the working state.
|
||||
|
||||
Before unmounting, this function will wait for any active file system
|
||||
thread to complete by acquiring the FS mutex. The volume will be marked as
|
||||
unmounted before the FS mutex is released, so subsequent FS threads will
|
||||
possibly block and then see an error when attempting to access a volume
|
||||
which is unmounting or unmounted.
|
||||
|
||||
If the volume is already unmounted, this function does nothing and returns
|
||||
success.
|
||||
|
||||
@param bVolNum The volume number of the volume to be unmounted.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is
|
||||
uninitialized.
|
||||
@retval -RED_EIO I/O error during unmount automatic transaction point.
|
||||
*/
|
||||
REDSTATUS RedFseUnmount(
|
||||
uint8_t bVolNum)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(gpRedVolume->fMounted)
|
||||
{
|
||||
ret = RedCoreVolUnmount();
|
||||
}
|
||||
|
||||
FseLeave();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1)
|
||||
/** @brief Format a file system volume.
|
||||
|
||||
Uses the statically defined volume configuration. After calling this
|
||||
function, the volume needs to be mounted -- see RedFseMount().
|
||||
|
||||
An error is returned if the volume is mounted.
|
||||
|
||||
@param bVolNum The volume number of the volume to be formatted.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EBUSY The volume is mounted.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is
|
||||
uninitialized.
|
||||
@retval -RED_EIO I/O error formatting the volume.
|
||||
*/
|
||||
REDSTATUS RedFseFormat(
|
||||
uint8_t bVolNum)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreVolFormat();
|
||||
|
||||
FseLeave();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Read from a file.
|
||||
|
||||
Data which has not yet been written, but which is before the end-of-file
|
||||
(sparse data), shall read as zeroes. A short read -- where the number of
|
||||
bytes read is less than requested -- indicates that the requested read was
|
||||
partially or, if zero bytes were read, entirely beyond the end-of-file.
|
||||
|
||||
If @p ullFileOffset is at or beyond the maximum file size, it is treated
|
||||
like any other read entirely beyond the end-of-file: no data is read and
|
||||
zero is returned.
|
||||
|
||||
@param bVolNum The volume number of the file to read.
|
||||
@param ulFileNum The file number of the file to read.
|
||||
@param ullFileOffset The file offset to read from.
|
||||
@param ulLength The number of bytes to read.
|
||||
@param pBuffer The buffer to populate with the data read. Must be
|
||||
at least ulLength bytes in size.
|
||||
|
||||
@return The number of bytes read (nonnegative) or a negated ::REDSTATUS
|
||||
code indicating the operation result (negative).
|
||||
|
||||
@retval >=0 The number of bytes read from the file.
|
||||
@retval -RED_EBADF @p ulFileNum is not a valid file number.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
|
||||
or @p pBuffer is `NULL`; or @p ulLength exceeds
|
||||
INT32_MAX and cannot be returned properly.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
int32_t RedFseRead(
|
||||
uint8_t bVolNum,
|
||||
uint32_t ulFileNum,
|
||||
uint64_t ullFileOffset,
|
||||
uint32_t ulLength,
|
||||
void *pBuffer)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if(ulLength > (uint32_t)INT32_MAX)
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = FseEnter(bVolNum);
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
uint32_t ulReadLen = ulLength;
|
||||
|
||||
ret = RedCoreFileRead(ulFileNum, ullFileOffset, &ulReadLen, pBuffer);
|
||||
|
||||
FseLeave();
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = (int32_t)ulReadLen;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Write to a file.
|
||||
|
||||
If the write extends beyond the end-of-file, the file size will be
|
||||
increased.
|
||||
|
||||
A short write -- where the number of bytes written is less than requested
|
||||
-- indicates either that the file system ran out of space but was still
|
||||
able to write some of the request; or that the request would have caused
|
||||
the file to exceed the maximum file size, but some of the data could be
|
||||
written prior to the file size limit.
|
||||
|
||||
If an error is returned (negative return), either none of the data was
|
||||
written or a critical error occurred (like an I/O error) and the file
|
||||
system volume will be read-only.
|
||||
|
||||
@param bVolNum The volume number of the file to write.
|
||||
@param ulFileNum The file number of the file to write.
|
||||
@param ullFileOffset The file offset to write at.
|
||||
@param ulLength The number of bytes to write.
|
||||
@param pBuffer The buffer containing the data to be written. Must
|
||||
be at least ulLength bytes in size.
|
||||
|
||||
@return The number of bytes written (nonnegative) or a negated ::REDSTATUS
|
||||
code indicating the operation result (negative).
|
||||
|
||||
@retval >0 The number of bytes written to the file.
|
||||
@retval -RED_EBADF @p ulFileNum is not a valid file number.
|
||||
@retval -RED_EFBIG No data can be written to the given file offset since
|
||||
the resulting file size would exceed the maximum file
|
||||
size.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
|
||||
or @p pBuffer is `NULL`; or @p ulLength exceeds
|
||||
INT32_MAX and cannot be returned properly.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOSPC No data can be written because there is insufficient
|
||||
free space.
|
||||
@retval -RED_EROFS The file system volume is read-only.
|
||||
*/
|
||||
int32_t RedFseWrite(
|
||||
uint8_t bVolNum,
|
||||
uint32_t ulFileNum,
|
||||
uint64_t ullFileOffset,
|
||||
uint32_t ulLength,
|
||||
const void *pBuffer)
|
||||
{
|
||||
int32_t ret;
|
||||
|
||||
if(ulLength > (uint32_t)INT32_MAX)
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = FseEnter(bVolNum);
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
uint32_t ulWriteLen = ulLength;
|
||||
|
||||
ret = RedCoreFileWrite(ulFileNum, ullFileOffset, &ulWriteLen, pBuffer);
|
||||
|
||||
FseLeave();
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = (int32_t)ulWriteLen;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1)
|
||||
/** @brief Truncate a file (set the file size).
|
||||
|
||||
Allows the file size to be increased, decreased, or to remain the same. If
|
||||
the file size is increased, the new area is sparse (will read as zeroes).
|
||||
If the file size is decreased, the data beyond the new end-of-file will
|
||||
return to free space once it is no longer part of the committed state
|
||||
(either immediately or after the next transaction point).
|
||||
|
||||
This function can fail when the disk is full if @p ullNewFileSize is
|
||||
non-zero. If decreasing the file size, this can be fixed by transacting and
|
||||
trying again: Reliance Edge guarantees that it is possible to perform a
|
||||
truncate of at least one file that decreases the file size after a
|
||||
transaction point. If disk full transactions are enabled, this will happen
|
||||
automatically.
|
||||
|
||||
@param bVolNum The volume number of the file to truncate.
|
||||
@param ulFileNum The file number of the file to truncate.
|
||||
@param ullNewFileSize The new file size, in bytes.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EBADF @p ulFileNum is not a valid file number.
|
||||
@retval -RED_EFBIG @p ullNewFileSize exceeds the maximum file size.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOSPC Insufficient free space to perform the truncate.
|
||||
@retval -RED_EROFS The file system volume is read-only.
|
||||
*/
|
||||
REDSTATUS RedFseTruncate(
|
||||
uint8_t bVolNum,
|
||||
uint32_t ulFileNum,
|
||||
uint64_t ullNewFileSize)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreFileTruncate(ulFileNum, ullNewFileSize);
|
||||
|
||||
FseLeave();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Retrieve the size of a file.
|
||||
|
||||
@param bVolNum The volume number of the file whose size is being read.
|
||||
@param ulFileNum The file number of the file whose size is being read.
|
||||
|
||||
@return The size of the file (nonnegative) or a negated ::REDSTATUS code
|
||||
indicating the operation result (negative).
|
||||
|
||||
@retval >=0 The size of the file.
|
||||
@retval -RED_EBADF @p ulFileNum is not a valid file number.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
*/
|
||||
int64_t RedFseSizeGet(
|
||||
uint8_t bVolNum,
|
||||
uint32_t ulFileNum)
|
||||
{
|
||||
int64_t ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
uint64_t ullSize;
|
||||
|
||||
ret = RedCoreFileSizeGet(ulFileNum, &ullSize);
|
||||
|
||||
FseLeave();
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
/* Unless there is an on-disk format change, the maximum file size
|
||||
is guaranteed to be less than INT64_MAX, and so it can be safely
|
||||
returned in an int64_t.
|
||||
*/
|
||||
REDASSERT(ullSize < (uint64_t)INT64_MAX);
|
||||
|
||||
ret = (int64_t)ullSize;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1)
|
||||
/** @brief Update the transaction mask.
|
||||
|
||||
The following events are available:
|
||||
|
||||
- #RED_TRANSACT_UMOUNT
|
||||
- #RED_TRANSACT_WRITE
|
||||
- #RED_TRANSACT_TRUNCATE
|
||||
- #RED_TRANSACT_VOLFULL
|
||||
|
||||
The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all
|
||||
automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of
|
||||
all transaction flags, excluding those representing excluded functionality.
|
||||
|
||||
Attempting to enable events for excluded functionality will result in an
|
||||
error.
|
||||
|
||||
@param bVolNum The volume number of the volume whose transaction mask
|
||||
is being changed.
|
||||
@param ulEventMask A bitwise-OR'd mask of automatic transaction events to
|
||||
be set as the current transaction mode.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
|
||||
or @p ulEventMask contains invalid bits.
|
||||
@retval -RED_EROFS The file system volume is read-only.
|
||||
*/
|
||||
REDSTATUS RedFseTransMaskSet(
|
||||
uint8_t bVolNum,
|
||||
uint32_t ulEventMask)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreTransMaskSet(ulEventMask);
|
||||
|
||||
FseLeave();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if REDCONF_API_FSE_TRANSMASKGET == 1
|
||||
/** @brief Read the transaction mask.
|
||||
|
||||
If the volume is read-only, the returned event mask is always zero.
|
||||
|
||||
@param bVolNum The volume number of the volume whose transaction mask
|
||||
is being retrieved.
|
||||
@param pulEventMask Populated with a bitwise-OR'd mask of automatic
|
||||
transaction events which represent the current
|
||||
transaction mode for the volume.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted;
|
||||
or @p pulEventMask is `NULL`.
|
||||
*/
|
||||
REDSTATUS RedFseTransMaskGet(
|
||||
uint8_t bVolNum,
|
||||
uint32_t *pulEventMask)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreTransMaskGet(pulEventMask);
|
||||
|
||||
FseLeave();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** @brief Commit a transaction point.
|
||||
|
||||
Reliance Edge is a transactional file system. All modifications, of both
|
||||
metadata and filedata, are initially working state. A transaction point
|
||||
is a process whereby the working state atomically becomes the committed
|
||||
state, replacing the previous committed state. Whenever Reliance Edge is
|
||||
mounted, including after power loss, the state of the file system after
|
||||
mount is the most recent committed state. Nothing from the committed
|
||||
state is ever missing, and nothing from the working state is ever included.
|
||||
|
||||
@param bVolNum The volume number of the volume to transact.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_EROFS The file system volume is read-only.
|
||||
*/
|
||||
REDSTATUS RedFseTransact(
|
||||
uint8_t bVolNum)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
ret = FseEnter(bVolNum);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreVolTransact();
|
||||
|
||||
FseLeave();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @brief Enter the file system driver.
|
||||
|
||||
@param bVolNum The volume to be accessed.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL The file system driver is uninitialized; or @p bVolNum
|
||||
is not a valid volume number.
|
||||
*/
|
||||
static REDSTATUS FseEnter(
|
||||
uint8_t bVolNum)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if(gfFseInited)
|
||||
{
|
||||
#if REDCONF_TASK_COUNT > 1U
|
||||
RedOsMutexAcquire();
|
||||
#endif
|
||||
|
||||
/* This also serves to range-check the volume number (even in single
|
||||
volume configurations).
|
||||
*/
|
||||
ret = RedCoreVolSetCurrent(bVolNum);
|
||||
|
||||
#if REDCONF_TASK_COUNT > 1U
|
||||
if(ret != 0)
|
||||
{
|
||||
RedOsMutexRelease();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Leave the file system driver.
|
||||
*/
|
||||
static void FseLeave(void)
|
||||
{
|
||||
REDASSERT(gfFseInited);
|
||||
|
||||
#if REDCONF_TASK_COUNT > 1U
|
||||
RedOsMutexRelease();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#endif /* REDCONF_API_FSE == 1 */
|
||||
|
112
FreeRTOS-Plus/Source/Reliance-Edge/include/redapimacs.h
Normal file
112
FreeRTOS-Plus/Source/Reliance-Edge/include/redapimacs.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Defines macros used to interact with the Reliance Edge API.
|
||||
*/
|
||||
#ifndef REDAPIMACS_H
|
||||
#define REDAPIMACS_H
|
||||
|
||||
|
||||
/** Clear all events: manual transactions only. */
|
||||
#define RED_TRANSACT_MANUAL 0x00000000U
|
||||
|
||||
/** Transact prior to unmounting in red_umount() or RedFseUnmount(). */
|
||||
#define RED_TRANSACT_UMOUNT 0x00000001U
|
||||
|
||||
/** Transact after a successful red_open() which created a file. */
|
||||
#define RED_TRANSACT_CREAT 0x00000002U
|
||||
|
||||
/** Transact after a successful red_unlink() or red_rmdir(). */
|
||||
#define RED_TRANSACT_UNLINK 0x00000004U
|
||||
|
||||
/** Transact after a successful red_mkdir(). */
|
||||
#define RED_TRANSACT_MKDIR 0x00000008U
|
||||
|
||||
/** Transact after a successful red_rename(). */
|
||||
#define RED_TRANSACT_RENAME 0x00000010U
|
||||
|
||||
/** Transact after a successful red_link(). */
|
||||
#define RED_TRANSACT_LINK 0x00000020U
|
||||
|
||||
/** Transact after a successful red_close(). */
|
||||
#define RED_TRANSACT_CLOSE 0x00000040U
|
||||
|
||||
/** Transact after a successful red_write() or RedFseWrite(). */
|
||||
#define RED_TRANSACT_WRITE 0x00000080U
|
||||
|
||||
/** Transact after a successful red_fsync(). */
|
||||
#define RED_TRANSACT_FSYNC 0x00000100U
|
||||
|
||||
/** Transact after a successful red_ftruncate(), RedFseTruncate(), or red_open() with RED_O_TRUNC that actually truncates. */
|
||||
#define RED_TRANSACT_TRUNCATE 0x00000200U
|
||||
|
||||
/** Transact to free space in disk full situations. */
|
||||
#define RED_TRANSACT_VOLFULL 0x00000400U
|
||||
|
||||
#if REDCONF_READ_ONLY == 1
|
||||
|
||||
/** Mask of all supported automatic transaction events. */
|
||||
#define RED_TRANSACT_MASK 0U
|
||||
|
||||
#elif REDCONF_API_POSIX == 1
|
||||
|
||||
/** @brief Mask of all supported automatic transaction events.
|
||||
*/
|
||||
#define RED_TRANSACT_MASK \
|
||||
( \
|
||||
RED_TRANSACT_UMOUNT | \
|
||||
RED_TRANSACT_CREAT | \
|
||||
((REDCONF_API_POSIX_UNLINK == 1) ? RED_TRANSACT_UNLINK : 0U) | \
|
||||
((REDCONF_API_POSIX_MKDIR == 1) ? RED_TRANSACT_MKDIR : 0U) | \
|
||||
((REDCONF_API_POSIX_RENAME == 1) ? RED_TRANSACT_RENAME : 0U) | \
|
||||
((REDCONF_API_POSIX_LINK == 1) ? RED_TRANSACT_LINK : 0U) | \
|
||||
RED_TRANSACT_CLOSE | \
|
||||
RED_TRANSACT_WRITE | \
|
||||
RED_TRANSACT_FSYNC | \
|
||||
((REDCONF_API_POSIX_FTRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \
|
||||
RED_TRANSACT_VOLFULL \
|
||||
)
|
||||
|
||||
#else /* REDCONF_API_FSE == 1 */
|
||||
|
||||
/** @brief Mask of all supported automatic transaction events.
|
||||
*/
|
||||
#define RED_TRANSACT_MASK \
|
||||
( \
|
||||
RED_TRANSACT_UMOUNT | \
|
||||
RED_TRANSACT_WRITE | \
|
||||
((REDCONF_API_FSE_TRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \
|
||||
RED_TRANSACT_VOLFULL \
|
||||
)
|
||||
|
||||
#endif /* REDCONF_READ_ONLY */
|
||||
|
||||
#if (REDCONF_TRANSACT_DEFAULT & RED_TRANSACT_MASK) != REDCONF_TRANSACT_DEFAULT
|
||||
#error "Configuration error: invalid value of REDCONF_TRANSACT_DEFAULT"
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
317
FreeRTOS-Plus/Source/Reliance-Edge/include/redconfigchk.h
Normal file
317
FreeRTOS-Plus/Source/Reliance-Edge/include/redconfigchk.h
Normal file
|
@ -0,0 +1,317 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Compile-time validity checks for the REDCONF macros.
|
||||
*/
|
||||
#ifndef REDCONFIGCHK_H
|
||||
#define REDCONFIGCHK_H
|
||||
|
||||
#ifndef REDCONF_READ_ONLY
|
||||
#error "Configuration error: REDCONF_READ_ONLY must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX
|
||||
#error "Configuration error: REDCONF_API_POSIX must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_FSE
|
||||
#error "Configuration error: REDCONF_API_FSE must be defined."
|
||||
#endif
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
#ifndef REDCONF_API_POSIX_FORMAT
|
||||
#error "Configuration error: REDCONF_API_POSIX_FORMAT must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX_UNLINK
|
||||
#error "Configuration error: REDCONF_API_POSIX_UNLINK must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX_MKDIR
|
||||
#error "Configuration error: REDCONF_API_POSIX_MKDIR must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX_RMDIR
|
||||
#error "Configuration error: REDCONF_API_POSIX_RMDIR must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX_RENAME
|
||||
#error "Configuration error: REDCONF_API_POSIX_RENAME must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX_LINK
|
||||
#error "Configuration error: REDCONF_API_POSIX_LINK must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX_FTRUNCATE
|
||||
#error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_POSIX_READDIR
|
||||
#error "Configuration error: REDCONF_API_POSIX_READDIR must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_NAME_MAX
|
||||
#error "Configuration error: REDCONF_NAME_MAX must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_PATH_SEPARATOR
|
||||
#error "Configuration error: REDCONF_PATH_SEPARATOR must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_RENAME_ATOMIC
|
||||
#error "Configuration error: REDCONF_RENAME_ATOMIC must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_HANDLE_COUNT
|
||||
#error "Configuration error: REDCONF_HANDLE_COUNT must be defined."
|
||||
#endif
|
||||
#endif
|
||||
#if REDCONF_API_FSE == 1
|
||||
#ifndef REDCONF_API_FSE_FORMAT
|
||||
#error "Configuration error: REDCONF_API_FSE_FORMAT must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_FSE_TRUNCATE
|
||||
#error "Configuration error: REDCONF_API_FSE_TRUNCATE must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_FSE_TRANSMASKSET
|
||||
#error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_API_FSE_TRANSMASKGET
|
||||
#error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be defined."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef REDCONF_TASK_COUNT
|
||||
#error "Configuration error: REDCONF_TASK_COUNT must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_ENDIAN_BIG
|
||||
#error "Configuration error: REDCONF_ENDIAN_BIG must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_ALIGNMENT_SIZE
|
||||
#error "Configuration error: REDCONF_ALIGNMENT_SIZE must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_CRC_ALGORITHM
|
||||
#error "Configuration error: REDCONF_CRC_ALGORITHM must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_INODE_TIMESTAMPS
|
||||
#error "Configuration error: REDCONF_INODE_TIMESTAMPS must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_ATIME
|
||||
#error "Configuration error: REDCONF_ATIME must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_DIRECT_POINTERS
|
||||
#error "Configuration error: REDCONF_DIRECT_POINTERS must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_INDIRECT_POINTERS
|
||||
#error "Configuration error: REDCONF_INDIRECT_POINTERS must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_INODE_BLOCKS
|
||||
#error "Configuration error: REDCONF_INODE_BLOCKS must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_IMAP_EXTERNAL
|
||||
#error "Configuration error: REDCONF_IMAP_EXTERNAL must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_IMAP_INLINE
|
||||
#error "Configuration error: REDCONF_IMAP_INLINE must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_OUTPUT
|
||||
#error "Configuration error: REDCONF_OUTPUT must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_ASSERTS
|
||||
#error "Configuration error: REDCONF_ASSERTS must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_TRANSACT_DEFAULT
|
||||
#error "Configuration error: REDCONF_TRANSACT_DEFAULT must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_BUFFER_COUNT
|
||||
#error "Configuration error: REDCONF_BUFFER_COUNT must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_BLOCK_SIZE
|
||||
#error "Configuration error: REDCONF_BLOCK_SIZE must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_VOLUME_COUNT
|
||||
#error "Configuration error: REDCONF_VOLUME_COUNT must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_IMAGE_BUILDER
|
||||
#error "Configuration error: REDCONF_IMAGE_BUILDER must be defined."
|
||||
#endif
|
||||
#ifndef REDCONF_CHECKER
|
||||
#error "Configuration error: REDCONF_CHECKER must be defined."
|
||||
#endif
|
||||
|
||||
|
||||
#if (REDCONF_READ_ONLY != 0) && (REDCONF_READ_ONLY != 1)
|
||||
#error "Configuration error: REDCONF_READ_ONLY must be either 0 or 1"
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX != 0) && (REDCONF_API_POSIX != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX must be either 0 or 1."
|
||||
#endif
|
||||
#if (REDCONF_API_FSE != 0) && (REDCONF_API_FSE != 1)
|
||||
#error "Configuration error: REDCONF_API_FSE must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_FSE == 0) && (REDCONF_API_POSIX == 0)
|
||||
#error "Configuration error: either REDCONF_API_FSE or REDCONF_API_POSIX must be set to 1."
|
||||
#endif
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
#if REDCONF_API_FSE != 0
|
||||
#error "Configuration error: REDCONF_API_FSE must be 0 if REDCONF_API_POSIX is 1"
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_FORMAT != 0) && (REDCONF_API_POSIX_FORMAT != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_FORMAT must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_UNLINK != 0) && (REDCONF_API_POSIX_UNLINK != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_UNLINK must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_MKDIR != 0) && (REDCONF_API_POSIX_MKDIR != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_MKDIR must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_RMDIR != 0) && (REDCONF_API_POSIX_RMDIR != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_RMDIR must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_RENAME != 0) && (REDCONF_API_POSIX_RENAME != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_RENAME must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_LINK != 0) && (REDCONF_API_POSIX_LINK != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_LINK must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_FTRUNCATE != 0) && (REDCONF_API_POSIX_FTRUNCATE != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX_READDIR != 0) && (REDCONF_API_POSIX_READDIR != 1)
|
||||
#error "Configuration error: REDCONF_API_POSIX_READDIR must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_NAME_MAX < 1U) || (REDCONF_NAME_MAX > (REDCONF_BLOCK_SIZE - 4U))
|
||||
#error "Configuration error: invalid value of REDCONF_NAME_MAX"
|
||||
#endif
|
||||
|
||||
#if (REDCONF_PATH_SEPARATOR < 1) || (REDCONF_PATH_SEPARATOR > 127)
|
||||
#error "Configuration error: invalid value of REDCONF_PATH_SEPARATOR"
|
||||
#endif
|
||||
|
||||
#if (REDCONF_RENAME_ATOMIC != 0) && (REDCONF_RENAME_ATOMIC != 1)
|
||||
#error "Configuration error: REDCONF_RENAME_ATOMIC must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_HANDLE_COUNT < 1U) || (REDCONF_HANDLE_COUNT > 4096U)
|
||||
#error "Configuration error: invalid value of REDCONF_HANDLE_COUNT"
|
||||
#endif
|
||||
#endif
|
||||
#if REDCONF_API_FSE == 1
|
||||
#if (REDCONF_API_FSE_FORMAT != 0) && (REDCONF_API_FSE_FORMAT != 1)
|
||||
#error "Configuration error: REDCONF_API_FSE_FORMAT must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_FSE_TRUNCATE != 0) && (REDCONF_API_FSE_TRUNCATE != 1)
|
||||
#error "Configuration error: REDCONF_API_FSE_TRUNCATE must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_FSE_TRANSMASKSET != 0) && (REDCONF_API_FSE_TRANSMASKSET != 1)
|
||||
#error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_FSE_TRANSMASKGET != 0) && (REDCONF_API_FSE_TRANSMASKGET != 1)
|
||||
#error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be either 0 or 1."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if REDCONF_TASK_COUNT < 1U
|
||||
#error "Configuration error: invalid value of REDCONF_TASK_COUNT"
|
||||
#endif
|
||||
|
||||
#if (REDCONF_ENDIAN_BIG != 0) && (REDCONF_ENDIAN_BIG != 1)
|
||||
#error "Configuration error: REDCONF_ENDIAN_BIG must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_ALIGNMENT_SIZE != 1U) && (REDCONF_ALIGNMENT_SIZE != 2U) && (REDCONF_ALIGNMENT_SIZE != 4U) && (REDCONF_ALIGNMENT_SIZE != 8U)
|
||||
#error "Configuration error: invalid value REDCONF_ALIGNMENT_SIZE"
|
||||
#endif
|
||||
|
||||
/* REDCONF_CRC_ALGORITHM checked in crc.c
|
||||
*/
|
||||
|
||||
#if (REDCONF_INODE_TIMESTAMPS != 0) && (REDCONF_INODE_TIMESTAMPS != 1)
|
||||
#error "Configuration error: REDCONF_INODE_TIMESTAMPS must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_ATIME != 0) && (REDCONF_ATIME != 1)
|
||||
#error "Configuration error: REDCONF_ATIME must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_INODE_TIMESTAMPS == 0) && (REDCONF_ATIME == 1)
|
||||
#error "Configuration error: REDCONF_ATIME must be 0 when REDCONF_INODE_TIMESTAMPS is 0."
|
||||
#endif
|
||||
|
||||
/* REDCONF_DIRECT_POINTERS and REDCONF_INDIRECT_POINTERS checked in rednodes.h
|
||||
*/
|
||||
|
||||
#if (REDCONF_INODE_BLOCKS != 0) && (REDCONF_INODE_BLOCKS != 1)
|
||||
#error "Configuration error: REDCONF_INODE_BLOCKS must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
/* Further validity checking of imap specs done in RelCoreInit()
|
||||
*/
|
||||
#if (REDCONF_IMAP_EXTERNAL != 0) && (REDCONF_IMAP_EXTERNAL != 1)
|
||||
#error "Configuration error: REDCONF_IMAP_EXTERNAL must be either 0 or 1."
|
||||
#endif
|
||||
#if (REDCONF_IMAP_INLINE != 0) && (REDCONF_IMAP_INLINE != 1)
|
||||
#error "Configuration error: REDCONF_IMAP_INLINE must be either 0 or 1."
|
||||
#endif
|
||||
#if (REDCONF_IMAP_INLINE == 0) && (REDCONF_IMAP_EXTERNAL == 0)
|
||||
#error "Configuration error: At least one of REDCONF_IMAP_INLINE and REDCONF_IMAP_EXTERNAL must be set"
|
||||
#endif
|
||||
|
||||
#if (REDCONF_OUTPUT != 0) && (REDCONF_OUTPUT != 1)
|
||||
#error "Configuration error: REDCONF_OUTPUT must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_ASSERTS != 0) && (REDCONF_ASSERTS != 1)
|
||||
#error "Configuration error: REDCONF_ASSERTS must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
/* REDCONF_BLOCK_SIZE checked in redmacs.h
|
||||
*/
|
||||
|
||||
#if (REDCONF_VOLUME_COUNT < 1U) || (REDCONF_VOLUME_COUNT > 255U)
|
||||
#error "REDCONF_VOLUME_COUNT must be an integer between 1 and 255"
|
||||
#endif
|
||||
|
||||
/* REDCONF_BUFFER_COUNT lower limit checked in buffer.c
|
||||
*/
|
||||
#if REDCONF_BUFFER_COUNT > 255U
|
||||
#error "REDCONF_BUFFER_COUNT cannot be greater than 255"
|
||||
#endif
|
||||
|
||||
#if (REDCONF_IMAGE_BUILDER != 0) && (REDCONF_IMAGE_BUILDER != 1)
|
||||
#error "Configuration error: REDCONF_IMAGE_BUILDER must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
#if (REDCONF_CHECKER != 0) && (REDCONF_CHECKER != 1)
|
||||
#error "Configuration error: REDCONF_CHECKER must be either 0 or 1."
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
97
FreeRTOS-Plus/Source/Reliance-Edge/include/redcoreapi.h
Normal file
97
FreeRTOS-Plus/Source/Reliance-Edge/include/redcoreapi.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDCOREAPI_H
|
||||
#define REDCOREAPI_H
|
||||
|
||||
|
||||
#include <redstat.h>
|
||||
|
||||
|
||||
REDSTATUS RedCoreInit(void);
|
||||
REDSTATUS RedCoreUninit(void);
|
||||
|
||||
REDSTATUS RedCoreVolSetCurrent(uint8_t bVolNum);
|
||||
|
||||
#if FORMAT_SUPPORTED
|
||||
REDSTATUS RedCoreVolFormat(void);
|
||||
#endif
|
||||
#if REDCONF_CHECKER == 1
|
||||
REDSTATUS RedCoreVolCheck(void);
|
||||
#endif
|
||||
REDSTATUS RedCoreVolMount(void);
|
||||
REDSTATUS RedCoreVolUnmount(void);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedCoreVolTransact(void);
|
||||
#endif
|
||||
#if REDCONF_API_POSIX == 1
|
||||
REDSTATUS RedCoreVolStat(REDSTATFS *pStatFS);
|
||||
#endif
|
||||
|
||||
#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKSET == 1))
|
||||
REDSTATUS RedCoreTransMaskSet(uint32_t ulEventMask);
|
||||
#endif
|
||||
#if (REDCONF_API_POSIX == 1) || (REDCONF_API_FSE_TRANSMASKGET == 1)
|
||||
REDSTATUS RedCoreTransMaskGet(uint32_t *pulEventMask);
|
||||
#endif
|
||||
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1)
|
||||
REDSTATUS RedCoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1)
|
||||
REDSTATUS RedCoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1))
|
||||
REDSTATUS RedCoreUnlink(uint32_t ulPInode, const char *pszName);
|
||||
#endif
|
||||
#if REDCONF_API_POSIX == 1
|
||||
REDSTATUS RedCoreLookup(uint32_t ulPInode, const char *pszName, uint32_t *pulInode);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1)
|
||||
REDSTATUS RedCoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName);
|
||||
#endif
|
||||
#if REDCONF_API_POSIX == 1
|
||||
REDSTATUS RedCoreStat(uint32_t ulInode, REDSTAT *pStat);
|
||||
#endif
|
||||
#if REDCONF_API_FSE == 1
|
||||
REDSTATUS RedCoreFileSizeGet(uint32_t ulInode, uint64_t *pullSize);
|
||||
#endif
|
||||
|
||||
REDSTATUS RedCoreFileRead(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedCoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer);
|
||||
#endif
|
||||
#if TRUNCATE_SUPPORTED
|
||||
REDSTATUS RedCoreFileTruncate(uint32_t ulInode, uint64_t ullSize);
|
||||
#endif
|
||||
|
||||
#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1)
|
||||
REDSTATUS RedCoreDirRead(uint32_t ulInode, uint32_t *pulPos, char *pszName, uint32_t *pulInode);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
224
FreeRTOS-Plus/Source/Reliance-Edge/include/reddeviations.h
Normal file
224
FreeRTOS-Plus/Source/Reliance-Edge/include/reddeviations.h
Normal file
|
@ -0,0 +1,224 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief This header contains macros which deviate from MISRA C:2012
|
||||
*/
|
||||
#ifndef REDDEVIATIONS_H
|
||||
#define REDDEVIATIONS_H
|
||||
|
||||
|
||||
/** @brief Append a suffix to a constant so that it is an unsigned 64-bit value.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The
|
||||
rule prohibits the use of language extensions. The ULL suffix became part
|
||||
of the C standard with C99. Since this code base adheres to C89, use of
|
||||
this suffix is a language extension. Reliance Edge needs to deal with
|
||||
64-bit quantities, which by convention are explicitly suffixed. In at
|
||||
least one case, with the INODE_SIZE_MAX macro, the code needs a way to force
|
||||
a constant to be 64-bits even though its value is not so large that it would
|
||||
be automatically promoted to 64-bits. Thus the need for this macro and the
|
||||
deviation. In practice, the ULL suffix has proven to be a nearly universal
|
||||
extension among C89 compilers.
|
||||
|
||||
As rule 19.2 is advisory, a deviation record is not required. This notice
|
||||
is the only record of the deviation. PC-Lint does not issue an error for
|
||||
this deviation so there is no error inhibition option.
|
||||
|
||||
Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory).
|
||||
The rule prohibits use of the ## preprocessor operator. The code is not
|
||||
obscure, and the operator is used only once, so this is deemed to be safe.
|
||||
|
||||
As rule 20.10 is advisory, a deviation record is not required. This notice
|
||||
is the only record of the deviation.
|
||||
|
||||
Consistent use of this macro, even in non MISRA C code, is encouraged to
|
||||
make it easier to search for 64-bit values.
|
||||
|
||||
*/
|
||||
#define UINT64_SUFFIX(number) (number##ULL)
|
||||
|
||||
|
||||
/** @brief Append a suffix to a constant so that it is a signed 64-bit value.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the
|
||||
description of UINT64_SUFFIX() for details.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See
|
||||
the description of UINT64_SUFFIX() for details.
|
||||
*/
|
||||
#define INT64_SUFFIX(number) (number##LL)
|
||||
|
||||
|
||||
/** @brief Cast a pointer to a const uint8_t pointer.
|
||||
|
||||
All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).
|
||||
Because there are no alignment requirements for a uint8_t pointer, this is
|
||||
safe. However, it is technically a deviation from the rule.
|
||||
|
||||
As Rule 11.5 is advisory, a deviation record is not required. This notice
|
||||
and the PC-Lint error inhibition option are the only records of the
|
||||
deviation.
|
||||
*/
|
||||
#define CAST_VOID_PTR_TO_CONST_UINT8_PTR(PTR) ((const uint8_t *)(PTR))
|
||||
|
||||
|
||||
/** @brief Cast a pointer to a uint8_t pointer.
|
||||
|
||||
All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).
|
||||
Because there are no alignment requirements for a uint8_t pointer, this is
|
||||
safe. However, it is technically a deviation from the rule.
|
||||
|
||||
As Rule 11.5 is advisory, a deviation record is not required. This notice
|
||||
and the PC-Lint error inhibition option are the only records of the
|
||||
deviation.
|
||||
*/
|
||||
#define CAST_VOID_PTR_TO_UINT8_PTR(PTR) ((uint8_t *)(PTR))
|
||||
|
||||
|
||||
/** @brief Cast a pointer to a const uint32_t pointer.
|
||||
|
||||
Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory).
|
||||
It is only used in cases where the pointer is known to be aligned, and thus
|
||||
it is safe to do so.
|
||||
|
||||
As Rule 11.5 is advisory, a deviation record is not required. This notice
|
||||
and the PC-Lint error inhibition option are the only records of the
|
||||
deviation.
|
||||
|
||||
Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required).
|
||||
As Rule 11.3 is required, a separate deviation record is required.
|
||||
|
||||
Regarding the cast to (const void *): this is there to placate some
|
||||
compilers which emit warnings when a type with lower alignment requirements
|
||||
(such as const uint8_t *) is cast to a type with higher alignment
|
||||
requirements. In the places where this macro is used, the pointer is
|
||||
checked to be of sufficient alignment.
|
||||
*/
|
||||
#define CAST_CONST_UINT32_PTR(PTR) ((const uint32_t *)(const void *)(PTR))
|
||||
|
||||
|
||||
/** @brief Cast a pointer to a pointer to (void **).
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required).
|
||||
It is only used for populating a node structure pointer with a buffer
|
||||
pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so.
|
||||
|
||||
As Rule 11.3 is required, a separate deviation record is required.
|
||||
*/
|
||||
#define CAST_VOID_PTR_PTR(PTRPTR) ((void **)(PTRPTR))
|
||||
|
||||
|
||||
/** @brief Create a two-dimensional byte array which is safely aligned.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory).
|
||||
A union is required to force alignment of the block buffers, which are used
|
||||
to access metadata nodes, which must be safely aligned for 64-bit types.
|
||||
|
||||
As rule 19.2 is advisory, a deviation record is not required. This notice
|
||||
and the PC-Lint error inhibition option are the only records of the
|
||||
deviation.
|
||||
*/
|
||||
#define ALIGNED_2D_BYTE_ARRAY(un, nam, size1, size2) \
|
||||
union \
|
||||
{ \
|
||||
uint8_t nam[size1][size2]; \
|
||||
uint64_t DummyAlign; \
|
||||
} un
|
||||
|
||||
|
||||
/** @brief Determine whether RedMemMove() must copy memory in the forward
|
||||
direction, instead of in the reverse.
|
||||
|
||||
In order to copy between overlapping memory regions, RedMemMove() must copy
|
||||
forward if the destination memory is lower, and backward if the destination
|
||||
memory is higher. Failure to do so would yield incorrect results.
|
||||
|
||||
The only way to make this determination without gross inefficiency is to
|
||||
use pointer comparison. Pointer comparisons are undefined unless both
|
||||
pointers point within the same object or array (or one element past the end
|
||||
of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is
|
||||
normally only used when memory regions overlap, which would not result in
|
||||
undefined behavior, it (like memmove()) is supposed to work even for non-
|
||||
overlapping regions, which would make this function invoke undefined
|
||||
behavior. Experience has shown the pointer comparisons of this sort behave
|
||||
intuitively on common platforms, even though the behavior is undefined. For
|
||||
those platforms where this is not the case, this implementation of memmove()
|
||||
should be replaced with an alternate one.
|
||||
|
||||
Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As
|
||||
Rule 18.3 is required, a separate deviation record is required.
|
||||
*/
|
||||
#define MEMMOVE_MUST_COPY_FORWARD(dest, src) ((dest) < (src))
|
||||
|
||||
|
||||
/** @brief Cast a pointer to a (const DIRENT *).
|
||||
|
||||
Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required).
|
||||
It is used for populating a directory entry structure pointer with a
|
||||
buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only
|
||||
requires 4-byte alignment, thus the typecast is safe.
|
||||
|
||||
As Rule 11.3 is required, a separate deviation record is required.
|
||||
*/
|
||||
#define CAST_CONST_DIRENT_PTR(PTR) ((const DIRENT *)(PTR))
|
||||
|
||||
|
||||
/** @brief Determine whether a pointer is aligned.
|
||||
|
||||
A pointer is aligned if its address is an even multiple of
|
||||
::REDCONF_ALIGNMENT_SIZE.
|
||||
|
||||
This is used in the slice-by-8 RedCrc32Update() function, which needs to
|
||||
know whether a pointer is aligned, since the slice-by-8 algorithm needs to
|
||||
access the memory in an aligned fashion, and if the pointer is not aligned,
|
||||
this can result in faults or suboptimal performance (depending on platform).
|
||||
|
||||
There is no way to perform this check without deviating from MISRA C rules
|
||||
against casting pointers to integer types. Usage of this macro deviates
|
||||
from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites
|
||||
against converting pointers to integers is that the chosen integer type may
|
||||
not be able to represent the pointer; this is a non-issue here since we use
|
||||
uintptr_t. The text says the rule still applies when using uintptr_t due to
|
||||
concern about unaligned pointers, but that is not an issue here since the
|
||||
integer value of the pointer is not saved and not converted back into a
|
||||
pointer and dereferenced. The result of casting a pointer to a sufficiently
|
||||
large integer is implementation-defined, but macros similar to this one have
|
||||
been used by Datalight for a long time in a wide variety of environments and
|
||||
they have always worked as expected.
|
||||
|
||||
As Rule 11.4 is advisory, a deviation record is not required. This notice
|
||||
and the PC-Lint error inhibition option are the only records of the
|
||||
deviation.
|
||||
|
||||
@note PC-Lint also thinks this macro as it is used below violates Rule 11.6
|
||||
(required). This is a false positive, since Rule 11.6 only applies to
|
||||
void pointers. Below, we use it on a pointer-to-object (uint8_t *),
|
||||
which is covered by Rule 11.4.
|
||||
*/
|
||||
#define IS_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (REDCONF_ALIGNMENT_SIZE - 1U)) == 0U)
|
||||
|
||||
|
||||
#endif
|
||||
|
114
FreeRTOS-Plus/Source/Reliance-Edge/include/rederrno.h
Normal file
114
FreeRTOS-Plus/Source/Reliance-Edge/include/rederrno.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Error values for Reliance Edge APIs
|
||||
*/
|
||||
#ifndef REDERRNO_H
|
||||
#define REDERRNO_H
|
||||
|
||||
|
||||
/** @brief Return type for Reliance Edge error values.
|
||||
*/
|
||||
typedef int32_t REDSTATUS;
|
||||
|
||||
|
||||
/* The errno numbers are the same as Linux.
|
||||
*/
|
||||
|
||||
/** Operation not permitted. */
|
||||
#define RED_EPERM 1
|
||||
|
||||
/** No such file or directory. */
|
||||
#define RED_ENOENT 2
|
||||
|
||||
/** I/O error. */
|
||||
#define RED_EIO 5
|
||||
|
||||
/** Bad file number. */
|
||||
#define RED_EBADF 9
|
||||
|
||||
/** Out of memory */
|
||||
#define RED_ENOMEM 12
|
||||
|
||||
/** Device or resource busy. */
|
||||
#define RED_EBUSY 16
|
||||
|
||||
/** File exists. */
|
||||
#define RED_EEXIST 17
|
||||
|
||||
/** Cross-device link. */
|
||||
#define RED_EXDEV 18
|
||||
|
||||
/** Not a directory. */
|
||||
#define RED_ENOTDIR 20
|
||||
|
||||
/** Is a directory. */
|
||||
#define RED_EISDIR 21
|
||||
|
||||
/** Invalid argument. */
|
||||
#define RED_EINVAL 22
|
||||
|
||||
/** File table overflow. */
|
||||
#define RED_ENFILE 23
|
||||
|
||||
/** Too many open files. */
|
||||
#define RED_EMFILE 24
|
||||
|
||||
/** File too large. */
|
||||
#define RED_EFBIG 27
|
||||
|
||||
/** No space left on device. */
|
||||
#define RED_ENOSPC 28
|
||||
|
||||
/** Read-only file system. */
|
||||
#define RED_EROFS 30
|
||||
|
||||
/** Too many links. */
|
||||
#define RED_EMLINK 31
|
||||
|
||||
/** Math result not representable. */
|
||||
#define RED_ERANGE 34
|
||||
|
||||
/** File name too long. */
|
||||
#define RED_ENAMETOOLONG 36
|
||||
|
||||
/** Function not implemented. */
|
||||
#define RED_ENOSYS 38
|
||||
|
||||
/** Directory not empty. */
|
||||
#define RED_ENOTEMPTY 39
|
||||
|
||||
/** No data available. */
|
||||
#define RED_ENODATA 61
|
||||
|
||||
/** Too many users. */
|
||||
#define RED_EUSERS 87
|
||||
|
||||
/** Nothing will be okay ever again. */
|
||||
#define RED_EFUBAR RED_EINVAL
|
||||
|
||||
|
||||
#endif
|
||||
|
54
FreeRTOS-Plus/Source/Reliance-Edge/include/redexclude.h
Normal file
54
FreeRTOS-Plus/Source/Reliance-Edge/include/redexclude.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDEXCLUDE_H
|
||||
#define REDEXCLUDE_H
|
||||
|
||||
|
||||
#define DELETE_SUPPORTED \
|
||||
( \
|
||||
(REDCONF_READ_ONLY == 0) \
|
||||
&& ( (REDCONF_API_POSIX == 1) \
|
||||
&& ( (REDCONF_API_POSIX_RMDIR == 1) \
|
||||
|| (REDCONF_API_POSIX_UNLINK == 1) \
|
||||
|| ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1)))))
|
||||
|
||||
#define TRUNCATE_SUPPORTED \
|
||||
( \
|
||||
(REDCONF_READ_ONLY == 0) \
|
||||
&& ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) \
|
||||
|| ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1))))
|
||||
|
||||
#define FORMAT_SUPPORTED \
|
||||
( \
|
||||
(REDCONF_READ_ONLY == 0) \
|
||||
&& ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) \
|
||||
|| ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_FORMAT == 1)) \
|
||||
|| (REDCONF_IMAGE_BUILDER == 1)))
|
||||
|
||||
|
||||
#endif
|
||||
|
46
FreeRTOS-Plus/Source/Reliance-Edge/include/redfs.h
Normal file
46
FreeRTOS-Plus/Source/Reliance-Edge/include/redfs.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDFS_H
|
||||
#define REDFS_H
|
||||
|
||||
|
||||
#include <redconf.h>
|
||||
#include "redconfigchk.h"
|
||||
#include <redtypes.h>
|
||||
#include "rederrno.h"
|
||||
#include "reddeviations.h"
|
||||
#include "redmacs.h"
|
||||
#include "redapimacs.h"
|
||||
#include "redutils.h"
|
||||
#include "redosserv.h"
|
||||
#include "redmisc.h"
|
||||
#include "redver.h"
|
||||
#include "redexclude.h"
|
||||
|
||||
|
||||
#endif
|
||||
|
105
FreeRTOS-Plus/Source/Reliance-Edge/include/redfse.h
Normal file
105
FreeRTOS-Plus/Source/Reliance-Edge/include/redfse.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Interface for the Reliance Edge FSE API.
|
||||
|
||||
The FSE (File Systems Essentials) API is a minimalist file system API
|
||||
intended for simple use cases with a fixed number of statically-defined
|
||||
files. It does not support creating or deleting files dynamically. Files
|
||||
are referenced by a fixed file number, rather than by name; there are no
|
||||
file names and no directories. There are also no file handles: files are
|
||||
not opened or closed, and file offsets are given explicitly.
|
||||
|
||||
If the FSE API is too limited to meet the needs of your application,
|
||||
consider using the more feature-rich POSIX-like file system API instead.
|
||||
*/
|
||||
#ifndef REDFSE_H
|
||||
#define REDFSE_H
|
||||
|
||||
/* This header is intended for application use; some applications are written
|
||||
in C++.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <redconf.h>
|
||||
|
||||
#if REDCONF_API_FSE == 1
|
||||
|
||||
#include <redtypes.h>
|
||||
#include "redapimacs.h"
|
||||
#include "rederrno.h"
|
||||
|
||||
|
||||
/** @brief First valid file number.
|
||||
|
||||
This macro can be used to statically define file numbers for given files,
|
||||
as in the below example:
|
||||
|
||||
~~~{.c}
|
||||
#define LOG_FILE (RED_FILENUM_FIRST_VALID)
|
||||
#define DATABASE_FILE (RED_FILENUM_FIRST_VALID + 1U)
|
||||
#define ICON1_FILE (RED_FILENUM_FIRST_VALID + 2U)
|
||||
#define ICON2_FILE (RED_FILENUM_FIRST_VALID + 3U)
|
||||
~~~
|
||||
*/
|
||||
#define RED_FILENUM_FIRST_VALID (2U)
|
||||
|
||||
|
||||
REDSTATUS RedFseInit(void);
|
||||
REDSTATUS RedFseUninit(void);
|
||||
REDSTATUS RedFseMount(uint8_t bVolNum);
|
||||
REDSTATUS RedFseUnmount(uint8_t bVolNum);
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_FORMAT == 1)
|
||||
REDSTATUS RedFseFormat(uint8_t bVolNum);
|
||||
#endif
|
||||
int32_t RedFseRead(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, void *pBuffer);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
int32_t RedFseWrite(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, const void *pBuffer);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1)
|
||||
REDSTATUS RedFseTruncate(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullNewFileSize);
|
||||
#endif
|
||||
int64_t RedFseSizeGet(uint8_t bVolNum, uint32_t ulFileNum);
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1)
|
||||
REDSTATUS RedFseTransMaskSet(uint8_t bVolNum, uint32_t ulEventMask);
|
||||
#endif
|
||||
#if REDCONF_API_FSE_TRANSMASKGET == 1
|
||||
REDSTATUS RedFseTransMaskGet(uint8_t bVolNum, uint32_t *pulEventMask);
|
||||
#endif
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedFseTransact(uint8_t bVolNum);
|
||||
#endif
|
||||
|
||||
#endif /* REDCONF_API_FSE == 1 */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
77
FreeRTOS-Plus/Source/Reliance-Edge/include/redgetopt.h
Normal file
77
FreeRTOS-Plus/Source/Reliance-Edge/include/redgetopt.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Dieter Baron and Thomas Klausner.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** @file
|
||||
@brief Interfaces for getopt() and getopt_long() work-alike functions.
|
||||
|
||||
This code was taken from FreeBSD and slightly modified, mostly to rename
|
||||
symbols with external linkage to avoid naming conflicts in systems where
|
||||
there are real getopt()/getopt_long() implementations. Changed to use
|
||||
fixed-width types to allow code using these interfaces to be consistent
|
||||
with the rest of the product.
|
||||
*/
|
||||
#ifndef REDGETOPT_H
|
||||
#define REDGETOPT_H
|
||||
|
||||
|
||||
#define red_no_argument 0
|
||||
#define red_required_argument 1
|
||||
#define red_optional_argument 2
|
||||
|
||||
|
||||
/** @brief Specifies a long option.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/* name of long option */
|
||||
const char *name;
|
||||
/*
|
||||
* one of red_no_argument, red_required_argument, and red_optional_argument:
|
||||
* whether option takes an argument
|
||||
*/
|
||||
int32_t has_arg;
|
||||
/* if not NULL, set *flag to val when option found */
|
||||
int32_t *flag;
|
||||
/* if flag not NULL, value to set *flag to; else return value */
|
||||
int32_t val;
|
||||
} REDOPTION;
|
||||
|
||||
|
||||
int32_t RedGetopt(int32_t nargc, char * const *nargv, const char *options);
|
||||
int32_t RedGetoptLong(int32_t nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx);
|
||||
|
||||
|
||||
extern const char *red_optarg;
|
||||
extern int32_t red_optind;
|
||||
extern int32_t red_opterr;
|
||||
extern int32_t red_optopt;
|
||||
extern int32_t red_optreset;
|
||||
|
||||
|
||||
#endif
|
||||
|
103
FreeRTOS-Plus/Source/Reliance-Edge/include/redmacs.h
Normal file
103
FreeRTOS-Plus/Source/Reliance-Edge/include/redmacs.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDMACS_H
|
||||
#define REDMACS_H
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef UINT8_MAX
|
||||
#define UINT8_MAX (0xFFU)
|
||||
#endif
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX (0xFFFFU)
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX (0xFFFFFFFFU)
|
||||
#endif
|
||||
#ifndef UINT64_MAX
|
||||
#define UINT64_MAX UINT64_SUFFIX(0xFFFFFFFFFFFFFFFF)
|
||||
#endif
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (0x7FFFFFFF)
|
||||
#endif
|
||||
#ifndef INT64_MAX
|
||||
#define INT64_MAX INT64_SUFFIX(0x7FFFFFFFFFFFFFFF)
|
||||
#endif
|
||||
|
||||
#ifndef true
|
||||
#define true (1)
|
||||
#endif
|
||||
#ifndef false
|
||||
#define false (0)
|
||||
#endif
|
||||
|
||||
#define SECTOR_SIZE_MIN (256U)
|
||||
|
||||
#if REDCONF_BLOCK_SIZE == 256U
|
||||
#define BLOCK_SIZE_P2 8U
|
||||
#elif REDCONF_BLOCK_SIZE == 512U
|
||||
#define BLOCK_SIZE_P2 9U
|
||||
#elif REDCONF_BLOCK_SIZE == 1024U
|
||||
#define BLOCK_SIZE_P2 10U
|
||||
#elif REDCONF_BLOCK_SIZE == 2048U
|
||||
#define BLOCK_SIZE_P2 11U
|
||||
#elif REDCONF_BLOCK_SIZE == 4096U
|
||||
#define BLOCK_SIZE_P2 12U
|
||||
#elif REDCONF_BLOCK_SIZE == 8192U
|
||||
#define BLOCK_SIZE_P2 13U
|
||||
#elif REDCONF_BLOCK_SIZE == 16384U
|
||||
#define BLOCK_SIZE_P2 14U
|
||||
#elif REDCONF_BLOCK_SIZE == 32768U
|
||||
#define BLOCK_SIZE_P2 15U
|
||||
#elif REDCONF_BLOCK_SIZE == 65536U
|
||||
#define BLOCK_SIZE_P2 16U
|
||||
#else
|
||||
#error "REDCONF_BLOCK_SIZE must be a power of two value between 256 and 65536"
|
||||
#endif
|
||||
|
||||
#define REDMIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define INODE_INVALID (0U) /* General-purpose invalid inode number (must be zero). */
|
||||
#define INODE_FIRST_VALID (2U) /* First valid inode number. */
|
||||
#define INODE_ROOTDIR (INODE_FIRST_VALID) /* Inode number of the root directory. */
|
||||
|
||||
/* Expands to a "const" qualifier when the volume count is one, otherwise
|
||||
expands to nothing. This is useful for variables that never change in
|
||||
single-volume configurations but do change in multi-volume configurations.
|
||||
*/
|
||||
#if REDCONF_VOLUME_COUNT == 1U
|
||||
#define CONST_IF_ONE_VOLUME const
|
||||
#else
|
||||
#define CONST_IF_ONE_VOLUME
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
48
FreeRTOS-Plus/Source/Reliance-Edge/include/redmisc.h
Normal file
48
FreeRTOS-Plus/Source/Reliance-Edge/include/redmisc.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDMISC_H
|
||||
#define REDMISC_H
|
||||
|
||||
|
||||
/** @brief Type of an inode or handle.
|
||||
|
||||
Used to indicate the actual or expected type of an inode or handle.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FTYPE_FILE, /**< Type is file. */
|
||||
FTYPE_DIR, /**< Type is directory. */
|
||||
|
||||
/** Type is either file or directory: used only to indicate an expected
|
||||
type, never as an actual type.
|
||||
*/
|
||||
FTYPE_EITHER
|
||||
} FTYPE;
|
||||
|
||||
|
||||
#endif
|
||||
|
86
FreeRTOS-Plus/Source/Reliance-Edge/include/redosserv.h
Normal file
86
FreeRTOS-Plus/Source/Reliance-Edge/include/redosserv.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDOSSERV_H
|
||||
#define REDOSSERV_H
|
||||
|
||||
|
||||
#include <redostypes.h>
|
||||
|
||||
|
||||
/** @brief Type of access requested when opening a block device.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
BDEV_O_RDONLY, /**< Open block device for read access. */
|
||||
BDEV_O_WRONLY, /**< Open block device for write access. */
|
||||
BDEV_O_RDWR /**< Open block device for read and write access. */
|
||||
} BDEVOPENMODE;
|
||||
|
||||
REDSTATUS RedOsBDevOpen(uint8_t bVolNum, BDEVOPENMODE mode);
|
||||
REDSTATUS RedOsBDevClose(uint8_t bVolNum);
|
||||
REDSTATUS RedOsBDevRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer);
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
REDSTATUS RedOsBDevWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer);
|
||||
REDSTATUS RedOsBDevFlush(uint8_t bVolNum);
|
||||
#endif
|
||||
|
||||
/* Non-standard API: for host machines only.
|
||||
*/
|
||||
REDSTATUS RedOsBDevConfig(uint8_t bVolNum, const char *pszBDevSpec);
|
||||
|
||||
|
||||
#if REDCONF_TASK_COUNT > 1U
|
||||
REDSTATUS RedOsMutexInit(void);
|
||||
REDSTATUS RedOsMutexUninit(void);
|
||||
void RedOsMutexAcquire(void);
|
||||
void RedOsMutexRelease(void);
|
||||
#endif
|
||||
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
|
||||
uint32_t RedOsTaskId(void);
|
||||
#endif
|
||||
|
||||
REDSTATUS RedOsClockInit(void);
|
||||
REDSTATUS RedOsClockUninit(void);
|
||||
uint32_t RedOsClockGetTime(void);
|
||||
|
||||
REDSTATUS RedOsTimestampInit(void);
|
||||
REDSTATUS RedOsTimestampUninit(void);
|
||||
REDTIMESTAMP RedOsTimestamp(void);
|
||||
uint64_t RedOsTimePassed(REDTIMESTAMP tsSince);
|
||||
|
||||
#if REDCONF_OUTPUT == 1
|
||||
void RedOsOutputString(const char *pszString);
|
||||
#endif
|
||||
|
||||
#if REDCONF_ASSERTS == 1
|
||||
void RedOsAssertFail(const char *pszFileName, uint32_t ulLineNum);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
196
FreeRTOS-Plus/Source/Reliance-Edge/include/redposix.h
Normal file
196
FreeRTOS-Plus/Source/Reliance-Edge/include/redposix.h
Normal file
|
@ -0,0 +1,196 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Interface for the Reliance Edge POSIX-like API.
|
||||
|
||||
The POSIX-like file system API is the primary file system API for
|
||||
Reliance Edge, which supports the full functionality of the file system.
|
||||
This API aims to be compatible with POSIX where reasonable, but it is
|
||||
simplified considerably to meet the needs of resource-constrained embedded
|
||||
systems. The API has also been extended to provide access to the unique
|
||||
features of Reliance Edge, and to cover areas (like mountins and formatting)
|
||||
which do not have APIs in the POSIX specification.
|
||||
*/
|
||||
#ifndef REDPOSIX_H
|
||||
#define REDPOSIX_H
|
||||
|
||||
/* This header is intended for application use; some applications are written
|
||||
in C++.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <redconf.h>
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
|
||||
#include <redtypes.h>
|
||||
#include "redapimacs.h"
|
||||
#include "rederrno.h"
|
||||
#include "redstat.h"
|
||||
|
||||
/** Open for reading only. */
|
||||
#define RED_O_RDONLY 0x00000001U
|
||||
|
||||
/** Open for writing only. */
|
||||
#define RED_O_WRONLY 0x00000002U
|
||||
|
||||
/** Open for reading and writing. */
|
||||
#define RED_O_RDWR 0x00000004U
|
||||
|
||||
/** File offset for all writes is end-of-file. */
|
||||
#define RED_O_APPEND 0x00000008U
|
||||
|
||||
/** Create the file. */
|
||||
#define RED_O_CREAT 0x00000010U
|
||||
|
||||
/** Error if path already exists. */
|
||||
#define RED_O_EXCL 0x00000020U
|
||||
|
||||
/** Truncate file to size zero. */
|
||||
#define RED_O_TRUNC 0x00000040U
|
||||
|
||||
|
||||
/** @brief Last file system error (errno).
|
||||
|
||||
Under normal circumstances, each task using the file system has an
|
||||
independent `red_errno` value. Applications do not need to worry about
|
||||
one task obliterating an error value that another task needed to read. The
|
||||
value is initially zero. When one of the POSIX-like APIs return an
|
||||
indication of error, `red_errno` is set to an error value.
|
||||
|
||||
In some circumstances, `red_errno` will be a global errno location which
|
||||
is shared by multiple tasks. If the calling task is not registered as a
|
||||
file system user and all of the task slots are full, there can be no
|
||||
task-specific errno, so the global errno is used. Likewise, if the file
|
||||
system driver is uninitialized, there are no registered file system users
|
||||
and `red_errno` always refers to the global errno. Under these
|
||||
circumstances, multiple tasks manipulating `red_errno` could be
|
||||
problematic. When the task count is set to one, `red_errno` always refers
|
||||
to the global errno.
|
||||
|
||||
Note that `red_errno` is usable as an lvalue; i.e., in addition to reading
|
||||
the error value, the error value can be set:
|
||||
|
||||
~~~{.c}
|
||||
red_errno = 0;
|
||||
~~~
|
||||
*/
|
||||
#define red_errno (*red_errnoptr())
|
||||
|
||||
|
||||
/** @brief Positions from which to seek within a file.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
/* 0/1/2 are the traditional values for SET/CUR/END, respectively. Prior
|
||||
to the release of Unix System V in 1983, the SEEK_* symbols did not
|
||||
exist and C programs hard-coded the 0/1/2 values with those meanings.
|
||||
*/
|
||||
RED_SEEK_SET = 0, /**< Set file offset to given offset. */
|
||||
RED_SEEK_CUR = 1, /**< Set file offset to current offset plus signed offset. */
|
||||
RED_SEEK_END = 2 /**< Set file offset to EOF plus signed offset. */
|
||||
} REDWHENCE;
|
||||
|
||||
|
||||
#if REDCONF_API_POSIX_READDIR == 1
|
||||
/** @brief Opaque directory handle.
|
||||
*/
|
||||
typedef struct sREDHANDLE REDDIR;
|
||||
|
||||
|
||||
/** @brief Directory entry information.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t d_ino; /**< File serial number (inode number). */
|
||||
char d_name[REDCONF_NAME_MAX+1U]; /**< Name of entry. */
|
||||
REDSTAT d_stat; /**< File information (POSIX extension). */
|
||||
} REDDIRENT;
|
||||
#endif
|
||||
|
||||
|
||||
int32_t red_init(void);
|
||||
int32_t red_uninit(void);
|
||||
int32_t red_mount(const char *pszVolume);
|
||||
int32_t red_umount(const char *pszVolume);
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1)
|
||||
int32_t red_format(const char *pszVolume);
|
||||
#endif
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
int32_t red_transact(const char *pszVolume);
|
||||
#endif
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
int32_t red_settransmask(const char *pszVolume, uint32_t ulEventMask);
|
||||
#endif
|
||||
int32_t red_gettransmask(const char *pszVolume, uint32_t *pulEventMask);
|
||||
int32_t red_statvfs(const char *pszVolume, REDSTATFS *pStatvfs);
|
||||
int32_t red_open(const char *pszPath, uint32_t ulOpenMode);
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1)
|
||||
int32_t red_unlink(const char *pszPath);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1)
|
||||
int32_t red_mkdir(const char *pszPath);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1)
|
||||
int32_t red_rmdir(const char *pszPath);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1)
|
||||
int32_t red_rename(const char *pszOldPath, const char *pszNewPath);
|
||||
#endif
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1)
|
||||
int32_t red_link(const char *pszPath, const char *pszHardLink);
|
||||
#endif
|
||||
int32_t red_close(int32_t iFildes);
|
||||
int32_t red_read(int32_t iFildes, void *pBuffer, uint32_t ulLength);
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
int32_t red_write(int32_t iFildes, const void *pBuffer, uint32_t ulLength);
|
||||
#endif
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
int32_t red_fsync(int32_t iFildes);
|
||||
#endif
|
||||
int64_t red_lseek(int32_t iFildes, int64_t llOffset, REDWHENCE whence);
|
||||
#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1)
|
||||
int32_t red_ftruncate(int32_t iFildes, uint64_t ullSize);
|
||||
#endif
|
||||
int32_t red_fstat(int32_t iFildes, REDSTAT *pStat);
|
||||
#if REDCONF_API_POSIX_READDIR == 1
|
||||
REDDIR *red_opendir(const char *pszPath);
|
||||
REDDIRENT *red_readdir(REDDIR *pDirStream);
|
||||
void red_rewinddir(REDDIR *pDirStream);
|
||||
int32_t red_closedir(REDDIR *pDirStream);
|
||||
#endif
|
||||
REDSTATUS *red_errnoptr(void);
|
||||
|
||||
#endif /* REDCONF_API_POSIX */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
94
FreeRTOS-Plus/Source/Reliance-Edge/include/redstat.h
Normal file
94
FreeRTOS-Plus/Source/Reliance-Edge/include/redstat.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDSTAT_H
|
||||
#define REDSTAT_H
|
||||
|
||||
|
||||
/** Mode bit for a directory. */
|
||||
#define RED_S_IFDIR 0x4000U
|
||||
|
||||
/** Mode bit for a regular file. */
|
||||
#define RED_S_IFREG 0x8000U
|
||||
|
||||
/** @brief Test for a directory.
|
||||
*/
|
||||
#define RED_S_ISDIR(m) (((m) & RED_S_IFDIR) != 0U)
|
||||
|
||||
/** @brief Test for a regular file.
|
||||
*/
|
||||
#define RED_S_ISREG(m) (((m) & RED_S_IFREG) != 0U)
|
||||
|
||||
|
||||
/** File system is read-only. */
|
||||
#define RED_ST_RDONLY 0x00000001U
|
||||
|
||||
/** File system ignores suid and sgid bits. */
|
||||
#define RED_ST_NOSUID 0x00000002U
|
||||
|
||||
|
||||
/** @brief Status information on an inode.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t st_dev; /**< Volume number of volume containing file. */
|
||||
uint32_t st_ino; /**< File serial number (inode number). */
|
||||
uint16_t st_mode; /**< Mode of file. */
|
||||
uint16_t st_nlink; /**< Number of hard links to the file. */
|
||||
uint64_t st_size; /**< File size in bytes. */
|
||||
#if REDCONF_INODE_TIMESTAMPS == 1
|
||||
uint32_t st_atime; /**< Time of last access (seconds since 01-01-1970). */
|
||||
uint32_t st_mtime; /**< Time of last data modification (seconds since 01-01-1970). */
|
||||
uint32_t st_ctime; /**< Time of last status change (seconds since 01-01-1970). */
|
||||
#endif
|
||||
#if REDCONF_INODE_BLOCKS == 1
|
||||
uint32_t st_blocks; /**< Number of blocks allocated for this object. */
|
||||
#endif
|
||||
} REDSTAT;
|
||||
|
||||
|
||||
/** @brief Status information on a file system volume.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t f_bsize; /**< File system block size. */
|
||||
uint32_t f_frsize; /**< Fundamental file system block size. */
|
||||
uint32_t f_blocks; /**< Total number of blocks on file system in units of f_frsize. */
|
||||
uint32_t f_bfree; /**< Total number of free blocks. */
|
||||
uint32_t f_bavail; /**< Number of free blocks available to non-privileged process. */
|
||||
uint32_t f_files; /**< Total number of file serial numbers. */
|
||||
uint32_t f_ffree; /**< Total number of free file serial numbers. */
|
||||
uint32_t f_favail; /**< Number of file serial numbers available to non-privileged process. */
|
||||
uint32_t f_fsid; /**< File system ID (useless, populated with zero). */
|
||||
uint32_t f_flag; /**< Bit mask of f_flag values. Includes read-only file system flag. */
|
||||
uint32_t f_namemax; /**< Maximum filename length. */
|
||||
uint64_t f_maxfsize; /**< Maximum file size (POSIX extension). */
|
||||
uint32_t f_dev; /**< Volume number (POSIX extension). */
|
||||
} REDSTATFS;
|
||||
|
||||
|
||||
#endif
|
||||
|
249
FreeRTOS-Plus/Source/Reliance-Edge/include/redtests.h
Normal file
249
FreeRTOS-Plus/Source/Reliance-Edge/include/redtests.h
Normal file
|
@ -0,0 +1,249 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Prototypes for Reliance Edge test entry points.
|
||||
*/
|
||||
#ifndef REDTESTS_H
|
||||
#define REDTESTS_H
|
||||
|
||||
#include <redtypes.h>
|
||||
#include "redtestutils.h"
|
||||
#include "redver.h"
|
||||
|
||||
/* This macro is only defined by the error injection project.
|
||||
*/
|
||||
#ifdef REDCONF_ERROR_INJECTION
|
||||
#include <rederrinject.h>
|
||||
#endif
|
||||
|
||||
#define FSSTRESS_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_GPL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_PATH_SEPARATOR == '/') \
|
||||
&& (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_UNLINK == 1) && (REDCONF_API_POSIX_MKDIR == 1) \
|
||||
&& (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_RENAME == 1) && (REDCONF_API_POSIX_LINK == 1) \
|
||||
&& (REDCONF_API_POSIX_FTRUNCATE == 1) && (REDCONF_API_POSIX_READDIR == 1))
|
||||
|
||||
#define FSE_STRESS_TEST_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \
|
||||
&& (REDCONF_API_FSE_FORMAT == 1) && (REDCONF_API_FSE_TRANSMASKSET == 1) && (REDCONF_API_FSE_TRANSMASKGET == 1) \
|
||||
&& (REDCONF_API_FSE_TRUNCATE == 1))
|
||||
|
||||
#define POSIX_API_TEST_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \
|
||||
&& (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_UNLINK == 1))
|
||||
|
||||
#define FSE_API_TEST_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE == 1) \
|
||||
&& (REDCONF_API_FSE_FORMAT == 1))
|
||||
|
||||
#define STOCH_POSIX_TEST_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \
|
||||
&& (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_READDIR == 1) \
|
||||
&& (REDCONF_API_POSIX_MKDIR == 1) && (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_UNLINK == 1) \
|
||||
&& (REDCONF_API_POSIX_RENAME == 1))
|
||||
|
||||
#define FSIOTEST_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_API_POSIX == 1))
|
||||
|
||||
#define BDEVTEST_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0))
|
||||
|
||||
#define DISKFULL_TEST_SUPPORTED \
|
||||
( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \
|
||||
&& (REDCONF_OUTPUT == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) \
|
||||
&& (REDCONF_API_POSIX_FORMAT == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1))
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PARAMSTATUS_OK, /* Parameters were good; continue. */
|
||||
PARAMSTATUS_BAD, /* Parameters were bad; stop. */
|
||||
PARAMSTATUS_HELP /* Help request; not an error, but stop. */
|
||||
} PARAMSTATUS;
|
||||
|
||||
|
||||
#if FSSTRESS_SUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
bool fNoCleanup; /**< --no-cleanup */
|
||||
uint32_t ulLoops; /**< --loops */
|
||||
uint32_t ulNops; /**< --nops */
|
||||
bool fNamePad; /**< --namepad */
|
||||
uint32_t ulSeed; /**< --seed */
|
||||
bool fVerbose; /**< --verbose */
|
||||
} FSSTRESSPARAM;
|
||||
|
||||
PARAMSTATUS FsstressParseParams(int argc, char *argv[], FSSTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void FsstressDefaultParams(FSSTRESSPARAM *pParam);
|
||||
int FsstressStart(const FSSTRESSPARAM *pParam);
|
||||
#endif
|
||||
|
||||
#if STOCH_POSIX_TEST_SUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
const char *pszVolume; /**< Volume path prefix. */
|
||||
uint32_t ulIterations; /**< --iterations */
|
||||
uint32_t ulFileListMax; /**< --files */
|
||||
uint32_t ulDirListMax; /**< --dirs */
|
||||
uint32_t ulOpenFileListMax; /**< --open-files */
|
||||
uint32_t ulOpenDirListMax; /**< --open-dirs */
|
||||
uint32_t ulRandomSeed; /**< --seed */
|
||||
} STOCHPOSIXPARAM;
|
||||
|
||||
PARAMSTATUS RedStochPosixParseParams(int argc, char *argv[], STOCHPOSIXPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void RedStochPosixDefaultParams(STOCHPOSIXPARAM *pParam);
|
||||
int RedStochPosixStart(const STOCHPOSIXPARAM *pParam);
|
||||
#endif
|
||||
|
||||
#if FSE_STRESS_TEST_SUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bVolNum; /**< Volume number. */
|
||||
uint32_t ulFileCount; /**< --files */
|
||||
uint32_t ulMaxFileSize; /**< --max */
|
||||
uint32_t ulMaxOpSize; /**< --buffer-size */
|
||||
uint32_t ulNops; /**< --nops */
|
||||
uint32_t ulLoops; /**< --loops */
|
||||
uint32_t ulSampleRate; /**< --sample-rate */
|
||||
uint64_t ullSeed; /**< --seed */
|
||||
} FSESTRESSPARAM;
|
||||
|
||||
PARAMSTATUS FseStressParseParams(int argc, char *argv[], FSESTRESSPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void FseStressDefaultParams(FSESTRESSPARAM *pParam);
|
||||
int FseStressStart(const FSESTRESSPARAM *pParam);
|
||||
#endif
|
||||
|
||||
#if POSIX_API_TEST_SUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
const char *pszVolume; /**< Volume path prefix. */
|
||||
bool fQuick; /**< --quick */
|
||||
bool fQuitOnFailure; /**< --quit-on-failure */
|
||||
bool fDebugErrors; /**< --debug */
|
||||
} POSIXTESTPARAM;
|
||||
|
||||
PARAMSTATUS RedPosixTestParseParams(int argc, char *argv[], POSIXTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void RedPosixTestDefaultParams(POSIXTESTPARAM *pParam);
|
||||
int RedPosixTestStart(const POSIXTESTPARAM *pParam);
|
||||
#endif
|
||||
|
||||
|
||||
#if FSE_API_TEST_SUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bVolNum; /**< Volume number. */
|
||||
bool fQuitOnFailure; /**< --quit-on-failure */
|
||||
bool fDebugErrors; /**< --debug */
|
||||
} FSETESTPARAM;
|
||||
|
||||
PARAMSTATUS RedFseTestParseParams(int argc, char *argv[], FSETESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void RedFseTestDefaultParams(FSETESTPARAM *pParam);
|
||||
int RedFseTestStart(const FSETESTPARAM *pParam);
|
||||
#endif
|
||||
|
||||
#if FSIOTEST_SUPPORTED
|
||||
typedef enum
|
||||
{
|
||||
TESTFS_RELEDGE, /* Datalight Reliance Edge */
|
||||
TESTFS_FATFS, /* ChaN's FatFs */
|
||||
TESTFS_FATSL /* FreeRTOS+FAT SL */
|
||||
} TESTFS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TESTFS testfs; /**< --fs */
|
||||
const char *pszVolume; /**< Volume path prefix. */
|
||||
bool fSeqRead; /**< --seq=r */
|
||||
bool fSeqWrite; /**< --seq=w */
|
||||
bool fSeqRewrite; /**< --seq=e */
|
||||
bool fRandomRead; /**< --rand=r */
|
||||
bool fRandomWrite; /**< --rand=w */
|
||||
bool fMixedWrite; /**< --mixed */
|
||||
bool fScanTest; /**< --scan */
|
||||
uint32_t ulFSBlockSize; /**< --block-size */
|
||||
uint32_t ulMaxFileSize; /**< --max */
|
||||
uint32_t ulRandomReadPasses; /**< --rand-pass=r:w (r part) */
|
||||
uint32_t ulRandomWritePasses; /**< --rand-pass=r:w (w part) */
|
||||
uint32_t ulMixedWritePasses; /**< --mixed-pass */
|
||||
int32_t iFlushOnWriteRatio; /**< --rand-fow */
|
||||
uint32_t ulBufferMin; /**< --start */
|
||||
uint32_t ulBufferSize; /**< --buffer-size */
|
||||
bool fWriteVerify; /**< --verify */
|
||||
uint32_t ulSampleRate; /**< --sample-rate */
|
||||
uint32_t ulScanCount; /**< --scan-files */
|
||||
uint64_t ullSeed; /**< --seed */
|
||||
} FSIOTESTPARAM;
|
||||
|
||||
PARAMSTATUS FSIOTestParseParams(int argc, char *argv[], FSIOTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void FSIOTestDefaultParams(FSIOTESTPARAM *pParam);
|
||||
int FSIOTestStart(const FSIOTESTPARAM *pParam);
|
||||
#endif
|
||||
|
||||
#if BDEVTEST_SUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
uint8_t bDrvNum; /**< Volume number (for sector size/count). */
|
||||
bool fSeqWrite; /**< --seq:w */
|
||||
bool fSeqRead; /**< --seq:r */
|
||||
bool fRandWrite; /**< --rand:w */
|
||||
bool fRandRead; /**< --rand:r */
|
||||
uint32_t ulSampleSecs; /**< --sample-rate */
|
||||
uint32_t ulPasses; /**< --passes */
|
||||
uint32_t ulMinIOSectors; /**< --count=min[:max] (min part) */
|
||||
uint32_t ulMaxIOSectors; /**< --count=min[:max] (max part) */
|
||||
uint32_t ulMaxSizeKB; /**< --max */
|
||||
uint32_t ulTestSeconds; /**< --time */
|
||||
bool fVerify; /**< --verify */
|
||||
bool fAsyncWrites; /**< --async */
|
||||
uint64_t ullSeed; /**< --seed */
|
||||
} BDEVTESTPARAM;
|
||||
|
||||
PARAMSTATUS BDevTestParseParams(int argc, char *argv[], BDEVTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void BDevTestDefaultParams(BDEVTESTPARAM *pParam);
|
||||
int BDevTestStart(const BDEVTESTPARAM *pParam);
|
||||
#endif
|
||||
|
||||
#if DISKFULL_TEST_SUPPORTED
|
||||
typedef struct
|
||||
{
|
||||
const char *pszVolume; /**< Volume path prefix. */
|
||||
bool fQuitOnFailure; /**< --quit-on-failure */
|
||||
bool fDebugErrors; /**< --debug */
|
||||
} DISKFULLTESTPARAM;
|
||||
|
||||
PARAMSTATUS DiskFullTestParseParams(int argc, char *argv[], DISKFULLTESTPARAM *pParam, uint8_t *pbVolNum, const char **ppszDevice);
|
||||
void DiskFullTestDefaultParams(DISKFULLTESTPARAM *pParam);
|
||||
int DiskFullTestStart(const DISKFULLTESTPARAM *pParam);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
71
FreeRTOS-Plus/Source/Reliance-Edge/include/redtestutils.h
Normal file
71
FreeRTOS-Plus/Source/Reliance-Edge/include/redtestutils.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Reliance Edge utilities only needed for tests.
|
||||
*/
|
||||
#ifndef REDTESTUTILS_H
|
||||
#define REDTESTUTILS_H
|
||||
|
||||
|
||||
#define ISDIGIT(c) (((c) >= '0') && ((c) <= '9'))
|
||||
|
||||
|
||||
void RedRandSeed(uint64_t ullSeed);
|
||||
uint64_t RedRand64(uint64_t *pullSeed);
|
||||
uint32_t RedRand32(uint32_t *pulSeed);
|
||||
|
||||
char *RedRatio(char *pBuffer, uint32_t ulBufferLen, uint64_t ullDividend, uint64_t ullDivisor, uint32_t ulDecPlaces);
|
||||
uint64_t RedMulDiv64(uint64_t ullBase, uint32_t ulMultiplier, uint64_t ullDivisor);
|
||||
uint64_t RedUint64DivMod32(uint64_t ullDividend, uint32_t ulDivisor, uint32_t *pulRemainder);
|
||||
uint64_t RedUint64DivMod64(uint64_t ullDividend, uint64_t ullDivisor, uint64_t *pullRemainder);
|
||||
|
||||
char *RedScaleBytes(uint32_t ulByteValue, char *pszBuffer, uint32_t ulBufferSize);
|
||||
char *RedScaleKB(uint32_t ulKBValue, char *pszBuffer, uint32_t ulBufferSize);
|
||||
uint32_t RedGetKBPerSecond(uint64_t ullKB, uint32_t ulMS);
|
||||
uint32_t RedGetKBPerSecondSectors(uint32_t ulBytesPerSector, uint64_t ullSectors, uint64_t ullUS);
|
||||
|
||||
int32_t RedAtoI(const char *pszNum);
|
||||
const char *RedHtoUL(const char *pszNum, uint32_t *pulNum);
|
||||
const char *RedHtoULL(const char *pszNum, uint64_t *pullNum);
|
||||
const char *RedNtoUL(const char *pszNum, uint32_t *pulNum);
|
||||
const char *RedNtoULL(const char *pszNum, uint64_t *pullNum);
|
||||
const char *RedSizeToUL(const char *pszNum, uint32_t *pulResult);
|
||||
|
||||
int32_t RedStrICmp(const char *pszStr1, const char *pszStr2);
|
||||
int32_t RedStrNICmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen);
|
||||
char RedToLower(char c);
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if REDCONF_OUTPUT == 1
|
||||
void RedPrintf(const char *pszFormat, ...);
|
||||
void RedVPrintf(const char *pszFormat, va_list arglist);
|
||||
#endif
|
||||
int32_t RedSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, ...);
|
||||
int32_t RedVSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, va_list arglist);
|
||||
|
||||
|
||||
#endif
|
||||
|
36
FreeRTOS-Plus/Source/Reliance-Edge/include/redtoolcmn.h
Normal file
36
FreeRTOS-Plus/Source/Reliance-Edge/include/redtoolcmn.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Interfaces for common-code utilities for tools and tests.
|
||||
*/
|
||||
#ifndef REDTOOLCMN_H
|
||||
#define REDTOOLCMN_H
|
||||
|
||||
|
||||
uint8_t RedFindVolumeNumber(const char *pszVolume);
|
||||
|
||||
|
||||
#endif
|
||||
|
71
FreeRTOS-Plus/Source/Reliance-Edge/include/redutils.h
Normal file
71
FreeRTOS-Plus/Source/Reliance-Edge/include/redutils.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDUTILS_H
|
||||
#define REDUTILS_H
|
||||
|
||||
|
||||
#if REDCONF_ASSERTS == 1
|
||||
#define REDERROR() RedOsAssertFail(__FILE__, __LINE__)
|
||||
#define REDASSERT(EXP) ((EXP) ? (void)0 : REDERROR())
|
||||
#else
|
||||
#define REDERROR() ((void)0)
|
||||
#define REDASSERT(EXP) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
void RedMemCpy(void *pDest, const void *pSrc, uint32_t ulLen);
|
||||
void RedMemMove(void *pDest, const void *pSrc, uint32_t ulLen);
|
||||
void RedMemSet(void *pDest, uint8_t bVal, uint32_t ulLen);
|
||||
int32_t RedMemCmp(const void *pMem1, const void *pMem2, uint32_t ulLen);
|
||||
|
||||
uint32_t RedStrLen(const char *pszStr);
|
||||
int32_t RedStrCmp(const char *pszStr1, const char *pszStr2);
|
||||
int32_t RedStrNCmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen);
|
||||
void RedStrNCpy(char *pszDst, const char *pszSrc, uint32_t ulLen);
|
||||
|
||||
uint32_t RedCrc32Update(uint32_t ulInitCrc32, const void *pBuffer, uint32_t ulLength);
|
||||
uint32_t RedCrcNode(const void *pBuffer);
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
uint32_t RedNameLen(const char *pszName);
|
||||
#endif
|
||||
|
||||
bool RedBitGet(const uint8_t *pbBitmap, uint32_t ulBit);
|
||||
void RedBitSet(uint8_t *pbBitmap, uint32_t ulBit);
|
||||
void RedBitClear(uint8_t *pbBitmap, uint32_t ulBit);
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
uint64_t RedRev64(uint64_t ullToRev);
|
||||
uint32_t RedRev32(uint32_t ulToRev);
|
||||
uint16_t RedRev16(uint16_t uToRev);
|
||||
#endif
|
||||
|
||||
void RedSignOn(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
106
FreeRTOS-Plus/Source/Reliance-Edge/include/redver.h
Normal file
106
FreeRTOS-Plus/Source/Reliance-Edge/include/redver.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Macros for version numbers, build number, and product information.
|
||||
*/
|
||||
#ifndef REDVER_H
|
||||
#define REDVER_H
|
||||
|
||||
|
||||
/** @brief Consecutive number assigned to each automated build.
|
||||
|
||||
<!-- This macro is updated automatically: do not edit! -->
|
||||
*/
|
||||
#define RED_BUILD_NUMBER "664"
|
||||
|
||||
#define RED_KIT_GPL 0U /* Open source GPL kit. */
|
||||
#define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */
|
||||
#define RED_KIT_SANDBOX 2U /* Not a kit: developer sandbox. */
|
||||
|
||||
/** @brief Indicates the Reliance Edge kit.
|
||||
|
||||
<!-- This macro is updated automatically: do not edit! -->
|
||||
*/
|
||||
#define RED_KIT RED_KIT_GPL
|
||||
|
||||
|
||||
/** @brief Version number to display in output.
|
||||
*/
|
||||
#define RED_VERSION "v1.0"
|
||||
|
||||
|
||||
/** @brief On-disk version number.
|
||||
|
||||
This is incremented only when the on-disk layout is updated in such a way
|
||||
which is incompatible with previously released versions of the file system.
|
||||
*/
|
||||
#define RED_DISK_LAYOUT_VERSION 1U
|
||||
|
||||
|
||||
/** @brief Base name of the file system product.
|
||||
*/
|
||||
#define RED_PRODUCT_BASE_NAME "Reliance Edge"
|
||||
|
||||
|
||||
/* Specifies whether the product is in alpha stage, beta stage, or neither.
|
||||
*/
|
||||
#if 0
|
||||
#if 1
|
||||
#define ALPHABETA " (Alpha)"
|
||||
#else
|
||||
#define ALPHABETA " (Beta)"
|
||||
#endif
|
||||
#else
|
||||
#define ALPHABETA ""
|
||||
#endif
|
||||
|
||||
/** @brief Full product name and version.
|
||||
*/
|
||||
#define RED_PRODUCT_NAME "Datalight "RED_PRODUCT_BASE_NAME" "RED_VERSION" Build "RED_BUILD_NUMBER ALPHABETA
|
||||
|
||||
|
||||
/** @brief Product copyright.
|
||||
*/
|
||||
#define RED_PRODUCT_LEGAL "Copyright (c) 2014-2015 Datalight, Inc. All Rights Reserved Worldwide."
|
||||
|
||||
|
||||
/** @brief Product patents.
|
||||
*/
|
||||
#define RED_PRODUCT_PATENT "Patents: US#7284101."
|
||||
|
||||
|
||||
/** @brief Product edition.
|
||||
*/
|
||||
#if RED_KIT == RED_KIT_GPL
|
||||
#define RED_PRODUCT_EDITION "Open-Source GPLv2 Edition -- Compiled "__DATE__" at "__TIME__
|
||||
#elif RED_KIT == RED_KIT_COMMERCIAL
|
||||
#define RED_PRODUCT_EDITION "Commercial Edition -- Compiled "__DATE__" at "__TIME__
|
||||
#else
|
||||
#define RED_PRODUCT_EDITION "Developer Sandbox -- Compiled "__DATE__" at "__TIME__
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
134
FreeRTOS-Plus/Source/Reliance-Edge/include/redvolume.h
Normal file
134
FreeRTOS-Plus/Source/Reliance-Edge/include/redvolume.h
Normal file
|
@ -0,0 +1,134 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
*/
|
||||
#ifndef REDVOLUME_H
|
||||
#define REDVOLUME_H
|
||||
|
||||
|
||||
/** @brief Per-volume configuration structure.
|
||||
|
||||
Contains the configuration values that may differ between volumes. Must be
|
||||
declared in an array in redconf.c in the Reliance Edge project directory and
|
||||
statically initialized with values representing the volume configuration of
|
||||
the target system.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** The sector size for the block device underlying the volume: the basic
|
||||
unit for reading and writing to the storage media. Commonly ranges
|
||||
between 512 and 4096, but any power-of-two value not greater than the
|
||||
block size will work.
|
||||
*/
|
||||
uint32_t ulSectorSize;
|
||||
|
||||
/** The number of sectors in this file system volume.
|
||||
*/
|
||||
uint64_t ullSectorCount;
|
||||
|
||||
/** Whether a sector write on the block device underlying the volume is
|
||||
atomic. It is atomic if when the sector write is interrupted, the
|
||||
contents of the sector are guaranteed to be either all of the new data,
|
||||
or all of the old data. If unsure, leave as false.
|
||||
*/
|
||||
bool fAtomicSectorWrite;
|
||||
|
||||
/** This is the maximum number of inodes (files and directories). This
|
||||
number includes the root directory inode (inode 2; created during
|
||||
format), but does not include inodes 0 or 1, which do not exist on
|
||||
disk. The number of inodes cannot be less than 1.
|
||||
*/
|
||||
uint32_t ulInodeCount;
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
/** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc.
|
||||
*/
|
||||
const char *pszPathPrefix;
|
||||
#endif
|
||||
} VOLCONF;
|
||||
|
||||
extern const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT];
|
||||
extern const VOLCONF * CONST_IF_ONE_VOLUME gpRedVolConf;
|
||||
|
||||
|
||||
/** @brief Per-volume run-time data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/** Whether the volume is currently mounted.
|
||||
*/
|
||||
bool fMounted;
|
||||
|
||||
#if REDCONF_READ_ONLY == 0
|
||||
/** Whether the volume is read-only.
|
||||
*/
|
||||
bool fReadOnly;
|
||||
|
||||
/** The active automatic transaction mask.
|
||||
*/
|
||||
uint32_t ulTransMask;
|
||||
#endif
|
||||
|
||||
/** The power of 2 difference between sector size and block size.
|
||||
*/
|
||||
uint8_t bBlockSectorShift;
|
||||
|
||||
/** The number of logical blocks in this file system volume. The unit here
|
||||
is the global block size.
|
||||
*/
|
||||
uint32_t ulBlockCount;
|
||||
|
||||
/** The total number of allocable blocks; Also the maximum count of free
|
||||
blocks.
|
||||
*/
|
||||
uint32_t ulBlocksAllocable;
|
||||
|
||||
/** The maximum number of bytes that an inode is capable of addressing.
|
||||
*/
|
||||
uint64_t ullMaxInodeSize;
|
||||
|
||||
/** The current metadata sequence number. This value is included in all
|
||||
metadata nodes and incremented every time a metadata node is written.
|
||||
It is assumed to never wrap around.
|
||||
*/
|
||||
uint64_t ullSequence;
|
||||
} VOLUME;
|
||||
|
||||
/* Array of VOLUME structures, populated at during RedCoreInit().
|
||||
*/
|
||||
extern VOLUME gaRedVolume[REDCONF_VOLUME_COUNT];
|
||||
|
||||
/* Volume number currently being accessed; populated during
|
||||
RedCoreVolSetCurrent().
|
||||
*/
|
||||
extern CONST_IF_ONE_VOLUME uint8_t gbRedVolNum;
|
||||
|
||||
/* Pointer to the volume currently being accessed; populated during
|
||||
RedCoreVolSetCurrent().
|
||||
*/
|
||||
extern VOLUME * CONST_IF_ONE_VOLUME gpRedVolume;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Macros to encapsulate MISRA C:2012 deviations in OS-specific code.
|
||||
*/
|
||||
#ifndef REDOSDEVIATIONS_H
|
||||
#define REDOSDEVIATIONS_H
|
||||
|
||||
|
||||
#if REDCONF_OUTPUT == 1
|
||||
/* Needed for PRINT_ASSERT() and OUTPUT_CHARACTER().
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if REDCONF_ASSERTS == 1
|
||||
#if REDCONF_OUTPUT == 1
|
||||
/** Print a formatted message for an assertion.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required). Using
|
||||
printf() is the most convenient way to output this information; and the risk
|
||||
of "unspecified, undefined and implementation-defined" behavior causing
|
||||
problems (as cited in the rationale for the rule) is small. The driver does
|
||||
not depend on this string being outputted correctly. Furthermore, use of
|
||||
printf() disappears when either asserts or output are disabled.
|
||||
|
||||
As Rule 21.6 is required, a separate deviation record is required.
|
||||
*/
|
||||
#define PRINT_ASSERT(file, line) \
|
||||
(void)printf("Assertion failed in \"%s\" at line %u\n\r", ((file) == NULL) ? "" : (file), (unsigned)(line))
|
||||
#else
|
||||
#define PRINT_ASSERT(file, line) do { (void)(file); (void)(line); } while(false)
|
||||
#endif /* REDCONF_OUTPUT == 1 */
|
||||
#endif /* REDCONF_ASSERTS == 1 */
|
||||
|
||||
|
||||
/** Cast a value to unsigned long.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Directive 4.6. This macro is
|
||||
used in two places to cast a uint64_t value (used by the block device
|
||||
abstraction for sector numbers) to unsigned long, since third-party code
|
||||
which is not under the control of this project uses unsigned long for sector
|
||||
numbers. The cast is guaranteed to not lose any information, since when the
|
||||
disk is opened the sector count is verified to be less than or equal to an
|
||||
unsigned long value. The text of the directive mentions that "it might be
|
||||
desirable not to apply this guideline when interfacing with ... code outside
|
||||
the project's control", which describes the situation for this deviation.
|
||||
|
||||
As Directive 4.6 is advisory, a deviation record is not required. This
|
||||
notice is the only record of the deviation.
|
||||
*/
|
||||
#define CAST_ULONG(ull) ((unsigned long)(ull))
|
||||
|
||||
|
||||
/** Cast a const-qualified pointer to a pointer which is *not* const-qualified.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 11.8. This macro is
|
||||
used in exactly one place in order to cope with a poorly designed
|
||||
third-party interface. Reliance Edge, at every level of the stack, uses
|
||||
const-qualified pointers for buffers used in write operations, since the
|
||||
data is read from the buffer, and the buffer does not need to be modified
|
||||
(consistent with Rule 8.13). One of the third-party block device interfaces
|
||||
that Reliance Edge interfaces with does not follow this convention: it uses
|
||||
an unqualified pointer for the buffer parameter of its sector write
|
||||
function. This forces the need for the cast to avoid warnings. The
|
||||
implementation of the sector write function is provided by the user, so it
|
||||
is to be hoped that the buffer is not actually modified.
|
||||
|
||||
As Rule 11.8 is required, a separate deviation record is required.
|
||||
*/
|
||||
#define CAST_AWAY_CONST(type, ptr) ((type *)(ptr))
|
||||
|
||||
|
||||
/** Allocate zero-initialized (cleared) memory.
|
||||
|
||||
All usages of this macro deviate from MISRA C:2012 Directive 4.12 (required)
|
||||
and Rule 21.3 (required). In the context of the single place it is actually
|
||||
used, this macro also deviates from Rule 22.1 (required).
|
||||
|
||||
This macro is used in the FreeRTOS block device code in order to allocate a
|
||||
RAM disk, when that implementation of the block device is selected. The
|
||||
primary rationale for all these deviations is that a) the RAM disk cannot be
|
||||
allocated statically (since the volume information is stored in a
|
||||
structure), and b) the RAM disk is primarily intended as a temporary testing
|
||||
tool for users who want to try out Reliance Edge before the real storage
|
||||
media is available. In most real systems, Reliance Edge is used with
|
||||
non-volatile storage like SD/MMC or eMMC, not with RAM disks.
|
||||
|
||||
Rule 22.1 states that all resources which are allocated must also be
|
||||
explicitly freed. The RAM disk is allocated and never freed, deviating from
|
||||
that rule. This is done because the data in the RAM disk is emulating a
|
||||
non-volatile storage medium, and thus needs to persist even after the block
|
||||
device is closed, to allow the file system to be ormatted and then mounted,
|
||||
or unmounted and remounted in the course of a test. Thus the memory will
|
||||
remain allocated until the target device is rebooted. This is assumed to be
|
||||
acceptable for the primary purpose of the RAM disk, which is preliminary
|
||||
testing.
|
||||
|
||||
As Directive 4.12, Rule 21.3, and Rule 22.1 are all required, separate
|
||||
deviation records are required.
|
||||
*/
|
||||
#define ALLOCATE_CLEARED_MEMORY(nelem, elsize) calloc(nelem, elsize)
|
||||
|
||||
|
||||
#if REDCONF_OUTPUT == 1
|
||||
/** Output a character to a serial port or other display device.
|
||||
|
||||
Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required).
|
||||
FreeRTOS does not include a standard method of printing characters, so
|
||||
putchar() is the most convenient and portable way to accomplish the task.
|
||||
The risk of "unspecified, undefined and implementation-defined" behavior
|
||||
causing problems (as cited in the rationale for the rule) is small. The
|
||||
driver does not depend on the character being outputted correctly.
|
||||
Furthermore, use of putchar() disappears when output is disabled.
|
||||
|
||||
As Rule 21.6 is required, a separate deviation record is required.
|
||||
*/
|
||||
#define OUTPUT_CHARACTER(ch) (void)putchar(ch)
|
||||
#endif
|
||||
|
||||
|
||||
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
|
||||
/** Cast a TaskHandle_t (a pointer type) to uintptr_t.
|
||||
|
||||
Usage of this macro deivate from MISRA-C:2012 Rule 11.4 (advisory). This
|
||||
macro is used for the FreeRTOS version of RedOsTaskId(). Some RTOSes
|
||||
natively use an integer for task IDs; others use pointers. RedOsTaskId()
|
||||
uses integers, FreeRTOS uses pointers; to reconcile this difference, the
|
||||
pointer must be cast to integer. This is fairly safe, since the resulting
|
||||
integer is never cast back to a pointer; and although the integer
|
||||
representation of a pointer is implementation-defined, the representation is
|
||||
irrelevant provided that unique pointers are converted to unique integers.
|
||||
|
||||
As Rule 11.4 is advisory, a deviation record is not required. This notice
|
||||
is the only record of the deviation.
|
||||
*/
|
||||
#define CAST_TASK_PTR_TO_UINTPTR(taskptr) ((uintptr_t)(taskptr))
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Defines OS-specific types for use in common code.
|
||||
*/
|
||||
#ifndef REDOSTYPES_H
|
||||
#define REDOSTYPES_H
|
||||
|
||||
|
||||
/** @brief Implementation-defined timestamp type.
|
||||
|
||||
This can be an integer, a structure, or a pointer: anything that is
|
||||
convenient for the implementation. Since the underlying type is not fixed,
|
||||
common code should treat this as an opaque type.
|
||||
*/
|
||||
typedef uint32_t REDTIMESTAMP;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements assertion handling.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_ASSERTS == 1
|
||||
|
||||
#include <redosdeviations.h>
|
||||
|
||||
|
||||
/** @brief Invoke the native assertion handler.
|
||||
|
||||
@param pszFileName Null-terminated string containing the name of the file
|
||||
where the assertion fired.
|
||||
@param ulLineNum Line number in @p pszFileName where the assertion
|
||||
fired.
|
||||
*/
|
||||
void RedOsAssertFail(
|
||||
const char *pszFileName,
|
||||
uint32_t ulLineNum)
|
||||
{
|
||||
PRINT_ASSERT(pszFileName, ulLineNum);
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
1213
FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osbdev.c
Normal file
1213
FreeRTOS-Plus/Source/Reliance-Edge/os/freertos/services/osbdev.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,79 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements real-time clock functions.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
/** @brief Initialize the real time clock.
|
||||
|
||||
The behavior of calling this function when the RTC is already initialized
|
||||
is undefined.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
*/
|
||||
REDSTATUS RedOsClockInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Uninitialize the real time clock.
|
||||
|
||||
The behavior of calling this function when the RTC is not initialized is
|
||||
undefined.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
*/
|
||||
REDSTATUS RedOsClockUninit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Get the date/time.
|
||||
|
||||
The behavior of calling this function when the RTC is not initialized is
|
||||
undefined.
|
||||
|
||||
@return The number of seconds since January 1, 1970 excluding leap seconds
|
||||
(in other words, standard Unix time). If the resolution or epoch
|
||||
of the RTC is different than this, the implementation must convert
|
||||
it to the expected representation.
|
||||
*/
|
||||
uint32_t RedOsClockGetTime(void)
|
||||
{
|
||||
/* FreeRTOS does not provide an RTC abstraction since most of the systems
|
||||
it targets have no RTC hardware. If your hardware includes an RTC that
|
||||
you would like to use, this function must be customized.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements a synchronization object to provide mutual exclusion.
|
||||
*/
|
||||
#include <FreeRTOS.h>
|
||||
#include <semphr.h>
|
||||
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_TASK_COUNT > 1U
|
||||
|
||||
|
||||
static SemaphoreHandle_t xMutex;
|
||||
|
||||
|
||||
/** @brief Initialize the mutex.
|
||||
|
||||
After initialization, the mutex is in the released state.
|
||||
|
||||
The behavior of calling this function when the mutex is still initialized
|
||||
is undefined.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
*/
|
||||
REDSTATUS RedOsMutexInit(void)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
xMutex = xSemaphoreCreateMutex();
|
||||
if(xMutex != NULL)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -RED_ENOMEM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Uninitialize the mutex.
|
||||
|
||||
The behavior of calling this function when the mutex is not initialized is
|
||||
undefined; likewise, the behavior of uninitializing the mutex when it is
|
||||
in the acquired state is undefined.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
*/
|
||||
REDSTATUS RedOsMutexUninit(void)
|
||||
{
|
||||
vSemaphoreDelete(xMutex);
|
||||
xMutex = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Acquire the mutex.
|
||||
|
||||
The behavior of calling this function when the mutex is not initialized is
|
||||
undefined; likewise, the behavior of recursively acquiring the mutex is
|
||||
undefined.
|
||||
*/
|
||||
void RedOsMutexAcquire(void)
|
||||
{
|
||||
while(xSemaphoreTake(xMutex, portMAX_DELAY) != pdTRUE)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @brief Release the mutex.
|
||||
|
||||
The behavior is undefined in the following cases:
|
||||
|
||||
- Releasing the mutex when the mutex is not initialized.
|
||||
- Releasing the mutex when it is not in the acquired state.
|
||||
- Releasing the mutex from a task or thread other than the one which
|
||||
acquired the mutex.
|
||||
*/
|
||||
void RedOsMutexRelease(void)
|
||||
{
|
||||
BaseType_t xSuccess;
|
||||
|
||||
xSuccess = xSemaphoreGive(xMutex);
|
||||
REDASSERT(xSuccess == pdTRUE);
|
||||
(void)xSuccess;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements outputting a character string.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_OUTPUT == 1
|
||||
|
||||
#include <redosdeviations.h>
|
||||
|
||||
|
||||
/** @brief Write a string to a user-visible output location.
|
||||
|
||||
Write a null-terminated string to the serial port, console, terminal, or
|
||||
other display device, such that the text is visible to the user.
|
||||
|
||||
@param pszString A null-terminated string.
|
||||
*/
|
||||
void RedOsOutputString(
|
||||
const char *pszString)
|
||||
{
|
||||
if(pszString == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
while(pszString[ulIdx] != '\0')
|
||||
{
|
||||
OUTPUT_CHARACTER(pszString[ulIdx]);
|
||||
|
||||
/* Serial output often requires a \r to print newlines correctly.
|
||||
*/
|
||||
if(pszString[ulIdx] == '\n')
|
||||
{
|
||||
OUTPUT_CHARACTER('\r');
|
||||
}
|
||||
|
||||
ulIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements task functions.
|
||||
*/
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
#include <redfs.h>
|
||||
|
||||
#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1)
|
||||
|
||||
#include <redosdeviations.h>
|
||||
|
||||
#if INCLUDE_xTaskGetCurrentTaskHandle != 1
|
||||
#error "INCLUDE_xTaskGetCurrentTaskHandle must be 1 when REDCONF_TASK_COUNT > 1 and REDCONF_API_POSIX == 1"
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Get the current task ID.
|
||||
|
||||
This task ID must be unique for all tasks using the file system.
|
||||
|
||||
@return The task ID. Must not be 0.
|
||||
*/
|
||||
uint32_t RedOsTaskId(void)
|
||||
{
|
||||
/* Simply casting the xTaskGetCurrentTaskHandle() return value results in
|
||||
warnings from some compilers, so use variables.
|
||||
*/
|
||||
TaskHandle_t xTask = xTaskGetCurrentTaskHandle();
|
||||
uintptr_t taskptr = CAST_TASK_PTR_TO_UINTPTR(xTask);
|
||||
uint32_t ulTaskPtr = (uint32_t)taskptr;
|
||||
|
||||
/* Assert no information was lost casting from uintptr_t to uint32_t.
|
||||
*/
|
||||
REDASSERT(ulTaskPtr == taskptr);
|
||||
|
||||
/* NULL is a valid task handle in FreeRTOS, so add one to all task IDs.
|
||||
*/
|
||||
REDASSERT((ulTaskPtr + 1U) != 0U);
|
||||
return ulTaskPtr + 1U;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements timestamp functions.
|
||||
|
||||
The functionality implemented herein is not needed for the file system
|
||||
driver, only to provide accurate results with performance tests.
|
||||
*/
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
/* configTICK_RATE_HZ is almost always 100, 250, 500, or 1000. If
|
||||
1000000U % configTICK_RATE_HZ != 0, then RedOsTimePassed() will be a
|
||||
little inaccurate.
|
||||
*/
|
||||
#define MICROSECS_PER_TICK (1000000U / configTICK_RATE_HZ)
|
||||
|
||||
|
||||
/** @brief Initialize the timestamp service.
|
||||
|
||||
The behavior of invoking this function when timestamps are already
|
||||
initialized is undefined.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_ENOSYS The timestamp service has not been implemented.
|
||||
*/
|
||||
REDSTATUS RedOsTimestampInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Uninitialize the timestamp service.
|
||||
|
||||
The behavior of invoking this function when timestamps are not initialized
|
||||
is undefined.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
*/
|
||||
REDSTATUS RedOsTimestampUninit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Retrieve a timestamp.
|
||||
|
||||
The behavior of invoking this function when timestamps are not initialized
|
||||
is undefined
|
||||
|
||||
@return A timestamp which can later be passed to RedOsTimePassed() to
|
||||
determine the amount of time which passed between the two calls.
|
||||
*/
|
||||
REDTIMESTAMP RedOsTimestamp(void)
|
||||
{
|
||||
return xTaskGetTickCount();
|
||||
}
|
||||
|
||||
|
||||
/** @brief Determine how much time has passed since a timestamp was retrieved.
|
||||
|
||||
The behavior of invoking this function when timestamps are not initialized
|
||||
is undefined.
|
||||
|
||||
@param tsSince A timestamp acquired earlier via RedOsTimestamp().
|
||||
|
||||
@return The number of microseconds which have passed since @p tsSince.
|
||||
*/
|
||||
uint64_t RedOsTimePassed(
|
||||
REDTIMESTAMP tsSince)
|
||||
{
|
||||
/* This works even if the tick count has wrapped around, provided it has
|
||||
only wrapped around once.
|
||||
*/
|
||||
uint32_t ulTicksPassed = (uint32_t)xTaskGetTickCount() - tsSince;
|
||||
uint64_t ullMicrosecs = (uint64_t)ulTicksPassed * MICROSECS_PER_TICK;
|
||||
|
||||
return ullMicrosecs;
|
||||
}
|
||||
|
448
FreeRTOS-Plus/Source/Reliance-Edge/posix/path.c
Normal file
448
FreeRTOS-Plus/Source/Reliance-Edge/posix/path.c
Normal file
|
@ -0,0 +1,448 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements path utilities for the POSIX-like API layer.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
|
||||
#include <redcoreapi.h>
|
||||
#include <redvolume.h>
|
||||
#include <redposix.h>
|
||||
#include "redpath.h"
|
||||
|
||||
|
||||
static bool IsRootDir(const char *pszLocalPath);
|
||||
static bool PathHasMoreNames(const char *pszPathIdx);
|
||||
|
||||
|
||||
/** @brief Split a path into its component parts: a volume and a volume-local
|
||||
path.
|
||||
|
||||
@param pszPath The path to split.
|
||||
@param pbVolNum On successful return, if non-NULL, populated with
|
||||
the volume number extracted from the path.
|
||||
@param ppszLocalPath On successful return, populated with the
|
||||
volume-local path: the path stripped of any volume
|
||||
path prefixing. If this parameter is NULL, that
|
||||
indicates there should be no local path, and any
|
||||
characters beyond the prefix (other than path
|
||||
separators) are treated as an error.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p pszPath is `NULL`.
|
||||
@retval -RED_ENOENT @p pszPath could not be matched to any volume; or
|
||||
@p ppszLocalPath is NULL but @p pszPath includes a local
|
||||
path.
|
||||
*/
|
||||
REDSTATUS RedPathSplit(
|
||||
const char *pszPath,
|
||||
uint8_t *pbVolNum,
|
||||
const char **ppszLocalPath)
|
||||
{
|
||||
REDSTATUS ret = 0;
|
||||
|
||||
if(pszPath == NULL)
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *pszLocalPath = pszPath;
|
||||
uint8_t bMatchVol = UINT8_MAX;
|
||||
uint32_t ulMatchLen = 0U;
|
||||
uint8_t bDefaultVolNum = UINT8_MAX;
|
||||
uint8_t bVolNum;
|
||||
|
||||
for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++)
|
||||
{
|
||||
const char *pszPrefix = gaRedVolConf[bVolNum].pszPathPrefix;
|
||||
uint32_t ulPrefixLen = RedStrLen(pszPrefix);
|
||||
|
||||
if(ulPrefixLen == 0U)
|
||||
{
|
||||
/* A volume with a path prefix of an empty string is the
|
||||
default volume, used when the path does not match the
|
||||
prefix of any other volume.
|
||||
|
||||
The default volume should only be found once. During
|
||||
initialization, RedCoreInit() ensures that all volume
|
||||
prefixes are unique (including empty prefixes).
|
||||
*/
|
||||
REDASSERT(bDefaultVolNum == UINT8_MAX);
|
||||
bDefaultVolNum = bVolNum;
|
||||
}
|
||||
/* For a path to match, it must either be the prefix exactly, or
|
||||
be followed by a path separator character. Thus, with a volume
|
||||
prefix of "/foo", both "/foo" and "/foo/bar" are matches, but
|
||||
"/foobar" is not.
|
||||
*/
|
||||
else if( (RedStrNCmp(pszPath, pszPrefix, ulPrefixLen) == 0)
|
||||
&& ((pszPath[ulPrefixLen] == '\0') || (pszPath[ulPrefixLen] == REDCONF_PATH_SEPARATOR)))
|
||||
{
|
||||
/* The length of this match should never exactly equal the
|
||||
length of a previous match: that would require a duplicate
|
||||
volume name, which should have been detected during init.
|
||||
*/
|
||||
REDASSERT(ulPrefixLen != ulMatchLen);
|
||||
|
||||
/* If multiple prefixes match, the longest takes precedence.
|
||||
Thus, if there are two prefixes "Flash" and "Flash/Backup",
|
||||
the path "Flash/Backup/" will not be erroneously matched
|
||||
with the "Flash" volume.
|
||||
*/
|
||||
if(ulPrefixLen > ulMatchLen)
|
||||
{
|
||||
bMatchVol = bVolNum;
|
||||
ulMatchLen = ulPrefixLen;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No match, keep looking.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if(bMatchVol != UINT8_MAX)
|
||||
{
|
||||
/* The path matched a volume path prefix.
|
||||
*/
|
||||
bVolNum = bMatchVol;
|
||||
pszLocalPath = &pszPath[ulMatchLen];
|
||||
}
|
||||
else if(bDefaultVolNum != UINT8_MAX)
|
||||
{
|
||||
/* The path didn't match any of the prefixes, but one of the
|
||||
volumes has a path prefix of "", so an unprefixed path is
|
||||
assigned to that volume.
|
||||
*/
|
||||
bVolNum = bDefaultVolNum;
|
||||
REDASSERT(pszLocalPath == pszPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The path cannot be assigned a volume.
|
||||
*/
|
||||
ret = -RED_ENOENT;
|
||||
}
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
if(pbVolNum != NULL)
|
||||
{
|
||||
*pbVolNum = bVolNum;
|
||||
}
|
||||
|
||||
if(ppszLocalPath != NULL)
|
||||
{
|
||||
*ppszLocalPath = pszLocalPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If no local path is expected, then the string should either
|
||||
terminate after the path prefix or the local path should name
|
||||
the root directory. Allowing path separators here means that
|
||||
red_mount("/data/") is OK with a path prefix of "/data".
|
||||
*/
|
||||
if(pszLocalPath[0U] != '\0')
|
||||
{
|
||||
if(!IsRootDir(pszLocalPath))
|
||||
{
|
||||
ret = -RED_ENOENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Lookup the inode named by the given path.
|
||||
|
||||
@param pszLocalPath The path to lookup; this is a local path, without any
|
||||
volume prefix.
|
||||
@param pulInode On successful return, populated with the number of the
|
||||
inode named by @p pszLocalPath.
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulInode is
|
||||
`NULL`.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOENT @p pszLocalPath is an empty string; or
|
||||
@p pszLocalPath does not name an existing file
|
||||
or directory.
|
||||
@retval -RED_ENOTDIR A component of the path other than the last is
|
||||
not a directory.
|
||||
@retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is
|
||||
longer than #REDCONF_NAME_MAX.
|
||||
*/
|
||||
REDSTATUS RedPathLookup(
|
||||
const char *pszLocalPath,
|
||||
uint32_t *pulInode)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if((pszLocalPath == NULL) || (pulInode == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(pszLocalPath[0U] == '\0')
|
||||
{
|
||||
ret = -RED_ENOENT;
|
||||
}
|
||||
else if(IsRootDir(pszLocalPath))
|
||||
{
|
||||
ret = 0;
|
||||
*pulInode = INODE_ROOTDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulPInode;
|
||||
const char *pszName;
|
||||
|
||||
ret = RedPathToName(pszLocalPath, &ulPInode, &pszName);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = RedCoreLookup(ulPInode, pszName, pulInode);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Given a path, return the parent inode number and a pointer to the
|
||||
last component in the path (the name).
|
||||
|
||||
@param pszLocalPath The path to examine; this is a local path, without any
|
||||
volume prefix.
|
||||
@param pulPInode On successful return, populated with the inode number of
|
||||
the parent directory of the last component in the path.
|
||||
For example, with the path "a/b/c", populated with the
|
||||
inode number of "b".
|
||||
@param ppszName On successful return, populated with a pointer to the
|
||||
last component in the path. For example, with the path
|
||||
"a/b/c", populated with a pointer to "c".
|
||||
|
||||
@return A negated ::REDSTATUS code indicating the operation result.
|
||||
|
||||
@retval 0 Operation was successful.
|
||||
@retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulPInode is
|
||||
`NULL`; or @p ppszName is `NULL`; or the path
|
||||
names the root directory.
|
||||
@retval -RED_EIO A disk I/O error occurred.
|
||||
@retval -RED_ENOENT @p pszLocalPath is an empty string; or a
|
||||
component of the path other than the last does
|
||||
not exist.
|
||||
@retval -RED_ENOTDIR A component of the path other than the last is
|
||||
not a directory.
|
||||
@retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is
|
||||
longer than #REDCONF_NAME_MAX.
|
||||
*/
|
||||
REDSTATUS RedPathToName(
|
||||
const char *pszLocalPath,
|
||||
uint32_t *pulPInode,
|
||||
const char **ppszName)
|
||||
{
|
||||
REDSTATUS ret;
|
||||
|
||||
if((pszLocalPath == NULL) || (pulPInode == NULL) || (ppszName == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(IsRootDir(pszLocalPath))
|
||||
{
|
||||
ret = -RED_EINVAL;
|
||||
}
|
||||
else if(pszLocalPath[0U] == '\0')
|
||||
{
|
||||
ret = -RED_ENOENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulInode = INODE_ROOTDIR;
|
||||
uint32_t ulPInode = INODE_INVALID;
|
||||
uint32_t ulPathIdx = 0U;
|
||||
uint32_t ulLastNameIdx = 0U;
|
||||
|
||||
ret = 0;
|
||||
|
||||
do
|
||||
{
|
||||
uint32_t ulNameLen;
|
||||
|
||||
/* Skip over path separators, to get pszLocalPath[ulPathIdx]
|
||||
pointing at the next name.
|
||||
*/
|
||||
while(pszLocalPath[ulPathIdx] == REDCONF_PATH_SEPARATOR)
|
||||
{
|
||||
ulPathIdx++;
|
||||
}
|
||||
|
||||
if(pszLocalPath[ulPathIdx] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Point ulLastNameIdx at the first character of the name; after
|
||||
we exit the loop, it will point at the first character of the
|
||||
last name in the path.
|
||||
*/
|
||||
ulLastNameIdx = ulPathIdx;
|
||||
|
||||
/* Point ulPInode at the parent inode: either the root inode
|
||||
(first pass) or the inode of the previous name. After we exit
|
||||
the loop, this will point at the parent inode of the last name.
|
||||
*/
|
||||
ulPInode = ulInode;
|
||||
|
||||
ulNameLen = RedNameLen(&pszLocalPath[ulPathIdx]);
|
||||
|
||||
/* Lookup the inode of the name, unless we are at the last name in
|
||||
the path: we don't care whether the last name exists or not.
|
||||
*/
|
||||
if(PathHasMoreNames(&pszLocalPath[ulPathIdx + ulNameLen]))
|
||||
{
|
||||
ret = RedCoreLookup(ulPInode, &pszLocalPath[ulPathIdx], &ulInode);
|
||||
}
|
||||
|
||||
/* Move on to the next path element.
|
||||
*/
|
||||
if(ret == 0)
|
||||
{
|
||||
ulPathIdx += ulNameLen;
|
||||
}
|
||||
}
|
||||
while(ret == 0);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
*pulPInode = ulPInode;
|
||||
*ppszName = &pszLocalPath[ulLastNameIdx];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Determine whether a path names the root directory.
|
||||
|
||||
@param pszLocalPath The path to examine; this is a local path, without any
|
||||
volume prefix.
|
||||
|
||||
@return Returns whether @p pszLocalPath names the root directory.
|
||||
|
||||
@retval true @p pszLocalPath names the root directory.
|
||||
@retval false @p pszLocalPath does not name the root directory.
|
||||
*/
|
||||
static bool IsRootDir(
|
||||
const char *pszLocalPath)
|
||||
{
|
||||
bool fRet;
|
||||
|
||||
if(pszLocalPath == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
fRet = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
/* A string containing nothing but path separators (usually only one)
|
||||
names the root directory. An empty string does *not* name the root
|
||||
directory, since in POSIX empty strings typically elicit -RED_ENOENT
|
||||
errors.
|
||||
*/
|
||||
while(pszLocalPath[ulIdx] == REDCONF_PATH_SEPARATOR)
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
fRet = (ulIdx > 0U) && (pszLocalPath[ulIdx] == '\0');
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Determine whether there are more names in a path.
|
||||
|
||||
Example | Result
|
||||
------- | ------
|
||||
"" false
|
||||
"\" false
|
||||
"\\" false
|
||||
"a" true
|
||||
"\a" true
|
||||
"\\a" true
|
||||
|
||||
@param pszPathIdx The path to examine, incremented to the point of
|
||||
interest.
|
||||
|
||||
@return Returns whether there are more names in @p pszPathIdx.
|
||||
|
||||
@retval true @p pszPathIdx has more names.
|
||||
@retval false @p pszPathIdx has no more names.
|
||||
*/
|
||||
static bool PathHasMoreNames(
|
||||
const char *pszPathIdx)
|
||||
{
|
||||
bool fRet;
|
||||
|
||||
if(pszPathIdx == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
fRet = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
while(pszPathIdx[ulIdx] == REDCONF_PATH_SEPARATOR)
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
fRet = pszPathIdx[ulIdx] != '\0';
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
#endif /* REDCONF_API_POSIX */
|
||||
|
3088
FreeRTOS-Plus/Source/Reliance-Edge/posix/posix.c
Normal file
3088
FreeRTOS-Plus/Source/Reliance-Edge/posix/posix.c
Normal file
File diff suppressed because it is too large
Load diff
38
FreeRTOS-Plus/Source/Reliance-Edge/posix/redpath.h
Normal file
38
FreeRTOS-Plus/Source/Reliance-Edge/posix/redpath.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Interfaces of path utilities for the POSIX-like API layer.
|
||||
*/
|
||||
#ifndef REDPATH_H
|
||||
#define REDPATH_H
|
||||
|
||||
|
||||
REDSTATUS RedPathSplit(const char *pszPath, uint8_t *pbVolNum, const char **ppszLocalPath);
|
||||
REDSTATUS RedPathLookup(const char *pszLocalPath, uint32_t *pulInode);
|
||||
REDSTATUS RedPathToName(const char *pszLocalPath, uint32_t *pulPInode, const char **ppszName);
|
||||
|
||||
|
||||
#endif
|
||||
|
2049
FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/fsstress.c
Normal file
2049
FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/fsstress.c
Normal file
File diff suppressed because it is too large
Load diff
152
FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/redposixcompat.h
Normal file
152
FreeRTOS-Plus/Source/Reliance-Edge/tests/posix/redposixcompat.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Defines macros which make the Reliance Edge POSIX-like API look more
|
||||
like the actual POSIX API.
|
||||
|
||||
This file is intended for porting POSIX file system tests; it is not
|
||||
intended for application use.
|
||||
*/
|
||||
#ifndef REDPOSIXCOMPAT_H
|
||||
#define REDPOSIXCOMPAT_H
|
||||
|
||||
|
||||
#ifndef assert
|
||||
#define assert(x) REDASSERT(x)
|
||||
#endif
|
||||
|
||||
|
||||
#undef O_RDONLY
|
||||
#undef O_WRONLY
|
||||
#undef O_RDWR
|
||||
#undef O_APPEND
|
||||
#undef O_CREAT
|
||||
#undef O_EXCL
|
||||
#undef O_TRUNC
|
||||
#define O_RDONLY RED_O_RDONLY
|
||||
#define O_WRONLY RED_O_WRONLY
|
||||
#define O_RDWR RED_O_RDWR
|
||||
#define O_APPEND RED_O_APPEND
|
||||
#define O_CREAT RED_O_CREAT
|
||||
#define O_EXCL RED_O_EXCL
|
||||
#define O_TRUNC RED_O_TRUNC
|
||||
|
||||
#undef SEEK_SET
|
||||
#undef SEEK_CUR
|
||||
#undef SEEK_END
|
||||
#define SEEK_SET RED_SEEK_SET
|
||||
#define SEEK_CUR RED_SEEK_CUR
|
||||
#define SEEK_END RED_SEEK_END
|
||||
|
||||
/* Old-fashioned Linux seek names.
|
||||
*/
|
||||
#undef L_SET
|
||||
#undef L_INCR
|
||||
#undef L_XTND
|
||||
#define L_SET SEEK_SET
|
||||
#define L_INCR SEEK_CUR
|
||||
#define L_XTND SEEK_END
|
||||
|
||||
#undef S_IFDIR
|
||||
#undef S_IFREG
|
||||
#undef S_ISDIR
|
||||
#undef S_ISREG
|
||||
#define S_IFDIR RED_S_IFDIR
|
||||
#define S_IFREG RED_S_IFREG
|
||||
#define S_ISDIR(m) RED_S_ISDIR(m)
|
||||
#define S_ISREG(m) RED_S_ISREG(m)
|
||||
|
||||
#undef ST_RDONLY
|
||||
#undef ST_NOSUID
|
||||
#define ST_RDONLY RED_ST_RDONLY
|
||||
#define ST_NOSUID RED_ST_NOSUID
|
||||
|
||||
#undef open
|
||||
#undef creat
|
||||
#undef unlink
|
||||
#undef mkdir
|
||||
#undef rmdir
|
||||
#undef rename
|
||||
#undef link
|
||||
#undef close
|
||||
#undef read
|
||||
#undef write
|
||||
#undef fsync
|
||||
#undef fdatasync
|
||||
#undef lseek
|
||||
#undef ftruncate
|
||||
#undef fstat
|
||||
#undef opendir
|
||||
#undef readdir
|
||||
#undef rewinddir
|
||||
#undef closedir
|
||||
#define open(path, oflag) red_open(path, oflag)
|
||||
#define creat(path, mode) open(path, O_WRONLY|O_CREAT|O_TRUNC)
|
||||
#define unlink(path) red_unlink(path)
|
||||
#define mkdir(path) red_mkdir(path)
|
||||
#define rmdir(path) red_rmdir(path)
|
||||
#define rename(old, new) red_rename(old, new)
|
||||
#define link(path, hardlink) red_link(path, hardlink)
|
||||
#define close(fd) red_close(fd)
|
||||
#define read(fd, buf, len) red_read(fd, buf, len)
|
||||
#define write(fd, buf, len) red_write(fd, buf, len)
|
||||
#define fsync(fd) red_fsync(fd)
|
||||
#define fdatasync(fd) fsync(fd)
|
||||
#define lseek(fd, offset, whence) red_lseek(fd, offset, whence)
|
||||
#define lseek64(fd, offset, whence) lseek(fd, offset, whence)
|
||||
#define ftruncate(fd, size) red_ftruncate(fd, size)
|
||||
#define fstat(fd, stat) red_fstat(fd, stat)
|
||||
#define fstat64(fd, stat) fstat(fd, stat)
|
||||
#define opendir(path) red_opendir(path)
|
||||
#define readdir(dirp) red_readdir(dirp)
|
||||
#define readdir64(dirp) readdir(dirp)
|
||||
#define rewinddir(dirp) red_rewinddir(dirp)
|
||||
#define closedir(dirp) red_closedir(dirp)
|
||||
|
||||
#undef DIR
|
||||
#define DIR REDDIR
|
||||
|
||||
#undef errno
|
||||
#define errno (*(int *)red_errnoptr())
|
||||
|
||||
#undef memcpy
|
||||
#undef memmove
|
||||
#undef memset
|
||||
#undef strlen
|
||||
#undef strncmp
|
||||
#undef strcmp
|
||||
#undef strncpy
|
||||
#define memcpy(d, s, l) RedMemCpy(d, s, (uint32_t)(l))
|
||||
#define memmove(d, s, l) RedMemMove(d, s, (uint32_t)(l))
|
||||
#define memset(d, c, l) RedMemSet(d, (uint8_t)(c), (uint32_t)(l))
|
||||
#define strlen(s) RedStrLen(s)
|
||||
#define strncmp(s1, s2, l) RedStrNCmp(s1, s2, (uint32_t)(l))
|
||||
#define strcmp(s1, s2) RedStrCmp(s1, s2)
|
||||
#define strncpy(d, s, l) RedStrNCpy(d, s, (uint32_t)(l))
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
478
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/atoi.c
Normal file
478
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/atoi.c
Normal file
|
@ -0,0 +1,478 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements utilities that convert strings to numbers.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redtestutils.h>
|
||||
|
||||
|
||||
#define ISHEXDIGITU(c) (((c) >= 'A') && ((c) <= 'F'))
|
||||
#define ISHEXDIGITL(c) (((c) >= 'a') && ((c) <= 'f'))
|
||||
#define ISHEXDIGIT(c) (ISHEXDIGITL(c) || ISHEXDIGITU(c))
|
||||
|
||||
|
||||
/** @brief Converts an ASCII number into an int32_t.
|
||||
|
||||
Converts all decimal digit numbers up to the end of the string or to the
|
||||
first non-numerical character.
|
||||
|
||||
@note This function does *not* ignore leading white space.
|
||||
|
||||
@param pszNum Pointer to a constant array of characters.
|
||||
|
||||
@return The integer represented in the string.
|
||||
*/
|
||||
int32_t RedAtoI(
|
||||
const char *pszNum)
|
||||
{
|
||||
int32_t lValue = 0;
|
||||
int32_t lNegative = 1;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
if(pszNum[ulIdx] == '+')
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
else if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
ulIdx++;
|
||||
lNegative = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No sign, implicitly positive.
|
||||
*/
|
||||
}
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
lValue *= 10;
|
||||
lValue += pszNum[ulIdx] - '0';
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
lValue *= lNegative;
|
||||
|
||||
return lValue;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert a hexadecimal ASCII number into a uint32_t value.
|
||||
|
||||
The function processes all hex digits up to a NUL-terminator, or to the
|
||||
first non-hex character. Only hexadecimal digits are processed, so leading
|
||||
white space, or a leading "0x" prefix are not allowed.
|
||||
|
||||
If pachNum points to an empty string (points to a NUL), this function will
|
||||
return NULL, and the value at *pulNum will not be modified.
|
||||
|
||||
@note This function does not check for overflow. If there are more
|
||||
significant digits than can be represented in a uint32_t variable, the
|
||||
output is unspecified.
|
||||
|
||||
@param pachNum A pointer to a constant array of hex characters.
|
||||
@param pulNum A pointer to the location in which to store the uint32_t
|
||||
result. Upon return, this value will be modified ONLY if
|
||||
the function succeeds and the returned pointer is valid (not
|
||||
NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedHtoUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulNum)
|
||||
{
|
||||
uint64_t ullValue;
|
||||
const char *pszReturn;
|
||||
|
||||
pszReturn = RedHtoULL(pszNum, &ullValue);
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
if(ullValue < UINT32_MAX)
|
||||
{
|
||||
*pulNum = (uint32_t)ullValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert a hexadecimal ASCII number into a D_UINT64 value.
|
||||
|
||||
The function processes all hex digits up to a NUL-terminator, or to the
|
||||
first non-hex character. Only hexadecimal digits are processed, so leading
|
||||
white space, or a leading "0x" prefix are not allowed.
|
||||
|
||||
If pachNum points to an empty string (points to a NUL), this function will
|
||||
return NULL, and the value at *pulNum will not be modified.
|
||||
|
||||
@note This function does not check for overflow. If there are more
|
||||
significant digits than can be represented in a uint64_t variable, the
|
||||
output is unspecified.
|
||||
|
||||
@param pszNum A pointer to a constant array of hex characters.
|
||||
@param pullNum A pointer to the location in which to store the uint64_t
|
||||
result. Upon return, this value will be modified ONLY if
|
||||
the function succeeds and the returned pointer is valid (not
|
||||
NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedHtoULL(
|
||||
const char *pszNum,
|
||||
uint64_t *pullNum)
|
||||
{
|
||||
uint64_t ullValue = 0U;
|
||||
const char *pszReturn = NULL;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pullNum != NULL);
|
||||
|
||||
while(pszNum[ulIdx] != '\0')
|
||||
{
|
||||
char cDigit = pszNum[ulIdx];
|
||||
|
||||
if(ISDIGIT(cDigit))
|
||||
{
|
||||
cDigit -= '0';
|
||||
}
|
||||
else if(ISHEXDIGITU(cDigit))
|
||||
{
|
||||
cDigit -= ('A' - 10);
|
||||
}
|
||||
else if(ISHEXDIGITL(cDigit))
|
||||
{
|
||||
cDigit -= ('a' - 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
REDASSERT((ullValue & UINT64_SUFFIX(0xF000000000000000)) == 0U);
|
||||
|
||||
ullValue <<= 4U;
|
||||
ullValue += cDigit;
|
||||
|
||||
ulIdx++;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
|
||||
/* Modify the number returned only if we found one or more valid hex
|
||||
digits.
|
||||
*/
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
*pullNum = ullValue;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert the ASCII number to a uint32_t value.
|
||||
|
||||
The number may be hex or decimal. Hex numbers must be prefixed by '0x', and
|
||||
they may be upper or lower case. The conversion process will stop with the
|
||||
first non hex or decimal digit.
|
||||
|
||||
If the number is negative (the first character is a '-' sign), the value
|
||||
will be range checked and returned as the equivalent unsigned value.
|
||||
|
||||
@note This function will NOT fail for numbers which exceed the size of a
|
||||
uint32_t value.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert
|
||||
@param pulNum A pointer to the uint32_t location to store the result.
|
||||
This value will be modified on return only if the function
|
||||
succeeds and the returned pointer is valid (not NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedNtoUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulNum)
|
||||
{
|
||||
bool fNegative = false;
|
||||
uint32_t ulIdx = 0U;
|
||||
const char *pszReturn;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pulNum != NULL);
|
||||
|
||||
if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* Hex numbers must be prefixed with '0x'.
|
||||
*/
|
||||
if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
pszReturn = RedHtoUL(&pszNum[ulIdx], pulNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
else if(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
uint32_t ulTemp;
|
||||
|
||||
ulTemp = RedAtoI(&pszNum[ulIdx]);
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(fNegative)
|
||||
{
|
||||
/* Fail if the number is out of range.
|
||||
*/
|
||||
if(ulTemp > INT32_MAX)
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulNum = -((int32_t)ulTemp);
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulNum = ulTemp;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return an error if there is not at least one hex or decimal digit.
|
||||
*/
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert the ASCII number pointed to by pachNum to a uint64_t value.
|
||||
|
||||
The number may be hex or decimal. Hex numbers must be prefixed by '0x', and
|
||||
they may be upper or lower case. The conversion process will stop with the
|
||||
first non hex or decimal digit.
|
||||
|
||||
If the number is negative (the first character is a '-' sign), the value
|
||||
will be range checked and returned as the equivalent unsigned value.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert.
|
||||
@param pullNum A pointer to the uint64_t location to store the result.
|
||||
This value will be modified on return only if the function
|
||||
succeeds and the returned pointer is valid (not NULL).
|
||||
|
||||
@return A pointer to the byte following the converted number, or NULL to
|
||||
indicate failure.
|
||||
*/
|
||||
const char *RedNtoULL(
|
||||
const char *pszNum,
|
||||
uint64_t *pullNum)
|
||||
{
|
||||
bool fNegative = false;
|
||||
uint32_t ulIdx = 0U;
|
||||
const char *pszReturn;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pullNum != NULL);
|
||||
|
||||
if(pszNum[ulIdx] == '-')
|
||||
{
|
||||
fNegative = true;
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* Hex numbers must be prefixed with '0x'.
|
||||
*/
|
||||
if((pszNum[ulIdx] == '0') && ((pszNum[ulIdx + 1U] == 'x') || (pszNum[ulIdx + 1U] == 'X')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ISDIGIT(pszNum[ulIdx]) || ISHEXDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
pszReturn = RedHtoULL(&pszNum[ulIdx], pullNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
}
|
||||
else if(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
uint64_t ullTemp = 0U;
|
||||
|
||||
while(ISDIGIT(pszNum[ulIdx]))
|
||||
{
|
||||
ullTemp *= 10U;
|
||||
ullTemp += pszNum[ulIdx] - '0';
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(fNegative)
|
||||
{
|
||||
/* Fail if the number is out of range.
|
||||
*/
|
||||
if(ullTemp > INT64_MAX)
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullNum = (uint64_t)(-((int64_t)ullTemp));
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullNum = ullTemp;
|
||||
pszReturn = &pszNum[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return an error if there is not at least one hex or decimal digit.
|
||||
*/
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Convert an ASCII hex or decimal number, which may may have a "B",
|
||||
"KB", or "MB" suffix (case insensitive), to a binary value.
|
||||
|
||||
Hex numbers must be prefixed with "0x".
|
||||
|
||||
@note If there is no postfix, KB is assumed!
|
||||
|
||||
May fail due to bad formatting or overflow.
|
||||
|
||||
@param pszNum A pointer to the ASCII number to convert.
|
||||
@param pulResult A pointer to a uint32_t in which to place the result.
|
||||
|
||||
@return A pointer to the byte following the string, or NULL to indicate an
|
||||
error. In the event of an error, *pulResult will not be modified.
|
||||
*/
|
||||
const char *RedSizeToUL(
|
||||
const char *pszNum,
|
||||
uint32_t *pulResult)
|
||||
{
|
||||
uint32_t ulResult;
|
||||
const char *pszSuffix;
|
||||
const char *pszReturn;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
REDASSERT(pszNum != NULL);
|
||||
REDASSERT(pulResult != NULL);
|
||||
|
||||
/* Do the basic hex/decimal conversion
|
||||
*/
|
||||
pszSuffix = RedNtoUL(pszNum, &ulResult);
|
||||
if(pszSuffix != NULL)
|
||||
{
|
||||
if((pszSuffix[ulIdx] == 'B') || (pszSuffix[ulIdx] == 'b'))
|
||||
{
|
||||
ulIdx++;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
else if( ((pszSuffix[ulIdx] == 'M') || (pszSuffix[ulIdx] == 'm'))
|
||||
&& ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
|
||||
if(ulResult > (UINT32_MAX / (1024U * 1024U)))
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulResult *= 1024U * 1024U;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is either postfixed with "KB" or something
|
||||
else (we don't care), but we must increment the pointer
|
||||
if it is something recognize.
|
||||
*/
|
||||
if( ((pszSuffix[ulIdx] == 'K') || (pszSuffix[ulIdx] == 'k'))
|
||||
&& ((pszSuffix[ulIdx + 1U] == 'B') || (pszSuffix[ulIdx + 1U] == 'b')))
|
||||
{
|
||||
ulIdx += 2U;
|
||||
}
|
||||
|
||||
/* "B" or "MB" were not specified, so it must be "KB"
|
||||
*/
|
||||
if(ulResult > (UINT32_MAX / 1024U))
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulResult *= 1024UL;
|
||||
pszReturn = &pszSuffix[ulIdx];
|
||||
}
|
||||
}
|
||||
|
||||
if(pszReturn != NULL)
|
||||
{
|
||||
*pulResult = ulResult;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pszReturn = NULL;
|
||||
}
|
||||
|
||||
return pszReturn;
|
||||
}
|
||||
|
641
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/math.c
Normal file
641
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/math.c
Normal file
|
@ -0,0 +1,641 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements routines for certain 64-bit math operations and simulated
|
||||
floating point.
|
||||
|
||||
RedUint64DivMod32() and RedUint64DivMod64() are derived from code at
|
||||
http://www.hackersdelight.org. This web site states explicitly that "You
|
||||
are free to use, copy, and distribute any of the code on this web site,
|
||||
whether modified by you or not. You need not give attribution."
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redtestutils.h>
|
||||
|
||||
|
||||
static uint32_t nlz64(uint64_t ullValue);
|
||||
|
||||
|
||||
/** @brief Return a ratio value formatted as a floating point string accurate to
|
||||
the specified number of decimal places.
|
||||
|
||||
The function exists to provide floating point style output without using
|
||||
any actual floating point types.
|
||||
|
||||
This function may scale the numbers down to avoid overflow at the high end.
|
||||
Likewise, potential divide-by-zero errors are internally avoided. Here are
|
||||
some examples:
|
||||
|
||||
Dividend | Divisor | DecPlaces | Result
|
||||
-------- | ------- | --------- | ------
|
||||
12133 | 28545 | 2 | "0.42"
|
||||
1539 | 506 | 2 | "3.04"
|
||||
|
||||
To get a number formatted as a percentage, take the take the portion of the
|
||||
total (normally the smaller part), multiply it by 100, and pass it to this
|
||||
function as the Dividend, pass the "total" value to this function as the
|
||||
Divisor, and specify the desired number of decimal places.
|
||||
|
||||
For example, if you have a disk format overhead value of N blocks out of a
|
||||
total of Y blocks on the disk, and you want to display the format overhead
|
||||
as a percentage, you would use a function call
|
||||
similar to:
|
||||
|
||||
~~~{.c}
|
||||
RedRatio(szBuffer, sizeof(szBuffer), N*100U, Y, 2U);
|
||||
~~~
|
||||
|
||||
If N=145, Y=4096, and decimal places is 2, the resulting output would be
|
||||
"3.54".
|
||||
|
||||
The string returned will always be null-terminated, even if it means
|
||||
stomping on the least significant decimal digit.
|
||||
|
||||
If either the dividend or divisor values are zero, the string "0.0" will be
|
||||
returned, with the prescribed number of decimal places.
|
||||
|
||||
@note This function has "reasonable" limits which meet the needs of the
|
||||
various supplemental utilities which use this function. Extremely
|
||||
large ratios, or using many decimal places may not function as
|
||||
desired.
|
||||
|
||||
Parameters:
|
||||
@param pBuffer A pointer to the buffer in which to store the null
|
||||
terminated results.
|
||||
@param ulBufferLen The length of the output buffer.
|
||||
@param ullDividend The "total" value to divide.
|
||||
@param ullDivisor The portion of ullDividend for which to calculate the
|
||||
ratio (may be greater than ulDividend).
|
||||
@param ulDecPlaces The number of decimal places to use, from 0 to 9.
|
||||
|
||||
@return @p pBuffer.
|
||||
*/
|
||||
char *RedRatio(
|
||||
char *pBuffer,
|
||||
uint32_t ulBufferLen,
|
||||
uint64_t ullDividend,
|
||||
uint64_t ullDivisor,
|
||||
uint32_t ulDecPlaces)
|
||||
{
|
||||
REDASSERT(pBuffer != NULL);
|
||||
REDASSERT(ulBufferLen > 0U);
|
||||
REDASSERT(ulDecPlaces <= 9U); /* arbitrary */
|
||||
|
||||
if((ullDivisor > 0U) && (ullDividend > 0U))
|
||||
{
|
||||
uint32_t ii;
|
||||
uint32_t ulFactor = 1U;
|
||||
uint64_t ullDecimal;
|
||||
uint64_t ullTemp;
|
||||
|
||||
for(ii = 1U; ii <= ulDecPlaces; ii++)
|
||||
{
|
||||
ulFactor *= 10U;
|
||||
}
|
||||
|
||||
ullDecimal = RedMulDiv64(ullDividend, ulFactor, ullDivisor);
|
||||
|
||||
/* Shouldn't really be calling this function in a situation where we
|
||||
can overflow at this point...
|
||||
*/
|
||||
REDASSERT(ullDecimal != UINT64_MAX);
|
||||
|
||||
if(ullDivisor <= ullDividend)
|
||||
{
|
||||
uint32_t ulDecimal;
|
||||
|
||||
(void)RedUint64DivMod32(ullDecimal, ulFactor, &ulDecimal);
|
||||
ullDecimal = ulDecimal;
|
||||
}
|
||||
|
||||
ullTemp = RedUint64DivMod64(ullDividend, ullDivisor, NULL);
|
||||
|
||||
if(ulDecPlaces > 0U)
|
||||
{
|
||||
RedSNPrintf(pBuffer, ulBufferLen, "%llu.%0*llu", (unsigned long long)ullTemp,
|
||||
(unsigned)ulDecPlaces, (unsigned long long)ullDecimal);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedSNPrintf(pBuffer, ulBufferLen, "%llu", (unsigned long long)ullTemp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If either the dividend or divisor is zero, then just output a "0.0"
|
||||
string with the prescribed number of decimal places.
|
||||
*/
|
||||
if(ulDecPlaces > 0U)
|
||||
{
|
||||
RedSNPrintf(pBuffer, ulBufferLen, "0.%0*u", (unsigned)ulDecPlaces, 0U);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedStrNCpy(pBuffer, "0", ulBufferLen);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure the returned buffer is always null-terminated
|
||||
*/
|
||||
pBuffer[ulBufferLen - 1U] = '\0';
|
||||
|
||||
return pBuffer;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Multiply 64-bit and 32-bit numbers, and divide by a 64-bit number,
|
||||
returning a 64-bit result.
|
||||
|
||||
@note This function may return an approximate value if multiplying
|
||||
@p ullBase and @p ulMultplier results in a number larger than 64-bits
|
||||
_and_ this cannot be avoided by scaling.
|
||||
|
||||
@param ullBase The base 64-bit number number.
|
||||
@param ulMultiplier The 32-bit number by which to multiply.
|
||||
@param ullDivisor The 64-bit number by which to divide.
|
||||
|
||||
@return The 64-bit unsigned integer result. Always returns zero if either
|
||||
@p ullBase or @p ulMultiplier are zero (regardless what
|
||||
@p ullDivisor is). Returns UINT64_MAX if an overflow condition
|
||||
occurred, or if @p ullDivisor is zero.
|
||||
*/
|
||||
uint64_t RedMulDiv64(
|
||||
uint64_t ullBase,
|
||||
uint32_t ulMultiplier,
|
||||
uint64_t ullDivisor)
|
||||
{
|
||||
uint64_t ullTemp;
|
||||
|
||||
/* Result would always be zero if either of these are zero. Specifically
|
||||
test this case before looking for a zero divisor.
|
||||
*/
|
||||
if((ullBase == 0U) || (ulMultiplier == 0U))
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
if(ullDivisor == 0U)
|
||||
{
|
||||
return UINT64_MAX;
|
||||
}
|
||||
|
||||
/* Since we don't have the ability (yet) to use 128-bit numbers, we jump
|
||||
through the following hoops (in order) to try to determine the proper
|
||||
results without losing precision:
|
||||
|
||||
1) Shift the divisor and one of the multiplicands as many times as is
|
||||
necessary to reduce the scale -- only if it can be done without
|
||||
losing precision.
|
||||
2) Divide one of the multiplicands by the divisor first, but only if it
|
||||
divides evenly, preserving precision.
|
||||
3) Same as #2, but try it for the other multiplicand.
|
||||
4) Last ditch, divide the larger multiplicand by the divisor first, then
|
||||
do the multiply. This <WILL> lose precision.
|
||||
|
||||
These solutions are identified as CODE-PATHs #1-4 which are used to
|
||||
identify the matching tests in dltmain.c.
|
||||
|
||||
Note that execution might partially include CODE-PATH #1 up until
|
||||
shifting can no longer be done without losing precision. In that case,
|
||||
one of the three remaining options will be used.
|
||||
*/
|
||||
|
||||
ullTemp = RedUint64DivMod32(UINT64_MAX, ulMultiplier, NULL);
|
||||
while(ullBase > ullTemp)
|
||||
{
|
||||
uint64_t ullMod;
|
||||
uint64_t ullBaseTemp;
|
||||
uint64_t ullWideMultiplier;
|
||||
|
||||
/* CODE-PATH #1
|
||||
*/
|
||||
/* So long as ulDivisor, and at least one of the other numbers, are
|
||||
evenly divisible by 2, we can scale the numbers so the result does
|
||||
not overflow the intermediate 64-bit value.
|
||||
*/
|
||||
if((ullDivisor & 1U) == 0U)
|
||||
{
|
||||
if((ullBase & 1U) == 0U)
|
||||
{
|
||||
/* CODE-PATH #1a
|
||||
*/
|
||||
ullDivisor >>= 1U;
|
||||
ullBase >>= 1U;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(((ulMultiplier & 1U) == 0U) && ((ullTemp & UINT64_SUFFIX(0x8000000000000000)) == 0U))
|
||||
{
|
||||
/* CODE-PATH #1b
|
||||
*/
|
||||
ullDivisor >>= 1U;
|
||||
ulMultiplier >>= 1U;
|
||||
ullTemp <<= 1U;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we get to this point, the above method (#1) cannot be used
|
||||
because not enough of the numbers are even long enough to scale the
|
||||
operands down. We'll see if either multiplicand is evenly divisble
|
||||
by ulDivisor, and if so, do the divide first, then the multiply.
|
||||
(Note that once we get to this point, we will never exercise the
|
||||
while{} loop anymore.)
|
||||
*/
|
||||
|
||||
/* CODE-PATH #2
|
||||
*/
|
||||
ullBaseTemp = RedUint64DivMod64(ullBase, ullDivisor, &ullMod);
|
||||
if(ullMod == 0U)
|
||||
{
|
||||
/* Evenly divides, so check that we won't overflow, and finish up.
|
||||
*/
|
||||
ullBase = ullBaseTemp;
|
||||
if(ullBase > ullTemp)
|
||||
{
|
||||
return UINT64_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We've validated that this will not overflow.
|
||||
*/
|
||||
ullBase *= ulMultiplier;
|
||||
return ullBase;
|
||||
}
|
||||
}
|
||||
|
||||
/* CODE-PATH #3
|
||||
*/
|
||||
ullWideMultiplier = RedUint64DivMod64(ulMultiplier, ullDivisor, &ullMod);
|
||||
if(ullMod == 0U)
|
||||
{
|
||||
/* Evenly divides, so check that we won't overflow, and finish up.
|
||||
*/
|
||||
|
||||
/* Must recalculate ullTemp relative to ullBase
|
||||
*/
|
||||
ullTemp = RedUint64DivMod64(UINT64_MAX, ullBase, NULL);
|
||||
if(ullWideMultiplier > ullTemp)
|
||||
{
|
||||
return UINT64_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulNarrowMultiplier = (uint32_t)ullWideMultiplier;
|
||||
|
||||
/* We've validated that this will not overflow.
|
||||
*/
|
||||
ullBase *= ulNarrowMultiplier;
|
||||
return ullBase;
|
||||
}
|
||||
}
|
||||
|
||||
/* CODE-PATH #4
|
||||
|
||||
Neither of the multipliers is evenly divisible by the divisor, so
|
||||
just punt and divide the larger number first, then do the final
|
||||
multiply.
|
||||
|
||||
All the other attempts above would preserve precision -- this is the
|
||||
only case where precision may be lost.
|
||||
*/
|
||||
|
||||
/* If necessary reverse the ullBase and ulMultiplier operands so that
|
||||
ullBase contains the larger of the two values.
|
||||
*/
|
||||
if(ullBase < ulMultiplier)
|
||||
{
|
||||
uint32_t ulTemp = ulMultiplier;
|
||||
|
||||
ulMultiplier = (uint32_t)ullBase;
|
||||
ullBase = ulTemp;
|
||||
}
|
||||
|
||||
ullBase = RedUint64DivMod64(ullBase, ullDivisor, NULL);
|
||||
ullTemp = RedUint64DivMod32(UINT64_MAX, ulMultiplier, NULL);
|
||||
if(ullBase > ullTemp)
|
||||
{
|
||||
return UINT64_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
ullBase *= ulMultiplier;
|
||||
return ullBase;
|
||||
}
|
||||
}
|
||||
|
||||
/* We only get to this point if either there was never any chance of
|
||||
overflow, or if the pure shifting mechanism succeeded in reducing
|
||||
the scale so overflow is not a problem.
|
||||
*/
|
||||
|
||||
ullBase *= ulMultiplier;
|
||||
ullBase = RedUint64DivMod64(ullBase, ullDivisor, NULL);
|
||||
|
||||
return ullBase;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Divide a 64-bit value by a 32-bit value, returning the quotient and
|
||||
the remainder.
|
||||
|
||||
Essentially this function does the following:
|
||||
|
||||
~~~{.c}
|
||||
if(pulRemainder != NULL)
|
||||
{
|
||||
*pulRemainder = (uint32_t)(ullDividend % ulDivisor);
|
||||
}
|
||||
return ullDividend / ulDivisor;
|
||||
~~~
|
||||
|
||||
However, it does so without ever actually dividing/modulating a 64-bit
|
||||
value, since such operations are not allowed in all environments.
|
||||
|
||||
@param ullDividend The value to divide.
|
||||
@param ulDivisor The value to divide by.
|
||||
@param pulRemander Populated with the remainder; may be NULL.
|
||||
|
||||
@return The quotient (result of the division).
|
||||
*/
|
||||
uint64_t RedUint64DivMod32(
|
||||
uint64_t ullDividend,
|
||||
uint32_t ulDivisor,
|
||||
uint32_t *pulRemainder)
|
||||
{
|
||||
uint64_t ullQuotient;
|
||||
uint32_t ulResultRemainder;
|
||||
|
||||
/* Check for divide by zero.
|
||||
*/
|
||||
if(ulDivisor == 0U)
|
||||
{
|
||||
REDERROR();
|
||||
|
||||
/* Nonsense value if no asserts.
|
||||
*/
|
||||
ullQuotient = UINT64_SUFFIX(0xFFFFFFFFFFFFFBAD);
|
||||
ulResultRemainder = 0xFFFFFBADU;
|
||||
}
|
||||
else if(ullDividend <= UINT32_MAX)
|
||||
{
|
||||
uint32_t ulDividend = (uint32_t)ullDividend;
|
||||
|
||||
ullQuotient = ulDividend / ulDivisor;
|
||||
ulResultRemainder = ulDividend % ulDivisor;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t ulResultHi;
|
||||
uint32_t ulResultLo;
|
||||
uint32_t ulRemainder;
|
||||
uint8_t bIndex;
|
||||
uint32_t ulThisDivision;
|
||||
uint32_t ulMask;
|
||||
uint8_t ucNextValue;
|
||||
uint32_t ulInterimHi, ulInterimLo;
|
||||
uint32_t ulLowDword = (uint32_t)ullDividend;
|
||||
uint32_t ulHighDword = (uint32_t)(ullDividend >> 32U);
|
||||
|
||||
/* Compute the high part and get the remainder
|
||||
*/
|
||||
ulResultHi = ulHighDword / ulDivisor;
|
||||
ulResultLo = 0U;
|
||||
ulRemainder = ulHighDword % ulDivisor;
|
||||
|
||||
/* Compute the low part
|
||||
*/
|
||||
ulMask = 0xFF000000U;
|
||||
for(bIndex = 0U; bIndex < sizeof(uint32_t); bIndex++)
|
||||
{
|
||||
ucNextValue = (uint8_t)((ulLowDword & ulMask) >> ((sizeof(uint32_t) - 1U - bIndex) * 8U));
|
||||
ulInterimHi = ulRemainder >> 24U;
|
||||
ulInterimLo = (ulRemainder << 8U) | ucNextValue;
|
||||
ulThisDivision = 0U;
|
||||
while(ulInterimHi != 0U)
|
||||
{
|
||||
uint64_t ullInterim = ((uint64_t)ulInterimHi << 32U) + ulInterimLo;
|
||||
|
||||
ullInterim -= ulDivisor;
|
||||
ulThisDivision++;
|
||||
|
||||
ulInterimHi = (uint32_t)(ullInterim >> 32U);
|
||||
ulInterimLo = (uint32_t)ullInterim;
|
||||
}
|
||||
ulThisDivision += ulInterimLo / ulDivisor;
|
||||
ulRemainder = ulInterimLo % ulDivisor;
|
||||
ulResultLo <<= 8U;
|
||||
ulResultLo += ulThisDivision;
|
||||
ulMask >>= 8U;
|
||||
}
|
||||
|
||||
ullQuotient = ((uint64_t)ulResultHi << 32U) + ulResultLo;
|
||||
ulResultRemainder = (uint32_t)(ullDividend - (ullQuotient * ulDivisor));
|
||||
}
|
||||
|
||||
if(pulRemainder != NULL)
|
||||
{
|
||||
*pulRemainder = ulResultRemainder;
|
||||
}
|
||||
|
||||
return ullQuotient;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Divide a 64-bit value by a 64-bit value, returning the quotient and
|
||||
the remainder.
|
||||
|
||||
Essentially this function does the following:
|
||||
|
||||
~~~{.c}
|
||||
if(pullRemainder != NULL)
|
||||
{
|
||||
*pullRemainder = ullDividend % ullDivisor;
|
||||
}
|
||||
return ullDividend / ullDivisor;
|
||||
~~~
|
||||
|
||||
However, it does so without ever actually dividing/modulating a 64-bit
|
||||
value, since such operations are not allowed in all environments.
|
||||
|
||||
@param ullDividend The value to divide.
|
||||
@param ullDivisor The value to divide by.
|
||||
@param pullRemander Populated with the remainder; may be NULL.
|
||||
|
||||
@return The quotient (result of the division).
|
||||
*/
|
||||
uint64_t RedUint64DivMod64(
|
||||
uint64_t ullDividend,
|
||||
uint64_t ullDivisor,
|
||||
uint64_t *pullRemainder)
|
||||
{
|
||||
/* The variables u0, u1, etc. take on only 32-bit values, but they are
|
||||
declared uint64_t to avoid some compiler warning messages and to avoid
|
||||
some unnecessary EXTRs that the compiler would put in, to convert
|
||||
uint64_ts to ints.
|
||||
*/
|
||||
uint64_t u0;
|
||||
uint64_t u1;
|
||||
uint64_t q0;
|
||||
uint64_t q1;
|
||||
uint64_t ullQuotient;
|
||||
|
||||
/* First the procedure takes care of the case in which the divisor is a
|
||||
32-bit quantity. There are two subcases: (1) If the left half of the
|
||||
dividend is less than the divisor, one execution of RedUint64DivMod32()
|
||||
is all that is required (overflow is not possible). (2) Otherwise it
|
||||
does two divisions, using the grade school method.
|
||||
*/
|
||||
|
||||
if((ullDivisor >> 32U) == 0U)
|
||||
{
|
||||
if((ullDividend >> 32U) < ullDivisor)
|
||||
{
|
||||
/* If ullDividend/ullDivisor cannot overflow, just do one division.
|
||||
*/
|
||||
ullQuotient = RedUint64DivMod32(ullDividend, (uint32_t)ullDivisor, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t k;
|
||||
|
||||
/* If ullDividend/ullDivisor would overflow:
|
||||
*/
|
||||
|
||||
/* Break ullDividend up into two halves.
|
||||
*/
|
||||
u1 = ullDividend >> 32U;
|
||||
u0 = ullDividend & 0xFFFFFFFFU;
|
||||
|
||||
/* First quotient digit and first remainder.
|
||||
*/
|
||||
q1 = RedUint64DivMod32(u1, (uint32_t)ullDivisor, &k);
|
||||
|
||||
/* 2nd quot. digit.
|
||||
*/
|
||||
q0 = RedUint64DivMod32(((uint64_t)k << 32U) + u0, (uint32_t)ullDivisor, NULL);
|
||||
|
||||
ullQuotient = (q1 << 32U) + q0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t n;
|
||||
uint64_t v1;
|
||||
|
||||
n = nlz64(ullDivisor); /* 0 <= n <= 31. */
|
||||
v1 = (ullDivisor << n) >> 32U; /* Normalize the divisor so its MSB is 1. */
|
||||
u1 = ullDividend >> 1U; /* To ensure no overflow. */
|
||||
|
||||
/* Get quotient from divide unsigned insn.
|
||||
*/
|
||||
q1 = RedUint64DivMod32(u1, (uint32_t)v1, NULL);
|
||||
|
||||
q0 = (q1 << n) >> 31U; /* Undo normalization and division of ullDividend by 2. */
|
||||
|
||||
/* Make q0 correct or too small by 1.
|
||||
*/
|
||||
if(q0 != 0U)
|
||||
{
|
||||
q0--;
|
||||
}
|
||||
|
||||
if((ullDividend - (q0 * ullDivisor)) >= ullDivisor)
|
||||
{
|
||||
q0++; /* Now q0 is correct. */
|
||||
}
|
||||
|
||||
ullQuotient = q0;
|
||||
}
|
||||
|
||||
if(pullRemainder != NULL)
|
||||
{
|
||||
*pullRemainder = ullDividend - (ullQuotient * ullDivisor);
|
||||
}
|
||||
|
||||
return ullQuotient;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Compute the number of leading zeroes in a 64-bit value.
|
||||
|
||||
@param ullValue The value for which to compute the NLZ.
|
||||
|
||||
@return The number of leading zeroes in @p ullValue.
|
||||
*/
|
||||
static uint32_t nlz64(
|
||||
uint64_t ullValue)
|
||||
{
|
||||
uint32_t n;
|
||||
|
||||
if(ullValue == 0U)
|
||||
{
|
||||
n = 64U;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t x = ullValue;
|
||||
|
||||
n = 0U;
|
||||
|
||||
if(x <= UINT64_SUFFIX(0x00000000FFFFFFFF))
|
||||
{
|
||||
n += 32U;
|
||||
x <<= 32U;
|
||||
}
|
||||
|
||||
if(x <= UINT64_SUFFIX(0x0000FFFFFFFFFFFF))
|
||||
{
|
||||
n += 16U;
|
||||
x <<= 16U;
|
||||
}
|
||||
|
||||
if(x <= UINT64_SUFFIX(0x00FFFFFFFFFFFFFF))
|
||||
{
|
||||
n += 8U;
|
||||
x <<= 8U;
|
||||
}
|
||||
|
||||
if(x <= UINT64_SUFFIX(0x0FFFFFFFFFFFFFFF))
|
||||
{
|
||||
n += 4U;
|
||||
x <<= 4U;
|
||||
}
|
||||
|
||||
if(x <= UINT64_SUFFIX(0x3FFFFFFFFFFFFFFF))
|
||||
{
|
||||
n += 2U;
|
||||
x <<= 2U;
|
||||
}
|
||||
|
||||
if(x <= UINT64_SUFFIX(0x7FFFFFFFFFFFFFFF))
|
||||
{
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
1264
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/printf.c
Normal file
1264
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/printf.c
Normal file
File diff suppressed because it is too large
Load diff
159
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/rand.c
Normal file
159
FreeRTOS-Plus/Source/Reliance-Edge/tests/util/rand.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements a random number generator.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
#include <redtestutils.h>
|
||||
|
||||
|
||||
/* This is the global seed used by the random number generator when the caller
|
||||
has not provided a seed to either the RedRand32() or RedRand64() functions.
|
||||
*/
|
||||
static uint64_t ullGlobalRandomNumberSeed;
|
||||
|
||||
/* Whether the above seed has been initialized.
|
||||
*/
|
||||
static bool fGlobalSeedInited;
|
||||
|
||||
|
||||
/** @brief Set the global seed used by the random number generator.
|
||||
|
||||
The global seed gets used when RedRand64() or RedRand32() are called with
|
||||
a NULL seed argument.
|
||||
|
||||
@param ullSeed The value to use as the global RNG seed.
|
||||
*/
|
||||
void RedRandSeed(
|
||||
uint64_t ullSeed)
|
||||
{
|
||||
ullGlobalRandomNumberSeed = ullSeed;
|
||||
fGlobalSeedInited = true;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Generate a 64-bit pseudo-random number.
|
||||
|
||||
The period of this random number generator is 2^64 (1.8 x 1019). These
|
||||
parameters are the same as the default one-stream SPRNG lcg64 generator and
|
||||
it satisfies the requirements for a maximal period.
|
||||
|
||||
The tempering value is used and an AND mask and is specifically selected to
|
||||
favor the distribution of lower bits.
|
||||
|
||||
@param pullSeed A pointer to the seed to use. Set this value to NULL to
|
||||
use the internal global seed value.
|
||||
|
||||
@return A pseudo-random number in the range [0, UINT64_MAX].
|
||||
*/
|
||||
uint64_t RedRand64(
|
||||
uint64_t *pullSeed)
|
||||
{
|
||||
const uint64_t ullA = UINT64_SUFFIX(2862933555777941757);
|
||||
const uint64_t ullC = UINT64_SUFFIX(3037000493);
|
||||
const uint64_t ullT = UINT64_SUFFIX(4921441182957829599);
|
||||
uint64_t ullN;
|
||||
uint64_t *pullSeedPtr;
|
||||
uint64_t ullLocalSeed;
|
||||
|
||||
if(pullSeed != NULL)
|
||||
{
|
||||
ullLocalSeed = *pullSeed;
|
||||
pullSeedPtr = pullSeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!fGlobalSeedInited)
|
||||
{
|
||||
/* Unfortunately, the Reliance Edge OS services don't give us much
|
||||
to work with to initialize the global seed. There is no entropy
|
||||
abstraction, no tick count abstraction, and the timestamp
|
||||
abstraction uses an opaque type which is not guaranteed to be an
|
||||
integer. The best we can do is use the RTC.
|
||||
|
||||
Tests using the RNG should be supplying a seed anyway, for
|
||||
reproducibility.
|
||||
*/
|
||||
RedRandSeed((uint64_t)RedOsClockGetTime());
|
||||
}
|
||||
|
||||
ullLocalSeed = ullGlobalRandomNumberSeed;
|
||||
pullSeedPtr = &ullGlobalRandomNumberSeed;
|
||||
}
|
||||
|
||||
ullN = (ullLocalSeed * ullA) + ullC;
|
||||
|
||||
*pullSeedPtr = ullN;
|
||||
|
||||
/* The linear congruential generator used above produces good psuedo-random
|
||||
64-bit number sequences, however, as with any LCG, the period of the
|
||||
lower order bits is much shorter resulting in alternately odd/even pairs
|
||||
in bit zero.
|
||||
|
||||
The result of the LGC above is tempered below with a series of XOR and
|
||||
shift operations to produce a more acceptable equidistribution of bits
|
||||
throughout the 64-bit range.
|
||||
*/
|
||||
ullN ^= (ullN >> 21U) & ullT;
|
||||
ullN ^= (ullN >> 43U) & ullT;
|
||||
ullN ^= (ullN << 23U) & ~ullT;
|
||||
ullN ^= (ullN << 31U) & ~ullT;
|
||||
|
||||
return ullN;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Generate a 32-bit pseudo-random number.
|
||||
|
||||
@note The 32-bit random number generator internally uses the 64-bit random
|
||||
number generator, returning the low 32-bits of the pseudo-random
|
||||
64-bit value.
|
||||
|
||||
@param pulSeed A pointer to the seed to use. Set this value to NULL to use
|
||||
the internal global seed value.
|
||||
|
||||
@return A pseudo-random number in the range [0, UINT32_MAX].
|
||||
*/
|
||||
uint32_t RedRand32(
|
||||
uint32_t *pulSeed)
|
||||
{
|
||||
uint64_t ullN;
|
||||
|
||||
if(pulSeed != NULL)
|
||||
{
|
||||
uint64_t ullLocalSeed;
|
||||
|
||||
ullLocalSeed = *pulSeed;
|
||||
ullN = RedRand64(&ullLocalSeed);
|
||||
*pulSeed = (uint32_t)ullLocalSeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
ullN = RedRand64(NULL);
|
||||
}
|
||||
|
||||
return (uint32_t)ullN;
|
||||
}
|
||||
|
559
FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/getopt.c
Normal file
559
FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/getopt.c
Normal file
|
@ -0,0 +1,559 @@
|
|||
/*
|
||||
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Sponsored in part by the Defense Advanced Research Projects
|
||||
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Dieter Baron and Thomas Klausner.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implementations of getopt() and getopt_long() work-alike functions.
|
||||
|
||||
This code was taken from FreeBSD and slightly modified, mostly to rename
|
||||
symbols with external linkage to avoid naming conflicts in systems where
|
||||
there are real getopt()/getopt_long() implementations, and for portability.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <redfs.h>
|
||||
#include <redgetopt.h>
|
||||
#include <redtestutils.h>
|
||||
#include <rederrno.h>
|
||||
|
||||
|
||||
int32_t red_opterr = 1; /* if error message should be printed */
|
||||
int32_t red_optind = 1; /* index into parent argv vector */
|
||||
int32_t red_optopt = '?'; /* character checked for validity */
|
||||
int32_t red_optreset; /* reset RedGetopt */
|
||||
const char *red_optarg; /* argument associated with option */
|
||||
|
||||
#define PRINT_ERROR ((red_opterr) && (*options != ':'))
|
||||
|
||||
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
|
||||
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
|
||||
#define FLAG_LONGONLY 0x04 /* operate as RedGetoptLongOnly */
|
||||
|
||||
/* return values */
|
||||
#define BADCH (int)'?'
|
||||
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
|
||||
#define INORDER (int)1
|
||||
|
||||
#define EMSG ""
|
||||
|
||||
#define NO_PREFIX (-1)
|
||||
#define D_PREFIX 0
|
||||
#define DD_PREFIX 1
|
||||
#define W_PREFIX 2
|
||||
|
||||
static int gcd(int a, int b);
|
||||
static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv);
|
||||
static int parse_long_options(char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx, int short_too, int flags);
|
||||
static int getopt_internal(int nargc, char * const *nargv, const char *options, const REDOPTION *long_options, int32_t *idx, int flags);
|
||||
|
||||
static const char *place = EMSG; /* option letter processing */
|
||||
|
||||
/* XXX: set red_optreset to 1 rather than these two */
|
||||
static int nonopt_start = -1; /* first non option argument (for permute) */
|
||||
static int nonopt_end = -1; /* first option after non options (for permute) */
|
||||
|
||||
/* Error messages */
|
||||
static const char recargchar[] = "option requires an argument -- %c\n";
|
||||
static const char illoptchar[] = "illegal option -- %c\n"; /* From P1003.2 */
|
||||
static int dash_prefix = NO_PREFIX;
|
||||
static const char gnuoptchar[] = "invalid option -- %c\n";
|
||||
|
||||
static const char recargstring[] = "option `%s%s' requires an argument\n";
|
||||
static const char ambig[] = "option `%s%s' is ambiguous\n";
|
||||
static const char noarg[] = "option `%s%s' doesn't allow an argument\n";
|
||||
static const char illoptstring[] = "unrecognized option `%s%s'\n";
|
||||
|
||||
/*
|
||||
* Compute the greatest common divisor of a and b.
|
||||
*/
|
||||
static int
|
||||
gcd(int a, int b)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = a % b;
|
||||
while (c != 0) {
|
||||
a = b;
|
||||
b = c;
|
||||
c = a % b;
|
||||
}
|
||||
|
||||
return (b);
|
||||
}
|
||||
|
||||
/*
|
||||
* Exchange the block from nonopt_start to nonopt_end with the block
|
||||
* from nonopt_end to opt_end (keeping the same order of arguments
|
||||
* in each block).
|
||||
*/
|
||||
static void
|
||||
permute_args(int panonopt_start, int panonopt_end, int opt_end,
|
||||
char * const *nargv)
|
||||
{
|
||||
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
|
||||
char *swap;
|
||||
|
||||
/*
|
||||
* compute lengths of blocks and number and size of cycles
|
||||
*/
|
||||
nnonopts = panonopt_end - panonopt_start;
|
||||
nopts = opt_end - panonopt_end;
|
||||
ncycle = gcd(nnonopts, nopts);
|
||||
cyclelen = (opt_end - panonopt_start) / ncycle;
|
||||
|
||||
for (i = 0; i < ncycle; i++) {
|
||||
cstart = panonopt_end+i;
|
||||
pos = cstart;
|
||||
for (j = 0; j < cyclelen; j++) {
|
||||
if (pos >= panonopt_end)
|
||||
pos -= nnonopts;
|
||||
else
|
||||
pos += nopts;
|
||||
swap = nargv[pos];
|
||||
((char **) nargv)[pos] = nargv[cstart];
|
||||
((char **)nargv)[cstart] = swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* parse_long_options --
|
||||
* Parse long options in argc/argv argument vector.
|
||||
* Returns -1 if short_too is set and the option does not match long_options.
|
||||
*/
|
||||
static int
|
||||
parse_long_options(char * const *nargv, const char *options,
|
||||
const REDOPTION *long_options, int32_t *idx, int short_too, int flags)
|
||||
{
|
||||
const char *current_argv, *has_equal, *current_dash;
|
||||
size_t current_argv_len;
|
||||
int i, match, exact_match, second_partial_match;
|
||||
|
||||
current_argv = place;
|
||||
switch (dash_prefix) {
|
||||
case D_PREFIX:
|
||||
current_dash = "-";
|
||||
break;
|
||||
case DD_PREFIX:
|
||||
current_dash = "--";
|
||||
break;
|
||||
case W_PREFIX:
|
||||
current_dash = "-W ";
|
||||
break;
|
||||
default:
|
||||
current_dash = "";
|
||||
break;
|
||||
}
|
||||
match = -1;
|
||||
exact_match = 0;
|
||||
second_partial_match = 0;
|
||||
|
||||
red_optind++;
|
||||
|
||||
if ((has_equal = strchr(current_argv, '=')) != NULL) {
|
||||
/* argument found (--option=arg) */
|
||||
current_argv_len = has_equal - current_argv;
|
||||
has_equal++;
|
||||
} else
|
||||
current_argv_len = strlen(current_argv);
|
||||
|
||||
for (i = 0; long_options[i].name; i++) {
|
||||
/* find matching long option */
|
||||
if (strncmp(current_argv, long_options[i].name,
|
||||
current_argv_len))
|
||||
continue;
|
||||
|
||||
if (strlen(long_options[i].name) == current_argv_len) {
|
||||
/* exact match */
|
||||
match = i;
|
||||
exact_match = 1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* If this is a known short option, don't allow
|
||||
* a partial match of a single character.
|
||||
*/
|
||||
if (short_too && current_argv_len == 1)
|
||||
continue;
|
||||
|
||||
if (match == -1) /* first partial match */
|
||||
match = i;
|
||||
else if ((flags & FLAG_LONGONLY) ||
|
||||
long_options[i].has_arg !=
|
||||
long_options[match].has_arg ||
|
||||
long_options[i].flag != long_options[match].flag ||
|
||||
long_options[i].val != long_options[match].val)
|
||||
second_partial_match = 1;
|
||||
}
|
||||
if (!exact_match && second_partial_match) {
|
||||
/* ambiguous abbreviation */
|
||||
if (PRINT_ERROR)
|
||||
fprintf(stderr,
|
||||
ambig,
|
||||
current_dash,
|
||||
current_argv);
|
||||
red_optopt = 0;
|
||||
return (BADCH);
|
||||
}
|
||||
if (match != -1) { /* option found */
|
||||
if (long_options[match].has_arg == red_no_argument
|
||||
&& has_equal) {
|
||||
if (PRINT_ERROR)
|
||||
fprintf(stderr,
|
||||
noarg,
|
||||
current_dash,
|
||||
current_argv);
|
||||
/*
|
||||
* XXX: GNU sets red_optopt to val regardless of flag
|
||||
*/
|
||||
if (long_options[match].flag == NULL)
|
||||
red_optopt = long_options[match].val;
|
||||
else
|
||||
red_optopt = 0;
|
||||
return (BADCH);
|
||||
}
|
||||
if (long_options[match].has_arg == red_required_argument ||
|
||||
long_options[match].has_arg == red_optional_argument) {
|
||||
if (has_equal)
|
||||
red_optarg = has_equal;
|
||||
else if (long_options[match].has_arg ==
|
||||
red_required_argument) {
|
||||
/*
|
||||
* optional argument doesn't use next nargv
|
||||
*/
|
||||
red_optarg = nargv[red_optind++];
|
||||
}
|
||||
}
|
||||
if ((long_options[match].has_arg == red_required_argument)
|
||||
&& (red_optarg == NULL)) {
|
||||
/*
|
||||
* Missing argument; leading ':' indicates no error
|
||||
* should be generated.
|
||||
*/
|
||||
if (PRINT_ERROR)
|
||||
fprintf(stderr,
|
||||
recargstring,
|
||||
current_dash,
|
||||
current_argv);
|
||||
/*
|
||||
* XXX: GNU sets red_optopt to val regardless of flag
|
||||
*/
|
||||
if (long_options[match].flag == NULL)
|
||||
red_optopt = long_options[match].val;
|
||||
else
|
||||
red_optopt = 0;
|
||||
--red_optind;
|
||||
return (BADARG);
|
||||
}
|
||||
} else { /* unknown option */
|
||||
if (short_too) {
|
||||
--red_optind;
|
||||
return (-1);
|
||||
}
|
||||
if (PRINT_ERROR)
|
||||
fprintf(stderr,
|
||||
illoptstring,
|
||||
current_dash,
|
||||
current_argv);
|
||||
red_optopt = 0;
|
||||
return (BADCH);
|
||||
}
|
||||
if (idx)
|
||||
*idx = match;
|
||||
if (long_options[match].flag) {
|
||||
*long_options[match].flag = long_options[match].val;
|
||||
return (0);
|
||||
} else
|
||||
return (long_options[match].val);
|
||||
}
|
||||
|
||||
/*
|
||||
* getopt_internal --
|
||||
* Parse argc/argv argument vector. Called by user level routines.
|
||||
*/
|
||||
static int
|
||||
getopt_internal(int nargc, char * const *nargv, const char *options,
|
||||
const REDOPTION *long_options, int32_t *idx, int flags)
|
||||
{
|
||||
char *oli; /* option letter list index */
|
||||
int optchar, short_too;
|
||||
|
||||
if (options == NULL)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* XXX Some GNU programs (like cvs) set red_optind to 0 instead of
|
||||
* XXX using red_optreset. Work around this braindamage.
|
||||
*/
|
||||
if (red_optind == 0)
|
||||
red_optind = red_optreset = 1;
|
||||
|
||||
/*
|
||||
* Disable GNU extensions if options string begins with a '+'.
|
||||
*/
|
||||
if (*options == '-')
|
||||
flags |= FLAG_ALLARGS;
|
||||
else if (*options == '+')
|
||||
flags &= ~FLAG_PERMUTE;
|
||||
if (*options == '+' || *options == '-')
|
||||
options++;
|
||||
|
||||
red_optarg = NULL;
|
||||
if (red_optreset)
|
||||
nonopt_start = nonopt_end = -1;
|
||||
start:
|
||||
if (red_optreset || !*place) { /* update scanning pointer */
|
||||
red_optreset = 0;
|
||||
if (red_optind >= nargc) { /* end of argument vector */
|
||||
place = EMSG;
|
||||
if (nonopt_end != -1) {
|
||||
/* do permutation, if we have to */
|
||||
permute_args(nonopt_start, nonopt_end,
|
||||
red_optind, nargv);
|
||||
red_optind -= nonopt_end - nonopt_start;
|
||||
}
|
||||
else if (nonopt_start != -1) {
|
||||
/*
|
||||
* If we skipped non-options, set red_optind
|
||||
* to the first of them.
|
||||
*/
|
||||
red_optind = nonopt_start;
|
||||
}
|
||||
nonopt_start = nonopt_end = -1;
|
||||
return (-1);
|
||||
}
|
||||
if (*(place = nargv[red_optind]) != '-' || place[1] == '\0') {
|
||||
place = EMSG; /* found non-option */
|
||||
if (flags & FLAG_ALLARGS) {
|
||||
/*
|
||||
* GNU extension:
|
||||
* return non-option as argument to option 1
|
||||
*/
|
||||
red_optarg = nargv[red_optind++];
|
||||
return (INORDER);
|
||||
}
|
||||
if (!(flags & FLAG_PERMUTE)) {
|
||||
/*
|
||||
* If no permutation wanted, stop parsing
|
||||
* at first non-option.
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
/* do permutation */
|
||||
if (nonopt_start == -1)
|
||||
nonopt_start = red_optind;
|
||||
else if (nonopt_end != -1) {
|
||||
permute_args(nonopt_start, nonopt_end,
|
||||
red_optind, nargv);
|
||||
nonopt_start = red_optind -
|
||||
(nonopt_end - nonopt_start);
|
||||
nonopt_end = -1;
|
||||
}
|
||||
red_optind++;
|
||||
/* process next argument */
|
||||
goto start;
|
||||
}
|
||||
if (nonopt_start != -1 && nonopt_end == -1)
|
||||
nonopt_end = red_optind;
|
||||
|
||||
/*
|
||||
* If we have "-" do nothing, if "--" we are done.
|
||||
*/
|
||||
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
|
||||
red_optind++;
|
||||
place = EMSG;
|
||||
/*
|
||||
* We found an option (--), so if we skipped
|
||||
* non-options, we have to permute.
|
||||
*/
|
||||
if (nonopt_end != -1) {
|
||||
permute_args(nonopt_start, nonopt_end,
|
||||
red_optind, nargv);
|
||||
red_optind -= nonopt_end - nonopt_start;
|
||||
}
|
||||
nonopt_start = nonopt_end = -1;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check long options if:
|
||||
* 1) we were passed some
|
||||
* 2) the arg is not just "-"
|
||||
* 3) either the arg starts with -- we are RedGetoptLongOnly()
|
||||
*/
|
||||
if (long_options != NULL && place != nargv[red_optind] &&
|
||||
(*place == '-' || (flags & FLAG_LONGONLY))) {
|
||||
short_too = 0;
|
||||
dash_prefix = D_PREFIX;
|
||||
if (*place == '-') {
|
||||
place++; /* --foo long option */
|
||||
dash_prefix = DD_PREFIX;
|
||||
} else if (*place != ':' && strchr(options, *place) != NULL)
|
||||
short_too = 1; /* could be short option too */
|
||||
|
||||
optchar = parse_long_options(nargv, options, long_options,
|
||||
idx, short_too, flags);
|
||||
if (optchar != -1) {
|
||||
place = EMSG;
|
||||
return (optchar);
|
||||
}
|
||||
}
|
||||
|
||||
if ((optchar = (int)*place++) == (int)':' ||
|
||||
(optchar == (int)'-' && *place != '\0') ||
|
||||
(oli = strchr(options, optchar)) == NULL) {
|
||||
/*
|
||||
* If the user specified "-" and '-' isn't listed in
|
||||
* options, return -1 (non-option) as per POSIX.
|
||||
* Otherwise, it is an unknown option character (or ':').
|
||||
*/
|
||||
if (optchar == (int)'-' && *place == '\0')
|
||||
return (-1);
|
||||
if (!*place)
|
||||
++red_optind;
|
||||
if (PRINT_ERROR)
|
||||
fprintf(stderr, gnuoptchar, optchar);
|
||||
red_optopt = optchar;
|
||||
return (BADCH);
|
||||
}
|
||||
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
|
||||
/* -W long-option */
|
||||
if (*place) /* no space */
|
||||
/* NOTHING */;
|
||||
else if (++red_optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
fprintf(stderr, recargchar, optchar);
|
||||
red_optopt = optchar;
|
||||
return (BADARG);
|
||||
} else /* white space */
|
||||
place = nargv[red_optind];
|
||||
dash_prefix = W_PREFIX;
|
||||
optchar = parse_long_options(nargv, options, long_options,
|
||||
idx, 0, flags);
|
||||
place = EMSG;
|
||||
return (optchar);
|
||||
}
|
||||
if (*++oli != ':') { /* doesn't take argument */
|
||||
if (!*place)
|
||||
++red_optind;
|
||||
} else { /* takes (optional) argument */
|
||||
red_optarg = NULL;
|
||||
if (*place) /* no white space */
|
||||
red_optarg = place;
|
||||
else if (oli[1] != ':') { /* arg not optional */
|
||||
if (++red_optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
fprintf(stderr, recargchar, optchar);
|
||||
red_optopt = optchar;
|
||||
return (BADARG);
|
||||
} else
|
||||
red_optarg = nargv[red_optind];
|
||||
}
|
||||
place = EMSG;
|
||||
++red_optind;
|
||||
}
|
||||
/* dump back option letter */
|
||||
return (optchar);
|
||||
}
|
||||
|
||||
|
||||
/** @brief Get option character from command line argument list.
|
||||
|
||||
For more details, consult the getopt() man pages, since this function is
|
||||
generally similar.
|
||||
|
||||
@param nargc Number of arguments (argc passed into main()).
|
||||
@param nargv Argument vector (argv passed into main()).
|
||||
@param options String of option characters.
|
||||
|
||||
@return The next known option character in @p options. If a character not
|
||||
found in @p options is found or if an option is missing an argument,
|
||||
it returns '?'. Returns -1 when the argument list is exhausted.
|
||||
*/
|
||||
int32_t RedGetopt(
|
||||
int32_t nargc,
|
||||
char * const *nargv,
|
||||
const char *options)
|
||||
{
|
||||
return getopt_internal(nargc, nargv, options, NULL, NULL, FLAG_PERMUTE);
|
||||
}
|
||||
|
||||
|
||||
/** @brief Get long options from command line argument list.
|
||||
|
||||
For more details, consult the getopt_long() man pages, since this function
|
||||
is generally similar.
|
||||
|
||||
@param nargc Number of arguments (argc passed into main()).
|
||||
@param nargv Argument vector (argv passed into main()).
|
||||
@param options String of option characters.
|
||||
@param long_options The long options; the last element of this array must be
|
||||
filled with zeroes.
|
||||
@param idx If non-NULL, then populated with the index of the long
|
||||
option relative to @p long_options.
|
||||
|
||||
@return If the flag field in REDOPTION is NULL, returns the value specified
|
||||
in the val field, which is usually just the corresponding short
|
||||
option. If flag is non-NULL, returns zero and stores val in the
|
||||
location pointed to by flag. Returns ':' if an option was missing
|
||||
its argument, '?' for an unknown option, and -1 when the argument
|
||||
list is exhausted.
|
||||
*/
|
||||
int32_t RedGetoptLong(
|
||||
int32_t nargc,
|
||||
char * const *nargv,
|
||||
const char *options,
|
||||
const REDOPTION *long_options,
|
||||
int32_t *idx)
|
||||
{
|
||||
return getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE);
|
||||
}
|
||||
|
99
FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/toolcmn.c
Normal file
99
FreeRTOS-Plus/Source/Reliance-Edge/toolcmn/toolcmn.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements common-code utilities for tools and tests.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <redfs.h>
|
||||
#include <redcoreapi.h>
|
||||
#include <redvolume.h>
|
||||
#include <redtoolcmn.h>
|
||||
|
||||
|
||||
/** @brief Convert a string into a volume number.
|
||||
|
||||
In a POSIX-like configuration, @p pszVolume can either be a volume number or
|
||||
a volume path prefix. In case of ambiguity, the volume number of a matching
|
||||
path prefix takes precedence.
|
||||
|
||||
In an FSE configuration, @p pszVolume can be a volume number.
|
||||
|
||||
@param pszVolume The volume string.
|
||||
|
||||
@return On success, returns the volume number; on failure, returns
|
||||
#REDCONF_VOLUME_COUNT.
|
||||
*/
|
||||
uint8_t RedFindVolumeNumber(
|
||||
const char *pszVolume)
|
||||
{
|
||||
unsigned long ulNumber;
|
||||
const char *pszEndPtr;
|
||||
uint8_t bVolNum = REDCONF_VOLUME_COUNT;
|
||||
#if REDCONF_API_POSIX == 1
|
||||
uint8_t bIndex;
|
||||
#endif
|
||||
|
||||
/* Determine if pszVolume can be interpreted as a volume number.
|
||||
*/
|
||||
errno = 0;
|
||||
ulNumber = strtoul(pszVolume, (char **)&pszEndPtr, 10);
|
||||
if((errno == 0) && (ulNumber != ULONG_MAX) && (pszEndPtr[0U] == '\0') && (ulNumber < REDCONF_VOLUME_COUNT))
|
||||
{
|
||||
bVolNum = (uint8_t)ulNumber;
|
||||
}
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
/* Determine if pszVolume is a valid path prefix.
|
||||
*/
|
||||
for(bIndex = 0U; bIndex < REDCONF_VOLUME_COUNT; bIndex++)
|
||||
{
|
||||
if(strcmp(gaRedVolConf[bIndex].pszPathPrefix, pszVolume) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bIndex < REDCONF_VOLUME_COUNT)
|
||||
{
|
||||
/* Edge case: It is technically possible for pszVolume to be both a
|
||||
valid volume number and a valid volume prefix, for different
|
||||
volumes. For example, if pszVolume is "2", that would be recognized
|
||||
as volume number 2 above. But if "2" is the (poorly chosen) path
|
||||
prefix for volume number 4, that would also be matched. Since the
|
||||
POSIX-like API is primarily name based, and the ability to use
|
||||
volume numbers with this tool is just a convenience, the volume
|
||||
prefix takes precedence.
|
||||
*/
|
||||
bVolNum = bIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
return bVolNum;
|
||||
}
|
||||
|
101
FreeRTOS-Plus/Source/Reliance-Edge/util/bitmap.c
Normal file
101
FreeRTOS-Plus/Source/Reliance-Edge/util/bitmap.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements utilities for working with bitmaps.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
/** @brief Query the state of a bit in a bitmap.
|
||||
|
||||
Bits are counted from most significant to least significant. Thus, the mask
|
||||
for bit zero is 0x80 applied to the first byte in the bitmap.
|
||||
|
||||
@param pbBitmap Pointer to the bitmap.
|
||||
@param ulBit The bit to query.
|
||||
|
||||
@retval Whether the bit is set (true) or clear (false.
|
||||
*/
|
||||
bool RedBitGet(
|
||||
const uint8_t *pbBitmap,
|
||||
uint32_t ulBit)
|
||||
{
|
||||
bool fRet;
|
||||
|
||||
if(pbBitmap == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
fRet = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
fRet = (pbBitmap[ulBit >> 3U] & (0x80U >> (ulBit & 7U))) != 0U;
|
||||
}
|
||||
|
||||
return fRet;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Set a bit in a bitmap to one.
|
||||
|
||||
Bits are counted from most significant to least significant. Thus, the mask
|
||||
for bit zero is 0x80 applied to the first byte in the bitmap.
|
||||
|
||||
@param pbBitmap Pointer to the bitmap.
|
||||
@param ulBit The bit to set.
|
||||
*/
|
||||
void RedBitSet(
|
||||
uint8_t *pbBitmap,
|
||||
uint32_t ulBit)
|
||||
{
|
||||
REDASSERT(pbBitmap != NULL);
|
||||
|
||||
if(pbBitmap != NULL)
|
||||
{
|
||||
pbBitmap[ulBit >> 3U] |= (0x80U >> (ulBit & 7U));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @brief Clear a bit in a bitmap to zero.
|
||||
|
||||
Bits are counted from most significant to least significant. Thus, the mask
|
||||
for bit zero is 0x80 applied to the first byte in the bitmap.
|
||||
|
||||
@param pbBitmap Pointer to the bitmap.
|
||||
@param ulBit The bit to clear.
|
||||
*/
|
||||
void RedBitClear(
|
||||
uint8_t *pbBitmap,
|
||||
uint32_t ulBit)
|
||||
{
|
||||
REDASSERT(pbBitmap != NULL);
|
||||
|
||||
if(pbBitmap != NULL)
|
||||
{
|
||||
pbBitmap[ulBit >> 3U] &= ~(0x80U >> (ulBit & 7U));
|
||||
}
|
||||
}
|
||||
|
598
FreeRTOS-Plus/Source/Reliance-Edge/util/crc.c
Normal file
598
FreeRTOS-Plus/Source/Reliance-Edge/util/crc.c
Normal file
|
@ -0,0 +1,598 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements utilities for calculating CRC-32 checksums.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
/* The CRC functions do not return errors since the only detectable error
|
||||
condition is a NULL buffer pointer. If such a condition does arise, the
|
||||
functions assert and return the below CRC, which, although a legal CRC,
|
||||
is nonetheless suspicious and could provide a clue that something has
|
||||
gone wrong.
|
||||
*/
|
||||
#define SUSPICIOUS_CRC_VALUE (0xBAADC0DEU)
|
||||
|
||||
#define CRC_BITWISE (0U)
|
||||
#define CRC_SARWATE (1U)
|
||||
#define CRC_SLICEBY8 (2U)
|
||||
|
||||
|
||||
#if REDCONF_CRC_ALGORITHM == CRC_BITWISE
|
||||
|
||||
/* The following is representative of the polynomial accepted by CCITT 32-bit
|
||||
and in IEEE 802.3, Ethernet 2 specification.
|
||||
|
||||
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
|
||||
(reverse order)
|
||||
1110 1101 1011 1000 1000 0011 0010 0000 1
|
||||
(E) (D) (B) (8) (8) (3) (2) (0)
|
||||
*/
|
||||
#define CCITT_32_POLYNOMIAL (0xEDB88320U)
|
||||
|
||||
|
||||
/** @brief Compute a CRC32 for the given data buffer.
|
||||
|
||||
For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple
|
||||
buffers, call this function with the previously returned CRC value.
|
||||
|
||||
@param ulInitCrc32 Starting CRC value.
|
||||
@param pBuffer Data buffer to calculate the CRC from.
|
||||
@param ulLength Number of bytes of data in the given buffer.
|
||||
|
||||
@return The updated CRC value.
|
||||
*/
|
||||
uint32_t RedCrc32Update(
|
||||
uint32_t ulInitCrc32,
|
||||
const void *pBuffer,
|
||||
uint32_t ulLength)
|
||||
{
|
||||
uint32_t ulCrc32;
|
||||
|
||||
if(pBuffer == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
ulCrc32 = SUSPICIOUS_CRC_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);
|
||||
uint32_t ulIdx;
|
||||
|
||||
ulCrc32 = ~ulInitCrc32;
|
||||
|
||||
for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx)
|
||||
{
|
||||
uint32_t ulBit;
|
||||
|
||||
ulCrc32 ^= pbBuffer[ulIdx];
|
||||
|
||||
/* Branchless inner loop (greatly improves performance).
|
||||
*/
|
||||
for(ulBit = 0U; ulBit < 8U; ulBit++)
|
||||
{
|
||||
ulCrc32 = ((ulCrc32 & 1U) * CCITT_32_POLYNOMIAL) ^ (ulCrc32 >> 1U);
|
||||
}
|
||||
}
|
||||
|
||||
ulCrc32 = ~ulCrc32;
|
||||
}
|
||||
|
||||
return ulCrc32;
|
||||
}
|
||||
|
||||
#elif REDCONF_CRC_ALGORITHM == CRC_SARWATE
|
||||
|
||||
/** @brief Compute a CRC32 for the given data buffer.
|
||||
|
||||
For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple
|
||||
buffers, call this function with the previously returned CRC value.
|
||||
|
||||
@param ulInitCrc32 Starting CRC value.
|
||||
@param pBuffer Data buffer to calculate the CRC from.
|
||||
@param ulLength Number of bytes of data in the given buffer.
|
||||
|
||||
@return The updated CRC value.
|
||||
*/
|
||||
uint32_t RedCrc32Update(
|
||||
uint32_t ulInitCrc32,
|
||||
const void *pBuffer,
|
||||
uint32_t ulLength)
|
||||
{
|
||||
static const uint32_t aulCrc32Table[] =
|
||||
{
|
||||
0x00000000U, 0x77073096U, 0xEE0E612CU, 0x990951BAU, 0x076DC419U, 0x706AF48FU, 0xE963A535U, 0x9E6495A3U,
|
||||
0x0EDB8832U, 0x79DCB8A4U, 0xE0D5E91EU, 0x97D2D988U, 0x09B64C2BU, 0x7EB17CBDU, 0xE7B82D07U, 0x90BF1D91U,
|
||||
0x1DB71064U, 0x6AB020F2U, 0xF3B97148U, 0x84BE41DEU, 0x1ADAD47DU, 0x6DDDE4EBU, 0xF4D4B551U, 0x83D385C7U,
|
||||
0x136C9856U, 0x646BA8C0U, 0xFD62F97AU, 0x8A65C9ECU, 0x14015C4FU, 0x63066CD9U, 0xFA0F3D63U, 0x8D080DF5U,
|
||||
0x3B6E20C8U, 0x4C69105EU, 0xD56041E4U, 0xA2677172U, 0x3C03E4D1U, 0x4B04D447U, 0xD20D85FDU, 0xA50AB56BU,
|
||||
0x35B5A8FAU, 0x42B2986CU, 0xDBBBC9D6U, 0xACBCF940U, 0x32D86CE3U, 0x45DF5C75U, 0xDCD60DCFU, 0xABD13D59U,
|
||||
0x26D930ACU, 0x51DE003AU, 0xC8D75180U, 0xBFD06116U, 0x21B4F4B5U, 0x56B3C423U, 0xCFBA9599U, 0xB8BDA50FU,
|
||||
0x2802B89EU, 0x5F058808U, 0xC60CD9B2U, 0xB10BE924U, 0x2F6F7C87U, 0x58684C11U, 0xC1611DABU, 0xB6662D3DU,
|
||||
0x76DC4190U, 0x01DB7106U, 0x98D220BCU, 0xEFD5102AU, 0x71B18589U, 0x06B6B51FU, 0x9FBFE4A5U, 0xE8B8D433U,
|
||||
0x7807C9A2U, 0x0F00F934U, 0x9609A88EU, 0xE10E9818U, 0x7F6A0DBBU, 0x086D3D2DU, 0x91646C97U, 0xE6635C01U,
|
||||
0x6B6B51F4U, 0x1C6C6162U, 0x856530D8U, 0xF262004EU, 0x6C0695EDU, 0x1B01A57BU, 0x8208F4C1U, 0xF50FC457U,
|
||||
0x65B0D9C6U, 0x12B7E950U, 0x8BBEB8EAU, 0xFCB9887CU, 0x62DD1DDFU, 0x15DA2D49U, 0x8CD37CF3U, 0xFBD44C65U,
|
||||
0x4DB26158U, 0x3AB551CEU, 0xA3BC0074U, 0xD4BB30E2U, 0x4ADFA541U, 0x3DD895D7U, 0xA4D1C46DU, 0xD3D6F4FBU,
|
||||
0x4369E96AU, 0x346ED9FCU, 0xAD678846U, 0xDA60B8D0U, 0x44042D73U, 0x33031DE5U, 0xAA0A4C5FU, 0xDD0D7CC9U,
|
||||
0x5005713CU, 0x270241AAU, 0xBE0B1010U, 0xC90C2086U, 0x5768B525U, 0x206F85B3U, 0xB966D409U, 0xCE61E49FU,
|
||||
0x5EDEF90EU, 0x29D9C998U, 0xB0D09822U, 0xC7D7A8B4U, 0x59B33D17U, 0x2EB40D81U, 0xB7BD5C3BU, 0xC0BA6CADU,
|
||||
0xEDB88320U, 0x9ABFB3B6U, 0x03B6E20CU, 0x74B1D29AU, 0xEAD54739U, 0x9DD277AFU, 0x04DB2615U, 0x73DC1683U,
|
||||
0xE3630B12U, 0x94643B84U, 0x0D6D6A3EU, 0x7A6A5AA8U, 0xE40ECF0BU, 0x9309FF9DU, 0x0A00AE27U, 0x7D079EB1U,
|
||||
0xF00F9344U, 0x8708A3D2U, 0x1E01F268U, 0x6906C2FEU, 0xF762575DU, 0x806567CBU, 0x196C3671U, 0x6E6B06E7U,
|
||||
0xFED41B76U, 0x89D32BE0U, 0x10DA7A5AU, 0x67DD4ACCU, 0xF9B9DF6FU, 0x8EBEEFF9U, 0x17B7BE43U, 0x60B08ED5U,
|
||||
0xD6D6A3E8U, 0xA1D1937EU, 0x38D8C2C4U, 0x4FDFF252U, 0xD1BB67F1U, 0xA6BC5767U, 0x3FB506DDU, 0x48B2364BU,
|
||||
0xD80D2BDAU, 0xAF0A1B4CU, 0x36034AF6U, 0x41047A60U, 0xDF60EFC3U, 0xA867DF55U, 0x316E8EEFU, 0x4669BE79U,
|
||||
0xCB61B38CU, 0xBC66831AU, 0x256FD2A0U, 0x5268E236U, 0xCC0C7795U, 0xBB0B4703U, 0x220216B9U, 0x5505262FU,
|
||||
0xC5BA3BBEU, 0xB2BD0B28U, 0x2BB45A92U, 0x5CB36A04U, 0xC2D7FFA7U, 0xB5D0CF31U, 0x2CD99E8BU, 0x5BDEAE1DU,
|
||||
0x9B64C2B0U, 0xEC63F226U, 0x756AA39CU, 0x026D930AU, 0x9C0906A9U, 0xEB0E363FU, 0x72076785U, 0x05005713U,
|
||||
0x95BF4A82U, 0xE2B87A14U, 0x7BB12BAEU, 0x0CB61B38U, 0x92D28E9BU, 0xE5D5BE0DU, 0x7CDCEFB7U, 0x0BDBDF21U,
|
||||
0x86D3D2D4U, 0xF1D4E242U, 0x68DDB3F8U, 0x1FDA836EU, 0x81BE16CDU, 0xF6B9265BU, 0x6FB077E1U, 0x18B74777U,
|
||||
0x88085AE6U, 0xFF0F6A70U, 0x66063BCAU, 0x11010B5CU, 0x8F659EFFU, 0xF862AE69U, 0x616BFFD3U, 0x166CCF45U,
|
||||
0xA00AE278U, 0xD70DD2EEU, 0x4E048354U, 0x3903B3C2U, 0xA7672661U, 0xD06016F7U, 0x4969474DU, 0x3E6E77DBU,
|
||||
0xAED16A4AU, 0xD9D65ADCU, 0x40DF0B66U, 0x37D83BF0U, 0xA9BCAE53U, 0xDEBB9EC5U, 0x47B2CF7FU, 0x30B5FFE9U,
|
||||
0xBDBDF21CU, 0xCABAC28AU, 0x53B39330U, 0x24B4A3A6U, 0xBAD03605U, 0xCDD70693U, 0x54DE5729U, 0x23D967BFU,
|
||||
0xB3667A2EU, 0xC4614AB8U, 0x5D681B02U, 0x2A6F2B94U, 0xB40BBE37U, 0xC30C8EA1U, 0x5A05DF1BU, 0x2D02EF8DU,
|
||||
};
|
||||
|
||||
uint32_t ulCrc32;
|
||||
|
||||
if(pBuffer == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
ulCrc32 = SUSPICIOUS_CRC_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);
|
||||
uint32_t ulIdx;
|
||||
|
||||
ulCrc32 = ~ulInitCrc32;
|
||||
|
||||
for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx)
|
||||
{
|
||||
ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[(ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU];
|
||||
}
|
||||
|
||||
ulCrc32 = ~ulCrc32;
|
||||
}
|
||||
|
||||
return ulCrc32;
|
||||
}
|
||||
|
||||
#elif REDCONF_CRC_ALGORITHM == CRC_SLICEBY8
|
||||
|
||||
|
||||
/** @brief Compute a CRC32 for the given data buffer.
|
||||
|
||||
For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple
|
||||
buffers, call this function with the previously returned CRC value.
|
||||
|
||||
@param ulInitCrc32 Starting CRC value.
|
||||
@param pBuffer Data buffer to calculate the CRC from.
|
||||
@param ulLength Number of bytes of data in the given buffer.
|
||||
|
||||
@return The updated CRC value.
|
||||
*/
|
||||
uint32_t RedCrc32Update(
|
||||
uint32_t ulInitCrc32,
|
||||
const void *pBuffer,
|
||||
uint32_t ulLength)
|
||||
{
|
||||
/* CRC32 XOR table, with slicing-by-8 extensions.
|
||||
|
||||
This first column of the table contains the same XOR values as used in
|
||||
the classic byte-at-a-time Sarwate algorithm. The other seven columns
|
||||
are derived from the first, and are used in Intel's slicing-by-eight CRC
|
||||
algorithm.
|
||||
|
||||
The layout of this array in memory is novel and deserves explanation.
|
||||
In other implementations, including Intel's example, each of the below
|
||||
columns is an array. The first column is a 256-entry array, followed by
|
||||
another 256-entry array for the second column, etc. Testing on both ARM
|
||||
and x86 has shown the below mixed arrangement to be about 5-9% faster.
|
||||
One possible explanation: With the array-per-table approach, each of the
|
||||
eight table lookups is guaranteed to be in a separate 1 KB chunk of
|
||||
memory. With the below array, sometimes multiple table lookups will, by
|
||||
coincidence, be close together, making better use of the cache.
|
||||
*/
|
||||
static const uint32_t aulCrc32Table[] =
|
||||
{
|
||||
0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U,
|
||||
0x77073096U, 0x191B3141U, 0x01C26A37U, 0xB8BC6765U, 0x3D6029B0U, 0xCB5CD3A5U, 0xA6770BB4U, 0xCCAA009EU,
|
||||
0xEE0E612CU, 0x32366282U, 0x0384D46EU, 0xAA09C88BU, 0x7AC05360U, 0x4DC8A10BU, 0x979F1129U, 0x4225077DU,
|
||||
0x990951BAU, 0x2B2D53C3U, 0x0246BE59U, 0x12B5AFEEU, 0x47A07AD0U, 0x869472AEU, 0x31E81A9DU, 0x8E8F07E3U,
|
||||
0x076DC419U, 0x646CC504U, 0x0709A8DCU, 0x8F629757U, 0xF580A6C0U, 0x9B914216U, 0xF44F2413U, 0x844A0EFAU,
|
||||
0x706AF48FU, 0x7D77F445U, 0x06CBC2EBU, 0x37DEF032U, 0xC8E08F70U, 0x50CD91B3U, 0x52382FA7U, 0x48E00E64U,
|
||||
0xE963A535U, 0x565AA786U, 0x048D7CB2U, 0x256B5FDCU, 0x8F40F5A0U, 0xD659E31DU, 0x63D0353AU, 0xC66F0987U,
|
||||
0x9E6495A3U, 0x4F4196C7U, 0x054F1685U, 0x9DD738B9U, 0xB220DC10U, 0x1D0530B8U, 0xC5A73E8EU, 0x0AC50919U,
|
||||
0x0EDB8832U, 0xC8D98A08U, 0x0E1351B8U, 0xC5B428EFU, 0x30704BC1U, 0xEC53826DU, 0x33EF4E67U, 0xD3E51BB5U,
|
||||
0x79DCB8A4U, 0xD1C2BB49U, 0x0FD13B8FU, 0x7D084F8AU, 0x0D106271U, 0x270F51C8U, 0x959845D3U, 0x1F4F1B2BU,
|
||||
0xE0D5E91EU, 0xFAEFE88AU, 0x0D9785D6U, 0x6FBDE064U, 0x4AB018A1U, 0xA19B2366U, 0xA4705F4EU, 0x91C01CC8U,
|
||||
0x97D2D988U, 0xE3F4D9CBU, 0x0C55EFE1U, 0xD7018701U, 0x77D03111U, 0x6AC7F0C3U, 0x020754FAU, 0x5D6A1C56U,
|
||||
0x09B64C2BU, 0xACB54F0CU, 0x091AF964U, 0x4AD6BFB8U, 0xC5F0ED01U, 0x77C2C07BU, 0xC7A06A74U, 0x57AF154FU,
|
||||
0x7EB17CBDU, 0xB5AE7E4DU, 0x08D89353U, 0xF26AD8DDU, 0xF890C4B1U, 0xBC9E13DEU, 0x61D761C0U, 0x9B0515D1U,
|
||||
0xE7B82D07U, 0x9E832D8EU, 0x0A9E2D0AU, 0xE0DF7733U, 0xBF30BE61U, 0x3A0A6170U, 0x503F7B5DU, 0x158A1232U,
|
||||
0x90BF1D91U, 0x87981CCFU, 0x0B5C473DU, 0x58631056U, 0x825097D1U, 0xF156B2D5U, 0xF64870E9U, 0xD92012ACU,
|
||||
0x1DB71064U, 0x4AC21251U, 0x1C26A370U, 0x5019579FU, 0x60E09782U, 0x03D6029BU, 0x67DE9CCEU, 0x7CBB312BU,
|
||||
0x6AB020F2U, 0x53D92310U, 0x1DE4C947U, 0xE8A530FAU, 0x5D80BE32U, 0xC88AD13EU, 0xC1A9977AU, 0xB01131B5U,
|
||||
0xF3B97148U, 0x78F470D3U, 0x1FA2771EU, 0xFA109F14U, 0x1A20C4E2U, 0x4E1EA390U, 0xF0418DE7U, 0x3E9E3656U,
|
||||
0x84BE41DEU, 0x61EF4192U, 0x1E601D29U, 0x42ACF871U, 0x2740ED52U, 0x85427035U, 0x56368653U, 0xF23436C8U,
|
||||
0x1ADAD47DU, 0x2EAED755U, 0x1B2F0BACU, 0xDF7BC0C8U, 0x95603142U, 0x9847408DU, 0x9391B8DDU, 0xF8F13FD1U,
|
||||
0x6DDDE4EBU, 0x37B5E614U, 0x1AED619BU, 0x67C7A7ADU, 0xA80018F2U, 0x531B9328U, 0x35E6B369U, 0x345B3F4FU,
|
||||
0xF4D4B551U, 0x1C98B5D7U, 0x18ABDFC2U, 0x75720843U, 0xEFA06222U, 0xD58FE186U, 0x040EA9F4U, 0xBAD438ACU,
|
||||
0x83D385C7U, 0x05838496U, 0x1969B5F5U, 0xCDCE6F26U, 0xD2C04B92U, 0x1ED33223U, 0xA279A240U, 0x767E3832U,
|
||||
0x136C9856U, 0x821B9859U, 0x1235F2C8U, 0x95AD7F70U, 0x5090DC43U, 0xEF8580F6U, 0x5431D2A9U, 0xAF5E2A9EU,
|
||||
0x646BA8C0U, 0x9B00A918U, 0x13F798FFU, 0x2D111815U, 0x6DF0F5F3U, 0x24D95353U, 0xF246D91DU, 0x63F42A00U,
|
||||
0xFD62F97AU, 0xB02DFADBU, 0x11B126A6U, 0x3FA4B7FBU, 0x2A508F23U, 0xA24D21FDU, 0xC3AEC380U, 0xED7B2DE3U,
|
||||
0x8A65C9ECU, 0xA936CB9AU, 0x10734C91U, 0x8718D09EU, 0x1730A693U, 0x6911F258U, 0x65D9C834U, 0x21D12D7DU,
|
||||
0x14015C4FU, 0xE6775D5DU, 0x153C5A14U, 0x1ACFE827U, 0xA5107A83U, 0x7414C2E0U, 0xA07EF6BAU, 0x2B142464U,
|
||||
0x63066CD9U, 0xFF6C6C1CU, 0x14FE3023U, 0xA2738F42U, 0x98705333U, 0xBF481145U, 0x0609FD0EU, 0xE7BE24FAU,
|
||||
0xFA0F3D63U, 0xD4413FDFU, 0x16B88E7AU, 0xB0C620ACU, 0xDFD029E3U, 0x39DC63EBU, 0x37E1E793U, 0x69312319U,
|
||||
0x8D080DF5U, 0xCD5A0E9EU, 0x177AE44DU, 0x087A47C9U, 0xE2B00053U, 0xF280B04EU, 0x9196EC27U, 0xA59B2387U,
|
||||
0x3B6E20C8U, 0x958424A2U, 0x384D46E0U, 0xA032AF3EU, 0xC1C12F04U, 0x07AC0536U, 0xCFBD399CU, 0xF9766256U,
|
||||
0x4C69105EU, 0x8C9F15E3U, 0x398F2CD7U, 0x188EC85BU, 0xFCA106B4U, 0xCCF0D693U, 0x69CA3228U, 0x35DC62C8U,
|
||||
0xD56041E4U, 0xA7B24620U, 0x3BC9928EU, 0x0A3B67B5U, 0xBB017C64U, 0x4A64A43DU, 0x582228B5U, 0xBB53652BU,
|
||||
0xA2677172U, 0xBEA97761U, 0x3A0BF8B9U, 0xB28700D0U, 0x866155D4U, 0x81387798U, 0xFE552301U, 0x77F965B5U,
|
||||
0x3C03E4D1U, 0xF1E8E1A6U, 0x3F44EE3CU, 0x2F503869U, 0x344189C4U, 0x9C3D4720U, 0x3BF21D8FU, 0x7D3C6CACU,
|
||||
0x4B04D447U, 0xE8F3D0E7U, 0x3E86840BU, 0x97EC5F0CU, 0x0921A074U, 0x57619485U, 0x9D85163BU, 0xB1966C32U,
|
||||
0xD20D85FDU, 0xC3DE8324U, 0x3CC03A52U, 0x8559F0E2U, 0x4E81DAA4U, 0xD1F5E62BU, 0xAC6D0CA6U, 0x3F196BD1U,
|
||||
0xA50AB56BU, 0xDAC5B265U, 0x3D025065U, 0x3DE59787U, 0x73E1F314U, 0x1AA9358EU, 0x0A1A0712U, 0xF3B36B4FU,
|
||||
0x35B5A8FAU, 0x5D5DAEAAU, 0x365E1758U, 0x658687D1U, 0xF1B164C5U, 0xEBFF875BU, 0xFC5277FBU, 0x2A9379E3U,
|
||||
0x42B2986CU, 0x44469FEBU, 0x379C7D6FU, 0xDD3AE0B4U, 0xCCD14D75U, 0x20A354FEU, 0x5A257C4FU, 0xE639797DU,
|
||||
0xDBBBC9D6U, 0x6F6BCC28U, 0x35DAC336U, 0xCF8F4F5AU, 0x8B7137A5U, 0xA6372650U, 0x6BCD66D2U, 0x68B67E9EU,
|
||||
0xACBCF940U, 0x7670FD69U, 0x3418A901U, 0x7733283FU, 0xB6111E15U, 0x6D6BF5F5U, 0xCDBA6D66U, 0xA41C7E00U,
|
||||
0x32D86CE3U, 0x39316BAEU, 0x3157BF84U, 0xEAE41086U, 0x0431C205U, 0x706EC54DU, 0x081D53E8U, 0xAED97719U,
|
||||
0x45DF5C75U, 0x202A5AEFU, 0x3095D5B3U, 0x525877E3U, 0x3951EBB5U, 0xBB3216E8U, 0xAE6A585CU, 0x62737787U,
|
||||
0xDCD60DCFU, 0x0B07092CU, 0x32D36BEAU, 0x40EDD80DU, 0x7EF19165U, 0x3DA66446U, 0x9F8242C1U, 0xECFC7064U,
|
||||
0xABD13D59U, 0x121C386DU, 0x331101DDU, 0xF851BF68U, 0x4391B8D5U, 0xF6FAB7E3U, 0x39F54975U, 0x205670FAU,
|
||||
0x26D930ACU, 0xDF4636F3U, 0x246BE590U, 0xF02BF8A1U, 0xA121B886U, 0x047A07ADU, 0xA863A552U, 0x85CD537DU,
|
||||
0x51DE003AU, 0xC65D07B2U, 0x25A98FA7U, 0x48979FC4U, 0x9C419136U, 0xCF26D408U, 0x0E14AEE6U, 0x496753E3U,
|
||||
0xC8D75180U, 0xED705471U, 0x27EF31FEU, 0x5A22302AU, 0xDBE1EBE6U, 0x49B2A6A6U, 0x3FFCB47BU, 0xC7E85400U,
|
||||
0xBFD06116U, 0xF46B6530U, 0x262D5BC9U, 0xE29E574FU, 0xE681C256U, 0x82EE7503U, 0x998BBFCFU, 0x0B42549EU,
|
||||
0x21B4F4B5U, 0xBB2AF3F7U, 0x23624D4CU, 0x7F496FF6U, 0x54A11E46U, 0x9FEB45BBU, 0x5C2C8141U, 0x01875D87U,
|
||||
0x56B3C423U, 0xA231C2B6U, 0x22A0277BU, 0xC7F50893U, 0x69C137F6U, 0x54B7961EU, 0xFA5B8AF5U, 0xCD2D5D19U,
|
||||
0xCFBA9599U, 0x891C9175U, 0x20E69922U, 0xD540A77DU, 0x2E614D26U, 0xD223E4B0U, 0xCBB39068U, 0x43A25AFAU,
|
||||
0xB8BDA50FU, 0x9007A034U, 0x2124F315U, 0x6DFCC018U, 0x13016496U, 0x197F3715U, 0x6DC49BDCU, 0x8F085A64U,
|
||||
0x2802B89EU, 0x179FBCFBU, 0x2A78B428U, 0x359FD04EU, 0x9151F347U, 0xE82985C0U, 0x9B8CEB35U, 0x562848C8U,
|
||||
0x5F058808U, 0x0E848DBAU, 0x2BBADE1FU, 0x8D23B72BU, 0xAC31DAF7U, 0x23755665U, 0x3DFBE081U, 0x9A824856U,
|
||||
0xC60CD9B2U, 0x25A9DE79U, 0x29FC6046U, 0x9F9618C5U, 0xEB91A027U, 0xA5E124CBU, 0x0C13FA1CU, 0x140D4FB5U,
|
||||
0xB10BE924U, 0x3CB2EF38U, 0x283E0A71U, 0x272A7FA0U, 0xD6F18997U, 0x6EBDF76EU, 0xAA64F1A8U, 0xD8A74F2BU,
|
||||
0x2F6F7C87U, 0x73F379FFU, 0x2D711CF4U, 0xBAFD4719U, 0x64D15587U, 0x73B8C7D6U, 0x6FC3CF26U, 0xD2624632U,
|
||||
0x58684C11U, 0x6AE848BEU, 0x2CB376C3U, 0x0241207CU, 0x59B17C37U, 0xB8E41473U, 0xC9B4C492U, 0x1EC846ACU,
|
||||
0xC1611DABU, 0x41C51B7DU, 0x2EF5C89AU, 0x10F48F92U, 0x1E1106E7U, 0x3E7066DDU, 0xF85CDE0FU, 0x9047414FU,
|
||||
0xB6662D3DU, 0x58DE2A3CU, 0x2F37A2ADU, 0xA848E8F7U, 0x23712F57U, 0xF52CB578U, 0x5E2BD5BBU, 0x5CED41D1U,
|
||||
0x76DC4190U, 0xF0794F05U, 0x709A8DC0U, 0x9B14583DU, 0x58F35849U, 0x0F580A6CU, 0x440B7579U, 0x299DC2EDU,
|
||||
0x01DB7106U, 0xE9627E44U, 0x7158E7F7U, 0x23A83F58U, 0x659371F9U, 0xC404D9C9U, 0xE27C7ECDU, 0xE537C273U,
|
||||
0x98D220BCU, 0xC24F2D87U, 0x731E59AEU, 0x311D90B6U, 0x22330B29U, 0x4290AB67U, 0xD3946450U, 0x6BB8C590U,
|
||||
0xEFD5102AU, 0xDB541CC6U, 0x72DC3399U, 0x89A1F7D3U, 0x1F532299U, 0x89CC78C2U, 0x75E36FE4U, 0xA712C50EU,
|
||||
0x71B18589U, 0x94158A01U, 0x7793251CU, 0x1476CF6AU, 0xAD73FE89U, 0x94C9487AU, 0xB044516AU, 0xADD7CC17U,
|
||||
0x06B6B51FU, 0x8D0EBB40U, 0x76514F2BU, 0xACCAA80FU, 0x9013D739U, 0x5F959BDFU, 0x16335ADEU, 0x617DCC89U,
|
||||
0x9FBFE4A5U, 0xA623E883U, 0x7417F172U, 0xBE7F07E1U, 0xD7B3ADE9U, 0xD901E971U, 0x27DB4043U, 0xEFF2CB6AU,
|
||||
0xE8B8D433U, 0xBF38D9C2U, 0x75D59B45U, 0x06C36084U, 0xEAD38459U, 0x125D3AD4U, 0x81AC4BF7U, 0x2358CBF4U,
|
||||
0x7807C9A2U, 0x38A0C50DU, 0x7E89DC78U, 0x5EA070D2U, 0x68831388U, 0xE30B8801U, 0x77E43B1EU, 0xFA78D958U,
|
||||
0x0F00F934U, 0x21BBF44CU, 0x7F4BB64FU, 0xE61C17B7U, 0x55E33A38U, 0x28575BA4U, 0xD19330AAU, 0x36D2D9C6U,
|
||||
0x9609A88EU, 0x0A96A78FU, 0x7D0D0816U, 0xF4A9B859U, 0x124340E8U, 0xAEC3290AU, 0xE07B2A37U, 0xB85DDE25U,
|
||||
0xE10E9818U, 0x138D96CEU, 0x7CCF6221U, 0x4C15DF3CU, 0x2F236958U, 0x659FFAAFU, 0x460C2183U, 0x74F7DEBBU,
|
||||
0x7F6A0DBBU, 0x5CCC0009U, 0x798074A4U, 0xD1C2E785U, 0x9D03B548U, 0x789ACA17U, 0x83AB1F0DU, 0x7E32D7A2U,
|
||||
0x086D3D2DU, 0x45D73148U, 0x78421E93U, 0x697E80E0U, 0xA0639CF8U, 0xB3C619B2U, 0x25DC14B9U, 0xB298D73CU,
|
||||
0x91646C97U, 0x6EFA628BU, 0x7A04A0CAU, 0x7BCB2F0EU, 0xE7C3E628U, 0x35526B1CU, 0x14340E24U, 0x3C17D0DFU,
|
||||
0xE6635C01U, 0x77E153CAU, 0x7BC6CAFDU, 0xC377486BU, 0xDAA3CF98U, 0xFE0EB8B9U, 0xB2430590U, 0xF0BDD041U,
|
||||
0x6B6B51F4U, 0xBABB5D54U, 0x6CBC2EB0U, 0xCB0D0FA2U, 0x3813CFCBU, 0x0C8E08F7U, 0x23D5E9B7U, 0x5526F3C6U,
|
||||
0x1C6C6162U, 0xA3A06C15U, 0x6D7E4487U, 0x73B168C7U, 0x0573E67BU, 0xC7D2DB52U, 0x85A2E203U, 0x998CF358U,
|
||||
0x856530D8U, 0x888D3FD6U, 0x6F38FADEU, 0x6104C729U, 0x42D39CABU, 0x4146A9FCU, 0xB44AF89EU, 0x1703F4BBU,
|
||||
0xF262004EU, 0x91960E97U, 0x6EFA90E9U, 0xD9B8A04CU, 0x7FB3B51BU, 0x8A1A7A59U, 0x123DF32AU, 0xDBA9F425U,
|
||||
0x6C0695EDU, 0xDED79850U, 0x6BB5866CU, 0x446F98F5U, 0xCD93690BU, 0x971F4AE1U, 0xD79ACDA4U, 0xD16CFD3CU,
|
||||
0x1B01A57BU, 0xC7CCA911U, 0x6A77EC5BU, 0xFCD3FF90U, 0xF0F340BBU, 0x5C439944U, 0x71EDC610U, 0x1DC6FDA2U,
|
||||
0x8208F4C1U, 0xECE1FAD2U, 0x68315202U, 0xEE66507EU, 0xB7533A6BU, 0xDAD7EBEAU, 0x4005DC8DU, 0x9349FA41U,
|
||||
0xF50FC457U, 0xF5FACB93U, 0x69F33835U, 0x56DA371BU, 0x8A3313DBU, 0x118B384FU, 0xE672D739U, 0x5FE3FADFU,
|
||||
0x65B0D9C6U, 0x7262D75CU, 0x62AF7F08U, 0x0EB9274DU, 0x0863840AU, 0xE0DD8A9AU, 0x103AA7D0U, 0x86C3E873U,
|
||||
0x12B7E950U, 0x6B79E61DU, 0x636D153FU, 0xB6054028U, 0x3503ADBAU, 0x2B81593FU, 0xB64DAC64U, 0x4A69E8EDU,
|
||||
0x8BBEB8EAU, 0x4054B5DEU, 0x612BAB66U, 0xA4B0EFC6U, 0x72A3D76AU, 0xAD152B91U, 0x87A5B6F9U, 0xC4E6EF0EU,
|
||||
0xFCB9887CU, 0x594F849FU, 0x60E9C151U, 0x1C0C88A3U, 0x4FC3FEDAU, 0x6649F834U, 0x21D2BD4DU, 0x084CEF90U,
|
||||
0x62DD1DDFU, 0x160E1258U, 0x65A6D7D4U, 0x81DBB01AU, 0xFDE322CAU, 0x7B4CC88CU, 0xE47583C3U, 0x0289E689U,
|
||||
0x15DA2D49U, 0x0F152319U, 0x6464BDE3U, 0x3967D77FU, 0xC0830B7AU, 0xB0101B29U, 0x42028877U, 0xCE23E617U,
|
||||
0x8CD37CF3U, 0x243870DAU, 0x662203BAU, 0x2BD27891U, 0x872371AAU, 0x36846987U, 0x73EA92EAU, 0x40ACE1F4U,
|
||||
0xFBD44C65U, 0x3D23419BU, 0x67E0698DU, 0x936E1FF4U, 0xBA43581AU, 0xFDD8BA22U, 0xD59D995EU, 0x8C06E16AU,
|
||||
0x4DB26158U, 0x65FD6BA7U, 0x48D7CB20U, 0x3B26F703U, 0x9932774DU, 0x08F40F5AU, 0x8BB64CE5U, 0xD0EBA0BBU,
|
||||
0x3AB551CEU, 0x7CE65AE6U, 0x4915A117U, 0x839A9066U, 0xA4525EFDU, 0xC3A8DCFFU, 0x2DC14751U, 0x1C41A025U,
|
||||
0xA3BC0074U, 0x57CB0925U, 0x4B531F4EU, 0x912F3F88U, 0xE3F2242DU, 0x453CAE51U, 0x1C295DCCU, 0x92CEA7C6U,
|
||||
0xD4BB30E2U, 0x4ED03864U, 0x4A917579U, 0x299358EDU, 0xDE920D9DU, 0x8E607DF4U, 0xBA5E5678U, 0x5E64A758U,
|
||||
0x4ADFA541U, 0x0191AEA3U, 0x4FDE63FCU, 0xB4446054U, 0x6CB2D18DU, 0x93654D4CU, 0x7FF968F6U, 0x54A1AE41U,
|
||||
0x3DD895D7U, 0x188A9FE2U, 0x4E1C09CBU, 0x0CF80731U, 0x51D2F83DU, 0x58399EE9U, 0xD98E6342U, 0x980BAEDFU,
|
||||
0xA4D1C46DU, 0x33A7CC21U, 0x4C5AB792U, 0x1E4DA8DFU, 0x167282EDU, 0xDEADEC47U, 0xE86679DFU, 0x1684A93CU,
|
||||
0xD3D6F4FBU, 0x2ABCFD60U, 0x4D98DDA5U, 0xA6F1CFBAU, 0x2B12AB5DU, 0x15F13FE2U, 0x4E11726BU, 0xDA2EA9A2U,
|
||||
0x4369E96AU, 0xAD24E1AFU, 0x46C49A98U, 0xFE92DFECU, 0xA9423C8CU, 0xE4A78D37U, 0xB8590282U, 0x030EBB0EU,
|
||||
0x346ED9FCU, 0xB43FD0EEU, 0x4706F0AFU, 0x462EB889U, 0x9422153CU, 0x2FFB5E92U, 0x1E2E0936U, 0xCFA4BB90U,
|
||||
0xAD678846U, 0x9F12832DU, 0x45404EF6U, 0x549B1767U, 0xD3826FECU, 0xA96F2C3CU, 0x2FC613ABU, 0x412BBC73U,
|
||||
0xDA60B8D0U, 0x8609B26CU, 0x448224C1U, 0xEC277002U, 0xEEE2465CU, 0x6233FF99U, 0x89B1181FU, 0x8D81BCEDU,
|
||||
0x44042D73U, 0xC94824ABU, 0x41CD3244U, 0x71F048BBU, 0x5CC29A4CU, 0x7F36CF21U, 0x4C162691U, 0x8744B5F4U,
|
||||
0x33031DE5U, 0xD05315EAU, 0x400F5873U, 0xC94C2FDEU, 0x61A2B3FCU, 0xB46A1C84U, 0xEA612D25U, 0x4BEEB56AU,
|
||||
0xAA0A4C5FU, 0xFB7E4629U, 0x4249E62AU, 0xDBF98030U, 0x2602C92CU, 0x32FE6E2AU, 0xDB8937B8U, 0xC561B289U,
|
||||
0xDD0D7CC9U, 0xE2657768U, 0x438B8C1DU, 0x6345E755U, 0x1B62E09CU, 0xF9A2BD8FU, 0x7DFE3C0CU, 0x09CBB217U,
|
||||
0x5005713CU, 0x2F3F79F6U, 0x54F16850U, 0x6B3FA09CU, 0xF9D2E0CFU, 0x0B220DC1U, 0xEC68D02BU, 0xAC509190U,
|
||||
0x270241AAU, 0x362448B7U, 0x55330267U, 0xD383C7F9U, 0xC4B2C97FU, 0xC07EDE64U, 0x4A1FDB9FU, 0x60FA910EU,
|
||||
0xBE0B1010U, 0x1D091B74U, 0x5775BC3EU, 0xC1366817U, 0x8312B3AFU, 0x46EAACCAU, 0x7BF7C102U, 0xEE7596EDU,
|
||||
0xC90C2086U, 0x04122A35U, 0x56B7D609U, 0x798A0F72U, 0xBE729A1FU, 0x8DB67F6FU, 0xDD80CAB6U, 0x22DF9673U,
|
||||
0x5768B525U, 0x4B53BCF2U, 0x53F8C08CU, 0xE45D37CBU, 0x0C52460FU, 0x90B34FD7U, 0x1827F438U, 0x281A9F6AU,
|
||||
0x206F85B3U, 0x52488DB3U, 0x523AAABBU, 0x5CE150AEU, 0x31326FBFU, 0x5BEF9C72U, 0xBE50FF8CU, 0xE4B09FF4U,
|
||||
0xB966D409U, 0x7965DE70U, 0x507C14E2U, 0x4E54FF40U, 0x7692156FU, 0xDD7BEEDCU, 0x8FB8E511U, 0x6A3F9817U,
|
||||
0xCE61E49FU, 0x607EEF31U, 0x51BE7ED5U, 0xF6E89825U, 0x4BF23CDFU, 0x16273D79U, 0x29CFEEA5U, 0xA6959889U,
|
||||
0x5EDEF90EU, 0xE7E6F3FEU, 0x5AE239E8U, 0xAE8B8873U, 0xC9A2AB0EU, 0xE7718FACU, 0xDF879E4CU, 0x7FB58A25U,
|
||||
0x29D9C998U, 0xFEFDC2BFU, 0x5B2053DFU, 0x1637EF16U, 0xF4C282BEU, 0x2C2D5C09U, 0x79F095F8U, 0xB31F8ABBU,
|
||||
0xB0D09822U, 0xD5D0917CU, 0x5966ED86U, 0x048240F8U, 0xB362F86EU, 0xAAB92EA7U, 0x48188F65U, 0x3D908D58U,
|
||||
0xC7D7A8B4U, 0xCCCBA03DU, 0x58A487B1U, 0xBC3E279DU, 0x8E02D1DEU, 0x61E5FD02U, 0xEE6F84D1U, 0xF13A8DC6U,
|
||||
0x59B33D17U, 0x838A36FAU, 0x5DEB9134U, 0x21E91F24U, 0x3C220DCEU, 0x7CE0CDBAU, 0x2BC8BA5FU, 0xFBFF84DFU,
|
||||
0x2EB40D81U, 0x9A9107BBU, 0x5C29FB03U, 0x99557841U, 0x0142247EU, 0xB7BC1E1FU, 0x8DBFB1EBU, 0x37558441U,
|
||||
0xB7BD5C3BU, 0xB1BC5478U, 0x5E6F455AU, 0x8BE0D7AFU, 0x46E25EAEU, 0x31286CB1U, 0xBC57AB76U, 0xB9DA83A2U,
|
||||
0xC0BA6CADU, 0xA8A76539U, 0x5FAD2F6DU, 0x335CB0CAU, 0x7B82771EU, 0xFA74BF14U, 0x1A20A0C2U, 0x7570833CU,
|
||||
0xEDB88320U, 0x3B83984BU, 0xE1351B80U, 0xED59B63BU, 0xB1E6B092U, 0x1EB014D8U, 0x8816EAF2U, 0x533B85DAU,
|
||||
0x9ABFB3B6U, 0x2298A90AU, 0xE0F771B7U, 0x55E5D15EU, 0x8C869922U, 0xD5ECC77DU, 0x2E61E146U, 0x9F918544U,
|
||||
0x03B6E20CU, 0x09B5FAC9U, 0xE2B1CFEEU, 0x47507EB0U, 0xCB26E3F2U, 0x5378B5D3U, 0x1F89FBDBU, 0x111E82A7U,
|
||||
0x74B1D29AU, 0x10AECB88U, 0xE373A5D9U, 0xFFEC19D5U, 0xF646CA42U, 0x98246676U, 0xB9FEF06FU, 0xDDB48239U,
|
||||
0xEAD54739U, 0x5FEF5D4FU, 0xE63CB35CU, 0x623B216CU, 0x44661652U, 0x852156CEU, 0x7C59CEE1U, 0xD7718B20U,
|
||||
0x9DD277AFU, 0x46F46C0EU, 0xE7FED96BU, 0xDA874609U, 0x79063FE2U, 0x4E7D856BU, 0xDA2EC555U, 0x1BDB8BBEU,
|
||||
0x04DB2615U, 0x6DD93FCDU, 0xE5B86732U, 0xC832E9E7U, 0x3EA64532U, 0xC8E9F7C5U, 0xEBC6DFC8U, 0x95548C5DU,
|
||||
0x73DC1683U, 0x74C20E8CU, 0xE47A0D05U, 0x708E8E82U, 0x03C66C82U, 0x03B52460U, 0x4DB1D47CU, 0x59FE8CC3U,
|
||||
0xE3630B12U, 0xF35A1243U, 0xEF264A38U, 0x28ED9ED4U, 0x8196FB53U, 0xF2E396B5U, 0xBBF9A495U, 0x80DE9E6FU,
|
||||
0x94643B84U, 0xEA412302U, 0xEEE4200FU, 0x9051F9B1U, 0xBCF6D2E3U, 0x39BF4510U, 0x1D8EAF21U, 0x4C749EF1U,
|
||||
0x0D6D6A3EU, 0xC16C70C1U, 0xECA29E56U, 0x82E4565FU, 0xFB56A833U, 0xBF2B37BEU, 0x2C66B5BCU, 0xC2FB9912U,
|
||||
0x7A6A5AA8U, 0xD8774180U, 0xED60F461U, 0x3A58313AU, 0xC6368183U, 0x7477E41BU, 0x8A11BE08U, 0x0E51998CU,
|
||||
0xE40ECF0BU, 0x9736D747U, 0xE82FE2E4U, 0xA78F0983U, 0x74165D93U, 0x6972D4A3U, 0x4FB68086U, 0x04949095U,
|
||||
0x9309FF9DU, 0x8E2DE606U, 0xE9ED88D3U, 0x1F336EE6U, 0x49767423U, 0xA22E0706U, 0xE9C18B32U, 0xC83E900BU,
|
||||
0x0A00AE27U, 0xA500B5C5U, 0xEBAB368AU, 0x0D86C108U, 0x0ED60EF3U, 0x24BA75A8U, 0xD82991AFU, 0x46B197E8U,
|
||||
0x7D079EB1U, 0xBC1B8484U, 0xEA695CBDU, 0xB53AA66DU, 0x33B62743U, 0xEFE6A60DU, 0x7E5E9A1BU, 0x8A1B9776U,
|
||||
0xF00F9344U, 0x71418A1AU, 0xFD13B8F0U, 0xBD40E1A4U, 0xD1062710U, 0x1D661643U, 0xEFC8763CU, 0x2F80B4F1U,
|
||||
0x8708A3D2U, 0x685ABB5BU, 0xFCD1D2C7U, 0x05FC86C1U, 0xEC660EA0U, 0xD63AC5E6U, 0x49BF7D88U, 0xE32AB46FU,
|
||||
0x1E01F268U, 0x4377E898U, 0xFE976C9EU, 0x1749292FU, 0xABC67470U, 0x50AEB748U, 0x78576715U, 0x6DA5B38CU,
|
||||
0x6906C2FEU, 0x5A6CD9D9U, 0xFF5506A9U, 0xAFF54E4AU, 0x96A65DC0U, 0x9BF264EDU, 0xDE206CA1U, 0xA10FB312U,
|
||||
0xF762575DU, 0x152D4F1EU, 0xFA1A102CU, 0x322276F3U, 0x248681D0U, 0x86F75455U, 0x1B87522FU, 0xABCABA0BU,
|
||||
0x806567CBU, 0x0C367E5FU, 0xFBD87A1BU, 0x8A9E1196U, 0x19E6A860U, 0x4DAB87F0U, 0xBDF0599BU, 0x6760BA95U,
|
||||
0x196C3671U, 0x271B2D9CU, 0xF99EC442U, 0x982BBE78U, 0x5E46D2B0U, 0xCB3FF55EU, 0x8C184306U, 0xE9EFBD76U,
|
||||
0x6E6B06E7U, 0x3E001CDDU, 0xF85CAE75U, 0x2097D91DU, 0x6326FB00U, 0x006326FBU, 0x2A6F48B2U, 0x2545BDE8U,
|
||||
0xFED41B76U, 0xB9980012U, 0xF300E948U, 0x78F4C94BU, 0xE1766CD1U, 0xF135942EU, 0xDC27385BU, 0xFC65AF44U,
|
||||
0x89D32BE0U, 0xA0833153U, 0xF2C2837FU, 0xC048AE2EU, 0xDC164561U, 0x3A69478BU, 0x7A5033EFU, 0x30CFAFDAU,
|
||||
0x10DA7A5AU, 0x8BAE6290U, 0xF0843D26U, 0xD2FD01C0U, 0x9BB63FB1U, 0xBCFD3525U, 0x4BB82972U, 0xBE40A839U,
|
||||
0x67DD4ACCU, 0x92B553D1U, 0xF1465711U, 0x6A4166A5U, 0xA6D61601U, 0x77A1E680U, 0xEDCF22C6U, 0x72EAA8A7U,
|
||||
0xF9B9DF6FU, 0xDDF4C516U, 0xF4094194U, 0xF7965E1CU, 0x14F6CA11U, 0x6AA4D638U, 0x28681C48U, 0x782FA1BEU,
|
||||
0x8EBEEFF9U, 0xC4EFF457U, 0xF5CB2BA3U, 0x4F2A3979U, 0x2996E3A1U, 0xA1F8059DU, 0x8E1F17FCU, 0xB485A120U,
|
||||
0x17B7BE43U, 0xEFC2A794U, 0xF78D95FAU, 0x5D9F9697U, 0x6E369971U, 0x276C7733U, 0xBFF70D61U, 0x3A0AA6C3U,
|
||||
0x60B08ED5U, 0xF6D996D5U, 0xF64FFFCDU, 0xE523F1F2U, 0x5356B0C1U, 0xEC30A496U, 0x198006D5U, 0xF6A0A65DU,
|
||||
0xD6D6A3E8U, 0xAE07BCE9U, 0xD9785D60U, 0x4D6B1905U, 0x70279F96U, 0x191C11EEU, 0x47ABD36EU, 0xAA4DE78CU,
|
||||
0xA1D1937EU, 0xB71C8DA8U, 0xD8BA3757U, 0xF5D77E60U, 0x4D47B626U, 0xD240C24BU, 0xE1DCD8DAU, 0x66E7E712U,
|
||||
0x38D8C2C4U, 0x9C31DE6BU, 0xDAFC890EU, 0xE762D18EU, 0x0AE7CCF6U, 0x54D4B0E5U, 0xD034C247U, 0xE868E0F1U,
|
||||
0x4FDFF252U, 0x852AEF2AU, 0xDB3EE339U, 0x5FDEB6EBU, 0x3787E546U, 0x9F886340U, 0x7643C9F3U, 0x24C2E06FU,
|
||||
0xD1BB67F1U, 0xCA6B79EDU, 0xDE71F5BCU, 0xC2098E52U, 0x85A73956U, 0x828D53F8U, 0xB3E4F77DU, 0x2E07E976U,
|
||||
0xA6BC5767U, 0xD37048ACU, 0xDFB39F8BU, 0x7AB5E937U, 0xB8C710E6U, 0x49D1805DU, 0x1593FCC9U, 0xE2ADE9E8U,
|
||||
0x3FB506DDU, 0xF85D1B6FU, 0xDDF521D2U, 0x680046D9U, 0xFF676A36U, 0xCF45F2F3U, 0x247BE654U, 0x6C22EE0BU,
|
||||
0x48B2364BU, 0xE1462A2EU, 0xDC374BE5U, 0xD0BC21BCU, 0xC2074386U, 0x04192156U, 0x820CEDE0U, 0xA088EE95U,
|
||||
0xD80D2BDAU, 0x66DE36E1U, 0xD76B0CD8U, 0x88DF31EAU, 0x4057D457U, 0xF54F9383U, 0x74449D09U, 0x79A8FC39U,
|
||||
0xAF0A1B4CU, 0x7FC507A0U, 0xD6A966EFU, 0x3063568FU, 0x7D37FDE7U, 0x3E134026U, 0xD23396BDU, 0xB502FCA7U,
|
||||
0x36034AF6U, 0x54E85463U, 0xD4EFD8B6U, 0x22D6F961U, 0x3A978737U, 0xB8873288U, 0xE3DB8C20U, 0x3B8DFB44U,
|
||||
0x41047A60U, 0x4DF36522U, 0xD52DB281U, 0x9A6A9E04U, 0x07F7AE87U, 0x73DBE12DU, 0x45AC8794U, 0xF727FBDAU,
|
||||
0xDF60EFC3U, 0x02B2F3E5U, 0xD062A404U, 0x07BDA6BDU, 0xB5D77297U, 0x6EDED195U, 0x800BB91AU, 0xFDE2F2C3U,
|
||||
0xA867DF55U, 0x1BA9C2A4U, 0xD1A0CE33U, 0xBF01C1D8U, 0x88B75B27U, 0xA5820230U, 0x267CB2AEU, 0x3148F25DU,
|
||||
0x316E8EEFU, 0x30849167U, 0xD3E6706AU, 0xADB46E36U, 0xCF1721F7U, 0x2316709EU, 0x1794A833U, 0xBFC7F5BEU,
|
||||
0x4669BE79U, 0x299FA026U, 0xD2241A5DU, 0x15080953U, 0xF2770847U, 0xE84AA33BU, 0xB1E3A387U, 0x736DF520U,
|
||||
0xCB61B38CU, 0xE4C5AEB8U, 0xC55EFE10U, 0x1D724E9AU, 0x10C70814U, 0x1ACA1375U, 0x20754FA0U, 0xD6F6D6A7U,
|
||||
0xBC66831AU, 0xFDDE9FF9U, 0xC49C9427U, 0xA5CE29FFU, 0x2DA721A4U, 0xD196C0D0U, 0x86024414U, 0x1A5CD639U,
|
||||
0x256FD2A0U, 0xD6F3CC3AU, 0xC6DA2A7EU, 0xB77B8611U, 0x6A075B74U, 0x5702B27EU, 0xB7EA5E89U, 0x94D3D1DAU,
|
||||
0x5268E236U, 0xCFE8FD7BU, 0xC7184049U, 0x0FC7E174U, 0x576772C4U, 0x9C5E61DBU, 0x119D553DU, 0x5879D144U,
|
||||
0xCC0C7795U, 0x80A96BBCU, 0xC25756CCU, 0x9210D9CDU, 0xE547AED4U, 0x815B5163U, 0xD43A6BB3U, 0x52BCD85DU,
|
||||
0xBB0B4703U, 0x99B25AFDU, 0xC3953CFBU, 0x2AACBEA8U, 0xD8278764U, 0x4A0782C6U, 0x724D6007U, 0x9E16D8C3U,
|
||||
0x220216B9U, 0xB29F093EU, 0xC1D382A2U, 0x38191146U, 0x9F87FDB4U, 0xCC93F068U, 0x43A57A9AU, 0x1099DF20U,
|
||||
0x5505262FU, 0xAB84387FU, 0xC011E895U, 0x80A57623U, 0xA2E7D404U, 0x07CF23CDU, 0xE5D2712EU, 0xDC33DFBEU,
|
||||
0xC5BA3BBEU, 0x2C1C24B0U, 0xCB4DAFA8U, 0xD8C66675U, 0x20B743D5U, 0xF6999118U, 0x139A01C7U, 0x0513CD12U,
|
||||
0xB2BD0B28U, 0x350715F1U, 0xCA8FC59FU, 0x607A0110U, 0x1DD76A65U, 0x3DC542BDU, 0xB5ED0A73U, 0xC9B9CD8CU,
|
||||
0x2BB45A92U, 0x1E2A4632U, 0xC8C97BC6U, 0x72CFAEFEU, 0x5A7710B5U, 0xBB513013U, 0x840510EEU, 0x4736CA6FU,
|
||||
0x5CB36A04U, 0x07317773U, 0xC90B11F1U, 0xCA73C99BU, 0x67173905U, 0x700DE3B6U, 0x22721B5AU, 0x8B9CCAF1U,
|
||||
0xC2D7FFA7U, 0x4870E1B4U, 0xCC440774U, 0x57A4F122U, 0xD537E515U, 0x6D08D30EU, 0xE7D525D4U, 0x8159C3E8U,
|
||||
0xB5D0CF31U, 0x516BD0F5U, 0xCD866D43U, 0xEF189647U, 0xE857CCA5U, 0xA65400ABU, 0x41A22E60U, 0x4DF3C376U,
|
||||
0x2CD99E8BU, 0x7A468336U, 0xCFC0D31AU, 0xFDAD39A9U, 0xAFF7B675U, 0x20C07205U, 0x704A34FDU, 0xC37CC495U,
|
||||
0x5BDEAE1DU, 0x635DB277U, 0xCE02B92DU, 0x45115ECCU, 0x92979FC5U, 0xEB9CA1A0U, 0xD63D3F49U, 0x0FD6C40BU,
|
||||
0x9B64C2B0U, 0xCBFAD74EU, 0x91AF9640U, 0x764DEE06U, 0xE915E8DBU, 0x11E81EB4U, 0xCC1D9F8BU, 0x7AA64737U,
|
||||
0xEC63F226U, 0xD2E1E60FU, 0x906DFC77U, 0xCEF18963U, 0xD475C16BU, 0xDAB4CD11U, 0x6A6A943FU, 0xB60C47A9U,
|
||||
0x756AA39CU, 0xF9CCB5CCU, 0x922B422EU, 0xDC44268DU, 0x93D5BBBBU, 0x5C20BFBFU, 0x5B828EA2U, 0x3883404AU,
|
||||
0x026D930AU, 0xE0D7848DU, 0x93E92819U, 0x64F841E8U, 0xAEB5920BU, 0x977C6C1AU, 0xFDF58516U, 0xF42940D4U,
|
||||
0x9C0906A9U, 0xAF96124AU, 0x96A63E9CU, 0xF92F7951U, 0x1C954E1BU, 0x8A795CA2U, 0x3852BB98U, 0xFEEC49CDU,
|
||||
0xEB0E363FU, 0xB68D230BU, 0x976454ABU, 0x41931E34U, 0x21F567ABU, 0x41258F07U, 0x9E25B02CU, 0x32464953U,
|
||||
0x72076785U, 0x9DA070C8U, 0x9522EAF2U, 0x5326B1DAU, 0x66551D7BU, 0xC7B1FDA9U, 0xAFCDAAB1U, 0xBCC94EB0U,
|
||||
0x05005713U, 0x84BB4189U, 0x94E080C5U, 0xEB9AD6BFU, 0x5B3534CBU, 0x0CED2E0CU, 0x09BAA105U, 0x70634E2EU,
|
||||
0x95BF4A82U, 0x03235D46U, 0x9FBCC7F8U, 0xB3F9C6E9U, 0xD965A31AU, 0xFDBB9CD9U, 0xFFF2D1ECU, 0xA9435C82U,
|
||||
0xE2B87A14U, 0x1A386C07U, 0x9E7EADCFU, 0x0B45A18CU, 0xE4058AAAU, 0x36E74F7CU, 0x5985DA58U, 0x65E95C1CU,
|
||||
0x7BB12BAEU, 0x31153FC4U, 0x9C381396U, 0x19F00E62U, 0xA3A5F07AU, 0xB0733DD2U, 0x686DC0C5U, 0xEB665BFFU,
|
||||
0x0CB61B38U, 0x280E0E85U, 0x9DFA79A1U, 0xA14C6907U, 0x9EC5D9CAU, 0x7B2FEE77U, 0xCE1ACB71U, 0x27CC5B61U,
|
||||
0x92D28E9BU, 0x674F9842U, 0x98B56F24U, 0x3C9B51BEU, 0x2CE505DAU, 0x662ADECFU, 0x0BBDF5FFU, 0x2D095278U,
|
||||
0xE5D5BE0DU, 0x7E54A903U, 0x99770513U, 0x842736DBU, 0x11852C6AU, 0xAD760D6AU, 0xADCAFE4BU, 0xE1A352E6U,
|
||||
0x7CDCEFB7U, 0x5579FAC0U, 0x9B31BB4AU, 0x96929935U, 0x562556BAU, 0x2BE27FC4U, 0x9C22E4D6U, 0x6F2C5505U,
|
||||
0x0BDBDF21U, 0x4C62CB81U, 0x9AF3D17DU, 0x2E2EFE50U, 0x6B457F0AU, 0xE0BEAC61U, 0x3A55EF62U, 0xA386559BU,
|
||||
0x86D3D2D4U, 0x8138C51FU, 0x8D893530U, 0x2654B999U, 0x89F57F59U, 0x123E1C2FU, 0xABC30345U, 0x061D761CU,
|
||||
0xF1D4E242U, 0x9823F45EU, 0x8C4B5F07U, 0x9EE8DEFCU, 0xB49556E9U, 0xD962CF8AU, 0x0DB408F1U, 0xCAB77682U,
|
||||
0x68DDB3F8U, 0xB30EA79DU, 0x8E0DE15EU, 0x8C5D7112U, 0xF3352C39U, 0x5FF6BD24U, 0x3C5C126CU, 0x44387161U,
|
||||
0x1FDA836EU, 0xAA1596DCU, 0x8FCF8B69U, 0x34E11677U, 0xCE550589U, 0x94AA6E81U, 0x9A2B19D8U, 0x889271FFU,
|
||||
0x81BE16CDU, 0xE554001BU, 0x8A809DECU, 0xA9362ECEU, 0x7C75D999U, 0x89AF5E39U, 0x5F8C2756U, 0x825778E6U,
|
||||
0xF6B9265BU, 0xFC4F315AU, 0x8B42F7DBU, 0x118A49ABU, 0x4115F029U, 0x42F38D9CU, 0xF9FB2CE2U, 0x4EFD7878U,
|
||||
0x6FB077E1U, 0xD7626299U, 0x89044982U, 0x033FE645U, 0x06B58AF9U, 0xC467FF32U, 0xC813367FU, 0xC0727F9BU,
|
||||
0x18B74777U, 0xCE7953D8U, 0x88C623B5U, 0xBB838120U, 0x3BD5A349U, 0x0F3B2C97U, 0x6E643DCBU, 0x0CD87F05U,
|
||||
0x88085AE6U, 0x49E14F17U, 0x839A6488U, 0xE3E09176U, 0xB9853498U, 0xFE6D9E42U, 0x982C4D22U, 0xD5F86DA9U,
|
||||
0xFF0F6A70U, 0x50FA7E56U, 0x82580EBFU, 0x5B5CF613U, 0x84E51D28U, 0x35314DE7U, 0x3E5B4696U, 0x19526D37U,
|
||||
0x66063BCAU, 0x7BD72D95U, 0x801EB0E6U, 0x49E959FDU, 0xC34567F8U, 0xB3A53F49U, 0x0FB35C0BU, 0x97DD6AD4U,
|
||||
0x11010B5CU, 0x62CC1CD4U, 0x81DCDAD1U, 0xF1553E98U, 0xFE254E48U, 0x78F9ECECU, 0xA9C457BFU, 0x5B776A4AU,
|
||||
0x8F659EFFU, 0x2D8D8A13U, 0x8493CC54U, 0x6C820621U, 0x4C059258U, 0x65FCDC54U, 0x6C636931U, 0x51B26353U,
|
||||
0xF862AE69U, 0x3496BB52U, 0x8551A663U, 0xD43E6144U, 0x7165BBE8U, 0xAEA00FF1U, 0xCA146285U, 0x9D1863CDU,
|
||||
0x616BFFD3U, 0x1FBBE891U, 0x8717183AU, 0xC68BCEAAU, 0x36C5C138U, 0x28347D5FU, 0xFBFC7818U, 0x1397642EU,
|
||||
0x166CCF45U, 0x06A0D9D0U, 0x86D5720DU, 0x7E37A9CFU, 0x0BA5E888U, 0xE368AEFAU, 0x5D8B73ACU, 0xDF3D64B0U,
|
||||
0xA00AE278U, 0x5E7EF3ECU, 0xA9E2D0A0U, 0xD67F4138U, 0x28D4C7DFU, 0x16441B82U, 0x03A0A617U, 0x83D02561U,
|
||||
0xD70DD2EEU, 0x4765C2ADU, 0xA820BA97U, 0x6EC3265DU, 0x15B4EE6FU, 0xDD18C827U, 0xA5D7ADA3U, 0x4F7A25FFU,
|
||||
0x4E048354U, 0x6C48916EU, 0xAA6604CEU, 0x7C7689B3U, 0x521494BFU, 0x5B8CBA89U, 0x943FB73EU, 0xC1F5221CU,
|
||||
0x3903B3C2U, 0x7553A02FU, 0xABA46EF9U, 0xC4CAEED6U, 0x6F74BD0FU, 0x90D0692CU, 0x3248BC8AU, 0x0D5F2282U,
|
||||
0xA7672661U, 0x3A1236E8U, 0xAEEB787CU, 0x591DD66FU, 0xDD54611FU, 0x8DD55994U, 0xF7EF8204U, 0x079A2B9BU,
|
||||
0xD06016F7U, 0x230907A9U, 0xAF29124BU, 0xE1A1B10AU, 0xE03448AFU, 0x46898A31U, 0x519889B0U, 0xCB302B05U,
|
||||
0x4969474DU, 0x0824546AU, 0xAD6FAC12U, 0xF3141EE4U, 0xA794327FU, 0xC01DF89FU, 0x6070932DU, 0x45BF2CE6U,
|
||||
0x3E6E77DBU, 0x113F652BU, 0xACADC625U, 0x4BA87981U, 0x9AF41BCFU, 0x0B412B3AU, 0xC6079899U, 0x89152C78U,
|
||||
0xAED16A4AU, 0x96A779E4U, 0xA7F18118U, 0x13CB69D7U, 0x18A48C1EU, 0xFA1799EFU, 0x304FE870U, 0x50353ED4U,
|
||||
0xD9D65ADCU, 0x8FBC48A5U, 0xA633EB2FU, 0xAB770EB2U, 0x25C4A5AEU, 0x314B4A4AU, 0x9638E3C4U, 0x9C9F3E4AU,
|
||||
0x40DF0B66U, 0xA4911B66U, 0xA4755576U, 0xB9C2A15CU, 0x6264DF7EU, 0xB7DF38E4U, 0xA7D0F959U, 0x121039A9U,
|
||||
0x37D83BF0U, 0xBD8A2A27U, 0xA5B73F41U, 0x017EC639U, 0x5F04F6CEU, 0x7C83EB41U, 0x01A7F2EDU, 0xDEBA3937U,
|
||||
0xA9BCAE53U, 0xF2CBBCE0U, 0xA0F829C4U, 0x9CA9FE80U, 0xED242ADEU, 0x6186DBF9U, 0xC400CC63U, 0xD47F302EU,
|
||||
0xDEBB9EC5U, 0xEBD08DA1U, 0xA13A43F3U, 0x241599E5U, 0xD044036EU, 0xAADA085CU, 0x6277C7D7U, 0x18D530B0U,
|
||||
0x47B2CF7FU, 0xC0FDDE62U, 0xA37CFDAAU, 0x36A0360BU, 0x97E479BEU, 0x2C4E7AF2U, 0x539FDD4AU, 0x965A3753U,
|
||||
0x30B5FFE9U, 0xD9E6EF23U, 0xA2BE979DU, 0x8E1C516EU, 0xAA84500EU, 0xE712A957U, 0xF5E8D6FEU, 0x5AF037CDU,
|
||||
0xBDBDF21CU, 0x14BCE1BDU, 0xB5C473D0U, 0x866616A7U, 0x4834505DU, 0x15921919U, 0x647E3AD9U, 0xFF6B144AU,
|
||||
0xCABAC28AU, 0x0DA7D0FCU, 0xB40619E7U, 0x3EDA71C2U, 0x755479EDU, 0xDECECABCU, 0xC209316DU, 0x33C114D4U,
|
||||
0x53B39330U, 0x268A833FU, 0xB640A7BEU, 0x2C6FDE2CU, 0x32F4033DU, 0x585AB812U, 0xF3E12BF0U, 0xBD4E1337U,
|
||||
0x24B4A3A6U, 0x3F91B27EU, 0xB782CD89U, 0x94D3B949U, 0x0F942A8DU, 0x93066BB7U, 0x55962044U, 0x71E413A9U,
|
||||
0xBAD03605U, 0x70D024B9U, 0xB2CDDB0CU, 0x090481F0U, 0xBDB4F69DU, 0x8E035B0FU, 0x90311ECAU, 0x7B211AB0U,
|
||||
0xCDD70693U, 0x69CB15F8U, 0xB30FB13BU, 0xB1B8E695U, 0x80D4DF2DU, 0x455F88AAU, 0x3646157EU, 0xB78B1A2EU,
|
||||
0x54DE5729U, 0x42E6463BU, 0xB1490F62U, 0xA30D497BU, 0xC774A5FDU, 0xC3CBFA04U, 0x07AE0FE3U, 0x39041DCDU,
|
||||
0x23D967BFU, 0x5BFD777AU, 0xB08B6555U, 0x1BB12E1EU, 0xFA148C4DU, 0x089729A1U, 0xA1D90457U, 0xF5AE1D53U,
|
||||
0xB3667A2EU, 0xDC656BB5U, 0xBBD72268U, 0x43D23E48U, 0x78441B9CU, 0xF9C19B74U, 0x579174BEU, 0x2C8E0FFFU,
|
||||
0xC4614AB8U, 0xC57E5AF4U, 0xBA15485FU, 0xFB6E592DU, 0x4524322CU, 0x329D48D1U, 0xF1E67F0AU, 0xE0240F61U,
|
||||
0x5D681B02U, 0xEE530937U, 0xB853F606U, 0xE9DBF6C3U, 0x028448FCU, 0xB4093A7FU, 0xC00E6597U, 0x6EAB0882U,
|
||||
0x2A6F2B94U, 0xF7483876U, 0xB9919C31U, 0x516791A6U, 0x3FE4614CU, 0x7F55E9DAU, 0x66796E23U, 0xA201081CU,
|
||||
0xB40BBE37U, 0xB809AEB1U, 0xBCDE8AB4U, 0xCCB0A91FU, 0x8DC4BD5CU, 0x6250D962U, 0xA3DE50ADU, 0xA8C40105U,
|
||||
0xC30C8EA1U, 0xA1129FF0U, 0xBD1CE083U, 0x740CCE7AU, 0xB0A494ECU, 0xA90C0AC7U, 0x05A95B19U, 0x646E019BU,
|
||||
0x5A05DF1BU, 0x8A3FCC33U, 0xBF5A5EDAU, 0x66B96194U, 0xF704EE3CU, 0x2F987869U, 0x34414184U, 0xEAE10678U,
|
||||
0x2D02EF8DU, 0x9324FD72U, 0xBE9834EDU, 0xDE0506F1U, 0xCA64C78CU, 0xE4C4ABCCU, 0x92364A30U, 0x264B06E6U,
|
||||
};
|
||||
|
||||
uint32_t ulCrc32;
|
||||
|
||||
if(pBuffer == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
ulCrc32 = SUSPICIOUS_CRC_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);
|
||||
uint32_t ulIdx = 0U;
|
||||
const uint32_t *pulXorCrc0 = &aulCrc32Table[7U];
|
||||
const uint32_t *pulXorCrc1 = &aulCrc32Table[6U];
|
||||
const uint32_t *pulXorCrc2 = &aulCrc32Table[5U];
|
||||
const uint32_t *pulXorCrc3 = &aulCrc32Table[4U];
|
||||
const uint32_t *pulXorData4 = &aulCrc32Table[3U];
|
||||
const uint32_t *pulXorData5 = &aulCrc32Table[2U];
|
||||
const uint32_t *pulXorData6 = &aulCrc32Table[1U];
|
||||
const uint32_t *pulXorData7 = &aulCrc32Table[0U];
|
||||
uint32_t ulSliceLen;
|
||||
|
||||
ulCrc32 = ~ulInitCrc32;
|
||||
|
||||
/* Aligned memory access is used below. To avoid suboptimal
|
||||
performance and faults (depending on platform), handle the
|
||||
unaligned initial bytes (if any) using the Sarwate algorithm.
|
||||
*/
|
||||
while((ulIdx < ulLength) && !IS_ALIGNED_PTR(&pbBuffer[ulIdx]))
|
||||
{
|
||||
ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U];
|
||||
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* Round down the length to the nearest multiple of eight.
|
||||
*/
|
||||
ulSliceLen = (((ulLength - ulIdx) >> 3U) << 3U) + ulIdx;
|
||||
|
||||
/* Compute the CRC in eight byte "slices". Takes advantage of
|
||||
modern processors which can load in parallel from multiple
|
||||
memory locations.
|
||||
*/
|
||||
while(ulIdx < ulSliceLen)
|
||||
{
|
||||
#if REDCONF_ENDIAN_BIG == 1
|
||||
ulCrc32 ^= pbBuffer[ulIdx] | ((uint32_t)pbBuffer[ulIdx+1U] << 8U) |
|
||||
((uint32_t)pbBuffer[ulIdx+2U] << 16U) | ((uint32_t)pbBuffer[ulIdx+3U] << 24U);
|
||||
#else
|
||||
ulCrc32 ^= *CAST_CONST_UINT32_PTR(&pbBuffer[ulIdx]);
|
||||
#endif
|
||||
|
||||
ulCrc32 =
|
||||
pulXorCrc3[((ulCrc32 >> 24U) & 0xFFU) << 3U] ^
|
||||
pulXorCrc2[((ulCrc32 >> 16U) & 0xFFU) << 3U] ^
|
||||
pulXorCrc1[((ulCrc32 >> 8U) & 0xFFU) << 3U] ^
|
||||
pulXorCrc0[ (ulCrc32 & 0xFFU) << 3U] ^
|
||||
pulXorData7[pbBuffer[ulIdx+7U] << 3U] ^
|
||||
pulXorData6[pbBuffer[ulIdx+6U] << 3U] ^
|
||||
pulXorData5[pbBuffer[ulIdx+5U] << 3U] ^
|
||||
pulXorData4[pbBuffer[ulIdx+4U] << 3U];
|
||||
|
||||
ulIdx += 8U;
|
||||
}
|
||||
|
||||
/* Compute the remaining bytes with the Sarwate algorithm.
|
||||
*/
|
||||
while(ulIdx < ulLength)
|
||||
{
|
||||
ulCrc32 = (ulCrc32 >> 8U) ^ aulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U];
|
||||
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
ulCrc32 = ~ulCrc32;
|
||||
}
|
||||
|
||||
return ulCrc32;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error "REDCONF_CRC_ALGORITHM must be set to CRC_BITWISE, CRC_SARWATE, or CRC_SLICEBY8"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Compute a CRC32 for a metadata node buffer.
|
||||
|
||||
@param pBuffer The metadata node buffer for which to compute a CRC. Must
|
||||
be a block sized buffer.
|
||||
|
||||
@return The CRC of the buffer.
|
||||
*/
|
||||
uint32_t RedCrcNode(
|
||||
const void *pBuffer)
|
||||
{
|
||||
uint32_t ulCrc;
|
||||
|
||||
if(pBuffer == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
ulCrc = SUSPICIOUS_CRC_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer);
|
||||
|
||||
/* The first eight bytes of a metadata node contain the signature and
|
||||
the CRC. There is little value in CRCing the signature, and the
|
||||
CRC cannot be CRC'd, so skip over that part of the buffer.
|
||||
*/
|
||||
ulCrc = RedCrc32Update(0U, &pbBuffer[8U], REDCONF_BLOCK_SIZE - 8U);
|
||||
}
|
||||
|
||||
return ulCrc;
|
||||
}
|
||||
|
82
FreeRTOS-Plus/Source/Reliance-Edge/util/endian.c
Normal file
82
FreeRTOS-Plus/Source/Reliance-Edge/util/endian.c
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements utilities for performing endian swaps.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
#ifdef REDCONF_ENDIAN_SWAP
|
||||
|
||||
/** @brief Reverse the byte order of a 64-bit number.
|
||||
|
||||
@param ullToRev Number whose bytes will be reversed
|
||||
|
||||
@retval @p ullToRev with its bytes reversed.
|
||||
*/
|
||||
uint64_t RedRev64(
|
||||
uint64_t ullToRev)
|
||||
{
|
||||
uint64_t ullRet = ullToRev;
|
||||
|
||||
ullRet = ((ullRet & UINT64_SUFFIX(0x00000000FFFFFFFF)) << 32U) | ((ullRet & UINT64_SUFFIX(0xFFFFFFFF00000000)) >> 32U);
|
||||
ullRet = ((ullRet & UINT64_SUFFIX(0x0000FFFF0000FFFF)) << 16U) | ((ullRet & UINT64_SUFFIX(0xFFFF0000FFFF0000)) >> 16U);
|
||||
ullRet = ((ullRet & UINT64_SUFFIX(0x00FF00FF00FF00FF)) << 8U) | ((ullRet & UINT64_SUFFIX(0xFF00FF00FF00FF00)) >> 8U);
|
||||
|
||||
return ullRet;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Reverse the byte order of a 32-bit number.
|
||||
|
||||
@param ulToRev Number whose bytes will be reversed
|
||||
|
||||
@retval @p ulToRev with its bytes reversed.
|
||||
*/
|
||||
uint32_t RedRev32(
|
||||
uint32_t ulToRev)
|
||||
{
|
||||
return ((ulToRev & 0x000000FFU) << 24U)
|
||||
| ((ulToRev & 0x0000FF00U) << 8U)
|
||||
| ((ulToRev & 0x00FF0000U) >> 8U)
|
||||
| ((ulToRev & 0xFF000000U) >> 24U);
|
||||
}
|
||||
|
||||
|
||||
/** @brief Reverse the byte order of a 16-bit number.
|
||||
|
||||
@param uToRev Number whose bytes will be reversed
|
||||
|
||||
@retval @p uToRev with its bytes reversed.
|
||||
*/
|
||||
uint16_t RedRev16(
|
||||
uint16_t uToRev)
|
||||
{
|
||||
return ((uToRev & 0xFF00U) >> 8U)
|
||||
| ((uToRev & 0x00FFU) << 8U);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
301
FreeRTOS-Plus/Source/Reliance-Edge/util/memory.c
Normal file
301
FreeRTOS-Plus/Source/Reliance-Edge/util/memory.c
Normal file
|
@ -0,0 +1,301 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Default implementations of memory manipulation functions.
|
||||
|
||||
These implementations are intended to be small and simple, and thus forego
|
||||
all optimizations. If the C library is available, or if there are better
|
||||
third-party implementations available in the system, those can be used
|
||||
instead by defining the appropriate macros in redconf.h.
|
||||
|
||||
These functions are not intended to be completely 100% ANSI C compatible
|
||||
implementations, but rather are designed to meet the needs of Reliance Edge.
|
||||
The compatibility is close enough that ANSI C compatible implementations
|
||||
can be "dropped in" as replacements without difficulty.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
#ifndef RedMemCpyUnchecked
|
||||
static void RedMemCpyUnchecked(void *pDest, const void *pSrc, uint32_t ulLen);
|
||||
#endif
|
||||
#ifndef RedMemMoveUnchecked
|
||||
static void RedMemMoveUnchecked(void *pDest, const void *pSrc, uint32_t ulLen);
|
||||
#endif
|
||||
#ifndef RedMemSetUnchecked
|
||||
static void RedMemSetUnchecked(void *pDest, uint8_t bVal, uint32_t ulLen);
|
||||
#endif
|
||||
#ifndef RedMemCmpUnchecked
|
||||
static int32_t RedMemCmpUnchecked(const void *pMem1, const void *pMem2, uint32_t ulLen);
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Copy memory from one address to another.
|
||||
|
||||
The source and destination memory buffers should not overlap. If the
|
||||
buffers overlap, use RedMemMove() instead.
|
||||
|
||||
@param pDest The destination buffer.
|
||||
@param pSrc The source buffer.
|
||||
@param ulLen The number of bytes to copy.
|
||||
*/
|
||||
void RedMemCpy(
|
||||
void *pDest,
|
||||
const void *pSrc,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
if((pDest == NULL) || (pSrc == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else
|
||||
{
|
||||
RedMemCpyUnchecked(pDest, pSrc, ulLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedMemCpyUnchecked
|
||||
/** @brief Copy memory from one address to another.
|
||||
|
||||
This function should only be called from RedMemCpy().
|
||||
|
||||
@param pDest The destination buffer.
|
||||
@param pSrc The source buffer.
|
||||
@param ulLen The number of bytes to copy.
|
||||
*/
|
||||
static void RedMemCpyUnchecked(
|
||||
void *pDest,
|
||||
const void *pSrc,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);
|
||||
const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc);
|
||||
uint32_t ulIdx;
|
||||
|
||||
for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)
|
||||
{
|
||||
pbDest[ulIdx] = pbSrc[ulIdx];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Move memory from one address to another.
|
||||
|
||||
Supports overlapping memory regions. If memory regions do not overlap, it
|
||||
is generally better to use RedMemCpy() instead.
|
||||
|
||||
@param pDest The destination buffer.
|
||||
@param pSrc The source buffer.
|
||||
@param ulLen The number of bytes to copy.
|
||||
*/
|
||||
void RedMemMove(
|
||||
void *pDest,
|
||||
const void *pSrc,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
if((pDest == NULL) || (pSrc == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else
|
||||
{
|
||||
RedMemMoveUnchecked(pDest, pSrc, ulLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedMemMoveUnchecked
|
||||
/** @brief Move memory from one address to another.
|
||||
|
||||
This function should only be called from RedMemMove().
|
||||
|
||||
@param pDest The destination buffer.
|
||||
@param pSrc The source buffer.
|
||||
@param ulLen The number of bytes to copy.
|
||||
*/
|
||||
static void RedMemMoveUnchecked(
|
||||
void *pDest,
|
||||
const void *pSrc,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);
|
||||
const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc);
|
||||
uint32_t ulIdx;
|
||||
|
||||
if(MEMMOVE_MUST_COPY_FORWARD(pbDest, pbSrc))
|
||||
{
|
||||
/* If the destination is lower than the source with overlapping memory
|
||||
regions, we must copy from start to end in order to copy the memory
|
||||
correctly.
|
||||
|
||||
Don't use RedMemCpy() to do this. It is possible that RedMemCpy()
|
||||
has been replaced (even though this function has not been replaced)
|
||||
with an implementation that cannot handle any kind of buffer
|
||||
overlap.
|
||||
*/
|
||||
for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)
|
||||
{
|
||||
pbDest[ulIdx] = pbSrc[ulIdx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ulIdx = ulLen;
|
||||
|
||||
while(ulIdx > 0U)
|
||||
{
|
||||
ulIdx--;
|
||||
pbDest[ulIdx] = pbSrc[ulIdx];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* RedMemMoveUnchecked */
|
||||
|
||||
|
||||
/** @brief Initialize a buffer with the specified byte value.
|
||||
|
||||
@param pDest The buffer to initialize.
|
||||
@param bVal The byte value with which to initialize @p pDest.
|
||||
@param ulLen The number of bytes to initialize.
|
||||
*/
|
||||
void RedMemSet(
|
||||
void *pDest,
|
||||
uint8_t bVal,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
if(pDest == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else
|
||||
{
|
||||
RedMemSetUnchecked(pDest, bVal, ulLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedMemSetUnchecked
|
||||
/** @brief Initialize a buffer with the specified byte value.
|
||||
|
||||
This function should only be called from RedMemSet().
|
||||
|
||||
@param pDest The buffer to initialize.
|
||||
@param bVal The byte value with which to initialize @p pDest.
|
||||
@param ulLen The number of bytes to initialize.
|
||||
*/
|
||||
static void RedMemSetUnchecked(
|
||||
void *pDest,
|
||||
uint8_t bVal,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest);
|
||||
uint32_t ulIdx;
|
||||
|
||||
for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)
|
||||
{
|
||||
pbDest[ulIdx] = bVal;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Compare the contents of two buffers.
|
||||
|
||||
@param pMem1 The first buffer to compare.
|
||||
@param pMem2 The second buffer to compare.
|
||||
@param ulLen The length to compare.
|
||||
|
||||
@return Zero if the two buffers are the same, otherwise nonzero.
|
||||
|
||||
@retval 0 @p pMem1 and @p pMem2 are the same.
|
||||
@retval 1 @p pMem1 is greater than @p pMem2, as determined by the
|
||||
values of the first differing bytes.
|
||||
@retval -1 @p pMem2 is greater than @p pMem1, as determined by the
|
||||
values of the first differing bytes.
|
||||
*/
|
||||
int32_t RedMemCmp(
|
||||
const void *pMem1,
|
||||
const void *pMem2,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
int32_t lResult;
|
||||
|
||||
if((pMem1 == NULL) || (pMem2 == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
lResult = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lResult = RedMemCmpUnchecked(pMem1, pMem2, ulLen);
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedMemCmpUnchecked
|
||||
/** @brief Compare the contents of two buffers.
|
||||
|
||||
@param pMem1 The first buffer to compare.
|
||||
@param pMem2 The second buffer to compare.
|
||||
@param ulLen The length to compare.
|
||||
|
||||
@return Zero if the two buffers are the same, otherwise nonzero.
|
||||
*/
|
||||
static int32_t RedMemCmpUnchecked(
|
||||
const void *pMem1,
|
||||
const void *pMem2,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
const uint8_t *pbMem1 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem1);
|
||||
const uint8_t *pbMem2 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem2);
|
||||
uint32_t ulIdx = 0U;
|
||||
int32_t lResult;
|
||||
|
||||
while((ulIdx < ulLen) && (pbMem1[ulIdx] == pbMem2[ulIdx]))
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
if(ulIdx == ulLen)
|
||||
{
|
||||
lResult = 0;
|
||||
}
|
||||
else if(pbMem1[ulIdx] > pbMem2[ulIdx])
|
||||
{
|
||||
lResult = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lResult = -1;
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
#endif
|
||||
|
61
FreeRTOS-Plus/Source/Reliance-Edge/util/namelen.c
Normal file
61
FreeRTOS-Plus/Source/Reliance-Edge/util/namelen.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements a utility to find the length of a name.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
#if REDCONF_API_POSIX == 1
|
||||
|
||||
|
||||
/** @brief Determine the length of a name, terminated either by a null or a path
|
||||
separator character.
|
||||
|
||||
@param pszName The name whose length is to be determined.
|
||||
|
||||
@return The length of the name.
|
||||
*/
|
||||
uint32_t RedNameLen(
|
||||
const char *pszName)
|
||||
{
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
if(pszName == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else
|
||||
{
|
||||
while((pszName[ulIdx] != '\0') && (pszName[ulIdx] != REDCONF_PATH_SEPARATOR))
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
return ulIdx;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
63
FreeRTOS-Plus/Source/Reliance-Edge/util/sign.c
Normal file
63
FreeRTOS-Plus/Source/Reliance-Edge/util/sign.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Implements a sign on message.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
/** @brief Display the Reliance Edge signon message.
|
||||
*/
|
||||
void RedSignOn(void)
|
||||
{
|
||||
#if REDCONF_OUTPUT == 1
|
||||
|
||||
/* Use RedOsOutputString() instead of RedPrintf() to avoid using variadic
|
||||
arguments, since this function is called from the driver and cannot use
|
||||
functions that violate MISRA-C:2012.
|
||||
*/
|
||||
RedOsOutputString(RED_PRODUCT_NAME "\n");
|
||||
RedOsOutputString(RED_PRODUCT_EDITION "\n");
|
||||
RedOsOutputString(RED_PRODUCT_LEGAL "\n");
|
||||
RedOsOutputString(RED_PRODUCT_PATENT "\n");
|
||||
|
||||
#else
|
||||
|
||||
/* Always embed the copyright into the program data. Use "volatile" to try
|
||||
to avoid the compiler removing the variables.
|
||||
*/
|
||||
static volatile const char szVersion[] = RED_PRODUCT_NAME;
|
||||
static volatile const char szEdition[] = RED_PRODUCT_EDITION;
|
||||
static volatile const char szCopyright[] = RED_PRODUCT_LEGAL;
|
||||
static volatile const char szPatent[] = RED_PRODUCT_PATENT;
|
||||
|
||||
(void)szVersion;
|
||||
(void)szEdition;
|
||||
(void)szCopyright;
|
||||
(void)szPatent;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
329
FreeRTOS-Plus/Source/Reliance-Edge/util/string.c
Normal file
329
FreeRTOS-Plus/Source/Reliance-Edge/util/string.c
Normal file
|
@ -0,0 +1,329 @@
|
|||
/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
|
||||
|
||||
Copyright (c) 2014-2015 Datalight, Inc.
|
||||
All Rights Reserved Worldwide.
|
||||
|
||||
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; use version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but "AS-IS," 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.
|
||||
*/
|
||||
/* Businesses and individuals that for commercial or other reasons cannot
|
||||
comply with the terms of the GPLv2 license may obtain a commercial license
|
||||
before incorporating Reliance Edge into proprietary software for
|
||||
distribution in any form. Visit http://www.datalight.com/reliance-edge for
|
||||
more information.
|
||||
*/
|
||||
/** @file
|
||||
@brief Default implementations of string manipulation functions.
|
||||
|
||||
These implementations are intended to be small and simple, and thus forego
|
||||
all optimizations. If the C library is available, or if there are better
|
||||
third-party implementations available in the system, those can be used
|
||||
instead by defining the appropriate macros in redconf.h.
|
||||
|
||||
These functions are not intended to be completely 100% ANSI C compatible
|
||||
implementations, but rather are designed to meet the needs of Reliance Edge.
|
||||
The compatibility is close enough that ANSI C compatible implementations
|
||||
can be "dropped in" as replacements without difficulty.
|
||||
*/
|
||||
#include <redfs.h>
|
||||
|
||||
|
||||
#ifndef RedStrLenUnchecked
|
||||
static uint32_t RedStrLenUnchecked(const char *pszStr);
|
||||
#endif
|
||||
#ifndef RedStrCmpUnchecked
|
||||
static int32_t RedStrCmpUnchecked(const char *pszStr1, const char *pszStr2);
|
||||
#endif
|
||||
#ifndef RedStrNCmpUnchecked
|
||||
static int32_t RedStrNCmpUnchecked(const char *pszStr1, const char *pszStr2, uint32_t ulLen);
|
||||
#endif
|
||||
#ifndef RedStrNCpyUnchecked
|
||||
static void RedStrNCpyUnchecked(char *pszDst, const char *pszSrc, uint32_t ulLen);
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Determine the length (in bytes) of a null terminated string.
|
||||
|
||||
The length does not include the null terminator byte.
|
||||
|
||||
@param pszStr The null terminated string whose length is to be determined.
|
||||
|
||||
@return The length of the @p pszStr string.
|
||||
*/
|
||||
uint32_t RedStrLen(
|
||||
const char *pszStr)
|
||||
{
|
||||
uint32_t ulLen;
|
||||
|
||||
if(pszStr == NULL)
|
||||
{
|
||||
REDERROR();
|
||||
ulLen = 0U;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Cast the result to uint32_t, since RedStrLenUnchecked() might be
|
||||
strlen(), which returns size_t, which is possibly a 64-bit value.
|
||||
*/
|
||||
ulLen = (uint32_t)RedStrLenUnchecked(pszStr);
|
||||
}
|
||||
|
||||
return ulLen;
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedStrLenUnchecked
|
||||
/** @brief Determine the length (in bytes) of a null terminated string.
|
||||
|
||||
@param pszStr The null terminated string whose length is to be determined.
|
||||
|
||||
@return The length of the @p pszStr string.
|
||||
*/
|
||||
static uint32_t RedStrLenUnchecked(
|
||||
const char *pszStr)
|
||||
{
|
||||
uint32_t ulLen = 0U;
|
||||
|
||||
while(pszStr[ulLen] != '\0')
|
||||
{
|
||||
ulLen++;
|
||||
}
|
||||
|
||||
return ulLen;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Compare two null terminated strings.
|
||||
|
||||
@param pszStr1 The first string to compare.
|
||||
@param pszStr2 The second string to compare.
|
||||
|
||||
@return Zero if the two strings are the same, otherwise nonzero.
|
||||
|
||||
@retval 0 @p pszStr1 and @p pszStr2 are the same.
|
||||
@retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the
|
||||
values of the first differing bytes.
|
||||
@retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the
|
||||
values of the first differing bytes.
|
||||
*/
|
||||
int32_t RedStrCmp(
|
||||
const char *pszStr1,
|
||||
const char *pszStr2)
|
||||
{
|
||||
int32_t lResult;
|
||||
|
||||
if((pszStr1 == NULL) || (pszStr2 == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
lResult = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lResult = RedStrCmpUnchecked(pszStr1, pszStr2);
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedStrCmpUnchecked
|
||||
/** @brief Compare two null terminated strings.
|
||||
|
||||
@param pszStr1 The first string to compare.
|
||||
@param pszStr2 The second string to compare.
|
||||
|
||||
@return Zero if the two strings are the same, otherwise nonzero.
|
||||
*/
|
||||
static int32_t RedStrCmpUnchecked(
|
||||
const char *pszStr1,
|
||||
const char *pszStr2)
|
||||
{
|
||||
int32_t lResult;
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
while((pszStr1[ulIdx] == pszStr2[ulIdx]) && (pszStr1[ulIdx] != '\0'))
|
||||
{
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
/* "The sign of a non-zero return value is determined by the sign of the
|
||||
difference between the values of the first pair of bytes (both
|
||||
interpreted as type unsigned char) that differ in the strings being
|
||||
compared." Use uint8_t instead of unsigned char to avoid MISRA C
|
||||
deviations.
|
||||
*/
|
||||
if((uint8_t)pszStr1[ulIdx] > (uint8_t)pszStr2[ulIdx])
|
||||
{
|
||||
lResult = 1;
|
||||
}
|
||||
else if((uint8_t)pszStr1[ulIdx] < (uint8_t)pszStr2[ulIdx])
|
||||
{
|
||||
lResult = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lResult = 0;
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Compare the first @p ulLen characters of two null terminated strings.
|
||||
|
||||
@param pszStr1 The first string to compare.
|
||||
@param pszStr2 The second string to compare.
|
||||
@param ulLen The maximum length to compare. The comparison stops when
|
||||
either of the strings end or when @p ulLen bytes have been
|
||||
compared.
|
||||
|
||||
@return Zero if the two strings are the same, otherwise nonzero.
|
||||
|
||||
@retval 0 @p pszStr1 and @p pszStr2 are the same.
|
||||
@retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the
|
||||
values of the first differing bytes.
|
||||
@retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the
|
||||
values of the first differing bytes.
|
||||
*/
|
||||
int32_t RedStrNCmp(
|
||||
const char *pszStr1,
|
||||
const char *pszStr2,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
int32_t lResult;
|
||||
|
||||
if((pszStr1 == NULL) || (pszStr2 == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
lResult = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lResult = RedStrNCmpUnchecked(pszStr1, pszStr2, ulLen);
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedStrNCmpUnchecked
|
||||
/** @brief Compare the first @p ulLen characters of two null terminated strings.
|
||||
|
||||
@param pszStr1 The first string to compare.
|
||||
@param pszStr2 The second string to compare.
|
||||
@param ulLen The maximum length to compare. The comparison stops when
|
||||
either of the strings end or when @p ulLen bytes have been
|
||||
compared.
|
||||
|
||||
@return Zero if the two strings are the same, otherwise nonzero.
|
||||
*/
|
||||
static int32_t RedStrNCmpUnchecked(
|
||||
const char *pszStr1,
|
||||
const char *pszStr2,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
int32_t lResult = 0;
|
||||
uint32_t ulIdx;
|
||||
|
||||
for(ulIdx = 0U; ulIdx < ulLen; ulIdx++)
|
||||
{
|
||||
if(pszStr1[ulIdx] != pszStr2[ulIdx])
|
||||
{
|
||||
/* "The sign of a non-zero return value is determined by the sign
|
||||
of the difference between the values of the first pair of bytes
|
||||
(both interpreted as type unsigned char) that differ in the
|
||||
strings being compared." Use uint8_t instead of unsigned char
|
||||
to avoid MISRA C deviations.
|
||||
*/
|
||||
if((uint8_t)pszStr1[ulIdx] > (uint8_t)pszStr2[ulIdx])
|
||||
{
|
||||
lResult = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lResult = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if((lResult != 0) || (pszStr1[ulIdx] == '\0'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return lResult;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** @brief Copy a string.
|
||||
|
||||
Copy up to @p ulLen bytes of a null-terminated string (@p pszSrc) to a
|
||||
destination buffer (@p pszDst). The result will not be null-terminated if
|
||||
@p pszSrc is longer than @p ulLen - 1 bytes.
|
||||
|
||||
If @p pszSrc is shorter than @p ulLen - 1 bytes, the remainder of @p pszDst
|
||||
will be filled with null bytes.
|
||||
|
||||
@param pszDst The destination buffer, which is at least @p ulLen bytes
|
||||
in size.
|
||||
@param pszSrc The null-terminated string to copy.
|
||||
@param ulLen The maximum number of characters to copy.
|
||||
*/
|
||||
void RedStrNCpy(
|
||||
char *pszDst,
|
||||
const char *pszSrc,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
if((pszDst == NULL) || (pszSrc == NULL))
|
||||
{
|
||||
REDERROR();
|
||||
}
|
||||
else
|
||||
{
|
||||
RedStrNCpyUnchecked(pszDst, pszSrc, ulLen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef RedStrNCpyUnchecked
|
||||
/** @brief Copy a string.
|
||||
|
||||
@param pszDst The destination buffer, which is at least @p ulLen bytes
|
||||
in size.
|
||||
@param pszSrc The null-terminated string to copy.
|
||||
@param ulLen The maximum number of characters to copy.
|
||||
*/
|
||||
static void RedStrNCpyUnchecked(
|
||||
char *pszDst,
|
||||
const char *pszSrc,
|
||||
uint32_t ulLen)
|
||||
{
|
||||
uint32_t ulIdx = 0U;
|
||||
|
||||
while((ulIdx < ulLen) && (pszSrc[ulIdx] != '\0'))
|
||||
{
|
||||
pszDst[ulIdx] = pszSrc[ulIdx];
|
||||
ulIdx++;
|
||||
}
|
||||
|
||||
while(ulIdx < ulLen)
|
||||
{
|
||||
pszDst[ulIdx] = '\0';
|
||||
ulIdx++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue