From 36c173e7057064dad5c5b6100b4b67a2ecade5da Mon Sep 17 00:00:00 2001 From: savelij13 Date: Thu, 11 Sep 2025 09:10:56 +0300 Subject: [PATCH] fatfs v0.05 Aug 25, 2007: - Changed arguments of f_read, f_write. - Changed arguments of f_mkfs. (FatFs) - Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) - Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) --- doc/00index_e.html | 11 ++- doc/00index_j.html | 11 ++- doc/en/appnote.html | 24 ++--- doc/en/dioctl.html | 11 +-- doc/en/dread.html | 6 +- doc/en/dstat.html | 10 +-- doc/en/dwrite.html | 6 +- doc/en/filename.html | 12 +-- doc/en/getfree.html | 4 +- doc/en/lseek.html | 4 +- doc/en/mkfs.html | 8 +- doc/en/open.html | 8 +- doc/en/read.html | 8 +- doc/en/readdir.html | 4 +- doc/en/sync.html | 2 +- doc/en/write.html | 10 +-- doc/ja/appnote.html | 22 ++--- doc/ja/dioctl.html | 6 +- doc/ja/dread.html | 4 +- doc/ja/lseek.html | 4 +- doc/ja/mkfs.html | 6 +- doc/ja/open.html | 6 +- doc/ja/read.html | 10 +-- doc/ja/readdir.html | 4 +- doc/ja/write.html | 6 +- doc/updates.txt | 16 ++-- src/00readme.txt | 32 ++++--- src/diskio.c | 204 +++++++++++++++++++++++++++++++++++++++++++ src/diskio.h | 19 ++-- src/ff.c | 119 +++++++++++++------------ src/ff.h | 20 ++--- src/integer.h | 1 + src/tff.c | 50 ++++++----- src/tff.h | 18 ++-- 34 files changed, 461 insertions(+), 225 deletions(-) create mode 100644 src/diskio.c diff --git a/doc/00index_e.html b/doc/00index_e.html index 8407cbb..85473a6 100644 --- a/doc/00index_e.html +++ b/doc/00index_e.html @@ -14,20 +14,20 @@
layer -

FatFs module is an experimental project to implement a FAT file system to small embdded systems. The FatFs module is written in compliance with ANSI C, therefore it is independent of hardware architecture. It can be incorporated into most 8-bit microcontrollers, such as 8051, PIC, AVR, H8, Z80 and etc..., without any change. I created two modules in different configurations in consideration of various use.

+

FatFs module is an experimental project to implement the FAT file system to small embedded systems. The FatFs module is written in compliance with ANSI C, therefore it is independent of hardware architecture. It can be incorporated into cheap microcontrollers, such as 8051, PIC, AVR, SH, Z80, H8, ARM and etc..., without any change.

Features of FatFs Module

  1. Separated buffer for FAT structure and each file, suitable for fast multiple file accsess.
  2. Supports multiple drives/partitions.
  3. -
  4. Supports FAT12, FAT16(+FAT64) and FAT32. (FAT64: FAT16 in 64KB/cluster)
  5. -
  6. Supports 8.3 format file name and NT lower case flag. (LFN is not supported)
  7. +
  8. Supports FAT12, FAT16 and FAT32.
  9. +
  10. Supports 8.3 format file name. (LFN is not supported)
  11. Supports two partitioning rules: FDISK and Super-floppy.
  12. Optimized for 8/16-bit microcontrollers.

Features of Tiny-FatFs Module (different to FatFs)

    -
  1. Very low memory consumption, suitable for small memory system. (RAM:1KB)
  2. +
  3. Very low memory consumption, suitable for small memory system. (1KB RAM)
  4. Supports only single drive.
@@ -59,7 +59,7 @@

Disk I/O Interface

-

Since the FatFs/Tiny-FatFs module is completely separated from disk I/O layer, it requires following functions to lower layer to read/write physical disk and to get current time. These functions must be provided by user. The low level disk I/O module that have this interace must be provided by user. The sample projects are also available.

+

Since the FatFs/Tiny-FatFs module is completely separated from disk I/O layer, it requires following functions to lower layer to read/write physical disk and to get current time. The low level disk I/O module with this interface must be provided by user. The sample drivers are also available in the next resources.

diff --git a/doc/en/dstat.html b/doc/en/dstat.html index b224956..54e716f 100644 --- a/doc/en/dstat.html +++ b/doc/en/dstat.html @@ -12,7 +12,7 @@

disk_status

-

The disk_status function gets the disk status.

+

The disk_status function return the current disk status.

 DSTATUS disk_status (
   BYTE Drive     /* Physical drive number */
@@ -31,14 +31,14 @@ DSTATUS disk_status (
 
 

Return Values

-

The disk status is returned in combinatin of following flags.

+

The disk status is returned in combination of following flags.

STA_NOINIT
-
Indicates that the disk drive has not been initialiezed. This flag is set on: power-on, disk removal and disk_initialize function failed, and cleared on: disk_initialize function succeeded.
+
Indicates that the disk drive has not been initialiezed. This flag is set on: system reset, disk removal and disk_initialize function failed, and cleared on: disk_initialize function succeeded.
STA_NODISK
-
Indicates that no medium in the drive. It is always cleared on fixed disk drive.
+
Indicates that no medium in the drive. This is always cleared on fixed disk drive.
STA_PROTECTED
-
Indicates that the medium is write protected. It is always cleared on the drive that does not support write protect notch.
+
Indicates that the medium is write protected. This is always cleared on the drive that does not support write protect notch.
diff --git a/doc/en/dwrite.html b/doc/en/dwrite.html index 857074b..ff73522 100644 --- a/doc/en/dwrite.html +++ b/doc/en/dwrite.html @@ -27,13 +27,13 @@ DRESULT disk_write (

Parameters

Drive
-
Specifies the physical drive number to write.
+
Specifies the physical drive number.
Buffer
Pointer to the data to be written.
SectorNumber
Specifies the start sector number in logical block address.
SectorCount
-
Specifies number of sectors to write. The value can be 1 to 255.
+
Specifies the number of sectors to write. The value can be 1 to 255.
@@ -50,7 +50,7 @@ DRESULT disk_write (
RES_PARERR
Invalid parameter.
RES_NOTRDY
-
The disk dirve has not been initialized.
+
The disk drive has not been initialized.
diff --git a/doc/en/filename.html b/doc/en/filename.html index d094482..20127d2 100644 --- a/doc/en/filename.html +++ b/doc/en/filename.html @@ -12,10 +12,10 @@

File and Path name on the FatFs module

-

The format of file and path name on the FatFs module is similer to MS-DOS. However it does not have a concept of current directory, all objects on the drive are specified in full path from the roor directory.

+

The format of file and path name on the FatFs module is similer to MS-DOS. However it does not have a concept of current directory, all objects on the drive are specified in full path name from the root directory.

 
- "[logical drive#:][/]directory/file"
+ "[drive#:][/]directory/file"
 
  "file1.txt"           a file on drive 0
  "/file1.txt"          (same as above)
@@ -28,13 +28,13 @@
 
 

The FatFs module supports only 8.3 format file name and long file name is currentry not supported. For directory separator, a '/' is used, not a '\'. Heading '/' is ignored and can be omitted.

-

The logical drive number is specified in a numeral with a colon. When drive number is omitted, it means the default drive (0). As for the Tiny-FatFs, it has only one logical drive and always works as drive 0. Any drive number cannot be contained in the path name.

+

The logical drive number is specified in a numeral with a colon. When the drive number is omitted, it means the default drive (0). As for the Tiny-FatFs, it has only one logical drive and always works as drive 0. Any drive number cannot be contained in the path name.


Correspondence between logical/physical drive

-

In default, the FatFs module has work areas that called file system object for each logical drive. The logical drive is bound simply to the physical drive that has same drive number, and first partition is mounted. When _MULTI_PARTITION is specified in configuration option, each individual logical drive can be bound to any physical drive/partition. In this case, a drive number resolution table must be defined as follows:

+

In default, the FatFs module has work areas that called `file system object' for each logical drive. The logical drive is bound simply to the physical drive that has same drive number, and first partition is mounted. When _MULTI_PARTITION is specified in configuration option, each individual logical drive can be bound to any physical drive/partition. In this case, a drive number resolution table must be defined as follows:

 Example: Logical drive 0-2 are assigned to three pri-partitions on the physical drive 0 (fixed disk)
          Logical drive 3 is assigned to physical drive 0 (removable disk)
@@ -49,8 +49,8 @@ const PARTITION Drives[] = {
 

There are some consideration when use _MULTI_PARTITION configuration.

  • Only pri-partition (0-3) can be mounted.
  • -
  • When the drive have no partition table (super floppy format), partition number is ignored.
  • -
  • The drive that has two or more logical drive must be fixed drive.
  • +
  • When the physical drive have no partition table (super floppy format), the partition number is ignored.
  • +
  • The physical drive that has two or more logical drives must be fixed drive.
diff --git a/doc/en/getfree.html b/doc/en/getfree.html index 1290cac..7d25fe0 100644 --- a/doc/en/getfree.html +++ b/doc/en/getfree.html @@ -39,7 +39,7 @@ FRESULT f_getfree (

Return Values

FR_OK (0)
-
The function succeeded. The *Clusters havs number of free clusters and *FileSystemObject points the file system object.
+
The function succeeded. The *Clusters has number of free clusters and *FileSystemObject points the file system object.
FR_INVALID_DRIVE
The drive number is invalid.
FR_NOT_READY
@@ -62,7 +62,7 @@ FRESULT f_getfree (
-

Samples Code

+

Example

     FATFS *fs;
     DWORD clust;
diff --git a/doc/en/lseek.html b/doc/en/lseek.html
index 42d58b7..1d76eea 100644
--- a/doc/en/lseek.html
+++ b/doc/en/lseek.html
@@ -49,7 +49,7 @@ FRESULT f_lseek (
 
 

Description

-

The f_lseek function moves the file R/W pointer of an open file. The offset can be specified in only origin from top of the file. When an offset above the file size is specified in write mode, the file is extended to the offset and the data in the extended area is undefined. After the function succeeded, member fptr in the file object should be checked in order to make sure the R/W pointer has been moved correctry. In case of fptr is less than Offset, any of the followings has been occured.

+

The f_lseek function moves the file R/W pointer of an open file. The offset can be specified in only origin from top of the file. When an offset above the file size is specified in write mode, the file size is extended to the offset and the data in the extended area is undefined. This is suitable to create a large file quickly, for fast write operation without cluster allocation delay. After the f_lseek function succeeded, member fptr in the file object should be checked in order to make sure the R/W pointer has been moved correctry. In case of fptr is less than Offset, any of the followings has been occured.

  • In read-only mode, the Offset was clipped in file size.
  • The drive gets full during the file extending process.
  • @@ -70,7 +70,7 @@ FRESULT f_lseek ( // Rewind 2000 bytes (take care on overflow) res = f_lseek(&file, file.fptr - 2000); - // Move to end of the file + // Move to end of the file to append data res = f_lseek(&file, file.fsize);
diff --git a/doc/en/mkfs.html b/doc/en/mkfs.html index f687352..57d9f63 100644 --- a/doc/en/mkfs.html +++ b/doc/en/mkfs.html @@ -17,7 +17,7 @@ FRESULT f_mkfs ( BYTE Drive, /* Logical drive number */ BYTE PartitioningRule, /* Partitioning rule */ - BYTE AllocSize /* Allocation unit size */ + WORD AllocSize /* Allocation unit size */ ); @@ -30,7 +30,7 @@ FRESULT f_mkfs (
PartitioningRule
When 0 is given, a partition table is created into first sector on the drive and then the file system is created on the partition. This is called FDISK format. When 1 is given, the file system starts from the first sector without partition table. This is often called super floppy (SFD) format.
AllocSize
-
Specifies allocation unit size (number of sectors per cluster). The value must be power of 2 in range of from 1 to 64.
+
Specifies allocation unit size (number of bytes per cluster). The value must be power of 2 in range of from 512 to 32768.
@@ -62,8 +62,8 @@ FRESULT f_mkfs (

Description

-

The f_mkfs function creates a FAT file system on the drive. There are two partitioning rules, FDISK and SFD, for removable media. It can be selected with a parameter and FDISK format is recommended for most case. This function currently does not support multiple partition, so that existing partitions on the physical dirve will be deleted and re-created a partition occupies entire disk space.

-

The FAT type, FAT12/FAT16/FAT32, is determined by only how many clusters on the drive and nothing else, according to FAT specification. Thus which FAT type is selected, is depends on the drive size and specified cluster size. The cluster size affects performance of file system and large cluster increases the performance, so that 64 sectors per cluster is recommended except for small drive.

+

The f_mkfs function creates a FAT file system on the drive. There are two partitioning rules, FDISK and SFD, for removable media. It can be selected with an argument. The FDISK format is recommended for most case. This function currently does not support multiple partition, so that existing partitions on the physical dirve will be deleted and re-created a partition occupies entire disk space.

+

The FAT type, FAT12/FAT16/FAT32, is determined by only how many clusters on the drive and nothing else, according to the FAT specification issued by Microsoft. Thus which FAT type is selected, is depends on the drive size and specified cluster size. The cluster size affects performance of file system and large cluster increases the performance, so that 32768 bytes per cluster is recommended for most case except for small drive.

This function is supported on only FatFs with _USE_MKFS option.

diff --git a/doc/en/open.html b/doc/en/open.html index d2c2c52..43c0d73 100644 --- a/doc/en/open.html +++ b/doc/en/open.html @@ -35,7 +35,7 @@ FRESULT f_open ( ValueDescription FA_READSpecifies read access to the object. Data can be read from the file.
Combine with FA_WRITE for read-write access. FA_WRITESpecifies write access to the object. Data can be written to the file.
Combine with FA_READ for read-write access. -FA_OPEN_EXISTINGOpens the file. The function fails if the file is not existing. +FA_OPEN_EXISTINGOpens the file. The function fails if the file is not existing. (Default) FA_OPEN_ALWAYSOpens the file, if it is existing. If not, the function creates the new file. FA_CREATE_NEWCreates a new file. The function fails if the file is already existing. FA_CREATE_ALWAYSCreates a new file. If the file is existing, it is truncated and overwritten. @@ -93,10 +93,10 @@ void main () FIL fsrc, fdst; // file objects BYTE buffer[4096]; // file copy buffer FRESULT res; // FatFs function common result code - WORD br, bw; // File R/W count + UINT br, bw; // File R/W count - // Register a work area to logical drive 0 + // Register a work area for logical drive 0 f_mount(0, &fs); // Open source file @@ -110,7 +110,7 @@ void main () // Copy source to destination for (;;) { res = f_read(&fsrc, buffer, sizeof(buffer), &br); - if (res || br == 0) break; // error or eof + if (res || br == 0) break; // error or eof res = f_write(&fdst, buffer, br, &bw); if (res || bw < br) break; // error or disk full } diff --git a/doc/en/read.html b/doc/en/read.html index 4e2254e..21765a9 100644 --- a/doc/en/read.html +++ b/doc/en/read.html @@ -17,8 +17,8 @@ FRESULT f_read ( FIL* FileObject, /* Pointer to the file object structure */ void* Buffer, /* Pointer to the buffer to store read data */ - WORD ByteToRead, /* Number of bytes to read */ - WORD* ByteRead /* Pointer to the variable to return number of bytes read */ + UINT ByteToRead, /* Number of bytes to read */ + UINT* ByteRead /* Pointer to the variable to return number of bytes read */ ); @@ -31,9 +31,9 @@ FRESULT f_read (
Buffer
Pointer to the buffer to store read data
ByteToRead
-
Number of bytes to read
+
Number of bytes to read in range of UINT.
ByteRead
-
Pointer to the WORD variable to return number of bytes read.
+
Pointer to the UINT variable to return number of bytes read.
diff --git a/doc/en/readdir.html b/doc/en/readdir.html index 7029838..996d683 100644 --- a/doc/en/readdir.html +++ b/doc/en/readdir.html @@ -66,9 +66,9 @@ void scan_files (char* path) i = strlen(path); while ((f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0]) { if (finfo.fattrib & AM_DIR) { - sprintf(path+i, "/%s", &finfo.fname[0]); + sprintf(&path[i], "/%s", &finfo.fname[0]); scan_files(path); - *(path+i) = '\0'; + path[i] = 0; } else { printf("%s/%s\n", path, &finfo.fname[0]); } diff --git a/doc/en/sync.html b/doc/en/sync.html index a2e98e6..de93af1 100644 --- a/doc/en/sync.html +++ b/doc/en/sync.html @@ -46,7 +46,7 @@ FRESULT f_sync (

Description

-

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 applications that open files for a long time in writing mode, such as data logger. Performing f_sync of periodic or immediataly after f_write can minimize risk of data loss due to sudden blackout or unintentional disk removal. This function is not supported in read-only configuration.

+

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 applications that open files for a long time in writing mode, such as data logger. Performing f_sync of periodic or immediataly after f_write can minimize risk of data loss due to a sudden blackout or an unintentional disk removal. This function is not supported in read-only configuration.

diff --git a/doc/en/write.html b/doc/en/write.html index e408150..8fd3d5c 100644 --- a/doc/en/write.html +++ b/doc/en/write.html @@ -17,8 +17,8 @@ FRESULT f_write ( FIL* FileObject, /* Pointer to the file object structure */ const void* Buffer, /* Pointer to the data to be written */ - WORD ByteToWrite, /* Number of bytes to write */ - WORD* ByteWritten /* Pointer to the variable to return number of bytes written */ + UINT ByteToWrite, /* Number of bytes to write */ + UINT* ByteWritten /* Pointer to the variable to return number of bytes written */ ); @@ -31,9 +31,9 @@ FRESULT f_write (
Buffer
Pointer to the data to be written.
ByteToWrite
-
Specifies number of bytes to write.
+
Specifies number of bytes to write in range of UINT.
ByteWritten
-
Pointer to the WORD variable to return number of bytes written.
+
Pointer to the UINT variable to return number of bytes written.
@@ -57,7 +57,7 @@ FRESULT f_write (

Description

-

The read/write pointer in the file object is increased in number of bytes written. The ByteWritten will become less than ByteToWrite when disk gets full during write function. This function is not supported in read-only configuration.

+

The read/write pointer in the file object is increased in number of bytes written. The ByteWritten will become less than ByteToWrite when the drive gets full during the write operation. This function is not supported in read-only configuration.

diff --git a/doc/ja/appnote.html b/doc/ja/appnote.html index 2b48a41..e55eb8a 100644 --- a/doc/ja/appnote.html +++ b/doc/ja/appnote.html @@ -24,24 +24,24 @@ FatFs
-

メモリ使用量 (R0.04b)

+

メモリ使用量 (R0.05)

各種環境でのモジュールのメモリ使用量の例を示します。数値の単位はバイトで、Dは論理ドライブ数、Fは同時オープン・ファイル数を示します。最適化オプションは、全てコード・サイズとしています。

- - - - + + + + - - - - - - + + + + + +
AVRH8/300HMSP430TLCS-870/CV850ESSH2
コンパイラgccCH38CL430CC870CCA850SHC
_MCU_ENDIAN122112
FatFs コード
(標準, R/W構成)
8722877664027338
FatFs コード
(最小, R/W構成)
5814572240944906
FatFs コード
(標準, R/O構成)
4248409630103506
FatFs コード
(最小, R/O構成)
3038311022102698
FatFs コード
(標準, R/W構成)
8810888064187830
FatFs コード
(最小, R/W構成)
5832574840725366
FatFs コード
(標準, R/O構成)
4264411029903420
FatFs コード
(最小, R/O構成)
3052312421942634
FatFs 静的ワークD*2 + 2D*4 + 2D*4 + 2D*4 + 2
FatFs 動的ワークD*554 + F*544D*554 + F*550D*554 + F*550D*554 + F*550
Tiny-FatFs コード
(標準, R/W構成)
7264724066348837
Tiny-FatFs コード
(最小, R/W構成)
4750480643666163
Tiny-FatFs コード
(標準, R/O構成)
3600354832124347
Tiny-FatFs コード
(最小, R/O構成)
2568270223943322
Tiny-FatFs 静的ワーク4644
Tiny-FatFs 動的ワーク544 + F*28544 + F*32544 + F*28544 + F*28
Tiny-FatFs コード
(標準, R/W構成)
73767274662288545670
Tiny-FatFs コード
(最小, R/W構成)
48664826435461763726
Tiny-FatFs コード
(標準, R/O構成)
36543554322043582710
Tiny-FatFs コード
(最小, R/O構成)
26202708240233291910
Tiny-FatFs 静的ワーク46446
Tiny-FatFs 動的ワーク544 + F*28544 + F*32544 + F*28544 + F*28544 + F*32
diff --git a/doc/ja/dioctl.html b/doc/ja/dioctl.html index c33c40e..51262c7 100644 --- a/doc/ja/dioctl.html +++ b/doc/ja/dioctl.html @@ -51,11 +51,11 @@ DRESULT disk_ioctl (

解説

物理ドライブの種類によりサポートされるコマンドは異なりますが、FatFsモジュールでは、ドライブの種類に依存した制御は行いません。次のドライブ共通コマンドを使用します。

-

リード・オンリー構成ではこの関数は必要とされません。

- - + + +
コマンド解説
GET_SECTOR_COUNTBufferの指すDWORD変数にドライブ上の総セクタ数を返します。
CTRL_SYNCドライブがデータの書き込みを完了するのを待ちます。ライト・バック・キャッシュを持っている場合は、書き込まれていないデータを即時書き戻します。
CTRL_SYNCドライブがデータの書き込みを完了するのを待ちます。ライト・バック・キャッシュを持っている場合は、書き込まれていないデータを即時書き戻します。リード・オンリー構成では使用されません。
GET_SECTOR_COUNTBufferの指すDWORD変数にドライブ上の総セクタ数を返します。f_mkfs内でのみ使用。
GET_BLOCK_SIZEBufferの指すDWORD変数にメモリ・アレーの消去ブロックサイズをセクタ単位で返します。不明な場合またはHDDでは1を返します。f_mkfs内でのみ使用。
diff --git a/doc/ja/dread.html b/doc/ja/dread.html index 40f7406..2b46292 100644 --- a/doc/ja/dread.html +++ b/doc/ja/dread.html @@ -29,11 +29,11 @@ DRESULT disk_read (
Drive
物理ドライブ番号(0-9)を指定します。
Buffer
-
ディスクから読み出したデータを格納するバッファ。SectorCount * 512バイトのサイズが必要です。
+
ディスクから読み出したデータを格納するバッファ。読み出されるバイト数分のサイズが必要です。
SectorNumber
読み出しを開始するセクタ番号。LBAで指定します。
SectorCount
-
読み出すセクタ数。 1〜255で設定します
+
読み出すセクタ数。 1〜255の範囲で設定します
diff --git a/doc/ja/lseek.html b/doc/ja/lseek.html index ea36566..6570041 100644 --- a/doc/ja/lseek.html +++ b/doc/ja/lseek.html @@ -49,7 +49,7 @@ FRESULT f_lseek (

解説

-

ファイルR/Wポインタ(ファイル・オブジェクト内のfptrメンバで、次に読み出し・書き込みされるバイトのオフセットを示す)を移動します。オフセットの原点はファイル先頭からです。書き込みモードでファイル・サイズより大きな値を指定すると、そこまでファイルが拡張され、拡張された部分のデータは未定義となります。大容量データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイルを拡張しておくと良いです。f_lseek関数が正常終了したあとは、ファイルR/Wポインタが正しく移動したかfptrをチェックするべきです。ファイルR/Wポインタが指定より小さいときは、次の原因が考えられます。

+

ファイルR/Wポインタ(ファイル・オブジェクト内のfptrメンバで、次に読み出し・書き込みされるバイトのオフセットを示す)を移動します。オフセットの原点はファイル先頭からです。書き込みモードでファイル・サイズより大きな値を指定すると、そこまでファイルが拡張され、拡張された部分のデータは未定義となります。大容量データを遅延無く高速に書き込みたいときは、予めこの関数で必要なサイズまでファイル・サイズを拡張しておくと良いでしょう。f_lseek関数が正常終了したあとは、ファイルR/Wポインタが正しく移動したかfptrをチェックするべきです。ファイルR/Wポインタが指定より小さいときは、次の原因が考えられます。

diff --git a/doc/ja/mkfs.html b/doc/ja/mkfs.html index dff5faa..bcb76ca 100644 --- a/doc/ja/mkfs.html +++ b/doc/ja/mkfs.html @@ -17,7 +17,7 @@ FRESULT f_mkfs ( BYTE Drive, /* Logical drive number */ BYTE PartitioningRule, /* Partitioning rule */ - BYTE AllocSize /* Allocation unit size */ + WORD AllocSize /* Allocation unit size */ ); @@ -30,7 +30,7 @@ FRESULT f_mkfs (
PartitioningRule
0を指定すると、区画テーブルを作成したあとその区画にファイル・システムを作成します(FDISKフォーマット)。1を指定すると、先頭セクタから直接ファイル・システムを構築します(super floppy (SFD) フォーマット)。
AllocSize
-
クラスタ・サイズをセクタ単位で指定します。2の累乗でかつクラスタ・サイズが32Kバイトまでの範囲でなければなりません。
+
クラスタ・サイズをバイト単位で指定します。512〜32768の範囲でかつ2の累乗でなければなりません。
@@ -63,7 +63,7 @@ FRESULT f_mkfs (

説明

f_mkfs関数はFATファイル・システムをドライブ上に作成します。リムーバブル・メディアのパーテーショニング・ルールとしては、FDISK形式とSFD形式がありますが、FDISK形式が一般的です。この関数は複数区画には対応していないので、その物理ドライブの既存の区画は全て削除され、全体が一つの区画になります。

-

FATタイプ(FAT12/FAT16/FAT32)は、ディスク上のクラスタ数によってのみ決定される[FAT仕様書より]決まりになっていて、それ以外の要因はありません。したがって、どのFATタイプになるかは、ディスク・サイズとクラスタ・サイズに依存します。クラスタ・サイズは大きいほど性能が上がるので、特に小容量のドライブでなければ64セクタを選択しておけばよいです。

+

FATタイプ(FAT12/FAT16/FAT32)は、ディスク上のクラスタ数によってのみ決定される[FAT仕様書より]決まりになっていて、それ以外の要因はありません。したがって、どのFATタイプになるかは、ディスク・サイズとクラスタ・サイズに依存します。クラスタ・サイズは大きいほど性能が上がるので、特に小容量のドライブでなければ32768バイトを選択しておけばよいです。

この関数は、FatFsで構成オプション_USE_MKFSを選択したときにサポートされます。また、Tiny-FatFsではサポートされません。

diff --git a/doc/ja/open.html b/doc/ja/open.html index 638230e..57e13e7 100644 --- a/doc/ja/open.html +++ b/doc/ja/open.html @@ -35,7 +35,7 @@ FRESULT f_open ( 値意味 FA_READ読み出しモードで開きます。読み書きする場合はFA_WRITEと共に指定します。 FA_WRITE書き込みモードで開きます。読み書きする場合はFA_READと共に指定します。 -FA_OPEN_EXISTING既存のファイルを開きます。ファイルが無いときはエラーになります。 +FA_OPEN_EXISTING既存のファイルを開きます。ファイルが無いときはエラーになります。(デフォルト) FA_OPEN_ALWAYS既存のファイルを開きます。ファイルが無いときはファイルを作成します。 FA_CREATE_NEWファイルを作成します。同名のファイルがある場合は、エラーになります。 FA_CREATE_ALWAYSファイルを作成します。同名のファイルがある場合は、サイズを0にしてから開きます。 @@ -93,9 +93,9 @@ void main () FIL fsrc, fdst; // ファイル・オブジェクト BYTE buffer[4096]; // file copy buffer FRESULT res; // FatFs function common result code - WORD br, bw; // File R/W count + UINT br, bw; // File R/W count - // ドライブ0にワーク・エリアを与える + // ドライブ0のワーク・エリアを与える f_mount(0, &fs); // ソース・ファイルを開く diff --git a/doc/ja/read.html b/doc/ja/read.html index 9c86eb9..ba55840 100644 --- a/doc/ja/read.html +++ b/doc/ja/read.html @@ -15,10 +15,10 @@

ファイルからデータを読み出します。

 FRESULT f_read (
-  FIL* FileObject,    // ファイル・オブジェクト構造体
-  void* Buffer,       // 読み出したデータを格納するバッファ
-  WORD ByteToRead,    // 読み出すバイト数
-  WORD* ByteRead      // 読み出されたバイト数
+  FIL* FileObject,    /* ファイル・オブジェクト構造体 */
+  void* Buffer,       /* 読み出したデータを格納するバッファ */
+  UINT ByteToRead,    /* 読み出すバイト数 */
+  UINT* ByteRead      /* 読み出されたバイト数 */
 );
 
@@ -31,7 +31,7 @@ FRESULT f_read (
Buffer
読み出したデータを格納するバッファを指すポインタを指定します。
ByteToRead
-
読み出すバイト数(0〜65535)を指定します。
+
読み出すバイト数(0〜UINTの最大値)を指定します。
ByteRead
実際に読み出されたバイト数を格納する変数を指すポインタを指定します。
diff --git a/doc/ja/readdir.html b/doc/ja/readdir.html index 7e4ec0a..3cc0821 100644 --- a/doc/ja/readdir.html +++ b/doc/ja/readdir.html @@ -66,9 +66,9 @@ void scan_files (char* path) i = strlen(path); while ((f_readdir(&dirs, &finfo) == FR_OK) && finfo.fname[0]) { if (finfo._attrib & AM_DIR) { - sprintf(path+i, "/%s", &finfo.fname[0]); + sprintf(&path[i], "/%s", &finfo.fname[0]); scan_files(path); - *(path+i) = '\0'; + path[i] = 0; } else { printf("%s/%s\n", path, &finfo.fname[0]); } diff --git a/doc/ja/write.html b/doc/ja/write.html index 56079f3..4609c97 100644 --- a/doc/ja/write.html +++ b/doc/ja/write.html @@ -17,8 +17,8 @@ FRESULT f_write ( FIL* FileObject, /* ファイル・オブジェクト */ const void* Buffer, /* 書き込みデータ */ - WORD ByteToWrite, /* 書き込むバイト数 */ - WORD* ByteWritten /* 書き込まれたバイト数 */ + UINT ByteToWrite, /* 書き込むバイト数 */ + UINT* ByteWritten /* 書き込まれたバイト数 */ ); @@ -31,7 +31,7 @@ FRESULT f_write (
Buffer
書き込むデータを格納したバッファを指すポインタを指定します。
ByteToWrite
-
書き込むバイト数(0〜65535)を指定します。
+
書き込むバイト数(0〜UINTの最大値)を指定します。
ByteWritten
書き込まれたバイト数を格納する変数を指すポインタを指定します。
diff --git a/doc/updates.txt b/doc/updates.txt index 740f0e2..1e1ba1f 100644 --- a/doc/updates.txt +++ b/doc/updates.txt @@ -1,3 +1,9 @@ +R0.05, Aug 26, 2007 + Changed arguments of f_read, f_write. + Changed arguments of f_mkfs. (FatFs) + Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) + Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) + R0.04b, May 05, 2007 Added _USE_NTFLAG option. Added FSInfo support. @@ -8,19 +14,19 @@ R0.04b, May 05, 2007 R0.04a, Apr 01, 2007 Supported multiple partitions on a plysical drive. (FatFs) Added minimization level 3. - Added a capability of extending file size to f_lseek(). - Fixed an endian sensitive code in f_mkfs(). (FatFs) + Added a capability of extending file size to f_lseek. + Fixed an endian sensitive code in f_mkfs. (FatFs) Fixed a problem corresponds to FAT32 support. (Tiny-FatFs) R0.04, Feb 04, 2007 Supported multiple drive system. (FatFs) Changed some APIs for multiple drive system. - Added f_mkfs(). (FatFs) + Added f_mkfs. (FatFs) Added _USE_FAT32 option. (Tiny-FatFs) R0.03a, Dec 11, 2006 Improved cluster scan algolithm to write files fast. - Fixed f_mkdir() creates incorrect directory on FAT32. + Fixed f_mkdir creates incorrect directory on FAT32. R0.02a, Jun 10, 2006 Added a configuration option _FS_MINIMUM. @@ -31,7 +37,7 @@ R0.02, Jun 01, 2006 Fixed a problem on small (<32M) patition. R0.03, Sep 22, 2006 - Added f_rename(). + Added f_rename. Changed option _FS_MINIMUM to _FS_MINIMIZE. R0.01, Apr 29, 2006 diff --git a/src/00readme.txt b/src/00readme.txt index 6d2697f..8458f29 100644 --- a/src/00readme.txt +++ b/src/00readme.txt @@ -1,4 +1,4 @@ -FatFs/Tiny-FatFs Module Source Files R0.04b (C)ChaN, 2007 +FatFs/Tiny-FatFs Module Source Files R0.05 (C)ChaN, 2007 FILES @@ -8,6 +8,7 @@ FILES tff.h Common include file for Tiny-FatFs and application module. tff.c Tiny-FatFs module. diskio.h Common include file for (Tiny-)FatFs and disk I/O module. + diskio.c Skeleton of low level disk I/O module. integer.h Alternative type definitions for integer variables. Low level disk I/O module is not included in this archive because the @@ -33,8 +34,8 @@ CONFIGURATION OPTIONS - Muti-byte integers (short, long) are stored in Big-Endian. - Address miss-aligned memory access results in an incorrect behavior. - If not the case, this can be set to 1 for good code efficiency. The initial - value is 0. (must be set to 1 or 2 properly) + If not the case, this can also be set to 1 for good code efficiency. The + initial value is 0. (must be set to 1 or 2 properly) _FS_READONLY @@ -133,26 +134,31 @@ REVISION HISTORY Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM. - Sep 22, 2006 R0.03 Added f_rename(). + Sep 22, 2006 R0.03 Added f_rename. Changed option _FS_MINIMUM to _FS_MINIMIZE. Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast. - Fixed f_mkdir() creates incorrect directory on FAT32. + Fixed f_mkdir creates incorrect directory on FAT32. Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs) Changed some APIs for multiple drive system. - Added f_mkfs(). (FatFs) + Added f_mkfs. (FatFs) Added _USE_FAT32 option. (Tiny-FatFs) Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs) - Fixed an endian sensitive code in f_mkfs(). (FatFs) - Added a capability of extending the file size to f_lseek(). + Fixed an endian sensitive code in f_mkfs. (FatFs) + Added a capability of extending the file size to f_lseek. Added minimization level 3. Fixed a problem that can collapse a sector when recreate an existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs) - May 05, 2007 R0.04b Added _USE_NTFLAG option. - Added FSInfo support. - Fixed some problems corresponds to FAT32. (Tiny-FatFs) - Fixed DBCS name can result FR_INVALID_NAME. - Fixed short seek (<= csize) collapses the file object. + May 05, 2007 R0.04b Added _USE_NTFLAG option. + Added FSInfo support. + Fixed some problems corresponds to FAT32. (Tiny-FatFs) + Fixed DBCS name can result FR_INVALID_NAME. + Fixed short seek (0 < ofs <= csize) collapses the file object. + + Aug 25, 2007 R0.05 Changed arguments of f_read, f_write. + Changed arguments of f_mkfs. (FatFs) + Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs) + Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs) diff --git a/src/diskio.c b/src/diskio.c new file mode 100644 index 0000000..3044a41 --- /dev/null +++ b/src/diskio.c @@ -0,0 +1,204 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */ +/*-----------------------------------------------------------------------*/ +/* This is a stub disk I/O module that acts as front end of the existing */ +/* disk I/O modules and attach it to FatFs module with common interface. */ +/*-----------------------------------------------------------------------*/ + +#include "diskio.h" + +/*-----------------------------------------------------------------------*/ +/* Correspondence between drive number and physical drive */ +/* Note that Tiny-FatFs supports only single drive and always */ +/* accesses drive number 0. */ + +#define ATA 0 +#define MMC 1 +#define USB 2 + + + +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ + +DSTATUS disk_initialize ( + BYTE drv /* Physical drive nmuber (0..) */ +) +{ + DSTATUS stat; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_initialize(); + // translate the reslut code here + + return stat; + + case MMC : + result = MMC_disk_initialize(); + // translate the reslut code here + + return stat; + + case USB : + result = USB_disk_initialize(); + // translate the reslut code here + + return stat; + } + return STA_NOINIT; +} + + + +/*-----------------------------------------------------------------------*/ +/* Return Disk Status */ + +DSTATUS disk_status ( + BYTE drv /* Physical drive nmuber (0..) */ +) +{ + DSTATUS stat; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_status(); + // translate the reslut code here + + return stat; + + case MMC : + result = MMC_disk_status(); + // translate the reslut code here + + return stat; + + case USB : + result = USB_disk_status(); + // translate the reslut code here + + return stat; + } + return STA_NOINIT; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ + +DRESULT disk_read ( + BYTE drv, /* Physical drive nmuber (0..) */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_read(buff, sector, count); + // translate the reslut code here + + return res; + + case MMC : + result = MMC_disk_read(buff, sector, count); + // translate the reslut code here + + return res; + + case USB : + result = USB_disk_read(buff, sector, count); + // translate the reslut code here + + return res; + } + return RES_PARERR; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ + +#if _READONLY == 0 +DRESULT disk_write ( + BYTE drv, /* Physical drive nmuber (0..) */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector number (LBA) */ + BYTE count /* Sector count (1..255) */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + result = ATA_disk_write(buff, sector, count); + // translate the reslut code here + + return res; + + case MMC : + result = MMC_disk_write(buff, sector, count); + // translate the reslut code here + + return res; + + case USB : + result = USB_disk_write(buff, sector, count); + // translate the reslut code here + + return res; + } + return RES_PARERR; +} +#endif /* _READONLY */ + + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ + +DRESULT disk_ioctl ( + BYTE drv, /* Physical drive nmuber (0..) */ + BYTE ctrl, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + // pre-process here + + result = ATA_disk_ioctl(ctrl, buff); + // post-process here + + return res; + + case MMC : + // pre-process here + + result = MMC_disk_ioctl(ctrl, buff); + // post-process here + + return res; + + case USB : + // pre-process here + + result = USB_disk_ioctl(ctrl, buff); + // post-process here + + return res; + } + return RES_PARERR; +} + diff --git a/src/diskio.h b/src/diskio.h index d58c41e..f28c9be 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -1,10 +1,11 @@ /*----------------------------------------------------------------------- -/ Low level disk interface modlue include file R0.04a (C)ChaN, 2007 +/ Low level disk interface modlue include file R0.05 (C)ChaN, 2007 /-----------------------------------------------------------------------*/ #ifndef _DISKIO #define _READONLY 0 /* 1: Read-only mode */ +#define _USE_IOCTL 1 #include "integer.h" @@ -46,15 +47,21 @@ void disk_timerproc (void); /* Command code for disk_ioctrl() */ -#define GET_SECTOR_COUNT 1 +/* Generic command */ +#define CTRL_SYNC 0 /* Mandatory for write functions */ +#define GET_SECTOR_COUNT 1 /* Mandatory for only f_mkfs() */ #define GET_SECTOR_SIZE 2 -#define CTRL_SYNC 3 +#define GET_BLOCK_SIZE 3 /* Mandatory for only f_mkfs() */ #define CTRL_POWER 4 #define CTRL_LOCK 5 #define CTRL_EJECT 6 -#define MMC_GET_CSD 10 -#define MMC_GET_CID 11 -#define MMC_GET_OCR 12 +/* MMC/SDC command */ +#define MMC_GET_TYPE 10 +#define MMC_GET_CSD 11 +#define MMC_GET_CID 12 +#define MMC_GET_OCR 13 +#define MMC_GET_SDSTAT 14 +/* ATA/CF command */ #define ATA_GET_REV 20 #define ATA_GET_MODEL 21 #define ATA_GET_SN 22 diff --git a/src/ff.c b/src/ff.c index 6e76bf2..7c1b2c0 100644 --- a/src/ff.c +++ b/src/ff.c @@ -1,5 +1,5 @@ /*--------------------------------------------------------------------------/ -/ FatFs - FAT file system module R0.04b (C)ChaN, 2007 +/ FatFs - FAT file system module R0.05 (C)ChaN, 2007 /---------------------------------------------------------------------------/ / The FatFs module is an experimenal project to implement FAT file system to / cheap microcontrollers. This is a free software and is opened for education, @@ -35,6 +35,9 @@ / Added FSInfo support. / Fixed DBCS name can result FR_INVALID_NAME. / Fixed short seek (<= csize) collapses the file object. +/ Aug 25, 2007 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. /---------------------------------------------------------------------------*/ #include @@ -109,7 +112,8 @@ FRESULT sync ( /* FR_OK: successful, FR_RW_ERROR: failed */ fs->winflag = 1; if (!move_window(fs, 0)) return FR_RW_ERROR; #if _USE_FSINFO - if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { /* Update FSInfo sector if needed */ + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { fs->winsect = 0; memset(fs->win, 0, 512); ST_WORD(&fs->win[BS_55AA], 0xAA55); @@ -117,10 +121,11 @@ FRESULT sync ( /* FR_OK: successful, FR_RW_ERROR: failed */ ST_DWORD(&fs->win[FSI_StrucSig], 0x61417272); ST_DWORD(&fs->win[FSI_Free_Count], fs->free_clust); ST_DWORD(&fs->win[FSI_Nxt_Free], fs->last_clust); - disk_write(0, fs->win, fs->fsi_sector, 1); + disk_write(fs->drive, fs->win, fs->fsi_sector, 1); fs->fsi_flag = 0; } #endif + /* Make sure that no pending write process in the physical drive */ if (disk_ioctl(fs->drive, CTRL_SYNC, NULL) != RES_OK) return FR_RW_ERROR; return FR_OK; } @@ -601,7 +606,7 @@ BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2 { if (disk_read(fs->drive, fs->win, sect, 1) != RES_OK) /* Load boot record */ return 2; - if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always offset 510) */ + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ return 2; if (!memcmp(&fs->win[BS_FilSysType], "FAT", 3)) /* Check FAT signature */ @@ -623,7 +628,7 @@ static FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */ const char **path, /* Pointer to pointer to the path name (drive number) */ FATFS **rfs, /* Pointer to pointer to the found file system object */ - BYTE chk_wp /* !=0: Check media write protection for wrinting fuctions */ + BYTE chk_wp /* !=0: Check media write protection for write access */ ) { BYTE drv, fmt, *tbl; @@ -639,7 +644,7 @@ FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */ if (drv <= 9 && p[1] == ':') p += 2; /* Found a drive number, get and strip it */ else - drv = 0; /* No drive number is given, select drive 0 in default */ + drv = 0; /* No drive number is given, use drive number 0 as default */ if (*p == '/') p++; /* Strip heading slash */ *path = p; /* Return pointer to the path name */ @@ -720,7 +725,7 @@ FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */ /* Load fsinfo sector if needed */ if (fmt == FS_FAT32) { fs->fsi_sector = bootsect + LD_WORD(&fs->win[BPB_FSInfo]); - if (disk_read(0, fs->win, fs->fsi_sector, 1) == RES_OK && + if (disk_read(fs->drive, fs->win, fs->fsi_sector, 1) == RES_OK && LD_WORD(&fs->win[BS_55AA]) == 0xAA55 && LD_DWORD(&fs->win[FSI_LeadSig]) == 0x41615252 && LD_DWORD(&fs->win[FSI_StrucSig]) == 0x61417272) { @@ -893,20 +898,20 @@ FRESULT f_open ( FRESULT f_read ( FIL *fp, /* Pointer to the file object */ void *buff, /* Pointer to data buffer */ - WORD btr, /* Number of bytes to read */ - WORD *br /* Pointer to number of bytes read */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ ) { DWORD clust, sect, remain; - WORD rcnt; - BYTE cc, *rbuff = buff; + UINT rcnt, cc; + BYTE *rbuff = buff; FRESULT res; FATFS *fs = fp->fs; *br = 0; res = validate(fs, fp->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; if (fp->flag & FA__ERROR) return FR_RW_ERROR; /* Check error flag */ if (!(fp->flag & FA_READ)) return FR_DENIED; /* Check access mode */ remain = fp->fsize - fp->fptr; @@ -937,11 +942,12 @@ FRESULT f_read ( cc = btr / S_SIZ; /* When left bytes >= S_SIZ, */ if (cc) { /* Read maximum contiguous sectors directly */ if (cc > fp->sect_clust) cc = fp->sect_clust; - if (disk_read(fs->drive, rbuff, sect, cc) != RES_OK) + if (disk_read(fs->drive, rbuff, sect, (BYTE)cc) != RES_OK) goto fr_error; - fp->sect_clust -= cc - 1; + fp->sect_clust -= (BYTE)(cc - 1); fp->curr_sect += cc - 1; - rcnt = cc * S_SIZ; continue; + rcnt = cc * S_SIZ; + continue; } if (disk_read(fs->drive, fp->buffer, sect, 1) != RES_OK) /* Load the sector into file I/O buffer */ goto fr_error; @@ -969,21 +975,20 @@ fr_error: /* Abort this file due to an unrecoverable error */ FRESULT f_write ( FIL *fp, /* Pointer to the file object */ const void *buff, /* Pointer to the data to be written */ - WORD btw, /* Number of bytes to write */ - WORD *bw /* Pointer to number of bytes written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ ) { DWORD clust, sect; - WORD wcnt; - BYTE cc; - FRESULT res; + UINT wcnt, cc; const BYTE *wbuff = buff; + FRESULT res; FATFS *fs = fp->fs; *bw = 0; res = validate(fs, fp->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; if (fp->flag & FA__ERROR) return FR_RW_ERROR; /* Check error flag */ if (!(fp->flag & FA_WRITE)) return FR_DENIED; /* Check access mode */ if (fp->fsize + btw < fp->fsize) return FR_OK; /* File size cannot reach 4GB */ @@ -1016,11 +1021,12 @@ FRESULT f_write ( cc = btw / S_SIZ; /* When left bytes >= S_SIZ, */ if (cc) { /* Write maximum contiguous sectors directly */ if (cc > fp->sect_clust) cc = fp->sect_clust; - if (disk_write(fs->drive, wbuff, sect, cc) != RES_OK) + if (disk_write(fs->drive, wbuff, sect, (BYTE)cc) != RES_OK) goto fw_error; - fp->sect_clust -= cc - 1; + fp->sect_clust -= (BYTE)(cc - 1); fp->curr_sect += cc - 1; - wcnt = cc * S_SIZ; continue; + wcnt = cc * S_SIZ; + continue; } if (fp->fptr < fp->fsize && /* Fill sector buffer with file data if needed */ disk_read(fs->drive, fp->buffer, sect, 1) != RES_OK) @@ -1045,7 +1051,7 @@ fw_error: /* Abort this file due to an unrecoverable error */ /*-----------------------------------------------------------------------*/ -/* Synchronize between File and Disk */ +/* Synchronize the file object */ /*-----------------------------------------------------------------------*/ FRESULT f_sync ( @@ -1130,7 +1136,7 @@ FRESULT f_lseek ( res = validate(fs, fp->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; if (fp->flag & FA__ERROR) return FR_RW_ERROR; #if !_FS_READONLY if (fp->flag & FA__DIRTY) { /* Write-back dirty buffer if needed */ @@ -1252,7 +1258,7 @@ FRESULT f_readdir ( res = validate(fs, dirobj->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; finfo->fname[0] = 0; while (dirobj->sect) { @@ -1469,14 +1475,12 @@ FRESULT f_mkdir ( tim = get_fattime(); ST_DWORD(&fw[DIR_WrtTime], tim); memcpy(&fw[32], &fw[0], 32); fw[33] = '.'; /* Create ".." entry */ - pclust = dirobj.sclust; -#if _FAT32 - ST_WORD(&fw[ DIR_FstClusHI], dclust >> 16); - if (fs->fs_type == FS_FAT32 && pclust == fs->dirbase) pclust = 0; - ST_WORD(&fw[32+DIR_FstClusHI], pclust >> 16); -#endif ST_WORD(&fw[ DIR_FstClusLO], dclust); + ST_WORD(&fw[ DIR_FstClusHI], dclust >> 16); + pclust = dirobj.sclust; + if (fs->fs_type == FS_FAT32 && pclust == fs->dirbase) pclust = 0; ST_WORD(&fw[32+DIR_FstClusLO], pclust); + ST_WORD(&fw[32+DIR_FstClusHI], pclust >> 16); fs->winflag = 1; if (!move_window(fs, sect)) return FR_RW_ERROR; @@ -1582,17 +1586,16 @@ FRESULT f_rename ( /* Create File System on the Drive */ /*-----------------------------------------------------------------------*/ -#define N_ROOTDIR 512 -#define N_FATS 1 -#define MAX_SECTOR 64000000UL -#define MIN_SECTOR 2000UL -#define ERASE_BLK 32 +#define N_ROOTDIR 512 /* Multiple of 32 and <= 2048 */ +#define N_FATS 1 /* 1 or 2 */ +#define MAX_SECTOR 64000000UL /* Maximum partition size */ +#define MIN_SECTOR 2000UL /* Minimum partition size */ FRESULT f_mkfs ( BYTE drv, /* Logical drive number */ BYTE partition, /* Partitioning rule 0:FDISK, 1:SFD */ - BYTE allocsize /* Allocation unit size [sectors] */ + WORD allocsize /* Allocation unit size [bytes] */ ) { BYTE fmt, m, *tbl; @@ -1603,17 +1606,18 @@ FRESULT f_mkfs ( DSTATUS stat; - /* Check and mounted drive and clear work area */ + /* Check validity of the parameters */ if (drv >= _DRIVES) return FR_INVALID_DRIVE; + if (partition >= 2) return FR_MKFS_ABORTED; + for (n = 512; n <= 32768U && n != allocsize; n <<= 1); + if (n != allocsize) return FR_MKFS_ABORTED; + + /* Check mounted drive and clear work area */ fs = FatFs[drv]; if (!fs) return FR_NOT_ENABLED; memset(fs, 0, sizeof(FATFS)); drv = LD2PD(drv); - /* Check validity of the parameters */ - for (n = 1; n <= 64 && allocsize != n; n <<= 1); - if (n > 64 || partition >= 2) return FR_MKFS_ABORTED; - /* Get disk statics */ stat = disk_initialize(drv); if (stat & STA_NOINIT) return FR_NOT_READY; @@ -1621,20 +1625,23 @@ FRESULT f_mkfs ( if (disk_ioctl(drv, GET_SECTOR_COUNT, &n_part) != RES_OK || n_part < MIN_SECTOR) return FR_MKFS_ABORTED; if (n_part > MAX_SECTOR) n_part = MAX_SECTOR; - b_part = (!partition) ? 63 : 0; + b_part = (!partition) ? 63 : 0; /* Boot sector */ n_part -= b_part; #if S_MAX_SIZ > 512 /* Check disk sector size */ if (disk_ioctl(drv, GET_SECTOR_SIZE, &S_SIZ) != RES_OK || S_SIZ > S_MAX_SIZ - || (DWORD)S_SIZ * allocsize > 32768U) + || S_SIZ > allocsize) return FR_MKFS_ABORTED; #endif + allocsize /= S_SIZ; /* Number of sectors per cluster */ /* Pre-compute number of clusters and FAT type */ n_clust = n_part / allocsize; fmt = FS_FAT12; if (n_clust >= 0xFF7) fmt = FS_FAT16; if (n_clust >= 0xFFF7) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ switch (fmt) { case FS_FAT12: n_fat = ((n_clust * 3 + 1) / 2 + 3 + S_SIZ - 1) / S_SIZ; @@ -1655,14 +1662,14 @@ FRESULT f_mkfs ( b_dir = b_fat + n_fat * N_FATS; /* Directory start sector */ b_data = b_dir + n_dir; /* Data start sector */ -#ifdef ERASE_BLK - /* Round up data start sector to erase block boundary */ - n = (b_data + ERASE_BLK - 1) & ~(ERASE_BLK - 1); - b_dir += n - b_data; + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(drv, GET_BLOCK_SIZE, &n) != RES_OK) return FR_MKFS_ABORTED; + n = (b_data + n - 1) & ~(n - 1); n_fat += (n - b_data) / N_FATS; -#endif + /* b_dir and b_data are no longer used below */ + /* Determine number of cluster and final check of validity of the FAT type */ - n_clust = (n_part - n_rsv - n_fat * 2 - n_dir) / allocsize; + n_clust = (n_part - n_rsv - n_fat * N_FATS - n_dir) / allocsize; if ( (fmt == FS_FAT16 && n_clust < 0xFF7) || (fmt == FS_FAT32 && n_clust < 0xFFF7)) return FR_MKFS_ABORTED; @@ -1693,7 +1700,8 @@ FRESULT f_mkfs ( } /* Create boot record */ - memset(tbl = fs->win, 0, S_SIZ); + tbl = fs->win; /* Clear buffer */ + memset(tbl, 0, S_SIZ); ST_DWORD(&tbl[BS_jmpBoot], 0x90FEEB); /* Boot code (jmp $, nop) */ ST_WORD(&tbl[BPB_BytsPerSec], S_SIZ); /* Sector size */ tbl[BPB_SecPerClus] = (BYTE)allocsize; /* Sectors per cluster */ @@ -1750,10 +1758,11 @@ FRESULT f_mkfs ( } /* Initialize Root directory */ - for (m = 0; m < 64; m++) { + m = (BYTE)((fmt == FS_FAT32) ? allocsize : n_dir); + do { if (disk_write(drv, tbl, b_fat++, 1) != RES_OK) return FR_RW_ERROR; - } + } while (--m); /* Create FSInfo record if needed */ if (fmt == FS_FAT32) { diff --git a/src/ff.h b/src/ff.h index ce30ae8..c3071d3 100644 --- a/src/ff.h +++ b/src/ff.h @@ -1,5 +1,5 @@ /*--------------------------------------------------------------------------/ -/ FatFs - FAT file system module include file R0.04b (C)ChaN, 2007 +/ FatFs - FAT file system module include file R0.05 (C)ChaN, 2007 /---------------------------------------------------------------------------/ / FatFs module is an experimenal project to implement FAT file system to / cheap microcontrollers. This is a free software and is opened for education, @@ -21,8 +21,8 @@ / 1: Enable word access. / 2: Disable word access and use byte-by-byte access instead. / When the architectural byte order of the MCU is big-endian and/or address -/ miss-aligned access is prohibited, the _MCU_ENDIAN must be set to 2. -/ If it is not the case, it can be set to 1 for good code efficiency. */ +/ miss-aligned access results incorrect behavior, the _MCU_ENDIAN must be set +/ to 2. If it is not the case, it can be set to 1 for good code efficiency. */ #define _FS_READONLY 0 /* Setting _FS_READONLY to 1 defines read only configuration. This removes @@ -193,8 +193,8 @@ typedef enum { FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */ -FRESULT f_read (FIL*, void*, WORD, WORD*); /* Read data from a file */ -FRESULT f_write (FIL*, const void*, WORD, WORD*); /* Write data to a file */ +FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ +FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ FRESULT f_close (FIL*); /* Close an open file object */ FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */ @@ -206,7 +206,7 @@ FRESULT f_unlink (const char*); /* Delete an existing file or directory */ FRESULT f_mkdir (const char*); /* Create a new directory */ FRESULT f_chmod (const char*, BYTE, BYTE); /* Change file/dir attriburte */ FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */ -FRESULT f_mkfs (BYTE, BYTE, BYTE); /* Create a file system on the drive */ +FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */ /* User defined function to give a current time to fatfs module */ @@ -315,10 +315,10 @@ DWORD get_fattime (void); /* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20 #define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) #else #if _MCU_ENDIAN == 2 /* Use byte-by-byte access */ -#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) -#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) -#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) -#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#define LD_WORD(ptr) (WORD)(((WORD)*(volatile BYTE*)((ptr)+1)<<8)|(WORD)*(volatile BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(volatile BYTE*)((ptr)+3)<<24)|((DWORD)*(volatile BYTE*)((ptr)+2)<<16)|((WORD)*(volatile BYTE*)((ptr)+1)<<8)|*(volatile BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(volatile BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(volatile BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) #else #error Do not forget to set _MCU_ENDIAN properly! #endif diff --git a/src/integer.h b/src/integer.h index 8247065..74fd07f 100644 --- a/src/integer.h +++ b/src/integer.h @@ -1,5 +1,6 @@ #ifndef _INTEGER +/* These types are assumed as 16-bit or larger integer */ typedef signed int INT; typedef unsigned int UINT; diff --git a/src/tff.c b/src/tff.c index e4c9081..7fbbc20 100644 --- a/src/tff.c +++ b/src/tff.c @@ -1,5 +1,5 @@ /*--------------------------------------------------------------------------/ -/ FatFs - Tiny FAT file system module R0.04b (C)ChaN, 2007 +/ FatFs - Tiny FAT file system module R0.05 (C)ChaN, 2007 /---------------------------------------------------------------------------/ / The FatFs module is an experimenal project to implement FAT file system to / cheap microcontrollers. This is a free software and is opened for education, @@ -33,6 +33,7 @@ / Fixed some problems corresponds to FAT32 support. / Fixed DBCS name can result FR_INVALID_NAME. / Fixed short seek (<= csize) collapses the file object. +/ Aug 25, 2007 R0.05 Changed arguments of f_read() and f_write(). /---------------------------------------------------------------------------*/ #include @@ -108,7 +109,8 @@ FRESULT sync (void) /* FR_OK: successful, FR_RW_ERROR: failed */ fs->winflag = 1; if (!move_window(0)) return FR_RW_ERROR; #if _USE_FSINFO - if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { /* Update FSInfo sector if needed */ + /* Update FSInfo sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag) { fs->winsect = 0; memset(fs->win, 0, 512); ST_WORD(&fs->win[BS_55AA], 0xAA55); @@ -120,6 +122,7 @@ FRESULT sync (void) /* FR_OK: successful, FR_RW_ERROR: failed */ fs->fsi_flag = 0; } #endif + /* Make sure that no pending write process in the physical drive */ if (disk_ioctl(0, CTRL_SYNC, NULL) != RES_OK) return FR_RW_ERROR; return FR_OK; } @@ -633,7 +636,7 @@ BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2 static FRESULT auto_mount ( /* FR_OK(0): successful, !=0: any error occured */ const char **path, /* Pointer to pointer to the path name (drive number) */ - BYTE chk_wp /* !=0: Check media write protection for wrinting fuctions */ + BYTE chk_wp /* !=0: Check media write protection for write access */ ) { BYTE fmt; @@ -901,21 +904,21 @@ FRESULT f_open ( FRESULT f_read ( FIL *fp, /* Pointer to the file object */ void *buff, /* Pointer to data buffer */ - WORD btr, /* Number of bytes to read */ - WORD *br /* Pointer to number of bytes read */ + UINT btr, /* Number of bytes to read */ + UINT *br /* Pointer to number of bytes read */ ) { DWORD sect, remain; - WORD rcnt; + UINT rcnt, cc; CLUST clust; - BYTE cc, *rbuff = buff; + BYTE *rbuff = buff; FRESULT res; FATFS *fs = fp->fs; *br = 0; res = validate(fs, fp->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; if (fp->flag & FA__ERROR) return FR_RW_ERROR; /* Check error flag */ if (!(fp->flag & FA_READ)) return FR_DENIED; /* Check access mode */ remain = fp->fsize - fp->fptr; @@ -939,11 +942,12 @@ FRESULT f_read ( cc = btr / 512; /* When left bytes >= 512, */ if (cc) { /* Read maximum contiguous sectors directly */ if (cc > fp->sect_clust) cc = fp->sect_clust; - if (disk_read(0, rbuff, sect, cc) != RES_OK) + if (disk_read(0, rbuff, sect, (BYTE)cc) != RES_OK) goto fr_error; - fp->sect_clust -= cc - 1; + fp->sect_clust -= (BYTE)(cc - 1); fp->curr_sect += cc - 1; - rcnt = cc * 512; continue; + rcnt = cc * 512; + continue; } } if (!move_window(fp->curr_sect)) goto fr_error; /* Move sector window */ @@ -970,14 +974,13 @@ fr_error: /* Abort this function due to an unrecoverable error */ FRESULT f_write ( FIL *fp, /* Pointer to the file object */ const void *buff, /* Pointer to the data to be written */ - WORD btw, /* Number of bytes to write */ - WORD *bw /* Pointer to number of bytes written */ + UINT btw, /* Number of bytes to write */ + UINT *bw /* Pointer to number of bytes written */ ) { DWORD sect; - WORD wcnt; + UINT wcnt, cc; CLUST clust; - BYTE cc; FRESULT res; const BYTE *wbuff = buff; FATFS *fs = fp->fs; @@ -985,7 +988,7 @@ FRESULT f_write ( *bw = 0; res = validate(fs, fp->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; if (fp->flag & FA__ERROR) return FR_RW_ERROR; /* Check error flag */ if (!(fp->flag & FA_WRITE)) return FR_DENIED; /* Check access mode */ if (fp->fsize + btw < fp->fsize) return FR_OK; /* File size cannot reach 4GB */ @@ -1013,11 +1016,12 @@ FRESULT f_write ( cc = btw / 512; /* When left bytes >= 512, */ if (cc) { /* Write maximum contiguous sectors directly */ if (cc > fp->sect_clust) cc = fp->sect_clust; - if (disk_write(0, wbuff, sect, cc) != RES_OK) + if (disk_write(0, wbuff, sect, (BYTE)cc) != RES_OK) goto fw_error; - fp->sect_clust -= cc - 1; + fp->sect_clust -= (BYTE)(cc - 1); fp->curr_sect += cc - 1; - wcnt = cc * 512; continue; + wcnt = cc * 512; + continue; } if (fp->fptr >= fp->fsize) { /* Flush R/W window if needed */ if (!move_window(0)) goto fw_error; @@ -1026,7 +1030,7 @@ FRESULT f_write ( } if (!move_window(fp->curr_sect)) /* Move sector window */ goto fw_error; - wcnt = 512 - (WORD)(fp->fptr % 512); /* Copy fractional bytes bytes to sector window */ + wcnt = 512 - (WORD)(fp->fptr % 512); /* Copy fractional bytes bytes to sector window */ if (wcnt > btw) wcnt = btw; memcpy(&fs->win[(WORD)fp->fptr % 512], wbuff, wcnt); fs->winflag = 1; @@ -1045,7 +1049,7 @@ fw_error: /* Abort this function due to an unrecoverable error */ /*-----------------------------------------------------------------------*/ -/* Synchronize between File and Disk */ +/* Synchronize the file object */ /*-----------------------------------------------------------------------*/ FRESULT f_sync ( @@ -1128,7 +1132,7 @@ FRESULT f_lseek ( res = validate(fs, fp->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; if (fp->flag & FA__ERROR) return FR_RW_ERROR; #if !_FS_READONLY @@ -1247,7 +1251,7 @@ FRESULT f_readdir ( res = validate(fs, dirobj->id); /* Check validity of the object */ - if (res) return res; + if (res != FR_OK) return res; finfo->fname[0] = 0; while (dirobj->sect) { diff --git a/src/tff.h b/src/tff.h index e5f5807..73e3c4c 100644 --- a/src/tff.h +++ b/src/tff.h @@ -1,5 +1,5 @@ /*--------------------------------------------------------------------------/ -/ Tiny-FatFs - FAT file system module include file R0.04b (C)ChaN, 2007 +/ Tiny-FatFs - FAT file system module include file R0.05 (C)ChaN, 2007 /---------------------------------------------------------------------------/ / FatFs module is an experimenal project to implement FAT file system to / cheap microcontrollers. This is a free software and is opened for education, @@ -21,8 +21,8 @@ / 1: Enable word access. / 2: Disable word access and use byte-by-byte access instead. / When the architectural byte order of the MCU is big-endian and/or address -/ miss-aligned access is prohibited, the _MCU_ENDIAN must be set to 2. -/ If it is not the case, it can be set to 1 for good code efficiency. */ +/ miss-aligned access results incorrect behavior, the _MCU_ENDIAN must be set +/ to 2. If it is not the case, it can be set to 1 for good code efficiency. */ #define _FS_READONLY 0 /* Setting _FS_READONLY to 1 defines read only configuration. This removes @@ -155,8 +155,8 @@ typedef enum { FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */ FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */ -FRESULT f_read (FIL*, void*, WORD, WORD*); /* Read data from a file */ -FRESULT f_write (FIL*, const void*, WORD, WORD*); /* Write data to a file */ +FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */ +FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */ FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */ FRESULT f_close (FIL*); /* Close an open file object */ FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */ @@ -275,10 +275,10 @@ DWORD get_fattime (void); /* 31-25: Year(0-127 +1980), 24-21: Month(1-12), 20-16 #define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) #else #if _MCU_ENDIAN == 2 /* Use byte-by-byte access */ -#define LD_WORD(ptr) (WORD)(((WORD)*(BYTE*)((ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) -#define LD_DWORD(ptr) (DWORD)(((DWORD)*(BYTE*)((ptr)+3)<<24)|((DWORD)*(BYTE*)((ptr)+2)<<16)|((WORD)*(BYTE*)((ptr)+1)<<8)|*(BYTE*)(ptr)) -#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) -#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *(BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) +#define LD_WORD(ptr) (WORD)(((WORD)*(volatile BYTE*)((ptr)+1)<<8)|(WORD)*(volatile BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*(volatile BYTE*)((ptr)+3)<<24)|((DWORD)*(volatile BYTE*)((ptr)+2)<<16)|((WORD)*(volatile BYTE*)((ptr)+1)<<8)|*(volatile BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(volatile BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(volatile BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24) #else #error Do not forget to set _MCU_ENDIAN properly! #endif