📄 readme.txt
字号:
Writing a file
==============
--Call DFS_OpenFile with mode = DFS_WRITE and supply a path and the relevant
VOLINFO structure. DFS_OpenFile will populate a FILEINFO that can be used to
refer to the file.
--Optionally call DFS_Seek to set the file pointer. Refer to the notes on
this topic in the section on reading files, above.
--Call DFS_WriteFile with the FILEINFO you obtained from OpenFile, and a
pointer to the source buffer, and a pointer to a sector-sized scratch
buffer.
--Note that a file open for writing can also be read.
--Files are created automatically if they do not exist. Subdirectories are
NOT automatically created.
--If you open an existing file for writing, the file pointer will start at
the beginning of the data; if you want to append, seek to the end before
writing new data.
--If you perform random-access writes to a file, the length will NOT change
unless you exceed the file's original length. There is currently no
function to truncate a file at the current pointer position.
--On-disk consistency is guaranteed when DFS_WriteFile exits, unless your
physical layer has a writeback cache in it.
Deleting a file
===============
--Call DFS_UnlinkFile
--WARNING: This call will delete a subdirectory (correctly) but will NOT
first recurse the directory to delete the contents - so you will end up
with lost clusters.
Notes
=====
Some platforms may require explicit pragmas or attributes to the structures
and unions. For example, arm-gcc will require __attribute__ ((__packed__))
otherwise it will try to be "smart" and place the uint8_t members on 4-byte
boundaries. There is no truly elegant compiler-independent method to get
around this sort of problem.
The code assumes either a von Neumann architecture, or a compiler that
is smart enough to understand where your pointers are aimed and emit
the right kind of memory read and write instructions. The implications
of this statement depend on your target processor and the compiler you
are using. Be very careful not to straddle bank boundaries on bank-
switched memory systems.
Physical 32-bit sector numbers are used throughout. Therefore, the
CHS geometry (if any) of the storage media is not known to DOSFS. Your
sector r/w functions may need to query the CHS geometry and perform
mapping.
File timestamps set by DOSFS are always 1:01:00am on Jan 1, 2006. If
your system has a concept of real time, you can enhance this.
FILEINFO structures contain a pointer to the corresponding VOLINFO
used to open the file, mainly in order to avoid mixups but also to
obviate the need for an extra parameter to every file read/write. DOSFS
assumes that the VOLINFO won't move around. If you need to move or
destroy VOLINFOs pertaining to open files, you'll have to fix up the
pointer in the FILEINFO structure yourself.
The subdirectory delimiter is a forward slash ( '/' ) by default. The
reason for this is to avoid the common programming error of forgetting
that backslash is an escape character in C strings; i.e. "\MYDIR\FILE"
is NOT what you want; "\\MYDIR\\FILE" is what you wanted to type. If you
are porting DOS code into an embedded environment, feel free to change
this #define.
DOSFS does not have a concept of "current directory". A current directory
is owned by a process, and a process is an operating system concept.
DOSFS is a filesystem library, not an operating system. Therefore, any
path you provide to a DOSFS call is assumed to be relative to the root of
the volume.
There is no call to close a file or directory that is open for reading or
writing. You can simply destroy or reuse the data structures allocated for
that operation; there is no internal state in DOSFS so no cleanup is
necessary. Similarly, there is no call to close a file that is open for
writing. (Observe that dosfs.c has no global variables. All state information
is stored in data structures provided by the caller).
MAX_PATH is defined as 64. MS-type DOS filesystems support 128 characters
or more in paths. You can increase this define, but it may GREATLY
increase memory requirements.
VFAT long filenames are not supported. There is a certain amount of
patent controversy about them, but more importantly they don't really
belong in the scope of a "minimalist embedded filesystem".
Improving Performance
=====================
Read performance is fairly good, but can be improved by implementing read
caching on the FAT (see below) and, depending on your hardware platform,
possibly by implementing multi-sector reads.
Write performance may benefit ENORMOUSLY from platform-specific
optimization, especially if you are working with a flash media type that
has a large erase block size. While it is not possible to offer detailed
platform-independent advice, my general advice is to implement writeback
caching on the FAT area. One method for doing this would be to have a
cache system that lives in the DFS_ReadSector/WriteSector functions (on
top of the physical sector r/w functions) and is initially switched off.
Once you have called DFS_GetVolInfo, you then extract the VOLINFO.fat1
and VOLINFO.rootdir parameters and pass them to your caching layer.
Sectors >= fat1 and < rootdir should be cached. The cache strategy is
determined by the physical storage medium underlying the filesystem.
CACHING HINT:
Observe that there will be numerous read-modify-write operations in the
region from VOLINFO.fat1 through VOLINFO.fat1+VOLINFO.secperfat-1, but
in the region from VOLINFO.fat1+VOLINFO.secperfat through VOLINFO.rootdir
there will ONLY be write operations.
Platform Compatibility
======================
DOSFS was derived from code originally written for ARM7TDMI but
designed to be portable. It has been tested on AVR (using avrgcc),
MSP430 (using Rowley's CrossWorks) and PPC603e (using gcc); the host
test suite has also been validated on x86 using gcc under both Cygwin
and 32-bit Fedora Core 4 Linux.
TODO list
=========
* Add function to create subdirectory
* Make DFS_UnlinkFile recognize non-empty subdirectories
* Support "fast write" files where the FAT is not updated, for
logging applications where latency is important.
Test cases for V1.02
====================
Version 1.02 has NOT been through full regression testing. However the
bugs fixed in this version are important, and people have been asking
about them.
Test cases for V1.01
====================
See below.
Test cases for V1.00
====================
These are the test cases that were used to validate the correct
functionality of the DOSFS suite. Each test was performed on FAT12,
FAT16 and FAT32 volumes. P=Pass, F=Fail.
Case F12 F16 F32
---------------------------------------------------------------------
Get volume information P P P
Open root directory P P P
List contents of root directory (fully populated) P P P
Open subdirectory P P P
List contents of subdirectory (<= 1 cluster) P P P
List contents of large subdirectory (> 1 cluster) P P P
Open 5-level nested subdirectory P P P
Open existing file for reading P P P
Open nonexistent file for reading P P P
Seek past EOF, file open for reading P P P
Seek to cluster boundary P P P
Seek past cluster boundary P P P
Seek backwards to nonzero offset, pointer > cluster size P P P
Block-read entire file >1 cluster in size, odd size P P P
Seek to odd location in file P P P
Perform <1 sector reads from random file locations P P P
Open nonexistent file for writing in root dir P P P
Open nonexistent file for writing in subdir P P P
Repeat prev. 2 tests on volume with 0 free clusters P P P
Seek past EOF, file open for writing P P P
Open existing file for writing in root dir P P P
Write random-length records to file, 20 clusters total P P P
MS-DOS 6.0 SCANDISK cross-check P P P
Revision History
================
Jan-06-2005 larwe Initial release (1.0)
Jan-29-2006 larwe Bugfix release (1.01)
- Fixed error in FAT12 FAT read on boundary of sector
- Improved compilability under avrgcc
Sep-16-2006 larwe Bugfix release (1.02)
- DFS_Seek would not correctly rewind to start of file
- DFS_Seek would not correctly seek to a position not on a cluster
boundary
- DFS_OpenFile fencepost error caused memory access at [start of
string-1] with a local variable
- DFS_OpenFile could not open a file in the root directory
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -