diff --git a/doc/00index_e.html b/doc/00index_e.html index dbdf70a..90f8db9 100644 --- a/doc/00index_e.html +++ b/doc/00index_e.html @@ -4,8 +4,6 @@ - - ELM - FatFs Generic FAT File System Module @@ -96,7 +94,7 @@

The FatFs module is a free software opened for education, research and development. You can use, modify and/or redistribute it for personal projects or commercial products without any restriction under your responsibility. For further information, refer to the application note.

- -
-

Return

diff --git a/doc/00index_j.html b/doc/00index_j.html index 0793a19..1b7a5bf 100644 --- a/doc/00index_j.html +++ b/doc/00index_j.html @@ -4,8 +4,6 @@ - - ELM - FatFs 汎用FATファイルシステム・モジュール @@ -95,7 +93,7 @@

FatFsモジュールはフリー・ソフトウェアとして教育・研究・開発用に公開しています。どのような利用目的(個人利用から商用まで)でも使用・改変・配布について一切の制限はありませんが、全て利用者の責任の下での利用とします。詳しくはアプリケーション・ノートを参照してください。

- -
-

戻る

diff --git a/doc/en/appnote.html b/doc/en/appnote.html index c7ed26b..15c7ca3 100644 --- a/doc/en/appnote.html +++ b/doc/en/appnote.html @@ -41,7 +41,7 @@ The FatFs module assumes that size of char/short/long are 8/16/32 bit and int is

System organizations

The dependency diagram shown below is a typical configuration of the embedded system with FatFs module.

-dependency diagram +

dependency diagram

Which function is required?

You need to provide only low level disk I/O functions that required by FatFs module and nothing else. If a working disk module for the target is already existing, you need to write only glue functions to attach it to the FatFs module. If not, you need to port any other disk module or write it from scratch. All defined functions are not that always required. For example, disk write function is not required in read-only configuration. Following table shows which function is required depends on configuration options.

@@ -72,17 +72,17 @@ The FatFs module assumes that size of char/short/long are 8/16/32 bit and int is
-

Memory Usage (R0.09)

+

Memory Usage (R0.09a)

- + - - - - - - + + + + + +
ARM7
32bit
ARM7
Thumb
Cortex-M3
Thumb-2
AVRH8/300HPIC24RL78V850ESSH-2ARX600IA-32
ARM7
32bit
ARM7
Thumb
CM3
Thumb-2
AVRH8/300HPIC24RL78V850ESSH-2ARX600IA-32
CompilerGCCGCCGCCGCCCH38C30CC78K0RCA850SHCRXCVC6
_WORD_ACCESS00010001011
text (Full, R/W)1045972016623126461068611466129677732875257477545
text (Min, R/W)65034745429783066986744087454938557637464923
text (Full, R/O)45353181286959604876528660603554380426593450
text (Min, R/O)33032493217143663770398446042684294020252664
bssD*4 + 2D*4 + 2D*4 + 2D*2 + 2D*4 + 2D*2 + 2D*2 + 2D*4 + 2D*4 + 2D*4 + 2D*4 + 2
Work area
(_FS_TINY == 0)
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
V*560 +
F*544
V*560 +
F*550
V*560 +
F*544
V*560 +
F*544
V*560 +
F*544
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
text (Full, R/W)1037570196561132671052511205128127783871557827615
text (Min, R/W) 648747274283 8521 6967 7398 88005019563537845003
text (Full, R/O) 455131252895 6219 4895 5268 61233629384326993527
text (Min, R/O) 332124572197 4527 3797 3999 46632773299920642736
bssD*4 + 2D*4 + 2D*4 + 2D*2 + 2D*4 + 2D*2 + 2D*2 + 2D*4 + 2D*4 + 2D*4 + 2D*4 + 2
Work area
(_FS_TINY == 0)
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
V*560 +
F*544
V*560 +
F*550
V*560 +
F*544
V*560 +
F*544
V*560 +
F*544
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
Work area
(_FS_TINY == 1)
V*560 +
F*36
V*560 +
F*36
V*560 +
F*36
V*560 +
F*32
V*560 +
F*36
V*560 +
F*32
V*560 +
F*32
V*560 +
F*36
V*560 +
F*36
V*560 +
F*36
V*560 +
F*36

These are the memory usage on some target systems with following condition. The memory sizes are in unit of byte, V means number of mounted volumes and F means number of open files. All samples are optimezed in code size.

@@ -100,7 +100,7 @@ _FS_RPATH 0 (Disable relative path) _VOLUMES D (Number of logical drives to be used) _MULTI_PARTITION 0 (Single partition per drive) _FS_REENTRANT 0 (Disable reentrancy) -_FS_SHARE 0 (Disable shareing control) +_FS_LOCK 0 (Disable shareing control)
@@ -172,7 +172,7 @@ _FS_SHARE 0 (Disable shareing control)

Duplicated File Access

FatFs module does not support the shareing controls of duplicated file access in default. It is permitted when open method to a file is only read mode. The duplicated open in write mode to a file is always prohibited and open file must not be renamed, deleted, or the FAT structure on the volume can be collapted.

-

The file shareing control can also be available when _FS_SHARE is set to 1 or grater. The value specifies the number of files to manage simultaneously. In this case, if any open, rename or remove that violating the file shareing rule that described above is attempted, the file function will fail with FR_LOCKED. If number of open files gets larger than _FS_SHARE, the f_open function will fail with FR_TOO_MANY_OPEN_FILES.

+

The file shareing control can also be available when _FS_LOCK is set to 1 or grater. The value specifies the number of files to manage simultaneously. In this case, if any open, rename or remove that violating the file shareing rule that described above is attempted, the file function will fail with FR_LOCKED. If number of open files gets larger than _FS_LOCK, the f_open function will fail with FR_TOO_MANY_OPEN_FILES.

diff --git a/doc/en/dinit.html b/doc/en/dinit.html index f7ac0bd..c02adc3 100644 --- a/doc/en/dinit.html +++ b/doc/en/dinit.html @@ -38,7 +38,7 @@ DSTATUS disk_initialize (

Description

The disk_initialize function initializes a physical drive and put it ready to read/write. When the function succeeded, STA_NOINIT flag in the return value is cleard.

-

Application program MUST NOT call this function, or FAT structure on the volume can be corrapted. To re-initialize the file system, use f_mount function.This function is called on volume mount process in the FatFs module to manage the media change.

+

Application program MUST NOT call this function, or FAT structure on the volume can be corrapted. To re-initialize the file system, use f_mount function instead.This function is called on volume mount process in the FatFs module to manage the media change.

Return

diff --git a/doc/en/dread.html b/doc/en/dread.html index 833a042..8708456 100644 --- a/doc/en/dread.html +++ b/doc/en/dread.html @@ -30,7 +30,7 @@ DRESULT disk_read (
Drive
Specifies the physical drive number.
Buffer
-
Pointer to the byte array to store the read data. The buffer size of number of bytes to be read, sector size * sector count, is required. Note that the specified memory address is not that always aligned to word boundary. If the hardware does not support misaligned data transfer, it must be solved in this function.
+
Pointer to the byte array to store the read data. The size of buffer must be in sector size * sector count.
SectorNumber
Specifies the start sector number in logical block address (LBA).
SectorCount
@@ -54,6 +54,17 @@ DRESULT disk_read (
+
+

Description

+

The specified memory address is not that always aligned to word boundary because the type of pointer is defined as BYTE. The misaligned read/write request can occure at direct transfer. If the bus architecture, especially DMA controller, does not allow misaligned memory access, it should be solved in this function. There are some workarounds below to avoid this problem.

+ +
+ +

Return

diff --git a/doc/en/dwrite.html b/doc/en/dwrite.html index c808cff..af80048 100644 --- a/doc/en/dwrite.html +++ b/doc/en/dwrite.html @@ -30,7 +30,7 @@ DRESULT disk_write (
Drive
Specifies the physical drive number.
Buffer
-
Pointer to the byte array to be written. Note that the specified memory address is not that always aligned to word boundary. If the hardware does not support misaligned data transfer, it must be solved in this function.
+
Pointer to the byte array to be written.
SectorNumber
Specifies the start sector number in logical block address (LBA).
SectorCount
@@ -58,7 +58,7 @@ DRESULT disk_write (

Description

-

This function is not required in read only configuration.

+

This function is not required in read only configuration. The specified memory address is not that always aligned to word boundary because the type of pointer is defined as BYTE. For more information, read description in disk_read function.

diff --git a/doc/en/rc.html b/doc/en/rc.html index 7544355..9c4881c 100644 --- a/doc/en/rc.html +++ b/doc/en/rc.html @@ -68,7 +68,7 @@
FR_TIMEOUT
The function canceled due to a timeout of thread-safe control. (Related option: _TIMEOUT)
FR_LOCKED
-
The file access is rejected by file sharing control. (Related option: _FS_SHARE)
+
The file access is rejected by file sharing control. (Related option: _FS_LOCK)
FR_NOT_ENOUGH_CORE
Not enough memory for the operation. There is one of the following reasons:
FR_TOO_MANY_OPEN_FILES
-
Number of open files has been reached maximum value and no more file can be opened. (Related option: _FS_SHARE)
+
Number of open files has been reached maximum value and no more file can be opened. (Related option: _FS_LOCK)
FR_INVALID_PARAMETER
The given parameter is invalid or there is any inconsistent.
diff --git a/doc/en/read.html b/doc/en/read.html index 52f824d..399dd27 100644 --- a/doc/en/read.html +++ b/doc/en/read.html @@ -54,7 +54,7 @@ FRESULT f_read (

Description

-

The file pointer of the file object increases in number of bytes read. After the function succeeded, *ByteRead should be checked to detect the end of file. In case of *ByteRead < ByteToRead, it means the read/write pointer reached end of the file during read operation.

+

The file read/write pointer of the file object advances number of bytes read. After the function succeeded, *ByteRead should be checked to detect the end of file. In case of *ByteRead < ByteToRead, it means the read/write pointer reached end of the file during read operation.

diff --git a/doc/en/write.html b/doc/en/write.html index 42ae73b..eb5e847 100644 --- a/doc/en/write.html +++ b/doc/en/write.html @@ -54,7 +54,7 @@ FRESULT f_write (

Description

-

The read/write pointer in the file object is increased in number of bytes written. After the function succeeded, *ByteWritten should be checked to detect the disk full. In case of *ByteWritten < ByteToWrite, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.

+

The read/write pointer of the file object advances number of bytes written. After the function succeeded, *ByteWritten should be checked to detect the disk full. In case of *ByteWritten < ByteToWrite, it means the volume got full during the write operation. The function can take a time when the volume is full or close to full.

diff --git a/doc/img/modules.png b/doc/img/modules.png new file mode 100644 index 0000000..f89d831 Binary files /dev/null and b/doc/img/modules.png differ diff --git a/doc/ja/appnote.html b/doc/ja/appnote.html index 5d84f37..cadd0aa 100644 --- a/doc/ja/appnote.html +++ b/doc/ja/appnote.html @@ -42,7 +42,7 @@ FatFs繝「繧ク繝・繝シ繝ォ縺ッANSI C(C89)貅匁侠縺ァ險倩ソー縺輔l縺ヲ縺繧九ョ縺ァ縲、NSI C

繧キ繧ケ繝繝讒区

荳九↓遉コ縺吩セ晏ュ倬未菫ょ峙縺ッ縲:atFs繝「繧ク繝・繝シ繝ォ蛻ゥ逕ィ縺ョ邨縺ソ霎シ縺ソ繧キ繧ケ繝繝縺ォ縺翫¢繧倶サ」陦ィ逧縺ェ讒区舌r遉コ縺励∪縺吶

-繧キ繧ケ繝繝讒区仙峙 +

繧キ繧ケ繝繝讒区仙峙

繝ヲ繝シ繧カ縺ョ菴懈舌☆繧矩未謨ー

蠢隕√↑縺ョ縺ッ FatFs繝「繧ク繝・繝シ繝ォ縺ョ隕∵アゅ☆繧九ョ繧」繧ケ繧ッ髢「謨ー繧堤畑諢上☆繧九%縺ィ縺縺代〒縲√◎繧御サ・螟悶↓縺吶k縺薙→縺ッ縺ゅj縺セ縺帙s縲よ里縺ォ蜍穂ス懊@縺ヲ縺繧九ョ繧」繧ケ繧ッ髢「謨ー縺後≠繧九↑繧峨◎縺ョ API繧 FatFs縺ォ蜷医o縺帙k縺縺代〒貂医∩縺セ縺吶′縲∫┌縺蝣エ蜷医ッ縺サ縺九°繧臥ァサ讀阪☆繧九°縲∵怙蛻昴°繧画嶌縺上°縺吶k蠢隕√′縺ゅj縺セ縺吶ょョ夂セゥ縺輔l縺ヲ縺繧句ィ縺ヲ縺ョ髢「謨ー縺悟クク縺ォ蠢隕√↑繧上¢縺ァ縺ッ縺ゅj縺セ縺帙s縲ゆセ九∴縺ー縲√Μ繝シ繝峨サ繧ェ繝ウ繝ェ繝シ讒区舌〒縺ッ譖ク縺崎セシ縺ソ邉サ髢「謨ー縺ッ蠢隕√≠繧翫∪縺帙s縲よャ。縺ョ陦ィ縺ォ讒区舌が繝励す繝ァ繝ウ縺ィ隕∵アゅ&繧後k髢「謨ー縺ョ蟇セ蠢懊r遉コ縺励∪縺吶

@@ -73,21 +73,22 @@ FatFs繝「繧ク繝・繝シ繝ォ縺ッANSI C(C89)貅匁侠縺ァ險倩ソー縺輔l縺ヲ縺繧九ョ縺ァ縲、NSI C
-

繝。繝「繝ェ菴ソ逕ィ驥 (R0.09)

+

繝。繝「繝ェ菴ソ逕ィ驥

谺。縺ョ陦ィ縺ォ縺縺上▽縺九ョ繧ソ繝シ繧イ繝繝医↓縺翫¢繧九Γ繝「繝ェ菴ソ逕ィ驥上ョ萓九r遉コ縺励∪縺吶ゅユ繧ケ繝域凾縺ョ讒区舌が繝励す繝ァ繝ウ縺ッ縺昴ョ荳九ョ騾壹j縺ァ縺吶よ焚蛟、縺ョ蜊倅ス阪ッ繝舌う繝医〒縲V縺ッ蜷梧凾繝槭え繝ウ繝医サ繝懊Μ繝・繝シ繝謨ー縲F縺ッ蜷梧凾繧ェ繝シ繝励Φ繝サ繝輔ぃ繧、繝ォ謨ー繧堤、コ縺励∪縺吶ゅさ繝ウ繝代う繝ゥ縺ョ譛驕ゥ蛹悶が繝励す繝ァ繝ウ縺ッ繧ウ繝シ繝峨サ繧オ繧、繧コ縺ィ縺励※縺縺セ縺吶

- + - - - - - - + + + + + +
ARM7
32bit
ARM7
Thumb
Cortex-M3
Thumb-2
AVRH8/300HPIC24RL78V850ESSH-2ARX600IA-32
ARM7
32bit
ARM7
Thumb
CM3
Thumb-2
AVRH8/300HPIC24RL78V850ESSH-2ARX600IA-32
CompilerGCCGCCGCCGCCCH38C30CC78K0RCA850SHCRXCVC6
_WORD_ACCESS00010001011
text (Full, R/W)1045972016623126461068611466129677732875257477545
text (Min, R/W)65034745429783066986744087454938557637464923
text (Full, R/O)45353181286959604876528660603554380426593450
text (Min, R/O)33032493217143663770398446042684294020252664
bssD*4 + 2D*4 + 2D*4 + 2D*2 + 2D*4 + 2D*2 + 2D*2 + 2D*4 + 2D*4 + 2D*4 + 2D*4 + 2
Work area
(_FS_TINY == 0)
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
V*560 +
F*544
V*560 +
F*550
V*560 +
F*544
V*560 +
F*544
V*560 +
F*544
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
text (Full, R/W)1037570196561132671052511205128127783871557827615
text (Min, R/W) 648747274283 8521 6967 7398 88005019563537845003
text (Full, R/O) 455131252895 6219 4895 5268 61233629384326993527
text (Min, R/O) 332124572197 4527 3797 3999 46632773299920642736
bssD*4 + 2D*4 + 2D*4 + 2D*2 + 2D*4 + 2D*2 + 2D*2 + 2D*4 + 2D*4 + 2D*4 + 2D*4 + 2
Work area
(_FS_TINY == 0)
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
V*560 +
F*544
V*560 +
F*550
V*560 +
F*544
V*560 +
F*544
V*560 +
F*544
V*560 +
F*550
V*560 +
F*550
V*560 +
F*550
Work area
(_FS_TINY == 1)
V*560 +
F*36
V*560 +
F*36
V*560 +
F*36
V*560 +
F*32
V*560 +
F*36
V*560 +
F*32
V*560 +
F*32
V*560 +
F*36
V*560 +
F*36
V*560 +
F*36
V*560 +
F*36
+FatFs R0.09a options:
 _FS_READONLY     0 (R/W), 1 (R/O)
 _FS_MINIMIZE     0 (Full function), 3 (Minimized function)
 _USE_STRFUNC     0 (Disable string functions)
@@ -101,7 +102,7 @@ _FS_RPATH        0 (Disable relative path)
 _VOLUMES         D (Number of logical drives to be used)
 _MULTI_PARTITION 0 (Single partition per drive)
 _FS_REENTRANT    0 (Disable reentrancy)
-_FS_SHARE        0 (Disable shareing control)
+_FS_LOCK         0 (Disable file lock control)
 
@@ -179,7 +180,7 @@ _FS_SHARE 0 (Disable shareing control)

螟夐阪ヵ繧。繧、繝ォ繝サ繧「繧ッ繧サ繧ケ

FatFs繝「繧ク繝・繝シ繝ォ縺ァ縺ッ繝繝輔か繝ォ繝医〒縺ッ螟夐阪い繧ッ繧サ繧ケ蛻カ蠕。讖溯ス繧偵し繝昴シ繝医@縺ヲ縺縺セ縺帙s縲ゅヵ繧。繧、繝ォ縺ォ蟇セ縺吶k螟夐阪い繧ッ繧サ繧ケ縺ッ縲√◎縺ョ繧「繧ッ繧サ繧ケ繝サ繝「繝シ繝峨↓繧医▲縺ヲ蛻カ髯舌&繧後∪縺吶ゆク縺、縺ョ繝輔ぃ繧、繝ォ縺ォ蟇セ縺吶k螟夐阪が繝シ繝励Φ縺ッ縲√◎繧後i縺悟ィ縺ヲ繝ェ繝シ繝峨サ繝「繝シ繝峨ョ縺ィ縺阪↓髯舌▲縺ヲ險ア蜿ッ縺輔l縺セ縺吶よ嶌縺崎セシ縺ソ繝「繝シ繝峨r蜷ォ繧螟夐阪が繝シ繝励Φ縲√∪縺滄幕縺九l縺ヲ縺繧九ヵ繧。繧、繝ォ縺ォ蟇セ縺吶k繝ェ繝阪シ繝繧蜑企勁繧定。後▲縺ヲ縺ッ縺ェ繧翫∪縺帙s縲ゅ&繧ゅ↑縺縺ィ縲√◎縺ョ繝懊Μ繝・繝シ繝縺ョFAT讒矩縺檎エ螢翫&繧後k蜿ッ閭ス諤ァ縺後≠繧翫∪縺吶

-

_FS_SHARE縺ォ1莉・荳翫ョ蛟、(蛟、縺ッ蜷梧凾縺ォ邂。逅縺ァ縺阪k繝輔ぃ繧、繝ォ謨ー)繧偵そ繝繝医☆繧九%縺ィ縺ァ螟夐阪い繧ッ繧サ繧ケ蛻カ蠕。讖溯ス縺梧怏蜉ケ縺ォ縺ェ繧翫√ヵ繧。繧、繝ォ蜊倅ス阪ョ謗剃サ門宛蠕。繧定ェ蜍輔〒陦後≧縺薙→繧ゅ〒縺阪∪縺吶ゅ%縺ョ蝣エ蜷医∽ク願ィ倥ョ繝ォ繝シ繝ォ繧堤エ縺」縺溘が繝シ繝励Φ繝サ繝ェ繝阪シ繝繝サ蜑企勁繧定ゥヲ縺ソ繧九→縲√◎縺ョ髢「謨ー縺ッFR_LOCKED縺ァ螟ア謨励@縺セ縺吶_FS_SHARE繧定カ翫∴縺滓焚縺ョ繝輔ぃ繧、繝ォ繧偵が繝シ繝励Φ縺励h縺縺ィ縺吶k縺ィ縲FR_TOO_MANY_OPEN_FILES縺ァ螟ア謨励@縺セ縺吶

+

_FS_LOCK縺ォ1莉・荳翫ョ蛟、(蛟、縺ッ蜷梧凾縺ォ邂。逅縺ァ縺阪k繝輔ぃ繧、繝ォ謨ー)繧偵そ繝繝医☆繧九%縺ィ縺ァ螟夐阪い繧ッ繧サ繧ケ蛻カ蠕。讖溯ス縺梧怏蜉ケ縺ォ縺ェ繧翫√ヵ繧。繧、繝ォ蜊倅ス阪ョ謗剃サ門宛蠕。繧定ェ蜍輔〒陦後≧縺薙→繧ゅ〒縺阪∪縺吶ゅ%縺ョ蝣エ蜷医∽ク願ィ倥ョ繝ォ繝シ繝ォ繧堤エ縺」縺溘が繝シ繝励Φ繝サ繝ェ繝阪シ繝繝サ蜑企勁繧定ゥヲ縺ソ繧九→縲√◎縺ョ髢「謨ー縺ッFR_LOCKED縺ァ螟ア謨励@縺セ縺吶_FS_LOCK繧定カ翫∴縺滓焚縺ョ繝輔ぃ繧、繝ォ繧偵が繝シ繝励Φ縺励h縺縺ィ縺吶k縺ィ縲FR_TOO_MANY_OPEN_FILES縺ァ螟ア謨励@縺セ縺吶

diff --git a/doc/updates.txt b/doc/updates.txt index a592ff2..99a03c6 100644 --- a/doc/updates.txt +++ b/doc/updates.txt @@ -1,11 +1,16 @@ -R0.09, Sep 6, 2011 +R0.09a, Aug 27, 2012 + Fixed assertion failure due to OS/2 EA on FAT12/16. + Changed API rejects null object pointer to avoid crash. + Changed option name _FS_SHARE to _FS_LOCK. + +R0.09, Sep 06, 2011 f_mkfs() supports multiple partition to finish the multiple partition feature. Added f_fdisk(). (_MULTI_PARTITION = 2) R0.08b, Jan 15, 2011 Fast seek feature is also applied to f_read() and f_write(). f_lseek() reports required table size on creating CLMP. - Extended format syntax of f_printf function. + Extended format syntax of f_printf(). Ignores duplicated directory separators in given path names. R0.08a, Aug 16, 2010 diff --git a/src/00readme.txt b/src/00readme.txt index cfcdd4a..768b40b 100644 --- a/src/00readme.txt +++ b/src/00readme.txt @@ -1,4 +1,4 @@ -FatFs Module Source Files R0.09 (C)ChaN, 2011 +FatFs Module Source Files R0.09a (C)ChaN, 2012 FILES @@ -7,7 +7,8 @@ FILES ff.h Common include file for FatFs and application module. ff.c FatFs module. diskio.h Common include file for FatFs and disk I/O module. - integer.h Alternative type definitions for integer variables. + diskio.c An example of glue function to attach existing disk I/O module to FatFs. + integer.h Integer type definitions for FatFs. option Optional external functions. Low level disk I/O module is not included in this archive because the FatFs @@ -23,7 +24,7 @@ AGREEMENTS small embedded systems. This is a free software and is opened for education, research and commercial developments under license policy of following trems. - Copyright (C) 2011, ChaN, all right reserved. + Copyright (C) 2012, ChaN, all right reserved. * The FatFs module is a free software and there is NO WARRANTY. * No restriction on use. You can use, modify and redistribute it for @@ -128,3 +129,7 @@ REVISION HISTORY Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. Added f_fdisk(). (_MULTI_PARTITION = 2) + + Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16. + Changed f_open() and f_opendir() reject null object pointer to avoid crash. + Changed option name _FS_SHARE to _FS_LOCK. diff --git a/src/diskio.c b/src/diskio.c new file mode 100644 index 0000000..60dff08 --- /dev/null +++ b/src/diskio.c @@ -0,0 +1,236 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2012 */ +/*-----------------------------------------------------------------------*/ +/* If a working storage control module is available, it should be */ +/* attached to the FatFs via a glue function rather than modifying it. */ +/* This is an example of glue functions to attach various exsisting */ +/* storage control module to the FatFs module with a defined API. */ +/*-----------------------------------------------------------------------*/ + +#include "diskio.h" /* FatFs lower layer API */ +#include "usbdisk.h" /* Example: USB drive control */ +#include "atadrive.h" /* Example: ATA drive control */ +#include "sdcard.h" /* Example: MMC/SDC contorl */ + +/* Definitions of physical drive number for each media */ +#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; +} + + + +/*-----------------------------------------------------------------------*/ +/* Get 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 address (LBA) */ + BYTE count /* Number of sectors to read (1..128) */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + // translate the arguments here + + result = ATA_disk_read(buff, sector, count); + + // translate the reslut code here + + return res; + + case MMC : + // translate the arguments here + + result = MMC_disk_read(buff, sector, count); + + // translate the reslut code here + + return res; + + case USB : + // translate the arguments here + + result = USB_disk_read(buff, sector, count); + + // translate the reslut code here + + return res; + } + return RES_PARERR; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +#if _USE_WRITE +DRESULT disk_write ( + BYTE drv, /* Physical drive nmuber (0..) */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector address (LBA) */ + BYTE count /* Number of sectors to write (1..128) */ +) +{ + DRESULT res; + int result; + + switch (drv) { + case ATA : + // translate the arguments here + + result = ATA_disk_write(buff, sector, count); + + // translate the reslut code here + + return res; + + case MMC : + // translate the arguments here + + result = MMC_disk_write(buff, sector, count); + + // translate the reslut code here + + return res; + + case USB : + // translate the arguments here + + result = USB_disk_write(buff, sector, count); + + // translate the reslut code here + + return res; + } + return RES_PARERR; +} +#endif + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +#if _USE_IOCTL +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; +} +#endif diff --git a/src/diskio.h b/src/diskio.h index 9573e6e..a6facab 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -1,11 +1,16 @@ /*----------------------------------------------------------------------- -/ Low level disk interface modlue include file +/ Low level disk interface modlue include file (C)ChaN, 2012 /-----------------------------------------------------------------------*/ -#ifndef _DISKIO +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED -#define _READONLY 0 /* 1: Remove write functions */ -#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */ +#ifdef __cplusplus +extern "C" { +#endif + +#define _USE_WRITE 1 /* 1: Enable disk_write function */ +#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */ #include "integer.h" @@ -26,19 +31,15 @@ typedef enum { /*---------------------------------------*/ /* Prototypes for disk control functions */ -int assign_drives (int, int); + DSTATUS disk_initialize (BYTE); DSTATUS disk_status (BYTE); DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); -#if _READONLY == 0 DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); -#endif DRESULT disk_ioctl (BYTE, BYTE, void*); - /* Disk Status Bits (DSTATUS) */ - #define STA_NOINIT 0x01 /* Drive not initialized */ #define STA_NODISK 0x02 /* No medium in the drive */ #define STA_PROTECT 0x04 /* Write protected */ @@ -46,17 +47,18 @@ DRESULT disk_ioctl (BYTE, BYTE, void*); /* Command code for disk_ioctrl fucntion */ -/* Generic command (defined for FatFs) */ +/* Generic command (used by FatFs) */ #define CTRL_SYNC 0 /* Flush disk cache (for write functions) */ #define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */ #define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ #define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */ #define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */ -/* Generic command */ +/* Generic command (not used by FatFs) */ #define CTRL_POWER 5 /* Get/Set power status */ #define CTRL_LOCK 6 /* Lock/Unlock media removal */ #define CTRL_EJECT 7 /* Eject media */ +#define CTRL_FORMAT 8 /* Create physical format on the media */ /* MMC/SDC specific ioctl command */ #define MMC_GET_TYPE 10 /* Get card type */ @@ -70,9 +72,17 @@ DRESULT disk_ioctl (BYTE, BYTE, void*); #define ATA_GET_MODEL 21 /* Get model name */ #define ATA_GET_SN 22 /* Get serial number */ -/* NAND specific ioctl command */ -#define NAND_FORMAT 30 /* Create physical format */ + +/* MMC card type flags (MMC_GET_TYPE) */ +#define CT_MMC 0x01 /* MMC ver 3 */ +#define CT_SD1 0x02 /* SD ver 1 */ +#define CT_SD2 0x04 /* SD ver 2 */ +#define CT_SDC (CT_SD1|CT_SD2) /* SD */ +#define CT_BLOCK 0x08 /* Block addressing */ -#define _DISKIO +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/ff.c b/src/ff.c index bc79e2f..059b588 100644 --- a/src/ff.c +++ b/src/ff.c @@ -1,11 +1,11 @@ /*----------------------------------------------------------------------------/ -/ FatFs - FAT file system module R0.09 (C)ChaN, 2011 +/ FatFs - FAT file system module R0.09a (C)ChaN, 2012 /-----------------------------------------------------------------------------/ / FatFs module is a generic FAT file system module for small embedded systems. / This is a free software that opened for education, research and commercial / developments under license policy of following terms. / -/ Copyright (C) 2011, ChaN, all right reserved. +/ Copyright (C) 2012, ChaN, all right reserved. / / * The FatFs module is a free software and there is NO WARRANTY. / * No restriction on use. You can use, modify and redistribute it for @@ -86,10 +86,13 @@ / Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). / f_lseek() reports required table size on creating CLMP. / Extended format syntax of f_printf function. -/ Ignores duplicated directory separators in given path names. +/ Ignores duplicated directory separators in given path name. / / Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. / Added f_fdisk(). (_MULTI_PARTITION = 2) +/ Aug 27,'12 R0.09a Fixed assertion failure due to OS/2 EA on FAT12/16 volume. +/ Changed f_open() and f_opendir reject null object pointer to avoid crash. +/ Changed option name _FS_SHARE to _FS_LOCK. /---------------------------------------------------------------------------*/ #include "ff.h" /* FatFs configurations and declarations */ @@ -102,7 +105,7 @@ ---------------------------------------------------------------------------*/ -#if _FATFS != 6502 /* Revision ID */ +#if _FATFS != 4004 /* Revision ID */ #error Wrong include file (ff.h). #endif @@ -133,10 +136,10 @@ #define ABORT(fs, res) { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); } -/* File shareing feature */ -#if _FS_SHARE +/* File access control feature */ +#if _FS_LOCK #if _FS_READONLY -#error _FS_SHARE must be 0 on read-only cfg. +#error _FS_LOCK must be 0 on read-only cfg. #endif typedef struct { FATFS *fs; /* File ID 1, volume (NULL:blank entry) */ @@ -147,10 +150,6 @@ typedef struct { #endif -/* Misc definitions */ -#define LD_CLUST(dir) (((DWORD)LD_WORD(dir+DIR_FstClusHI)<<16) | LD_WORD(dir+DIR_FstClusLO)) -#define ST_CLUST(dir,cl) {ST_WORD(dir+DIR_FstClusLO, cl); ST_WORD(dir+DIR_FstClusHI, (DWORD)cl>>16);} - /* DBCS code ranges and SBCS extend char conversion table */ @@ -420,7 +419,7 @@ typedef struct { #define BPB_FSVer 42 /* File system version (2) */ #define BPB_RootClus 44 /* Root dir first cluster (4) */ #define BPB_FSInfo 48 /* Offset of FSInfo sector (2) */ -#define BPB_BkBootSec 50 /* Offset of backup boot sectot (2) */ +#define BPB_BkBootSec 50 /* Offset of backup boot sector (2) */ #define BS_DrvNum32 64 /* Physical drive number (2) */ #define BS_BootSig32 66 /* Extended boot signature (1) */ #define BS_VolID32 67 /* Volume serial number (4) */ @@ -437,8 +436,10 @@ typedef struct { #define DIR_Name 0 /* Short file name (11) */ #define DIR_Attr 11 /* Attribute (1) */ #define DIR_NTres 12 /* NT flag (1) */ +#define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */ #define DIR_CrtTime 14 /* Created time (2) */ #define DIR_CrtDate 16 /* Created date (2) */ +#define DIR_LstAccDate 18 /* Last accessed date (2) */ #define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (2) */ #define DIR_WrtTime 22 /* Modified time (2) */ #define DIR_WrtDate 24 /* Modified date (2) */ @@ -451,8 +452,8 @@ typedef struct { #define LDIR_FstClusLO 26 /* Filled by zero (0) */ #define SZ_DIR 32 /* Size of a directory entry */ #define LLE 0x40 /* Last long entry flag in LDIR_Ord */ -#define DDE 0xE5 /* Deleted directory enrty mark in DIR_Name[0] */ -#define NDDE 0x05 /* Replacement of a character collides with DDE */ +#define DDE 0xE5 /* Deleted directory entry mark in DIR_Name[0] */ +#define NDDE 0x05 /* Replacement of the character collides with DDE */ /*------------------------------------------------------------*/ @@ -478,9 +479,9 @@ static BYTE CurrVol; /* Current drive */ #endif -#if _FS_SHARE +#if _FS_LOCK static -FILESEM Files[_FS_SHARE]; /* File lock semaphores */ +FILESEM Files[_FS_LOCK]; /* File lock semaphores */ #endif #if _USE_LFN == 0 /* No LFN feature */ @@ -531,10 +532,10 @@ void mem_cpy (void* dst, const void* src, UINT cnt) { const BYTE *s = (const BYTE*)src; #if _WORD_ACCESS == 1 - while (cnt >= sizeof(int)) { + while (cnt >= sizeof (int)) { *(int*)d = *(int*)s; - d += sizeof(int); s += sizeof(int); - cnt -= sizeof(int); + d += sizeof (int); s += sizeof (int); + cnt -= sizeof (int); } #endif while (cnt--) @@ -589,7 +590,8 @@ void unlock_fs ( FRESULT res /* Result code to be returned */ ) { - if (res != FR_NOT_ENABLED && + if (fs && + res != FR_NOT_ENABLED && res != FR_INVALID_DRIVE && res != FR_INVALID_OBJECT && res != FR_TIMEOUT) { @@ -601,9 +603,9 @@ void unlock_fs ( /*-----------------------------------------------------------------------*/ -/* File shareing control functions */ +/* File lock control functions */ /*-----------------------------------------------------------------------*/ -#if _FS_SHARE +#if _FS_LOCK static FRESULT chk_lock ( /* Check if the file can be accessed */ @@ -614,7 +616,7 @@ FRESULT chk_lock ( /* Check if the file can be accessed */ UINT i, be; /* Search file semaphore table */ - for (i = be = 0; i < _FS_SHARE; i++) { + for (i = be = 0; i < _FS_LOCK; i++) { if (Files[i].fs) { /* Existing entry */ if (Files[i].fs == dj->fs && /* Check if the file matched with an open file */ Files[i].clu == dj->sclust && @@ -623,7 +625,7 @@ FRESULT chk_lock ( /* Check if the file can be accessed */ be++; } } - if (i == _FS_SHARE) /* The file is not opened */ + if (i == _FS_LOCK) /* The file is not opened */ return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new file? */ /* The file has been opened. Reject any open against writing file and all write mode open */ @@ -636,8 +638,8 @@ int enq_lock (void) /* Check if an entry is available for a new file */ { UINT i; - for (i = 0; i < _FS_SHARE && Files[i].fs; i++) ; - return (i == _FS_SHARE) ? 0 : 1; + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + return (i == _FS_LOCK) ? 0 : 1; } @@ -650,15 +652,15 @@ UINT inc_lock ( /* Increment file open counter and returns its index (0:int erro UINT i; - for (i = 0; i < _FS_SHARE; i++) { /* Find the file */ + for (i = 0; i < _FS_LOCK; i++) { /* Find the file */ if (Files[i].fs == dj->fs && Files[i].clu == dj->sclust && Files[i].idx == dj->index) break; } - if (i == _FS_SHARE) { /* Not opened. Register it as new. */ - for (i = 0; i < _FS_SHARE && Files[i].fs; i++) ; - if (i == _FS_SHARE) return 0; /* No space to register (int err) */ + if (i == _FS_LOCK) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + if (i == _FS_LOCK) return 0; /* No space to register (int err) */ Files[i].fs = dj->fs; Files[i].clu = dj->sclust; Files[i].idx = dj->index; @@ -682,7 +684,7 @@ FRESULT dec_lock ( /* Decrement file open counter */ FRESULT res; - if (--i < _FS_SHARE) { + if (--i < _FS_LOCK) { n = Files[i].ctr; if (n == 0x100) n = 0; if (n) n--; @@ -703,7 +705,7 @@ void clear_lock ( /* Clear lock entries of the volume */ { UINT i; - for (i = 0; i < _FS_SHARE; i++) { + for (i = 0; i < _FS_LOCK; i++) { if (Files[i].fs == fs) Files[i].fs = 0; } } @@ -825,7 +827,7 @@ DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status BYTE *p; - if (clst < 2 || clst >= fs->n_fatent) /* Chack range */ + if (clst < 2 || clst >= fs->n_fatent) /* Check range */ return 1; switch (fs->fs_type) { @@ -876,7 +878,7 @@ FRESULT put_fat ( } else { switch (fs->fs_type) { case FS_FAT12 : - bc = clst; bc += bc / 2; + bc = (UINT)clst; bc += bc / 2; res = move_window(fs, fs->fatbase + (bc / SS(fs))); if (res != FR_OK) break; p = &fs->win[bc % SS(fs)]; @@ -930,7 +932,7 @@ FRESULT remove_chain ( FRESULT res; DWORD nxt; #if _USE_ERASE - DWORD scl = clst, ecl = clst, resion[2]; + DWORD scl = clst, ecl = clst, rt[2]; #endif if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ @@ -950,12 +952,12 @@ FRESULT remove_chain ( fs->fsi_flag = 1; } #if _USE_ERASE - if (ecl + 1 == nxt) { /* Next cluster is contiguous */ + if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ ecl = nxt; } else { /* End of contiguous clusters */ - resion[0] = clust2sect(fs, scl); /* Start sector */ - resion[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */ - disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, resion); /* Erase the block */ + rt[0] = clust2sect(fs, scl); /* Start sector */ + rt[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */ + disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, rt); /* Erase the block */ scl = ecl = nxt; } #endif @@ -1064,7 +1066,7 @@ DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ static FRESULT dir_sdi ( DIR *dj, /* Pointer to directory object */ - WORD idx /* Directory index number */ + WORD idx /* Index of directory table */ ) { DWORD clst; @@ -1106,7 +1108,7 @@ FRESULT dir_sdi ( /*-----------------------------------------------------------------------*/ -/* Directory handling - Move directory index next */ +/* Directory handling - Move directory table index next */ /*-----------------------------------------------------------------------*/ static @@ -1173,6 +1175,40 @@ FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:EOT an +/*-----------------------------------------------------------------------*/ +/* Directory handling - Load/Store start cluster number */ +/*-----------------------------------------------------------------------*/ + +static +DWORD ld_clust ( + FATFS *fs, /* Pointer to the fs object */ + BYTE *dir /* Pointer to the directory entry */ +) +{ + DWORD cl; + + cl = LD_WORD(dir+DIR_FstClusLO); + if (fs->fs_type == FS_FAT32) + cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16; + + return cl; +} + + +#if !_FS_READONLY +static +void st_clust ( + BYTE *dir, /* Pointer to the directory entry */ + DWORD cl /* Value to be set */ +) +{ + ST_WORD(dir+DIR_FstClusLO, cl); + ST_WORD(dir+DIR_FstClusHI, cl >> 16); +} +#endif + + + /*-----------------------------------------------------------------------*/ /* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ /*-----------------------------------------------------------------------*/ @@ -1784,7 +1820,7 @@ FRESULT create_name ( if (c >= 0x80) { /* Extended char? */ b |= 3; /* Eliminate NT flag */ #ifdef _EXCVT - c = excvt[c-0x80]; /* Upper conversion (SBCS) */ + c = excvt[c - 0x80]; /* Upper conversion (SBCS) */ #else #if !_DF1S /* ASCII only cfg */ return FR_INVALID_NAME; @@ -1940,7 +1976,6 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ if ((UINT)*path < ' ') { /* Nul path means the start directory itself */ res = dir_sdi(dj, 0); dj->dir = 0; - } else { /* Follow path */ for (;;) { res = create_name(dj, &path); /* Get a segment */ @@ -1948,7 +1983,7 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ res = dir_find(dj); /* Find it */ ns = *(dj->fn+NS); if (res != FR_OK) { /* Failed to find the object */ - if (res != FR_NO_FILE) break; /* Abort if any hard error occured */ + if (res != FR_NO_FILE) break; /* Abort if any hard error occurred */ /* Object not found */ if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exit */ dj->sclust = 0; dj->dir = 0; /* It is the root dir */ @@ -1964,7 +1999,7 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */ res = FR_NO_PATH; break; } - dj->sclust = LD_CLUST(dir); + dj->sclust = ld_clust(dj->fs, dir); } } @@ -1979,7 +2014,7 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ /*-----------------------------------------------------------------------*/ static -BYTE check_fs ( /* 0:FAT-VBR, 1:Valid BR but not FAT, 2:Not a BR, 3:Disk error */ +BYTE check_fs ( /* 0:FAT-VBR, 1:Any BR but not FAT, 2:Not a BR, 3:Disk error */ FATFS *fs, /* File system object */ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ ) @@ -2008,7 +2043,7 @@ static FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ const TCHAR **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 write access */ + BYTE wmode /* !=0: Check write protection for write access */ ) { BYTE fmt, b, pi, *tbl; @@ -2019,6 +2054,7 @@ FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ const TCHAR *p = *path; FATFS *fs; + /* Get logical drive number from the path name */ vol = p[0] - '0'; /* Is there a drive number? */ if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ @@ -2032,17 +2068,19 @@ FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ } /* Check if the file system object is valid or not */ + *rfs = 0; if (vol >= _VOLUMES) /* Is the drive number valid? */ return FR_INVALID_DRIVE; - *rfs = fs = FatFs[vol]; /* Return pointer to the corresponding file system object */ + fs = FatFs[vol]; /* Get corresponding file system object */ if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ ENTER_FF(fs); /* Lock file system */ - if (fs->fs_type) { /* If the logical drive has been mounted */ + *rfs = fs; /* Return pointer to the corresponding file system object */ + if (fs->fs_type) { /* If the volume has been mounted */ stat = disk_status(fs->drv); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ - if (!_FS_READONLY && chk_wp && (stat & STA_PROTECT)) /* Check write protection if needed */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check write protection if needed */ return FR_WRITE_PROTECTED; return FR_OK; /* The file system object is valid */ } @@ -2053,16 +2091,16 @@ FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ fs->fs_type = 0; /* Clear the file system object */ fs->drv = LD2PD(vol); /* Bind the logical drive and a physical drive */ - stat = disk_initialize(fs->drv); /* Initialize low level disk I/O layer */ + stat = disk_initialize(fs->drv); /* Initialize the physical drive */ if (stat & STA_NOINIT) /* Check if the initialization succeeded */ - return FR_NOT_READY; /* Failed to initialize due to no media or hard error */ - if (!_FS_READONLY && chk_wp && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check disk write protection if needed */ return FR_WRITE_PROTECTED; #if _MAX_SS != 512 /* Get disk sector size (variable sector size cfg only) */ if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK) return FR_DISK_ERR; #endif - /* Search FAT partition on the drive. Supports only generic partitionings, FDISK and SFD. */ + /* Search FAT partition on the drive. Supports only generic partitions, FDISK and SFD. */ fmt = check_fs(fs, bsect = 0); /* Load sector 0 and check if it is an FAT-VBR (in SFD) */ if (LD2PT(vol) && !fmt) fmt = 1; /* Force non-SFD if the volume is forced partition */ if (fmt == 1) { /* Not an FAT-VBR, the physical drive can be partitioned */ @@ -2154,7 +2192,7 @@ FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ #if _FS_RPATH fs->cdir = 0; /* Current directory (root dir) */ #endif -#if _FS_SHARE /* Clear file lock semaphores */ +#if _FS_LOCK /* Clear file lock semaphores */ clear_lock(fs); #endif @@ -2170,16 +2208,19 @@ FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ static FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ - FATFS *fs, /* Pointer to the file system object */ - WORD id /* Member id of the target object to be checked */ + void* obj /* Pointer to the object FIL/DIR to check validity */ ) { - if (!fs || !fs->fs_type || fs->id != id) + FIL *fil; + + + fil = (FIL*)obj; /* Assuming offset of fs and id in the FIL/DIR is identical */ + if (!fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id) return FR_INVALID_OBJECT; - ENTER_FF(fs); /* Lock file system */ + ENTER_FF(fil->fs); /* Lock file system */ - if (disk_status(fs->drv) & STA_NOINIT) + if (disk_status(fil->fs->drv) & STA_NOINIT) return FR_NOT_READY; return FR_OK; @@ -2213,7 +2254,7 @@ FRESULT f_mount ( rfs = FatFs[vol]; /* Get current fs object */ if (rfs) { -#if _FS_SHARE +#if _FS_LOCK clear_lock(rfs); #endif #if _FS_REENTRANT /* Discard sync object of the current volume */ @@ -2252,6 +2293,7 @@ FRESULT f_open ( DEF_NAMEBUF; + if (!fp) return FR_INVALID_OBJECT; fp->fs = 0; /* Clear file object */ #if !_FS_READONLY @@ -2261,103 +2303,104 @@ FRESULT f_open ( mode &= FA_READ; res = chk_mounted(&path, &dj.fs, 0); #endif - INIT_BUF(dj); - if (res == FR_OK) - res = follow_path(&dj, path); /* Follow the file path */ - dir = dj.dir; - -#if !_FS_READONLY /* R/W configuration */ if (res == FR_OK) { - if (!dir) /* Current dir itself */ - res = FR_INVALID_NAME; -#if _FS_SHARE - else - res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Current dir itself */ + res = FR_INVALID_NAME; +#if _FS_LOCK + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); #endif - } - /* Create or Open a file */ - if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { - DWORD dw, cl; + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; - if (res != FR_OK) { /* No file, create new */ - if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ -#if _FS_SHARE - res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_LOCK + res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; #else - res = dir_register(&dj); + res = dir_register(&dj); #endif - mode |= FA_CREATE_ALWAYS; /* File is created */ - dir = dj.dir; /* New entry */ - } - else { /* Any object is already existing */ - if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ - res = FR_DENIED; - } else { - if (mode & FA_CREATE_NEW) /* Cannot create as new file */ - res = FR_EXIST; + mode |= FA_CREATE_ALWAYS; /* File is created */ + dir = dj.dir; /* New entry */ } - } - if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ - dw = get_fattime(); /* Created time */ - ST_DWORD(dir+DIR_CrtTime, dw); - dir[DIR_Attr] = 0; /* Reset attribute */ - ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ - cl = LD_CLUST(dir); /* Get start cluster */ - ST_CLUST(dir, 0); /* cluster = 0 */ - dj.fs->wflag = 1; - if (cl) { /* Remove the cluster chain if exist */ - dw = dj.fs->winsect; - res = remove_chain(dj.fs, cl); - if (res == FR_OK) { - dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ - res = move_window(dj.fs, dw); + else { /* Any object is already existing */ + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } else { + if (mode & FA_CREATE_NEW) /* Cannot create as new file */ + res = FR_EXIST; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ld_clust(dj.fs, dir); /* Get start cluster */ + st_clust(dir, 0); /* cluster = 0 */ + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } } } } - } - else { /* Open an existing file */ - if (res == FR_OK) { /* Follow succeeded */ - if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ - res = FR_NO_FILE; - } else { - if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ - res = FR_DENIED; + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } } } - } - if (res == FR_OK) { - if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */ - mode |= FA__WRITTEN; - fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ - fp->dir_ptr = dir; -#if _FS_SHARE - fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); - if (!fp->lockid) res = FR_INT_ERR; + if (res == FR_OK) { + if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */ + mode |= FA__WRITTEN; + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_LOCK + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; #endif - } + } #else /* R/O configuration */ - if (res == FR_OK) { /* Follow succeeded */ - if (!dir) { /* Current dir itself */ - res = FR_INVALID_NAME; - } else { - if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ - res = FR_NO_FILE; + if (res == FR_OK) { /* Follow succeeded */ + dir = dj.dir; + if (!dir) { /* Current dir itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } } - } #endif - FREE_BUF(); + FREE_BUF(); - if (res == FR_OK) { - fp->flag = mode; /* File access mode */ - fp->sclust = LD_CLUST(dir); /* File start cluster */ - fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ - fp->fptr = 0; /* File pointer */ - fp->dsect = 0; + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */ + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; #if _USE_FASTSEEK - fp->cltbl = 0; /* Normal seek mode */ + fp->cltbl = 0; /* Normal seek mode */ #endif - fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ + fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */ + } } LEAVE_FF(dj.fs, res); @@ -2383,9 +2426,9 @@ FRESULT f_read ( BYTE csect, *rbuff = buff; - *br = 0; /* Initialize byte counter */ + *br = 0; /* Clear read byte counter */ - res = validate(fp->fs, fp->id); /* Check validity */ + res = validate(fp); /* Check validity */ if (res != FR_OK) LEAVE_FF(fp->fs, res); if (fp->flag & FA__ERROR) /* Aborted file? */ LEAVE_FF(fp->fs, FR_INT_ERR); @@ -2449,7 +2492,7 @@ FRESULT f_read ( #endif fp->dsect = sect; } - rcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ if (rcnt > btr) rcnt = btr; #if _FS_TINY if (move_window(fp->fs, fp->dsect)) /* Move sector window */ @@ -2485,9 +2528,9 @@ FRESULT f_write ( BYTE csect; - *bw = 0; /* Initialize byte counter */ + *bw = 0; /* Clear write byte counter */ - res = validate(fp->fs, fp->id); /* Check validity */ + res = validate(fp); /* Check validity */ if (res != FR_OK) LEAVE_FF(fp->fs, res); if (fp->flag & FA__ERROR) /* Aborted file? */ LEAVE_FF(fp->fs, FR_INT_ERR); @@ -2564,7 +2607,7 @@ FRESULT f_write ( #endif fp->dsect = sect; } - wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */ + wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */ if (wcnt > btw) wcnt = btw; #if _FS_TINY if (move_window(fp->fs, fp->dsect)) /* Move sector window */ @@ -2599,7 +2642,7 @@ FRESULT f_sync ( BYTE *dir; - res = validate(fp->fs, fp->id); /* Check validity of the object */ + res = validate(fp); /* Check validity of the object */ if (res == FR_OK) { if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ #if !_FS_TINY /* Write-back dirty buffer */ @@ -2615,9 +2658,10 @@ FRESULT f_sync ( dir = fp->dir_ptr; dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ - ST_CLUST(dir, fp->sclust); /* Update start cluster */ + st_clust(dir, fp->sclust); /* Update start cluster */ tim = get_fattime(); /* Update updated time */ ST_DWORD(dir+DIR_WrtTime, tim); + ST_WORD(dir+DIR_LstAccDate, 0); fp->flag &= ~FA__WRITTEN; fp->fs->wflag = 1; res = sync(fp->fs); @@ -2643,21 +2687,26 @@ FRESULT f_close ( { FRESULT res; -#if _FS_READONLY - FATFS *fs = fp->fs; - res = validate(fs, fp->id); - if (res == FR_OK) fp->fs = 0; /* Discard file object */ - LEAVE_FF(fs, res); +#if _FS_READONLY + res = validate(fp); + { +#if _FS_REENTRANT + FATFS *fs = fp->fs; +#endif + if (res == FR_OK) fp->fs = 0; /* Discard file object */ + LEAVE_FF(fs, res); + } #else res = f_sync(fp); /* Flush cached data */ -#if _FS_SHARE +#if _FS_LOCK if (res == FR_OK) { /* Decrement open counter */ #if _FS_REENTRANT - res = validate(fp->fs, fp->id); + FATFS *fs = fp->fs;; + res = validate(fp); if (res == FR_OK) { res = dec_lock(fp->lockid); - unlock_fs(fp->fs, FR_OK); + unlock_fs(fs, FR_OK); } #else res = dec_lock(fp->lockid); @@ -2710,7 +2759,7 @@ FRESULT f_chdir ( dj.fs->cdir = dj.sclust; /* Start directory itself */ } else { if (dj.dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ - dj.fs->cdir = LD_CLUST(dj.dir); + dj.fs->cdir = ld_clust(dj.fs, dj.dir); else res = FR_NO_PATH; /* Reached but a file */ } @@ -2748,13 +2797,13 @@ FRESULT f_getcwd ( if (res != FR_OK) break; res = dir_read(&dj); if (res != FR_OK) break; - dj.sclust = LD_CLUST(dj.dir); /* Goto parent dir */ + dj.sclust = ld_clust(dj.fs, dj.dir); /* Goto parent dir */ res = dir_sdi(&dj, 0); if (res != FR_OK) break; do { /* Find the entry links to the child dir */ res = dir_read(&dj); if (res != FR_OK) break; - if (ccl == LD_CLUST(dj.dir)) break; /* Found the entry */ + if (ccl == ld_clust(dj.fs, dj.dir)) break; /* Found the entry */ res = dir_next(&dj, 0); } while (res == FR_OK); if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ @@ -2809,7 +2858,7 @@ FRESULT f_lseek ( FRESULT res; - res = validate(fp->fs, fp->id); /* Check validity of the object */ + res = validate(fp); /* Check validity of the object */ if (res != FR_OK) LEAVE_FF(fp->fs, res); if (fp->flag & FA__ERROR) /* Check abort flag */ LEAVE_FF(fp->fs, FR_INT_ERR); @@ -2956,7 +3005,7 @@ FRESULT f_lseek ( #if _FS_MINIMIZE <= 1 /*-----------------------------------------------------------------------*/ -/* Create a Directroy Object */ +/* Create a Directory Object */ /*-----------------------------------------------------------------------*/ FRESULT f_opendir ( @@ -2965,10 +3014,14 @@ FRESULT f_opendir ( ) { FRESULT res; + FATFS *fs; DEF_NAMEBUF; + if (!dj) return FR_INVALID_OBJECT; + res = chk_mounted(&path, &dj->fs, 0); + fs = dj->fs; if (res == FR_OK) { INIT_BUF(*dj); res = follow_path(dj, path); /* Follow the path to the directory */ @@ -2976,27 +3029,30 @@ FRESULT f_opendir ( if (res == FR_OK) { /* Follow completed */ if (dj->dir) { /* It is not the root dir */ if (dj->dir[DIR_Attr] & AM_DIR) { /* The object is a directory */ - dj->sclust = LD_CLUST(dj->dir); + dj->sclust = ld_clust(fs, dj->dir); } else { /* The object is not a directory */ res = FR_NO_PATH; } } if (res == FR_OK) { - dj->id = dj->fs->id; + dj->id = fs->id; res = dir_sdi(dj, 0); /* Rewind dir */ } } if (res == FR_NO_FILE) res = FR_NO_PATH; + if (res != FR_OK) dj->fs = 0; /* Invalidate the dir object if function faild */ + } else { + dj->fs = 0; } - LEAVE_FF(dj->fs, res); + LEAVE_FF(fs, res); } /*-----------------------------------------------------------------------*/ -/* Read Directory Entry in Sequense */ +/* Read Directory Entry in Sequence */ /*-----------------------------------------------------------------------*/ FRESULT f_readdir ( @@ -3008,7 +3064,7 @@ FRESULT f_readdir ( DEF_NAMEBUF; - res = validate(dj->fs, dj->id); /* Check validity of the object */ + res = validate(dj); /* Check validity of the object */ if (res == FR_OK) { if (!fno) { res = dir_sdi(dj, 0); /* Rewind the directory object */ @@ -3081,6 +3137,7 @@ FRESULT f_getfree ( ) { FRESULT res; + FATFS *fs; DWORD n, clst, sect, stat; UINT i; BYTE fat, *p; @@ -3088,32 +3145,33 @@ FRESULT f_getfree ( /* Get drive number */ res = chk_mounted(&path, fatfs, 0); + fs = *fatfs; if (res == FR_OK) { /* If free_clust is valid, return it without full cluster scan */ - if ((*fatfs)->free_clust <= (*fatfs)->n_fatent - 2) { - *nclst = (*fatfs)->free_clust; + if (fs->free_clust <= fs->n_fatent - 2) { + *nclst = fs->free_clust; } else { /* Get number of free clusters */ - fat = (*fatfs)->fs_type; + fat = fs->fs_type; n = 0; if (fat == FS_FAT12) { clst = 2; do { - stat = get_fat(*fatfs, clst); + stat = get_fat(fs, clst); if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } if (stat == 1) { res = FR_INT_ERR; break; } if (stat == 0) n++; - } while (++clst < (*fatfs)->n_fatent); + } while (++clst < fs->n_fatent); } else { - clst = (*fatfs)->n_fatent; - sect = (*fatfs)->fatbase; + clst = fs->n_fatent; + sect = fs->fatbase; i = 0; p = 0; do { if (!i) { - res = move_window(*fatfs, sect++); + res = move_window(fs, sect++); if (res != FR_OK) break; - p = (*fatfs)->win; - i = SS(*fatfs); + p = fs->win; + i = SS(fs); } if (fat == FS_FAT16) { if (LD_WORD(p) == 0) n++; @@ -3124,12 +3182,12 @@ FRESULT f_getfree ( } } while (--clst); } - (*fatfs)->free_clust = n; - if (fat == FS_FAT32) (*fatfs)->fsi_flag = 1; + fs->free_clust = n; + if (fat == FS_FAT32) fs->fsi_flag = 1; *nclst = n; } } - LEAVE_FF(*fatfs, res); + LEAVE_FF(fs, res); } @@ -3147,7 +3205,9 @@ FRESULT f_truncate ( DWORD ncl; - res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (!fp) return FR_INVALID_OBJECT; + + res = validate(fp); /* Check validity of the object */ if (res == FR_OK) { if (fp->flag & FA__ERROR) { /* Check abort flag */ res = FR_INT_ERR; @@ -3204,7 +3264,7 @@ FRESULT f_unlink ( res = follow_path(&dj, path); /* Follow the file path */ if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) res = FR_INVALID_NAME; /* Cannot remove dot entry */ -#if _FS_SHARE +#if _FS_LOCK if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ #endif if (res == FR_OK) { /* The object is accessible */ @@ -3215,19 +3275,19 @@ FRESULT f_unlink ( if (dir[DIR_Attr] & AM_RDO) res = FR_DENIED; /* Cannot remove R/O object */ } - dclst = LD_CLUST(dir); + dclst = ld_clust(dj.fs, dir); if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ if (dclst < 2) { res = FR_INT_ERR; } else { - mem_cpy(&sdj, &dj, sizeof(DIR)); /* Check if the sub-dir is empty or not */ + mem_cpy(&sdj, &dj, sizeof (DIR)); /* Check if the sub-dir is empty or not */ sdj.sclust = dclst; res = dir_sdi(&sdj, 2); /* Exclude dot entries */ if (res == FR_OK) { res = dir_read(&sdj); - if (res == FR_OK /* Not empty dir */ + if (res == FR_OK /* Not empty dir */ #if _FS_RPATH - || dclst == sdj.fs->cdir /* Current dir */ + || dclst == dj.fs->cdir /* Current dir */ #endif ) res = FR_DENIED; if (res == FR_NO_FILE) res = FR_OK; /* Empty */ @@ -3289,12 +3349,12 @@ FRESULT f_mkdir ( dir[DIR_Name] = '.'; dir[DIR_Attr] = AM_DIR; ST_DWORD(dir+DIR_WrtTime, tim); - ST_CLUST(dir, dcl); + st_clust(dir, dcl); mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */ dir[33] = '.'; pcl = dj.sclust; if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) pcl = 0; - ST_CLUST(dir+SZ_DIR, pcl); + st_clust(dir+SZ_DIR, pcl); for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ dj.fs->winsect = dsc++; dj.fs->wflag = 1; @@ -3310,7 +3370,7 @@ FRESULT f_mkdir ( dir = dj.dir; dir[DIR_Attr] = AM_DIR; /* Attribute */ ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */ - ST_CLUST(dir, dcl); /* Table start cluster */ + st_clust(dir, dcl); /* Table start cluster */ dj.fs->wflag = 1; res = sync(dj.fs); } @@ -3430,7 +3490,7 @@ FRESULT f_rename ( res = follow_path(&djo, path_old); /* Check old object */ if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) res = FR_INVALID_NAME; -#if _FS_SHARE +#if _FS_LOCK if (res == FR_OK) res = chk_lock(&djo, 2); #endif if (res == FR_OK) { /* Old object is found */ @@ -3438,11 +3498,11 @@ FRESULT f_rename ( res = FR_NO_FILE; } else { mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */ - mem_cpy(&djn, &djo, sizeof(DIR)); /* Check new object */ + mem_cpy(&djn, &djo, sizeof (DIR)); /* Check new object */ res = follow_path(&djn, path_new); if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ -/* Start critical section that any interruption or error can cause cross-link */ +/* Start critical section that an interruption or error can cause cross-link */ res = dir_register(&djn); /* Register the new entry */ if (res == FR_OK) { dir = djn.dir; /* Copy object information except for name */ @@ -3450,16 +3510,16 @@ FRESULT f_rename ( dir[DIR_Attr] = buf[0] | AM_ARC; djo.fs->wflag = 1; if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ - dw = clust2sect(djn.fs, LD_CLUST(dir)); + dw = clust2sect(djo.fs, ld_clust(djo.fs, dir)); if (!dw) { res = FR_INT_ERR; } else { - res = move_window(djn.fs, dw); - dir = djn.fs->win+SZ_DIR; /* .. entry */ + res = move_window(djo.fs, dw); + dir = djo.fs->win+SZ_DIR; /* .. entry */ if (res == FR_OK && dir[1] == '.') { - dw = (djn.fs->fs_type == FS_FAT32 && djn.sclust == djn.fs->dirbase) ? 0 : djn.sclust; - ST_CLUST(dir, dw); - djn.fs->wflag = 1; + dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust; + st_clust(dir, dw); + djo.fs->wflag = 1; } } } @@ -3503,9 +3563,11 @@ FRESULT f_forward ( BYTE csect; - *bf = 0; /* Initialize byte counter */ + *bf = 0; /* Clear transfer byte counter */ - res = validate(fp->fs, fp->id); /* Check validity of the object */ + if (!fp) return FR_INVALID_OBJECT; + + res = validate(fp); /* Check validity of the object */ if (res != FR_OK) LEAVE_FF(fp->fs, res); if (fp->flag & FA__ERROR) /* Check error flag */ LEAVE_FF(fp->fs, FR_INT_ERR); @@ -3613,7 +3675,7 @@ FRESULT f_mkfs ( if (au == 0) au = 1; if (au > 128) au = 128; - /* Pre-compute number of clusters and FAT syb-type */ + /* Pre-compute number of clusters and FAT sub-type */ n_clst = n_vol / au; fmt = FS_FAT12; if (n_clst >= MIN_FAT16) fmt = FS_FAT16; @@ -3665,18 +3727,18 @@ FRESULT f_mkfs ( if (disk_write(pdrv, fs->win, 0, 1) != RES_OK) return FR_DISK_ERR; md = 0xF8; } else { - if (sfd) { /* No patition table (SFD) */ + if (sfd) { /* No partition table (SFD) */ md = 0xF0; } else { /* Create partition table (FDISK) */ mem_set(fs->win, 0, SS(fs)); - tbl = fs->win+MBR_Table; /* Create partiton table for single partition in the drive */ + tbl = fs->win+MBR_Table; /* Create partition table for single partition in the drive */ tbl[1] = 1; /* Partition start head */ tbl[2] = 1; /* Partition start sector */ tbl[3] = 0; /* Partition start cylinder */ tbl[4] = sys; /* System type */ tbl[5] = 254; /* Partition end head */ n = (b_vol + n_vol) / 63 / 255; - tbl[6] = (BYTE)((n >> 2) | 63); /* Partiiton end sector */ + tbl[6] = (BYTE)((n >> 2) | 63); /* Partition end sector */ tbl[7] = (BYTE)n; /* End cylinder */ ST_DWORD(tbl+8, 63); /* Partition start in LBA */ ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ @@ -3880,18 +3942,18 @@ TCHAR* f_gets ( #if _LFN_UNICODE /* Read a character in UTF-8 encoding */ if (c >= 0x80) { if (c < 0xC0) continue; /* Skip stray trailer */ - if (c < 0xE0) { /* Two-byte sequense */ + if (c < 0xE0) { /* Two-byte sequence */ f_read(fil, s, 1, &rc); if (rc != 1) break; c = ((c & 0x1F) << 6) | (s[0] & 0x3F); if (c < 0x80) c = '?'; } else { - if (c < 0xF0) { /* Three-byte sequense */ + if (c < 0xF0) { /* Three-byte sequence */ f_read(fil, s, 2, &rc); if (rc != 2) break; c = (c << 12) | ((s[0] & 0x3F) << 6) | (s[1] & 0x3F); if (c < 0x800) c = '?'; - } else { /* Reject four-byte sequense */ + } else { /* Reject four-byte sequence */ c = '?'; } } @@ -4044,7 +4106,7 @@ int f_printf ( r = 10; break; case 'X' : /* Hexdecimal */ r = 16; break; - default: /* Unknown type (passthrough) */ + default: /* Unknown type (pass-through) */ cc = f_putc(c, fil); continue; } @@ -4059,7 +4121,7 @@ int f_printf ( d = (TCHAR)(v % r); v /= r; if (d > 9) d += (c == 'x') ? 0x27 : 0x07; s[i++] = d + '0'; - } while (v && i < sizeof(s) / sizeof(s[0])); + } while (v && i < sizeof s / sizeof s[0]); if (f & 8) s[i++] = '-'; j = i; d = (f & 1) ? '0' : ' '; res = 0; diff --git a/src/ff.h b/src/ff.h index b1ff465..627cbaa 100644 --- a/src/ff.h +++ b/src/ff.h @@ -1,11 +1,11 @@ /*---------------------------------------------------------------------------/ -/ FatFs - FAT file system module include file R0.09 (C)ChaN, 2011 +/ FatFs - FAT file system module include file R0.09a (C)ChaN, 2012 /----------------------------------------------------------------------------/ / FatFs module is a generic FAT file system module for small embedded systems. / This is a free software that opened for education, research and commercial -/ developments under license policy of following trems. +/ developments under license policy of following terms. / -/ Copyright (C) 2011, ChaN, all right reserved. +/ Copyright (C) 2012, ChaN, all right reserved. / / * The FatFs module is a free software and there is NO WARRANTY. / * No restriction on use. You can use, modify and redistribute it for @@ -15,7 +15,7 @@ /----------------------------------------------------------------------------*/ #ifndef _FATFS -#define _FATFS 6502 /* Revision ID */ +#define _FATFS 4004 /* Revision ID */ #ifdef __cplusplus extern "C" { @@ -41,9 +41,9 @@ extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ #define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ #define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ -#else /* Single partition configuration */ -#define LD2PD(vol) (vol) /* Each logical drive is bound to the same physical drive number */ -#define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */ +#else /* Single partition configuration */ +#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */ +#define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */ #endif @@ -111,24 +111,24 @@ typedef struct { /* File object structure (FIL) */ typedef struct { - FATFS* fs; /* Pointer to the owner file system object */ - WORD id; /* Owner file system mount ID */ + FATFS* fs; /* Pointer to the related file system object */ + WORD id; /* File system mount ID of the related file system object */ BYTE flag; /* File status flags */ BYTE pad1; - DWORD fptr; /* File read/write pointer (0 on file open) */ + DWORD fptr; /* File read/write pointer (0ed on file open) */ DWORD fsize; /* File size */ - DWORD sclust; /* File start cluster (0 when fsize==0) */ - DWORD clust; /* Current cluster */ - DWORD dsect; /* Current data sector */ + DWORD sclust; /* File data start cluster (0:no data cluster, always 0 when fsize is 0) */ + DWORD clust; /* Current cluster of fpter */ + DWORD dsect; /* Current data sector of fpter */ #if !_FS_READONLY DWORD dir_sect; /* Sector containing the directory entry */ - BYTE* dir_ptr; /* Ponter to the directory entry in the window */ + BYTE* dir_ptr; /* Pointer to the directory entry in the window */ #endif #if _USE_FASTSEEK DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */ #endif -#if _FS_SHARE - UINT lockid; /* File lock ID (index of file semaphore table) */ +#if _FS_LOCK + UINT lockid; /* File lock ID (index of file semaphore table Files[]) */ #endif #if !_FS_TINY BYTE buf[_MAX_SS]; /* File data read/write buffer */ @@ -176,14 +176,14 @@ typedef struct { typedef enum { FR_OK = 0, /* (0) Succeeded */ - FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */ + FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ FR_INT_ERR, /* (2) Assertion failed */ FR_NOT_READY, /* (3) The physical drive cannot work */ FR_NO_FILE, /* (4) Could not find the file */ FR_NO_PATH, /* (5) Could not find the path */ FR_INVALID_NAME, /* (6) The path name format is invalid */ - FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */ - FR_EXIST, /* (8) Acces denied due to prohibited access */ + FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Access denied due to prohibited access */ FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ @@ -191,7 +191,7 @@ typedef enum { FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ - FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */ + FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ @@ -216,8 +216,8 @@ FRESULT f_truncate (FIL*); /* Truncate file */ FRESULT f_sync (FIL*); /* Flush cached data of a writing file */ FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */ FRESULT f_mkdir (const TCHAR*); /* Create a new directory */ -FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */ -FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */ +FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attribute of the file/dir */ +FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change times-tamp of the file/dir */ FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */ FRESULT f_chdrive (BYTE); /* Change current drive */ FRESULT f_chdir (const TCHAR*); /* Change current directory */ diff --git a/src/ffconf.h b/src/ffconf.h index 8733943..430138c 100644 --- a/src/ffconf.h +++ b/src/ffconf.h @@ -1,5 +1,5 @@ /*---------------------------------------------------------------------------/ -/ FatFs - FAT file system module configuration file R0.09 (C)ChaN, 2011 +/ FatFs - FAT file system module configuration file R0.09a (C)ChaN, 2012 /----------------------------------------------------------------------------/ / / CAUTION! Do not forget to make clean the project after any changes to @@ -7,7 +7,7 @@ / /----------------------------------------------------------------------------*/ #ifndef _FFCONF -#define _FFCONF 6502 /* Revision ID */ +#define _FFCONF 4004 /* Revision ID */ /*---------------------------------------------------------------------------/ @@ -182,9 +182,9 @@ / function must be added to the project. */ -#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */ -/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value - defines how many files can be opened simultaneously. */ +#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */ +/* To enable file lock control feature, set _FS_LOCK to 1 or greater. + The value defines how many files can be opened simultaneously. */ #endif /* _FFCONFIG */ diff --git a/src/option/syscall.c b/src/option/syscall.c index e5bb0e0..ad10cbb 100644 --- a/src/option/syscall.c +++ b/src/option/syscall.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------*/ -/* Sample code of OS dependent controls for FatFs R0.08b */ -/* (C)ChaN, 2011 */ +/* Sample code of OS dependent controls for FatFs */ +/* (C)ChaN, 2012 */ /*------------------------------------------------------------------------*/ #include /* ANSI memory controls */ diff --git a/src/option/unicode.c b/src/option/unicode.c new file mode 100644 index 0000000..7f33b11 --- /dev/null +++ b/src/option/unicode.c @@ -0,0 +1,17 @@ +#include "../ff.h" + +#if _USE_LFN != 0 + +#if _CODE_PAGE == 932 +#include "cc932.c" +#elif _CODE_PAGE == 936 +#include "cc936.c" +#elif _CODE_PAGE == 949 +#include "cc949.c" +#elif _CODE_PAGE == 950 +#include "cc950.c" +#else +#include "ccsbcs.c" +#endif + +#endif