mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2026-09-26 05:13:51 +08:00
Update version numbers in preparation for new release.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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! ;)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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.
|
||||
@@ -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 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user