diff --git a/documents/doc/appnote.html b/documents/doc/appnote.html index 591a91f..2c96520 100644 --- a/documents/doc/appnote.html +++ b/documents/doc/appnote.html @@ -32,22 +32,28 @@
The FatFs module is assuming following conditions on portability.
+The FatFs module assumes following conditions on portability.
The dependency diagram shown below is a typical but not specific configuration of the embedded system with FatFs module.
+The dependency diagram shown below is a typical, but not specific, configuration of the embedded system with FatFs module.

(a) If a working disk module with FatFs disk interface is provided, nothing else will be needed. (b) To attach existing disk drivers with different interface, glue functions are needed to translate the interfaces between FatFs and the drivers.
+(a) If a working disk module for FatFs is provided, nothing else will be needed. (b) To attach existing disk drivers with different interface, some glue functions are needed to translate the interfaces between FatFs and the driver.

You need to provide only low level disk I/O functions required by FatFs module and nothing else. If a working disk module for the target system is already provided, you need to write only glue functions to attach it to the FatFs module. If not, you need to port another disk I/O module or write it from scratch. Most of defined functions are not that always required. For example, any write function is not required at read-only configuration. Following table shows which function is required depends on the configuration options.
+You need to provide only low level disk I/O functions required by FatFs module and nothing else. If a working disk I/O module for the target system is already provided, you need to write only glue functions to attach it to the FatFs module. If not, you need to port another disk I/O module or write it from scratch. Most of defined functions are not that always required. For instance, any write function is not required at read-only configuration. Following table shows which function is required depends on the configuration options.
| Function | Required when | Note | 
|---|---|---|
| disk_status disk_initialize disk_read | Always | Disk I/O functions. Samples available in ffsample.zip. There are many implementations on the web. | 
| disk_ioctl (GET_SECTOR_COUNT) disk_ioctl (GET_BLOCK_SIZE) | FF_USE_MKFS == 1 | |
| disk_ioctl (GET_SECTOR_SIZE) | FF_MAX_SS != FF_MIN_SS | |
| disk_ioctl (CTRL_TRIM) | FF_USE_TRIM == 1 | |
| ff_uni2oem ff_oem2uni ff_wtoupper | FF_USE_LFN != 0 | Unicode support functions. Just add ffunicode.c to the project. | 
| ff_cre_syncobj ff_del_syncobj ff_req_grant ff_rel_grant | FF_FS_REENTRANT == 1 | O/S dependent functions. Samples available in ffsystem.c. | 
| ff_uni2oem ff_oem2uni ff_wtoupper | FF_USE_LFN != 0 | Unicode support functions. Add optional module ffunicode.c to the project. | 
| ff_cre_syncobj ff_del_syncobj ff_req_grant ff_rel_grant | FF_FS_REENTRANT == 1 | O/S dependent functions. Sample code is available in ffsystem.c. | 
| ff_mem_alloc ff_mem_free | FF_USE_LFN == 3 | 
FatFs cares about neither what kind of storage device is used nor how it is implemented. Only a requirement is that it is a block device read/written in fixed-size blocks that accessible via the disk I/O functions defined above.
These are the memory usage on some target systems with following condition. The memory sizes are in unit of byte, V denotes number of mounted volumes and F denotes number of open files. All samples here are optimezed in code size.
+These are the memory usage of FatFs module without lower layer on some target systems in following condition. V denotes number of mounted volumes and F denotes number of open files. Every samples here are optimezed in code size.
FatFs R0.13a options: FF_FS_READONLY 0 (Read/Write) or 1 (Read only) FF_FS_MINIMIZE 0 (Full, with all basic functions) or 3 (Min, with fully minimized) FF_FS_TINY 0 (Default) or 1 (Tiny file object) -And other options are left unchanged from original setting. +And any other options are left unchanged from original setting.
FatFs module supports long file name (LFN). The two different file names, short file name (SFN) and LFN, of a file is transparent on the API except for f_readdir function. The support for LFN is disabled by default. To enable the LFN, set FF_USE_LFN to 1, 2 or 3, and add ffunicode.c to the project. The LFN requiers a certain working buffer in addition. The buffer size can be configured by FF_MAX_LFN according to the available memory. The length of an LFN will be up to 255 characters, so that the FF_MAX_LFN should be set to 255 for all file names. If the size of working buffer is insufficient for the input file name, the file function fails with FR_INVALID_NAME. When use any re-entry to the API with LFN is enabled, FF_USE_LFN must be set to 2 or 3. In this case, the file function allocates the working buffer on the stack or heap. The working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
| FF_CODE_PAGE | Increment | 
|---|---|
| FF_CODE_PAGE | Code size | 
| 437-869 (SBCS) | +3.3k | 
| 932 (Japanese) | +62k | 
| 936 (Simplified Chinese) | +177k | 
| 950 (Traditional Chinese) | +111k | 
| 0 (All code pages) | +486k | 
When the LFN is enabled, the module size will be increased depends on the configured code page. Right table shows increment of code size by LFN function at different code pages. Especially, in the CJK region, tens of thousands of characters are being used. Unfortunately, it requires a huge OEM-Unicode bidirectional conversion table and the module size will be drastically increased as shown in the table. As the result, the FatFs with LFN enebled with those code pages will not able to be ported on the most 8-bit MCU systems.
-If you can discard ANSI/OEM code API and backward compatibility with non-ASCII SFN, you will able to configure FatFs for Unicode API with any SBCS.
-There ware some restrictions on using LFN for open source project because the support for LFN on the FAT volume was a patent of Microsoft Corporation. The related patents have expired and using the LFN function have got free for any projects.
+When the LFN is enabled, the module size will be increased depends on the configured code page. Right table shows increment of code size by LFN function at different code pages. Especially, in the CJK region, tens of thousands of characters are being used. Unfortunately, it requires a huge OEM-Unicode bidirectional conversion table and the module size will be drastically increased as shown in the table.
+As the result, the FatFs with LFN enebled with DBCS code pages will not able to be ported on the most 8-bit MCU systems. If the target system is in legacy-free, in only Unicode and any ANSI/OEM code is not used at all, the code page setting gets meaningless. You will able to reduce the code size by configureing FatFs for Unicode with any SBCS code page.
+There ware some restrictions on using LFN for open source project because the support for LFN on the FAT volume was a patent of Microsoft Corporation. The related patents have expired and using the LFN function has got free for any projects.
By default, FatFs uses ANSI/OEM code set on the API even at LFN configuration. FatFs can also switch the character encoding on the API to Unicode by configuration option FF_LFN_UNICODE. This means that FatFs supports the full featured LFN specification. The data type TCHAR specifies path name strings on the API is an alias of either char(ANSI/OEM or UTF-8), WCHAR(UTF-16) or DWORD(UTF-32) depends on that option. For more information, refer to the description in the file name.
-Note that code page setting, FF_CODE_PAGE, has actually no meaning for the path names at the Unicode API. However it still affects code conversion of string I/O functions at FF_STRF_ENCODE != 0 and backward compatibility with legacy systems, so that code page needs to be configured properly when it is considered a problem.
+By default, FatFs uses ANSI/OEM code set on the API even at LFN configuration. FatFs can also switch the character encoding on the API to Unicode by configuration option FF_LFN_UNICODE. This means that FatFs is compliant with the full featured LFN specification. The data type TCHAR specifies path name strings on the API is an alias of either char(ANSI/OEM or UTF-8), WCHAR(UTF-16) or DWORD(UTF-32) depends on that option. For more information, refer to the description in the file name.
+Note that setting of code page, FF_CODE_PAGE, has actually no meaning when FatFs is configured for the Unicode API. It should be set 437 anyway. However it still affects code conversion of string I/O functions at FF_STRF_ENCODE == 0 and backward compatibility with legacy systems, so that code page may need to be configured properly if it is considered a problem.
The exFAT (Microsoft's Extended File Allocation Table) filesystem is a succession of the FAT/FAT32 filesystem which has been widely used in embedded systems, consumer devices and portable storage media. It is adopted by SDA (SD Association) as a recommended filesystem for high capacity SD cards larger than 32 GB and they are being shipped with this format, so that the exFAT became one of the standard filesystems for removable media as well as FAT. The exFAT filesystem allows the file size beyond the 4 GB limit what FAT filesystem allows upto and some filesystem overhead, especially cluster allocation delay, are reduced as well. This feature improves the write throughput to the file.
-Note that the exFAT is a patent of Microsoft Corporation. The exFAT function of FatFs is an implementation based on US. Pat. App. Pub. No. 2009/0164440 A1. FatFs module can switch the support for exFAT on/off by configuration option, FF_FS_EXFAT. When enable the exFAT on the commercial products, a license by Microsoft will be needed depends on the final destination of the products.
-Remark: Enabling exFAT discards ANSI C (C89) compatibility because of need for 64-bit integer type.
+The exFAT (Microsoft's Extended File Allocation Table) filesystem is a succession of the FAT/FAT32 filesystem which has been widely used in embedded systems, consumer devices and portable storage media. It is adopted by SDA (SD Association) as the regular filesystem for SDXC card, 64 GB and larger, and they are being shipped with this format. Therefore the exFAT is one of the standard filesystems for removable media as well as FAT. The exFAT filesystem allows the file size beyond the 4 GB limit what FAT filesystem allows upto and some filesystem overhead, especially cluster allocation delay, are reduced as well. These features allow to record the large media file without dividing into some files and improve the write throughput to the file.
+Note that the exFAT is a patent of Microsoft Corporation. The support for exFAT of FatFs is an implementation based on US. Pat. App. Pub. No. 2009/0164440 A1. FatFs module can switch the exFAT on or off by configuration option, FF_FS_EXFAT. When enable the exFAT on the commercial products, a license by Microsoft will be needed depends on the final destination of the products.
+Remark: Enabling exFAT discards C89 compatibility because of need for 64-bit integer type.
These are examples of extended use of FatFs APIs. New item will be added whenever a useful code is found.
This option specifies the OEM code page to be used on the target system. Incorrect setting of the code page can cause a file open failure. If any non-ASCII character is not used at all, there is no difference between any code page settings.
+This option specifies the OEM code page to be used on the target system. Incorrect setting of the code page can cause a file open failure. If any non-ASCII character is not used for the path name, there is no difference between any code page settings. Set it 437 anyway.
| Value | Code page | |
|---|---|---|
| 0 | Include all code pages below and set by f_setcp() | |
| 0 | Includes all code pages below and set by f_setcp() | |
| 437 | U.S. | |
| 720 | Arabic | |
| 737 | Greek | 
| Value | Character Encoding | TCHAR | 
|---|---|---|
| 0 | ANSI/OEM in current CP | char | 
| Encoding | LFN length | SFN length | 
|---|---|---|
| ANSI/OEM at SBCS | 255 items | 12 items | 
| Value | Character encoding on the file | 
|---|---|
| 0 | ANSI/OEM in current code page | 
This option defines the volume ID strings for each logical drives. Number of items must not be less than FF_VOLUMES. Valid characters for the volume ID string are A-Z, a-z and 0-9, however, they are compared in case-insensitive. If FF_STR_VOLUME_ID == 0, this option has no effect. If FF_STR_VOLUME_ID >= 1 and this option is not defined, a user defined volume string table needs to be defined as shown below.
+This option defines the volume ID strings for each logical drives. Number of items must not be less than FF_VOLUMES. Valid characters for the volume ID string are A-Z, a-z and 0-9, however, they are compared in case-insensitive. If FF_STR_VOLUME_ID == 0, this option has no effect. If FF_STR_VOLUME_ID >= 1 and this option is not defined, a user defined volume string table needs to be defined as shown below. The table should not be modified on the fly.
 /* User defined volume ID strings for 0:    1:      2:    3:   ... */
 const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sdc","usb"};
@@ -268,7 +268,7 @@ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sdc","usb"};
 Disable (0) or Enable (1). This option switches the re-entrancy (thread safe) of the FatFs module itself. Note that file/directory access to the different volume is always re-entrant and it can work simultaneously regardless of this option but volume control functions. f_mount, f_mkfs and f_fdisk, are always not re-entrant. Only file/directory access to the same volume, in other words, exclusive use of each filesystem object, is under control of this function. To enable this feature, also user provided synchronization handlers, ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj, need to be added to the project. Sample code is available in ffsystem.c.
+Disable (0) or Enable (1). This option switches the re-entrancy (thread safe) of the FatFs module itself. Note that file/directory access to the different volume is always re-entrant and it can work simultaneously regardless of this option, however, volume management functions, f_mount, f_mkfs and f_fdisk, are always not re-entrant. Only file/directory access to the same volume, in other words, exclusive use of each filesystem object, is under control of this function. To enable this feature, also user provided synchronization handlers, ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj, need to be added to the project. Sample code is available in ffsystem.c.
Number of time ticks to abort the file function with FR_TIMEOUT when wait time is too long. This option has no effect when FF_FS_REENTRANT == 0.
diff --git a/documents/doc/dread.html b/documents/doc/dread.html index 890bcdc..52d60f1 100644 --- a/documents/doc/dread.html +++ b/documents/doc/dread.html @@ -61,7 +61,7 @@ DRESULT disk_read (Generally, a multiple sector read request must not be split into single sector transactions to the storage device, or read throughput gets worse.
diff --git a/documents/doc/expand.html b/documents/doc/expand.html index 9517609..12e5559 100644 --- a/documents/doc/expand.html +++ b/documents/doc/expand.html @@ -61,7 +61,7 @@ FRESULT f_expand (When opt is 0, the function finds a contiguous data area and set it as suggested point for next allocation instead of allocating it to the file. The next cluster allocation is started at top of the contiguous area found by this function. Thus the write file is guaranteed be contiguous and no allocation delay until the size reaches that size at least unless any other changes to the volume is performed.
The contiguous file would have an advantage at time-critical read/write operations. It eliminates some overheads in the filesystem and the storage media caused by random access due to fragmented file data. Especially FAT access for the contiguous file on the exFAT volume is completely eliminated and storage media will be accessed sequentially.
-Also the contiguous file can be easily accessed directly via low-level disk functions. But this is not recommended in consideration for future compatibility.
+Also the contiguous file can be easily accessed directly via low-level disk functions. But this is not recommended in consideration for future compatibility. Use this function to examine if the file is contiguous or not.
Also the drive prefix can be in pre-defined arbitrary string. When the option FF_STR_VOLUME_ID == 1, also arbitrary string volume ID can be used as drive prefix. e.g. "flash:file1.txt", "ram:temp.dat" or "usb:". When FF_STR_VOLUME_ID == 2, Unix style drive prefix can be used. e.g. "/flash/file1.txt", "/ram/temp.dat" or "/usb". However, it cannot traverse the drives such as "/flash/../ram/temp.dat". The Unix style drive prefix may lead a confusion in identification between volume ID and file name. For instance, which does "/flash" mean, a file "flash" on the root directory without drive prefix or a drive prefix of "flash"? If the string following a heading slash matches with any volume ID, it is treated as a drive prefix and skipped over.
+Also the drive prefix can be in pre-defined arbitrary string. When the option FF_STR_VOLUME_ID == 1, also arbitrary string volume ID can be used as drive prefix. e.g. "flash:file1.txt", "ram:temp.dat" or "sd:". When FF_STR_VOLUME_ID == 2, Unix style drive prefix can be used. e.g. "/flash/file1.txt", "/ram/temp.dat" or "/usb". However, it cannot traverse the drives such as "/flash/../ram/temp.dat". The Unix style drive prefix may lead a confusion in identification between volume ID and file name. For instance, which does "/flash" mean, a file "flash" on the root directory without drive prefix or a drive prefix of "flash"? If the string following a heading slash matches with any volume ID, it is treated as a drive prefix.
Remark: In this revision, double dot name ".." cannot follow the parent directory on the exFAT volume. It will work as "." and stay there.
On the FAT filesystem, legal characters for object name (file/directory name) are, 0-9 A-Z ! # $ % & ' ( ) - @ ^ _ ` { } ~ and extended characters (\x80-\xFF). Under LFN supported system, also + , ; = [ ] and white space are legal for the object name and the white spaces and dots can be placed anywhere in the path name except for end of the object name.
+On the FAT filesystem, legal characters for object name (file/directory name) are, 0-9 A-Z ! # $ % & ' ( ) - @ ^ _ ` { } ~ and any extended character. The valid character codes of extended characters are depends on the configured code page. Under LFN supported system, also + , ; = [ ] and white space are legal for the object name and the white spaces and dots can be placed anywhere in the path name except for end of the name.
FAT filesystem is case-insensitive to the object names on the volume. Object name on the FAT volume is compared in case-insensitive. For instance, these three names, file.txt, File.Txt and FILE.TXT, are identical. This is applied to extended charactres as well. When an object is created on the FAT volume, up converted name is recorded to the SFN entry, and the raw name is recorded to the LFN entry when LFN function is enabled.
-As for the MS-DOS and PC DOS for CJK, it was case-sensitive to the DBCS extended characters. To follow this specification, FatFs works with case-sensitive to the extended characters at only non-LFN with DBCS configuration (DOS/DBCS specs). But at LFN configuration, FatFs works with case-insensitive to the extended character (WindowsNT specs). This can cause a problem on compatibility with Windows system when an object with extended characters is created on the volume at non-LFN and DBCS configuration; therfore the object names with DBCS extended characters should not be used on the FAT volume shared by those systems.
+As for the MS-DOS and PC DOS for CJK (DOS/DBCS), extended characters are recorded to the SFN entry without up-case conversion and compared in case-sensitive. This causes a problem on compatibility with Windows system when any object with extended characters is created on the volume by DOS/DBCS system; therfore the object names with DBCS extended characters should not be used on the FAT volume shared by those systems. FatFs works with case-sensitive to the extended characters at only non-LFN with DBCS configuration (DOS/DBCS specs). But at LFN configuration, FatFs works with case-insensitive to the extended character (WindowsNT specs).
The path names are input/output in either ANSI/OEM code or Unicode depends on the configuration options. The type of arguments which specifies the path names is defined as TCHAR. It is an alias of char by default and the code set used for the path name string is ANSI/OEM specifid by FF_CODE_PAGE. When FF_LFN_UNICODE is set to 1, the type of the TCHAR is switched to WCHAR to support UTF-16 encoded Unicode string. When UTF-16 or UTF-8 is specified by this option, the full-featured LFN specification is supported and the Unicode specific characters, such as ✝☪✡☸☭, can also be used for the path name. It also affects data types and encoding of the string I/O functions. To define literal strings, _T(s) and _TEXT(s) macro are available to select either ANSI/OEM or Unicode automatically. The code shown below is an example to define the literal strings.
+The path names are input/output in either ANSI/OEM code or Unicode depends on the configuration options. The type of arguments which specifies the path names is defined as TCHAR. It is an alias of char by default and the code set used for the path name string is ANSI/OEM specifid by FF_CODE_PAGE. When FF_LFN_UNICODE is set to 1 or larger, the type of the TCHAR is switched to proper type to support the Unicode string. When Unicode API is specified by this option, the full-featured LFN specification is supported and the Unicode specific characters, such as ✝☪✡☸☭, can also be used for the path name. It also affects data types and encoding of the string I/O functions. To define literal strings, _T(s) and _TEXT(s) macro are available to select either ANSI/OEM or Unicode automatically. The code shown below is an example to define the literal strings.
f_open(fp, "filename.txt", FA_READ); /* ANSI/OEM string (char) */ f_open(fp, L"filename.txt", FA_READ); /* UTF-16 string (WCHAR) */ diff --git a/documents/doc/getcwd.html b/documents/doc/getcwd.html index a2628fb..ac9a6d6 100644 --- a/documents/doc/getcwd.html +++ b/documents/doc/getcwd.html @@ -50,7 +50,7 @@ FRESULT f_getcwd (diff --git a/documents/doc/open.html b/documents/doc/open.html index c5dd7c5..c039826 100644 --- a/documents/doc/open.html +++ b/documents/doc/open.html @@ -118,7 +118,7 @@ int main (void) fr = f_open(&fil, "message.txt", FA_READ); if (fr) return (int)fr; - /* Read all lines and display it */ + /* Read every line and display it */ while (f_gets(line, sizeof line, &fil)) { printf(line); } @@ -134,7 +134,7 @@ int main (void) int main (void) { - FATFS fs[2]; /* Work area (filesystem object) for logical drives */ + FATFS fs0, fs1; /* Work area (filesystem object) for logical drives */ FIL fsrc, fdst; /* File objects */ BYTE buffer[4096]; /* File copy buffer */ FRESULT fr; /* FatFs function common result code */ @@ -142,8 +142,8 @@ int main (void) /* Register work area for each logical drive */ - f_mount(&fs[0], "0:", 0); - f_mount(&fs[1], "1:", 0); + f_mount(&fs0, "0:", 0); + f_mount(&fs1, "1:", 0); /* Open source file on the drive 1 */ fr = f_open(&fsrc, "1:file.bin", FA_READ); @@ -166,8 +166,8 @@ int main (void) f_close(&fdst); /* Unregister work area prior to discard it */ - f_mount(NULL, "0:", 0); - f_mount(NULL, "1:", 0); + f_mount(0, "0:", 0); + f_mount(0, "1:", 0); return (int)fr; } diff --git a/documents/doc/rc.html b/documents/doc/rc.html index 4b2ce43..114317b 100644 --- a/documents/doc/rc.html +++ b/documents/doc/rc.html @@ -38,15 +38,15 @@ Note that if once this error occured at any operation to an open file, the fileDescription
-The f_getcwd function retrieves full path name of the current directory of the current drive. When FF_VOLUMES >= 2, a heading drive prefix is added to the path name. The style of drive prefix is depends on FF_STR_VOLUME_ID.
+The f_getcwd function retrieves full path name of the current directory of the current drive. When FF_VOLUMES >= 2, a heading drive prefix is added to the path name. The style of drive prefix depends on FF_STR_VOLUME_ID.
Note: In this revision, this function cannot retrieve the current directory path on the exFAT volume. It always returns the root directory path.
The f_readdir function reads a directory item, informations about the object. All items in the directory can be read in sequence by f_readdir function calls. Dot entries ("." and "..") in the sub-directory are filtered out and they will never appear in the read items. When all directory items have been read and no item to read, a nul string is stored into the fno->fname[] without any error. When a null pointer is given to the fno, the read index of the directory object is rewinded.
+The f_readdir function reads a directory item, informations about the object. Every item in the directory can be read in sequence by f_readdir function calls. Dot entries ("." and "..") in the sub-directory are filtered out and they will never appear in the read items. When all directory items have been read and no item to read, a null string is stored into the fno->fname[] without any error. When a null pointer is given to the fno, the read index of the directory object is rewinded.
When support of long file name (LFN) is enabled, a member altname[] is defined in the file information structure to store the short file name of the object. If the long file name is not accessible due to some reason listed below, short file name is stored to the fname[] and altname[] has a null string.
There is a problem on reading a directory of exFAT volume. The exFAT does not support short file name. This means no name can be returned on the condition above. If it is the case, "?" is returned into the fname[] to indicate that the object is not accessible. To avoid this problem, configure FatFs FF_LFN_UNICODE >= 1 and FF_MAX_LFN == 255 to support the full feature of LFN specification.
Remark: The standard system (Windows) has a problem at the volume label with a heading \xE5 on the FAT volume. To avoid this problem, this function rejects such volume label as invalid name.
The f_sync function performs the same process as f_close function but the file is left opened and can continue read/write/seek operations to the file. This is suitable for the applications that open files for a long time in write mode, such as data logger. Performing f_sync function of periodic or immediataly after f_write function can minimize the risk of data loss due to a sudden blackout or an unintentional media removal. For more information, refer to application note.
+The f_sync function performs the same process as f_close function but the file is left opened and can continue read/write/seek operations to the file. This is suitable for the applications that open files for a long time in write mode, such as data logger. Performing f_sync function in certain interval can minimize the risk of data loss due to a sudden blackout or an unintentional media removal. For more information, refer to application note.
++Case 1. Normal write sequence + + Time --> ↓Power off after close +OwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwC + + +Case 2. Without using f_sync() + + Time --> ↓System crush +Owwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww + |<--------------- All data written will be lost ------------------>| + + +Case 3. Using f_sync() + Time --> ↓System crush +OwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwwwwwwSwwwww + Data after last f_sync will be lost |<->| +O - f_open() +C - f_close() +w - f_write() +S - f_sync() +
However there is no sense in f_sync function immediataly before f_close function because it performs f_sync function in it. In other words, the differnce between those functions is that the file object is invalidated or not.
The f_unlink function removes a file or sub-directory.
+The f_unlink function removes a file or sub-directory from the volume.
FRESULT f_unlink ( const TCHAR* path /* [IN] Object name */ diff --git a/documents/res/app2.c b/documents/res/app2.c index 49d322d..3d14709 100644 --- a/documents/res/app2.c +++ b/documents/res/app2.c @@ -1,65 +1,78 @@ /*------------------------------------------------------------/ -/ Remove all contents of a directory -/ This function works regardless of FF_FS_RPATH. -/------------------------------------------------------------*/ +/ Delete a sub-directory even if it contains any file +/-------------------------------------------------------------/ +/ The delete_node() function is for R0.12+. +/ It works regardless of FF_FS_RPATH. +*/ -FILINFO fno; - -FRESULT empty_directory ( - char* path /* Working buffer filled with start directory */ +FRESULT delete_node ( + TCHAR* path, /* Path name buffer with the sub-directory to delete */ + UINT sz_buff, /* Size of path name buffer (items) */ + FILINFO* fno /* Name read buffer */ ) { UINT i, j; FRESULT fr; DIR dir; - fr = f_opendir(&dir, path); - if (fr == FR_OK) { - for (i = 0; path[i]; i++) ; - path[i++] = '/'; - for (;;) { - fr = f_readdir(&dir, &fno); - if (fr != FR_OK || !fno.fname[0]) break; - if (_FS_RPATH && fno.fname[0] == '.') continue; - j = 0; - do - path[i+j] = fno.fname[j]; - while (fno.fname[j++]); - if (fno.fattrib & AM_DIR) { - fr = empty_directory(path); - if (fr != FR_OK) break; + + fr = f_opendir(&dir, path); /* Open the sub-directory to make it empty */ + if (fr != FR_OK) return fr; + + for (i = 0; path[i]; i++) ; /* Get current path length */ + path[i++] = _T('/'); + + for (;;) { + fr = f_readdir(&dir, fno); /* Get a directory item */ + if (fr != FR_OK || !fno->fname[0]) break; /* End of directory? */ + j = 0; + do { /* Make a path name */ + if (i + j >= sz_buff) { /* Buffer over flow? */ + fr = 100; break; /* Fails with 100 when buffer overflow */ } + path[i + j] = fno->fname[j]; + } while (fno->fname[j++]); + if (fno->fattrib & AM_DIR) { /* Item is a sub-directory */ + fr = delete_node(path, sz_buff, fno); + } else { /* Item is a file */ fr = f_unlink(path); - if (fr != FR_OK) break; } - path[--i] = '\0'; - closedir(&dir); + if (fr != FR_OK) break; } + path[--i] = 0; /* Restore the path name */ + f_closedir(&dir); + + if (fr == FR_OK) fr = f_unlink(path); /* Delete the empty sub-directory */ return fr; } -int main (void) + +int main (void) /* How to use */ { FRESULT fr; FATFS fs; - char buff[256]; /* Working buffer */ + TCHAR buff[256]; + FILINFO fno; + f_mount(&fs, _T("5:"), 0); - f_mount(&fs, "", 0); + /* Directory to be deleted */ + _tcscpy(buff, _T("5:dir")); - strcpy(buff, "/"); /* Directory to be emptied */ - fr = empty_directory(buff); + /* Delete the directory */ + fr = delete_node(buff, sizeof buff / sizeof buff[0], &fno); + /* Check the result */ if (fr) { - printf("Function failed. (%u)\n", fr); + _tprintf(_T("Failed to delete the directory. (%u)\n"), fr); return fr; } else { - printf("All contents in the %s are successfully removed.\n", buff); + _tprintf(_T("The directory and the contents have successfully been deleted.\n"), buff); return 0; } } diff --git a/documents/res/app5.c b/documents/res/app5.c new file mode 100644 index 0000000..6a0819d --- /dev/null +++ b/documents/res/app5.c @@ -0,0 +1,38 @@ +/*----------------------------------------------------------------------/ +/ Test if the file is contiguous / +/----------------------------------------------------------------------*/ + +FRESULT test_contiguous_file ( + FIL* fp, /* [IN] Open file object to be checked */ + int* cont /* [OUT] 1:Contiguous, 0:Fragmented or zero-length */ +) +{ + DWORD clst, clsz, step; + FSIZE_t fsz; + FRESULT fr; + + + *cont = 0; + fr = f_lseek(fp, 0); /* Validates and prepares the file */ + if (fr != FR_OK) return fr; + +#if FF_MAX_SS == FF_MIN_SS + clsz = (DWORD)fp->obj.fs->csize * FF_MAX_SS; /* Cluster size */ +#else + clsz = (DWORD)fp->obj.fs->csize * fp->obj.fs->ssize; +#endif + fsz = fp->obj.objsize; + if (fsz > 0) { + clst = fp->obj.sclust - 1; /* A cluster leading the first cluster for first test */ + while (fsz) { + step = (fsz >= clsz) ? clsz : (DWORD)fsz; + fr = f_lseek(fp, f_tell(fp) + step); /* Advances file pointer a cluster */ + if (fr != FR_OK) return fr; + if (clst + 1 != fp->clust) break; /* Is not the cluster next to previous one? */ + clst = fp->clust; fsz -= step; /* Get current cluster for next test */ + } + if (fsz == 0) *cont = 1; /* All done without fail? */ + } + + return FR_OK; +} diff --git a/documents/res/f4.png b/documents/res/f4.png index f9a6b46..2c00ddc 100644 Binary files a/documents/res/f4.png and b/documents/res/f4.png differ diff --git a/documents/res/f5.png b/documents/res/f5.png index b110b29..bc0171a 100644 Binary files a/documents/res/f5.png and b/documents/res/f5.png differ diff --git a/documents/res/mkfatimg.zip b/documents/res/mkfatimg.zip index 67d423b..63e6ad7 100644 Binary files a/documents/res/mkfatimg.zip and b/documents/res/mkfatimg.zip differ diff --git a/documents/res/modules.png b/documents/res/modules.png index b1ab987..885a15a 100644 Binary files a/documents/res/modules.png and b/documents/res/modules.png differ diff --git a/documents/updates.txt b/documents/updates.txt index 3b7d126..42405b9 100644 --- a/documents/updates.txt +++ b/documents/updates.txt @@ -1,6 +1,12 @@ +R0.13c (October 14, 2018) + Supported stdint.h for C99 and later. (integer.h was included in ff.h) + Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12) + Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12) + Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b) + R0.13b (April 07, 2018) Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3) - Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2) + Added support for Unix style volume prefix. (FF_STR_VOLUME_ID = 2) Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c) Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b) diff --git a/source/00history.txt b/source/00history.txt index 9b67d02..db12a9e 100644 --- a/source/00history.txt +++ b/source/00history.txt @@ -322,3 +322,9 @@ R0.13b (April 07, 2018) +R0.13c (October 14, 2018) + Supported stdint.h for C99 and later. (integer.h was included in ff.h) + Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12) + Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12) + Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b) + diff --git a/source/00readme.txt b/source/00readme.txt index 15426d2..dcccbdb 100644 --- a/source/00readme.txt +++ b/source/00readme.txt @@ -1,4 +1,4 @@ -FatFs Module Source Files R0.13b +FatFs Module Source Files R0.13c FILES @@ -10,7 +10,6 @@ FILES ff.h Common include file for FatFs and application module. diskio.h Common include file for FatFs and disk I/O module. diskio.c An example of glue function to attach existing disk I/O module to FatFs. - integer.h Integer type definitions for FatFs. ffunicode.c Optional Unicode utility functions. ffsystem.c An example of optional O/S related functions. diff --git a/source/diskio.c b/source/diskio.c index f611063..08ffcc8 100644 --- a/source/diskio.c +++ b/source/diskio.c @@ -7,7 +7,8 @@ /* storage control modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ -#include "diskio.h" /* FatFs lower layer API */ +#include "ff.h" /* Obtains integer types */ +#include "diskio.h" /* Declarations of disk functions */ /* Definitions of physical drive number for each drive */ #define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ @@ -143,6 +144,8 @@ DRESULT disk_read ( /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ +#if FF_FS_READONLY == 0 + DRESULT disk_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ @@ -185,6 +188,7 @@ DRESULT disk_write ( return RES_PARERR; } +#endif /*-----------------------------------------------------------------------*/ diff --git a/source/diskio.h b/source/diskio.h index 1fa4400..31776b8 100644 --- a/source/diskio.h +++ b/source/diskio.h @@ -9,9 +9,6 @@ extern "C" { #endif -#include "integer.h" - - /* Status of Disk Functions */ typedef BYTE DSTATUS; diff --git a/source/ff.c b/source/ff.c index 35c9755..290f577 100644 --- a/source/ff.c +++ b/source/ff.c @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT Filesystem Module R0.13b / +/ FatFs - Generic FAT Filesystem Module R0.13c / /-----------------------------------------------------------------------------/ / / Copyright (C) 2018, ChaN, all right reserved. @@ -29,11 +29,20 @@ ---------------------------------------------------------------------------*/ -#if FF_DEFINED != 63463 /* Revision ID */ +#if FF_DEFINED != 86604 /* Revision ID */ #error Wrong include file (ff.h). #endif +/* Limits and boundaries */ +#define MAX_DIR 0x200000 /* Max size of FAT directory */ +#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ +#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ +#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ +#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ + + /* Character code support macros */ #define IsUpper(c) ((c) >= 'A' && (c) <= 'Z') #define IsLower(c) ((c) >= 'a' && (c) <= 'z') @@ -43,18 +52,18 @@ #define IsSurrogateL(c) ((c) >= 0xDC00 && (c) <= 0xDFFF) -/* Additional file attribute bits for internal use */ -#define AM_VOL 0x08 /* Volume label */ -#define AM_LFN 0x0F /* LFN entry */ -#define AM_MASK 0x3F /* Mask of defined bits */ - - /* Additional file access control and file status flags for internal use */ #define FA_SEEKEND 0x20 /* Seek to end of the file on file open */ #define FA_MODIFIED 0x40 /* File has been modified */ #define FA_DIRTY 0x80 /* FIL.buf[] needs to be written-back */ +/* Additional file attribute bits for internal use */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + /* Name status flags in fn[11] */ #define NSFLAG 11 /* Index of the name status byte */ #define NS_LOSS 0x01 /* Out of 8.3 format */ @@ -67,13 +76,13 @@ #define NS_NONAME 0x80 /* Not followed */ -/* Limits and boundaries */ -#define MAX_DIR 0x200000 /* Max size of FAT directory */ -#define MAX_DIR_EX 0x10000000 /* Max size of exFAT directory */ -#define MAX_FAT12 0xFF5 /* Max FAT12 clusters (differs from specs, but right for real DOS/Windows behavior) */ -#define MAX_FAT16 0xFFF5 /* Max FAT16 clusters (differs from specs, but right for real DOS/Windows behavior) */ -#define MAX_FAT32 0x0FFFFFF5 /* Max FAT32 clusters (not specified, practical limit) */ -#define MAX_EXFAT 0x7FFFFFFD /* Max exFAT clusters (differs from specs, implementation limit) */ +/* exFAT directory entry types */ +#define ET_BITMAP 0x81 /* Allocation bitmap */ +#define ET_UPCASE 0x82 /* Up-case table */ +#define ET_VLABEL 0x83 /* Volume label */ +#define ET_FILEDIR 0x85 /* File and directory */ +#define ET_STREAM 0xC0 /* Stream extension */ +#define ET_FILENAME 0xC1 /* Name extension */ /* FatFs refers the FAT structure as simple byte array instead of structure member @@ -521,6 +530,7 @@ static WCHAR LfnBuf[FF_MAX_LFN + 1]; /* LFN working buffer */ #define CODEPAGE CodePage static WORD CodePage; /* Current code page */ static const BYTE *ExCvt, *DbcTbl; /* Pointer to current SBCS up-case table and DBCS code range table below */ + static const BYTE Ct437[] = TBL_CT437; static const BYTE Ct720[] = TBL_CT720; static const BYTE Ct737[] = TBL_CT737; @@ -1093,7 +1103,7 @@ static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */ if (res == FR_OK) { if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { /* FAT32: Update FSInfo sector if needed */ /* Create FSInfo structure */ - mem_set(fs->win, 0, SS(fs)); + mem_set(fs->win, 0, sizeof fs->win); st_word(fs->win + BS_55AA, 0xAA55); st_dword(fs->win + FSI_LeadSig, 0x41615252); st_dword(fs->win + FSI_StrucSig, 0x61417272); @@ -1293,7 +1303,7 @@ static DWORD find_bitmap ( /* 0:Not found, 2..:Cluster block found, 0xFFFFFFFF:D if (clst >= fs->n_fatent - 2) clst = 0; scl = val = clst; ctr = 0; for (;;) { - if (move_window(fs, fs->database + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; /* (assuming bitmap is located top of the cluster heap) */ + if (move_window(fs, fs->bitbase + val / 8 / SS(fs)) != FR_OK) return 0xFFFFFFFF; i = val / 8 % SS(fs); bm = 1 << (val % 8); do { do { @@ -1331,9 +1341,9 @@ static FRESULT change_bitmap ( clst -= 2; /* The first bit corresponds to cluster #2 */ - sect = fs->database + clst / 8 / SS(fs); /* Sector address (assuming bitmap is located top of the cluster heap) */ - i = clst / 8 % SS(fs); /* Byte offset in the sector */ - bm = 1 << (clst % 8); /* Bit mask in the byte */ + sect = fs->bitbase + clst / 8 / SS(fs); /* Sector address */ + i = clst / 8 % SS(fs); /* Byte offset in the sector */ + bm = 1 << (clst % 8); /* Bit mask in the byte */ for (;;) { if (move_window(fs, sect++) != FR_OK) return FR_DISK_ERR; do { @@ -1406,7 +1416,7 @@ static FRESULT fill_last_frag ( static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */ FFOBJID* obj, /* Corresponding object */ DWORD clst, /* Cluster to remove a chain from */ - DWORD pclst /* Previous cluster of clst (0:entire chain) */ + DWORD pclst /* Previous cluster of clst (0 if entire chain) */ ) { FRESULT res = FR_OK; @@ -1644,7 +1654,7 @@ static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */ if (sync_window(fs) != FR_OK) return FR_DISK_ERR; /* Flush disk access window */ sect = clst2sect(fs, clst); /* Top of the cluster */ fs->winsect = sect; /* Set window to top of the cluster */ - mem_set(fs->win, 0, SS(fs)); /* Clear window buffer */ + mem_set(fs->win, 0, sizeof fs->win); /* Clear window buffer */ #if FF_USE_LFN == 3 /* Quick table clear by using multi-secter write */ /* Allocate a temporary buffer */ for (szb = ((DWORD)fs->csize * SS(fs) >= MAX_MALLOC) ? MAX_MALLOC : fs->csize * SS(fs), ibuf = 0; szb > SS(fs) && (ibuf = ff_memalloc(szb)) == 0; szb /= 2) ; @@ -1728,7 +1738,8 @@ static FRESULT dir_next ( /* FR_OK(0):succeeded, FR_NO_FILE:End of table, FR_DEN ofs = dp->dptr + SZDIRE; /* Next entry */ - if (dp->sect == 0 || ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) return FR_NO_FILE; /* Report EOT when offset has reached max value */ + if (ofs >= (DWORD)((FF_FS_EXFAT && fs->fs_type == FS_EXFAT) ? MAX_DIR_EX : MAX_DIR)) dp->sect = 0; /* Disable it if the offset reached the max value */ + if (dp->sect == 0) return FR_NO_FILE; /* Report EOT if it has been disabled */ if (ofs % SS(fs) == 0) { /* Sector changed? */ dp->sect++; /* Next sector */ @@ -2153,33 +2164,33 @@ static FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */ BYTE* dirb = dp->obj.fs->dirbuf; /* Pointer to the on-memory direcotry entry block 85+C0+C1s */ - /* Load 85 entry */ + /* Load file-directory entry */ res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0x85) return FR_INT_ERR; /* Invalid order */ + if (dp->dir[XDIR_Type] != ET_FILEDIR) return FR_INT_ERR; /* Invalid order */ mem_cpy(dirb + 0 * SZDIRE, dp->dir, SZDIRE); sz_ent = (dirb[XDIR_NumSec] + 1) * SZDIRE; if (sz_ent < 3 * SZDIRE || sz_ent > 19 * SZDIRE) return FR_INT_ERR; - /* Load C0 entry */ + /* Load stream-extension entry */ res = dir_next(dp, 0); if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC0) return FR_INT_ERR; /* Invalid order */ + if (dp->dir[XDIR_Type] != ET_STREAM) return FR_INT_ERR; /* Invalid order */ mem_cpy(dirb + 1 * SZDIRE, dp->dir, SZDIRE); if (MAXDIRB(dirb[XDIR_NumName]) > sz_ent) return FR_INT_ERR; - /* Load C1 entries */ - i = 2 * SZDIRE; /* C1 offset to load */ + /* Load file-name entries */ + i = 2 * SZDIRE; /* Name offset to load */ do { res = dir_next(dp, 0); if (res == FR_NO_FILE) res = FR_INT_ERR; /* It cannot be */ if (res != FR_OK) return res; res = move_window(dp->obj.fs, dp->sect); if (res != FR_OK) return res; - if (dp->dir[XDIR_Type] != 0xC1) return FR_INT_ERR; /* Invalid order */ + if (dp->dir[XDIR_Type] != ET_FILENAME) return FR_INT_ERR; /* Invalid order */ if (i < MAXDIRB(FF_MAX_LFN)) mem_cpy(dirb + i, dp->dir, SZDIRE); } while ((i += SZDIRE) < sz_ent); @@ -2284,16 +2295,16 @@ static void create_xdir ( WCHAR wc; - /* Create 85,C0 entry */ + /* Create file-directory and stream-extension entry */ mem_set(dirb, 0, 2 * SZDIRE); - dirb[0 * SZDIRE + XDIR_Type] = 0x85; /* 85 entry */ - dirb[1 * SZDIRE + XDIR_Type] = 0xC0; /* C0 entry */ + dirb[0 * SZDIRE + XDIR_Type] = ET_FILEDIR; + dirb[1 * SZDIRE + XDIR_Type] = ET_STREAM; - /* Create C1 entries */ - i = SZDIRE * 2; /* Top of C1 entries */ + /* Create file-name entries */ + i = SZDIRE * 2; /* Top of file_name entries */ nlen = nc1 = 0; wc = 1; do { - dirb[i++] = 0xC1; dirb[i++] = 0; /* Entry type C1 */ + dirb[i++] = ET_FILENAME; dirb[i++] = 0; do { /* Fill name field */ if (wc != 0 && (wc = lfn[nlen]) != 0) nlen++; /* Get a character if exist */ st_word(dirb + i, wc); /* Store it */ @@ -2317,8 +2328,8 @@ static void create_xdir ( /* Read an object from the directory */ /*-----------------------------------------------------------------------*/ -#define dir_read_file(dp) dir_read(dp, 0) -#define dir_read_label(dp) dir_read(dp, 1) +#define DIR_READ_FILE(dp) dir_read(dp, 0) +#define DIR_READ_LABEL(dp) dir_read(dp, 1) static FRESULT dir_read ( DIR* dp, /* Pointer to the directory object */ @@ -2327,7 +2338,7 @@ static FRESULT dir_read ( { FRESULT res = FR_NO_FILE; FATFS *fs = dp->obj.fs; - BYTE a, c; + BYTE attr, b; #if FF_USE_LFN BYTE ord = 0xFF, sum = 0xFF; #endif @@ -2335,16 +2346,16 @@ static FRESULT dir_read ( while (dp->sect) { res = move_window(fs, dp->sect); if (res != FR_OK) break; - c = dp->dir[DIR_Name]; /* Test for the entry type */ - if (c == 0) { + b = dp->dir[DIR_Name]; /* Test for the entry type */ + if (b == 0) { res = FR_NO_FILE; break; /* Reached to end of the directory */ } #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ if (FF_USE_LABEL && vol) { - if (c == 0x83) break; /* Volume label entry? */ + if (b == ET_VLABEL) break; /* Volume label entry? */ } else { - if (c == 0x85) { /* Start of the file entry block? */ + if (b == ET_FILEDIR) { /* Start of the file entry block? */ dp->blk_ofs = dp->dptr; /* Get location of the block */ res = load_xdir(dp); /* Load the entry block */ if (res == FR_OK) { @@ -2356,19 +2367,19 @@ static FRESULT dir_read ( } else #endif { /* On the FAT/FAT32 volume */ - dp->obj.attr = a = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ + dp->obj.attr = attr = dp->dir[DIR_Attr] & AM_MASK; /* Get attribute */ #if FF_USE_LFN /* LFN configuration */ - if (c == DDEM || c == '.' || (int)((a & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ + if (b == DDEM || b == '.' || (int)((attr & ~AM_ARC) == AM_VOL) != vol) { /* An entry without valid data */ ord = 0xFF; } else { - if (a == AM_LFN) { /* An LFN entry is found */ - if (c & LLEF) { /* Is it start of an LFN sequence? */ + if (attr == AM_LFN) { /* An LFN entry is found */ + if (b & LLEF) { /* Is it start of an LFN sequence? */ sum = dp->dir[LDIR_Chksum]; - c &= (BYTE)~LLEF; ord = c; + b &= (BYTE)~LLEF; ord = b; dp->blk_ofs = dp->dptr; } /* Check LFN validity and capture it */ - ord = (c == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; + ord = (b == ord && sum == dp->dir[LDIR_Chksum] && pick_lfn(fs->lfnbuf, dp->dir)) ? ord - 1 : 0xFF; } else { /* An SFN entry is found */ if (ord != 0 || sum != sum_sfn(dp->dir)) { /* Is there a valid LFN? */ dp->blk_ofs = 0xFFFFFFFF; /* It has no LFN. */ @@ -2377,7 +2388,7 @@ static FRESULT dir_read ( } } #else /* Non LFN configuration */ - if (c != DDEM && c != '.' && a != AM_LFN && (int)((a & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ + if (b != DDEM && b != '.' && attr != AM_LFN && (int)((attr & ~AM_ARC) == AM_VOL) == vol) { /* Is it a valid entry? */ break; } #endif @@ -2417,7 +2428,7 @@ static FRESULT dir_find ( /* FR_OK(0):succeeded, !=0:error */ UINT di, ni; WORD hash = xname_sum(fs->lfnbuf); /* Hash value of the name to find */ - while ((res = dir_read_file(dp)) == FR_OK) { /* Read an item */ + while ((res = DIR_READ_FILE(dp)) == FR_OK) { /* Read an item */ #if FF_MAX_LFN < 255 if (fs->dirbuf[XDIR_NumName] > FF_MAX_LFN) continue; /* Skip comparison if inaccessible object name */ #endif @@ -2496,17 +2507,17 @@ static FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ nent = (nlen + 14) / 15 + 2; /* Number of entries to allocate (85+C0+C1s) */ - res = dir_alloc(dp, nent); /* Allocate entries */ + res = dir_alloc(dp, nent); /* Allocate directory entries */ if (res != FR_OK) return res; dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */ - if (dp->obj.stat & 4) { /* Has the directory been stretched? */ + if (dp->obj.stat & 4) { /* Has the directory been stretched by new allocation? */ dp->obj.stat &= ~4; res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */ if (res != FR_OK) return res; res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */ if (res != FR_OK) return res; - if (dp->obj.sclust != 0) { /* Is it a sub directory? */ + if (dp->obj.sclust != 0) { /* Is it a sub-directory? */ DIR dj; res = load_obj_xdir(&dj, &dp->obj); /* Load the object status */ @@ -3254,7 +3265,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR; #endif - /* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK and SFD. */ + /* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK (MBR) and SFD (w/o partition). */ bsect = 0; fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */ if (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) { /* Not an FAT-VBR or forced partition number */ @@ -3277,6 +3288,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ #if FF_FS_EXFAT if (fmt == 1) { QWORD maxlba; + DWORD so, cv, bcl; for (i = BPB_ZeroedEx; i < BPB_ZeroedEx + 53 && fs->win[i] == 0; i++) ; /* Check zero filler */ if (i < BPB_ZeroedEx + 53) return FR_NO_FILESYSTEM; @@ -3309,12 +3321,27 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */ if (maxlba < (QWORD)fs->database + nclst * fs->csize) return FR_NO_FILESYSTEM; /* (Volume size must not be smaller than the size requiered) */ fs->dirbase = ld_dword(fs->win + BPB_RootClusEx); - /* Check if bitmap location is in assumption (at the first cluster) */ - if (move_window(fs, clst2sect(fs, fs->dirbase)) != FR_OK) return FR_DISK_ERR; - for (i = 0; i < SS(fs); i += SZDIRE) { - if (fs->win[i] == 0x81 && ld_dword(fs->win + i + 20) == 2) break; /* 81 entry with cluster #2? */ + /* Get bitmap location and check if it is contiguous (implementation assumption) */ + so = i = 0; + for (;;) { /* Find the bitmap entry in the root directory (in only first cluster) */ + if (i == 0) { + if (so >= fs->csize) return FR_NO_FILESYSTEM; /* Not found? */ + if (move_window(fs, clst2sect(fs, fs->dirbase) + so) != FR_OK) return FR_DISK_ERR; + so++; + } + if (fs->win[i] == ET_BITMAP) break; /* Is it a bitmap entry? */ + i = (i + SZDIRE) % SS(fs); /* Next entry */ } - if (i == SS(fs)) return FR_NO_FILESYSTEM; + bcl = ld_dword(fs->win + i + 20); /* Bitmap cluster */ + if (bcl < 2 || bcl >= fs->n_fatent) return FR_NO_FILESYSTEM; + fs->bitbase = fs->database + fs->csize * (bcl - 2); /* Bitmap sector */ + for (;;) { /* Check if bitmap is contiguous */ + if (move_window(fs, fs->fatbase + bcl / (SS(fs) / 4)) != FR_OK) return FR_DISK_ERR; + cv = ld_dword(fs->win + bcl % (SS(fs) / 4) * 4); + if (cv == 0xFFFFFFFF) break; /* Last link? */ + if (cv != ++bcl) return FR_NO_FILESYSTEM; /* Fragmented? */ + } + #if !FF_FS_READONLY fs->last_clst = fs->free_clst = 0xFFFFFFFF; /* Initialize cluster allocation information */ #endif @@ -3664,7 +3691,7 @@ FRESULT f_open ( fp->fptr = 0; /* Set file pointer top of the file */ #if !FF_FS_READONLY #if !FF_FS_TINY - mem_set(fp->buf, 0, FF_MAX_SS); /* Clear sector buffer */ + mem_set(fp->buf, 0, sizeof fp->buf); /* Clear sector buffer */ #endif if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */ fp->fptr = fp->obj.objsize; /* Offset to seek */ @@ -4144,6 +4171,7 @@ FRESULT f_getcwd ( /* Get logical drive */ + buff[0] = 0; /* Set null string to get current volume */ res = find_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ if (res == FR_OK) { dj.obj.fs = fs; @@ -4162,7 +4190,7 @@ FRESULT f_getcwd ( res = dir_sdi(&dj, 0); if (res != FR_OK) break; do { /* Find the entry links to the child directory */ - res = dir_read_file(&dj); + res = DIR_READ_FILE(&dj); if (res != FR_OK) break; if (ccl == ld_clust(fs, dj.dir)) break; /* Found the entry */ res = dir_next(&dj, 0); @@ -4494,7 +4522,7 @@ FRESULT f_readdir ( res = dir_sdi(dp, 0); /* Rewind the directory object */ } else { INIT_NAMBUF(fs); - res = dir_read_file(dp); /* Read an item */ + res = DIR_READ_FILE(dp); /* Read an item */ if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */ if (res == FR_OK) { /* A valid entry is found */ get_fileinfo(dp, fno); /* Get the object information */ @@ -4639,7 +4667,7 @@ FRESULT f_getfree ( UINT b; clst = fs->n_fatent - 2; /* Number of clusters */ - sect = fs->database; /* Assuming bitmap starts at cluster 2 */ + sect = fs->bitbase; /* Bitmap sector */ i = 0; /* Offset in the sector */ do { /* Counts numbuer of bits with zero in the bitmap */ if (i == 0) { @@ -4802,7 +4830,7 @@ FRESULT f_unlink ( #endif res = dir_sdi(&sdj, 0); if (res == FR_OK) { - res = dir_read_file(&sdj); /* Test if the directory is empty */ + res = DIR_READ_FILE(&sdj); /* Test if the directory is empty */ if (res == FR_OK) res = FR_DENIED; /* Not empty? */ if (res == FR_NO_FILE) res = FR_OK; /* Empty? */ } @@ -4840,73 +4868,69 @@ FRESULT f_mkdir ( { FRESULT res; DIR dj; + FFOBJID sobj; FATFS *fs; - BYTE *dir; DWORD dcl, pcl, tm; DEF_NAMBUF - /* Get logical drive */ - res = find_volume(&path, &fs, FA_WRITE); + res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); res = follow_path(&dj, path); /* Follow the file path */ - if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ - if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { + if (res == FR_OK) res = FR_EXIST; /* Name collision? */ + if (FF_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) { /* Invalid name? */ res = FR_INVALID_NAME; } - if (res == FR_NO_FILE) { /* Can create a new directory */ - dcl = create_chain(&dj.obj, 0); /* Allocate a cluster for the new directory table */ - dj.obj.objsize = (DWORD)fs->csize * SS(fs); + if (res == FR_NO_FILE) { /* It is clear to create a new directory */ + sobj.fs = fs; /* New object id to create a new chain */ + dcl = create_chain(&sobj, 0); /* Allocate a cluster for the new directory */ res = FR_OK; - if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ - if (dcl == 1) res = FR_INT_ERR; - if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; - if (res == FR_OK) res = sync_window(fs); /* Flush FAT */ + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster? */ + if (dcl == 1) res = FR_INT_ERR; /* Any insanity? */ + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; /* Disk error? */ tm = GET_FATTIME(); - if (res == FR_OK) { /* Initialize the new directory table */ - res = dir_clear(fs, dcl); /* Clean up the new table */ - if (res == FR_OK && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT)) { /* Create dot entries (FAT only) */ - dir = fs->win; - mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */ - dir[DIR_Name] = '.'; - dir[DIR_Attr] = AM_DIR; - st_dword(dir + DIR_ModTime, tm); - st_clust(fs, dir, dcl); - mem_cpy(dir + SZDIRE, dir, SZDIRE); /* Create ".." entry */ - dir[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; - st_clust(fs, dir + SZDIRE, pcl); - fs->wflag = 1; - } - } if (res == FR_OK) { - res = dir_register(&dj); /* Register the object to the directoy */ + res = dir_clear(fs, dcl); /* Clean up the new table */ + if (res == FR_OK) { + if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) { /* Create dot entries (FAT only) */ + mem_set(fs->win + DIR_Name, ' ', 11); /* Create "." entry */ + fs->win[DIR_Name] = '.'; + fs->win[DIR_Attr] = AM_DIR; + st_dword(fs->win + DIR_ModTime, tm); + st_clust(fs, fs->win, dcl); + mem_cpy(fs->win + SZDIRE, fs->win, SZDIRE); /* Create ".." entry */ + fs->win[SZDIRE + 1] = '.'; pcl = dj.obj.sclust; + st_clust(fs, fs->win + SZDIRE, pcl); + fs->wflag = 1; + } + res = dir_register(&dj); /* Register the object to the parent directoy */ + } } if (res == FR_OK) { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */ st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */ st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */ - st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)dj.obj.objsize); /* File size needs to be valid */ - st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)dj.obj.objsize); + st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)fs->csize * SS(fs)); /* File size needs to be valid */ + st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)fs->csize * SS(fs)); fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag */ fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */ res = store_xdir(&dj); } else #endif { - dir = dj.dir; - st_dword(dir + DIR_ModTime, tm); /* Created time */ - st_clust(fs, dir, dcl); /* Table start cluster */ - dir[DIR_Attr] = AM_DIR; /* Attribute */ + st_dword(dj.dir + DIR_ModTime, tm); /* Created time */ + st_clust(fs, dj.dir, dcl); /* Table start cluster */ + dj.dir[DIR_Attr] = AM_DIR; /* Attribute */ fs->wflag = 1; } if (res == FR_OK) { res = sync_fs(fs); } } else { - remove_chain(&dj.obj, dcl, 0); /* Could not register, remove cluster chain */ + remove_chain(&sobj, dcl, 0); /* Could not register, remove the allocated cluster */ } } FREE_NAMBUF(); @@ -5146,7 +5170,7 @@ FRESULT f_getlabel ( dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { - res = dir_read_label(&dj); /* Find a volume label entry */ + res = DIR_READ_LABEL(&dj); /* Find a volume label entry */ if (res == FR_OK) { #if FF_FS_EXFAT if (fs->fs_type == FS_EXFAT) { @@ -5291,7 +5315,7 @@ FRESULT f_setlabel ( dj.obj.fs = fs; dj.obj.sclust = 0; /* Open root directory */ res = dir_sdi(&dj, 0); if (res == FR_OK) { - res = dir_read_label(&dj); /* Get volume label entry */ + res = DIR_READ_LABEL(&dj); /* Get volume label entry */ if (res == FR_OK) { if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { dj.dir[XDIR_NumLabel] = (BYTE)di; /* Change the volume label */ @@ -5313,7 +5337,7 @@ FRESULT f_setlabel ( if (res == FR_OK) { mem_set(dj.dir, 0, SZDIRE); /* Clean the entry */ if (FF_FS_EXFAT && fs->fs_type == FS_EXFAT) { - dj.dir[XDIR_Type] = 0x83; /* Create 83 entry */ + dj.dir[XDIR_Type] = ET_VLABEL; /* Create volume label entry */ dj.dir[XDIR_NumLabel] = (BYTE)di; mem_cpy(dj.dir + XDIR_Label, dirvn, 22); } else { @@ -5699,11 +5723,11 @@ FRESULT f_mkfs ( /* Initialize the root directory */ mem_set(buf, 0, szb_buf); - buf[SZDIRE * 0 + 0] = 0x83; /* 83 entry (volume label) */ - buf[SZDIRE * 1 + 0] = 0x81; /* 81 entry (allocation bitmap) */ + buf[SZDIRE * 0 + 0] = ET_VLABEL; /* Volume label entry */ + buf[SZDIRE * 1 + 0] = ET_BITMAP; /* Bitmap entry */ st_dword(buf + SZDIRE * 1 + 20, 2); /* cluster */ st_dword(buf + SZDIRE * 1 + 24, szb_bit); /* size */ - buf[SZDIRE * 2 + 0] = 0x82; /* 82 entry (up-case table) */ + buf[SZDIRE * 2 + 0] = ET_UPCASE; /* Up-case table entry */ st_dword(buf + SZDIRE * 2 + 4, sum); /* sum */ st_dword(buf + SZDIRE * 2 + 20, 2 + tbl[0]); /* cluster */ st_dword(buf + SZDIRE * 2 + 24, szb_case); /* size */ @@ -6191,8 +6215,7 @@ typedef struct { /* Putchar output buffer and work area */ } putbuff; -static -void putc_bfd ( /* Buffered write with code conversion */ +static void putc_bfd ( /* Buffered write with code conversion */ putbuff* pb, TCHAR c ) @@ -6303,7 +6326,7 @@ void putc_bfd ( /* Buffered write with code conversion */ #else /* Write it in ANSI/OEM */ if (hs != 0) return; wc = ff_uni2oem(wc, CODEPAGE); /* UTF-16 ==> ANSI/OEM */ - if (wc == 0) return;; + if (wc == 0) return; if (wc >= 0x100) { pb->buf[i++] = (BYTE)(wc >> 8); nc++; } @@ -6323,8 +6346,7 @@ void putc_bfd ( /* Buffered write with code conversion */ } -static -int putc_flush ( /* Flush left characters in the buffer */ +static int putc_flush ( /* Flush left characters in the buffer */ putbuff* pb ) { @@ -6337,8 +6359,7 @@ int putc_flush ( /* Flush left characters in the buffer */ } -static -void putc_init ( /* Initialize write buffer */ +static void putc_init ( /* Initialize write buffer */ putbuff* pb, FIL* fp ) diff --git a/source/ff.h b/source/ff.h index cd90d6d..a0792b2 100644 --- a/source/ff.h +++ b/source/ff.h @@ -1,5 +1,5 @@ /*----------------------------------------------------------------------------/ -/ FatFs - Generic FAT Filesystem module R0.13b / +/ FatFs - Generic FAT Filesystem module R0.13c / /-----------------------------------------------------------------------------/ / / Copyright (C) 2018, ChaN, all right reserved. @@ -20,13 +20,12 @@ #ifndef FF_DEFINED -#define FF_DEFINED 63463 /* Revision ID */ +#define FF_DEFINED 86604 /* Revision ID */ #ifdef __cplusplus extern "C" { #endif -#include "integer.h" /* Basic integer types */ #include "ffconf.h" /* FatFs configuration options */ #if FF_DEFINED != FFCONF_DEF @@ -34,6 +33,30 @@ extern "C" { #endif +/* Integer types used for FatFs API */ + +#if defined(_WIN32) /* Main development platform */ +#define FF_INTDEF 2 +#include+typedef unsigned __int64 QWORD; +#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ +#define FF_INTDEF 2 +#include +typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ +typedef unsigned char BYTE; /* char must be 8-bit */ +typedef uint16_t WORD; /* 16-bit unsigned integer */ +typedef uint16_t WCHAR; /* 16-bit unsigned integer */ +typedef uint32_t DWORD; /* 32-bit unsigned integer */ +typedef uint64_t QWORD; /* 64-bit unsigned integer */ +#else /* Earlier than C99 */ +#define FF_INTDEF 1 +typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ +typedef unsigned char BYTE; /* char must be 8-bit */ +typedef unsigned short WORD; /* 16-bit unsigned integer */ +typedef unsigned short WCHAR; /* 16-bit unsigned integer */ +typedef unsigned long DWORD; /* 32-bit unsigned integer */ +#endif + /* Definitions of volume management */ @@ -85,6 +108,9 @@ typedef char TCHAR; /* Type of file size variables */ #if FF_FS_EXFAT +#if FF_INTDEF != 2 +#error exFAT feature wants C99 or later +#endif typedef QWORD FSIZE_t; #else typedef DWORD FSIZE_t; @@ -95,8 +121,8 @@ typedef DWORD FSIZE_t; /* Filesystem object structure (FATFS) */ typedef struct { - BYTE fs_type; /* Filesystem type (0:N/A) */ - BYTE pdrv; /* Physical drive number */ + BYTE fs_type; /* Filesystem type (0:not mounted) */ + BYTE pdrv; /* Associated physical drive */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] flag (b0:dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ @@ -133,6 +159,9 @@ typedef struct { DWORD fatbase; /* FAT base sector */ DWORD dirbase; /* Root directory base sector/cluster */ DWORD database; /* Data base sector */ +#if FF_FS_EXFAT + DWORD bitbase; /* Allocation bitmap base sector */ +#endif DWORD winsect; /* Current sector appearing in the win[] */ BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ } FATFS; @@ -145,7 +174,7 @@ typedef struct { FATFS* fs; /* Pointer to the hosting volume of this object */ WORD id; /* Hosting volume mount ID */ BYTE attr; /* Object attribute */ - BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:flagmented in this session, b2:sub-directory stretched) */ + BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */ DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ FSIZE_t objsize; /* Object size (valid when sclust != 0) */ #if FF_FS_EXFAT diff --git a/source/ffconf.h b/source/ffconf.h index fe5aacd..5bd2f21 100644 --- a/source/ffconf.h +++ b/source/ffconf.h @@ -1,8 +1,8 @@ /*---------------------------------------------------------------------------/ -/ FatFs - Configuration file +/ FatFs Functional Configurations /---------------------------------------------------------------------------*/ -#define FFCONF_DEF 63463 /* Revision ID */ +#define FFCONF_DEF 86604 /* Revision ID */ /*---------------------------------------------------------------------------/ / Function Configurations @@ -232,7 +232,7 @@ #define FF_FS_EXFAT 0 /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) -/ To enable exFAT, also LFN needs to be enabled. +/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) / Note that enabling exFAT discards ANSI C (C89) compatibility. */ @@ -262,6 +262,7 @@ / lock control is independent of re-entrancy. */ +/* #include // O/S definitions */ #define FF_FS_REENTRANT 0 #define FF_FS_TIMEOUT 1000 #define FF_SYNC_t HANDLE @@ -282,8 +283,6 @@ / SemaphoreHandle_t and etc. A header file for O/S definitions needs to be / included somewhere in the scope of ff.h. */ -/* #include // O/S definitions */ - /*--- End of configuration options ---*/ diff --git a/source/ffsystem.c b/source/ffsystem.c index 9df330f..b88ce15 100644 --- a/source/ffsystem.c +++ b/source/ffsystem.c @@ -1,20 +1,19 @@ /*------------------------------------------------------------------------*/ /* Sample Code of OS Dependent Functions for FatFs */ -/* (C)ChaN, 2017 */ +/* (C)ChaN, 2018 */ /*------------------------------------------------------------------------*/ #include "ff.h" - #if FF_USE_LFN == 3 /* Dynamic memory allocation */ /*------------------------------------------------------------------------*/ /* Allocate a memory block */ /*------------------------------------------------------------------------*/ -void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on not enough core) */ +void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */ UINT msize /* Number of bytes to allocate */ ) { @@ -27,7 +26,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block (null on no /*------------------------------------------------------------------------*/ void ff_memfree ( - void* mblock /* Pointer to the memory block to free (nothing to do for null) */ + void* mblock /* Pointer to the memory block to free (nothing to do if null) */ ) { free(mblock); /* Free the memory block with POSIX API */ @@ -47,7 +46,7 @@ void ff_memfree ( / When a 0 is returned, the f_mount() function fails with FR_INT_ERR. */ -//const osMutexDef_t Mutex[FF_VOLUMES]; /* CMSIS-RTOS */ +//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */ int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */ @@ -74,7 +73,7 @@ int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object // return (int)(*sobj != NULL); /* CMSIS-RTOS */ -// *sobj = osMutexCreate(Mutex + vol); +// *sobj = osMutexCreate(&Mutex[vol]); // return (int)(*sobj != NULL); } diff --git a/source/ffunicode.c b/source/ffunicode.c index 9a5d37e..349901b 100644 --- a/source/ffunicode.c +++ b/source/ffunicode.c @@ -1,5 +1,5 @@ /*------------------------------------------------------------------------*/ -/* Unicode handling functions for FatFs R0.13b */ +/* Unicode handling functions for FatFs R0.13c */ /*------------------------------------------------------------------------*/ /* This module will occupy a huge memory in the .const section when the / / FatFs is configured for LFN with DBCS. If the system has any Unicode / @@ -25,9 +25,9 @@ #include "ff.h" -#if FF_USE_LFN /* This module is blanked when non-LFN configuration */ +#if FF_USE_LFN /* This module will be blanked at non-LFN configuration */ -#if FF_DEFINED != 63463 /* Revision ID */ +#if FF_DEFINED != 86604 /* Revision ID */ #error Wrong include file (ff.h). #endif diff --git a/source/integer.h b/source/integer.h deleted file mode 100644 index b3c70ca..0000000 --- a/source/integer.h +++ /dev/null @@ -1,36 +0,0 @@ -/*-------------------------------------------*/ -/* Integer type definitions for FatFs module */ -/*-------------------------------------------*/ - -#ifndef FF_INTEGER -#define FF_INTEGER - -#ifdef _WIN32 /* FatFs development platform */ - -#include -typedef unsigned __int64 QWORD; - -#else /* Embedded platform */ - -/* These types MUST be 16-bit or 32-bit */ -typedef int INT; -typedef unsigned int UINT; - -/* This type MUST be 8-bit */ -typedef unsigned char BYTE; - -/* These types MUST be 16-bit */ -typedef short SHORT; -typedef unsigned short WORD; -typedef unsigned short WCHAR; - -/* These types MUST be 32-bit */ -typedef long LONG; -typedef unsigned long DWORD; - -/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */ -typedef unsigned long long QWORD; - -#endif - -#endif