标题: [资料] 自己移植的SD卡的FATFS文件系统,FATFS R0.09 (MDK STM32f103) [打印本页] 作者: Gegu 时间: 2016-4-28 10:03 标题: [资料] 自己移植的SD卡的FATFS文件系统,FATFS R0.09 (MDK STM32f103) 自己移植的SD卡的FATFS文件系统,采用最新版FATFS R0.09,并且有详细的中文注释,和操作测试程序,完整的MDK STM32F103工程。下载即可使用。3 P) G* F1 J4 C9 B
/*----------------------------------------------------------------------------/ # G# e a0 e( T" H) \8 G/ FatFs - FAT file system module R0.09 (C)ChaN, 2011! [4 ]) l! S/ g s* b+ I" P
/-----------------------------------------------------------------------------/ ' V$ ]& G) T4 |5 `( \ J; W/ FatFs module is a generic FAT file system module for small embedded systems.# r2 I: r7 I2 \" F7 E- S
/ This is a free software that opened for education, research and commercial' p9 X [/ l: R9 _
/ developments under license policy of following terms.- |; B7 |, T9 o$ @$ o# Y! z
/* |: q! o ^( W2 }* p3 O' a
/ Copyright (C) 2011, ChaN, all right reserved. ! j" s( `; p9 H( n; R8 ?3 @/ + K- ^1 d4 H/ k* f+ u: U9 \6 Z) o! q/ * The FatFs module is a free software and there is NO WARRANTY. * \6 {/ b3 \7 P0 u/ K/ * No restriction on use. You can use, modify and redistribute it for 0 D3 a1 ?/ g: ?- }/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.6 }' I$ _5 d0 ^5 {; r
/ * Redistributions of source code must retain the above copyright notice.; W0 Z7 D7 }+ T& P% Q# W, {% V5 {
/8 O7 X; z: e6 J3 f s
/-----------------------------------------------------------------------------/ $ S6 Z l. [2 V7 M O3 O, X& P$ i: j$ D; |( d3 H9 Z, w, x; [. E) X& q3 {
/*--------------File Info-------------------------------------------------------& q& T, R% d$ T3 A5 _
** 文 件 名: FATFS_Function.c4 _8 u6 O6 G6 i
** 作 者:~风中的叶~ 整理 # [8 A- O$ M7 Q4 r: A** 最后修改日期: 2012.01.182 C9 ^1 {( @1 d& |
** 版 本: V1.0 " {8 r. V* o8 G8 @- S3 x# k** 描 述: FATFS常用功能测试函数 .连接PC机串口,观察超级终端输出( S$ [4 W4 |; v. ]7 x$ P- R9 J- M
**------------------------------------------------------------------------------, T" d9 p) p& \4 p) J K- ]
** Created by: Dt.1 E2 N0 X, d8 u& q6 N* Q
** Created date: % A7 |$ q2 l9 ^9 j4 @*******************************************************************************/ 2 d4 H: d" u2 n( w7 |% H
#include "TEST_FATFS.h"' |9 z/ i; k$ b; E
#include "string.h" 0 P+ e# W$ D$ J+ R" @) Y & h9 r6 \5 w- W5 r4 U% U#ifdef TEST_FATFS_EN 9 D5 T/ m6 b$ j3 t# f+ ? i7 r }: b: g
" p1 o( h# Z2 d& Y4 k' V" I t
+ l1 s0 B4 [+ H* h. W7 `4 c//检测磁盘是否插好6 f2 S$ d$ k6 K
BOOL disk_detect_OK(void) * M/ j+ p4 K" V" o5 i$ s5 P{ ' @ x" }2 p; i& o1 [4 {$ O' Q if( disk_status(0)==STA_NODISK )/* Physical drive nmuber (0..) */; N" C! I* Z! H; k! q
{; }' f* X z' x1 c: z# i
printf("\r\n\r\n%48s\r\n","<未检测到磁盘,请检查SD卡是否插好...>"); , q8 k: \4 w" w. S, x% v- T3 P return FALSE;2 Z+ v3 o" `* u% ]# p5 E
}. @- O6 W5 d* A( k& J/ d
return TRUE; 5 n( G, O) X9 {# G' Q" T}# v+ R* \# n' T* G
]& ?; [1 _, f! t. g3 |+ Z1 q" V c/ j; }* a# p
7 q9 ?# z: d! y6 l//测试函数执行结果分析8 {0 M3 U! e% x! j$ a
void die(FRESULT res) , k/ B: b. @+ d7 j{- O9 d. N, \6 u- b2 B, Y/ a
switch(res)* S! S+ ~6 b; m
{7 i6 ]0 u% h" V% R( l$ s7 R
case FR_OK: //The function succeeded. * @ n; S8 u: M1 n {7 d! }- I5 b; h) Y" n: F8 o# p. m( k
printf("\r\nThe function succeeded!\r\n"); 0 n3 t0 l5 L1 \" P% W' U break;3 ^+ B( O; y1 n4 Y, s8 a* R1 ~. g
}* x9 b8 @" V% Z) k! X
case FR_NOT_READY://The disk drive cannot work due to no medium in the drive or any other reason2 }& c9 X/ ~+ J& n1 c' i/ s3 E
{ 0 y$ y" j: [6 L- n8 G printf("\r\nThe disk drive cannot work due to no medium in the drive or any other reason!\r\n");/ S! x. h# K+ D, z
break; + K* [# x1 M; S. Q9 O } ' F J: T' B! Z0 r0 V1 n6 g) b& X( C) c case FR_NO_FILE://Could not find the file. : L* D% H- `2 d& a0 {4 m/ s" @ { ; U: X# R. X$ C! ?$ i$ J8 @ printf("\r\nCould not find the file!\r\n");5 M: _6 G7 v* K4 u1 O n( O
break; 6 ^) \& G+ _! N3 e& F9 t* I/ ` }- v) n+ R% n( A! R- k- @6 B. p6 ^
case FR_NO_PATH://Could not find the path# N1 K0 O* g- B3 E6 S; v b5 K
{ ) M, d% i& U9 `/ i+ m) W7 }0 ` printf("\r\nCould not find the path!\r\n"); % E2 `! U: C4 t/ z. w+ l break;7 \- \. X" U0 W5 o; T) L2 v
}, l% g3 q! x) t6 d9 Q- c
case FR_INVALID_NAME://The path name is invalid1 U/ \* w: y( c6 ^! Z! L5 J
{ ( g/ t1 A4 e/ a6 t8 N" I4 B9 ^ printf("\r\nThe path name is invalid!\r\n"); . \! ~' e% I! p" _" h break; % q" ^4 c' K7 c" | R }: f5 v+ d) O1 Y/ E
case FR_INVALID_DRIVE://The drive number is invalid3 X, c. ?3 l0 r% L- P J
{ 9 J# ~! i4 d1 J printf("\r\nThe drive number is invalid!\r\n");/ {7 _( \: L+ v3 N7 S
break;" K+ Z$ H) @/ O! r* X
}6 y( I M1 s. d3 P, S, C; C
case FR_DENIED://The directory cannot be created due to directory table or disk is full. " Z; h# g$ f& s" }! G$ y+ q1 } {6 u$ F2 s) G2 ^% S
printf("\r\nThe directory cannot be created due to directory table or disk is full!\r\n");/ U. g8 G& v4 r6 _/ m
break;/ g3 }6 O6 d. b
}) p; t: H4 O) W( b5 v! J
case FR_EXIST://A file or directory that has same name is already existing! u9 o1 X% X, O. o A& T4 n# P
{ " _9 q9 a" @; G: t ^' y printf("\r\nA file or directory that has same name is already existing!\r\n"); 8 u% M9 @* ` X9 y8 J" X& n break; ; `( \. t5 V# B* {! M" h" o+ s) [ } : |4 `: G; i7 }( E. n# O// case FR_RW_ERROR://The function failed due to a disk error or an internal error/ ~" Z2 y% |# q T9 S
/* : ^# w" Q- B+ ^/ L case FR_RW_ERROR://The function failed due to a disk error or an internal error* z4 k9 x2 u* F) X W% a1 m& ]
{& o) M$ l+ L0 D3 }
printp("\r\nThe function failed due to a disk error or an internal error!\r\n");6 T! ~, B& B" s/ P- i% g
break;% ]# E* n8 C1 p3 T
} + m* f/ s; n6 K: h*/3 L/ O9 E3 K% c. ?) [* g( F; Y/ o0 `4 Z
case FR_WRITE_PROTECTED://The medium is write protected C) T( c; N! P/ o& X: C# l
{4 \. `* d0 m& b: @$ g# t
printf("\r\nThe medium is write protected!\r\n"); 0 @& ^; k" c( L% J( B, \/ ? break; ) E3 g( O9 a/ s I } # E' a( g" Q& b" a$ w3 E# U; X case FR_NOT_ENABLED://The logical drive has no work area4 L7 g& P( g8 C
{ ' ]( V) k8 Y' G9 N) H# b printf("\r\nThe logical drive has no work area!\r\n"); . }) K, C$ _- c break;: I. P6 d9 X* s. K# L
}/ h2 A6 B# I3 m) H9 |0 r, `
case FR_NO_FILESYSTEM://There is no valid FAT partition on the disk " ^7 F3 ~9 N0 L) r9 R; A5 E! L g { ! C8 K! [2 N" I6 ?/ N+ ]/ X printf("\r\nThere is no valid FAT partition on the disk!\r\n");- w+ C9 l4 t7 b7 v$ s+ ]( `
break;0 h$ b5 p0 f: w x) ^$ C2 R2 D
}* Y6 c5 C Z: n% s
case FR_INVALID_OBJECT://The file object is invalid/ A. m5 Y' \: E/ O
{0 M' @: k' I4 V3 \+ G3 Z& j k
printf("\r\nThe file object is invalid!\r\n"); 4 A& A ? \, Y3 ` break;: F8 @* q/ @, ~. |8 C
}& c: }4 D+ m. b
I: `3 c2 \5 N
//The function aborted before start in format due to a reason as follows. 9 D6 q* z+ k) y9 I3 ~4 P7 q //The disk size is too small. * E7 G0 G1 p3 C/ ~7 h: o& w' J( Y
//Invalid parameter was given to any parameter. \7 U) N. v* \! c2 T
//Not allowable cluster size for this drive. This can occure when number of clusters becomes around 0xFF7 and 0xFFF7. 2 E* e! ?! ^& \/ m case FR_MKFS_ABORTED://: p2 f; F) t+ O2 Y$ f8 e
{5 n8 S3 c( ]( v7 L
printf("\r\nThe function aborted before start in format!\r\n"); 8 S% k- }1 d' D; {0 d* }# a break; % B. e6 O" J9 n- \* l. Q } ! S' y! ~7 I1 |& I& s! X" | 7 H# w6 n, t( ?0 y7 O3 a- Q( g. _" J default:- f, [6 P* p% {
{ - W$ T: m2 S2 Y) ~ printf("\r\nerror!\r\n");! r" b; R& Q j- L
break; 4 ?- a$ j3 V- _) I } 0 N3 u2 t3 e0 u( C8 Q! M; Y } ^( l7 M: i; b4 q) w) r# h2 H+ j return; ( P6 w+ W9 v8 ]0 T}7 y- f) Y o! O1 i! |) p* }0 _
void Test_f_getfree(void)//获取卡的总容量及剩余容量: N2 q" V% \; N4 i3 ~/ c1 {" U
{3 _9 p1 M2 s/ o$ l S; `( a
FATFS fs;% G5 ]! R, ]. c. |3 @! o& S- y/ B$ B9 d
FATFS *pfs; * c7 M$ x x0 h8 s1 d DWORD clust;8 \! M4 r( Z3 T, E
FRESULT res; // FatFs function common result code- O' a1 r; _; K* n& Q: T
+ T9 t& R9 X$ ] //检测磁盘是否插好 4 W( ~8 ]8 z- ~& u if( disk_detect_OK()==FALSE ) return; " ]9 ^) ?& w1 P2 {/ O+ f8 g 3 h8 n. A* d/ w" ~) i' w- W6 `0 a pfs=&fs;//指向: u6 l9 o. q8 `# o( F2 r! q
// Register a work area for logical drive 0! j* F7 K$ _3 U
f_mount(0, &fs);//安装FATFS,就是给FATFS分配空间 3 t% D) D6 s" @) x5 W6 I7 p7 F8 S1 V3 [+ V3 E/ Z9 R
// Get free clusters 9 y- P7 n3 q5 m# e9 p( A; o res = f_getfree("/", &clust, &pfs);//必须是根目录,默认磁盘0;"/"或者"0:/" # x) h, {9 _& {" i1 p if ( res==FR_OK ) ) Q6 w ^: _7 L5 \; F* P {- {1 {* O/ K$ Q8 u
// Get free space7 S5 E2 ~( d5 J# Z" n
printf("\r\n%d MB total disk space.\r\n%d MB available on the disk.\r\n", 2 A" T% X7 a$ Q$ f/ a9 e (DWORD)(pfs->n_fatent - 2) * pfs->csize /2/1024,//总的磁盘空间M =(总簇数-2)*每簇的扇区数/2/1024=可用簇数*每簇的扇区数/2/10243 t5 Y0 @& y. b$ r
clust * pfs->csize /2/1024);//空闲的磁盘空间M=剩余簇数*每簇的扇区数/2/1024 & o8 V" T+ {& I8 m" r }0 I4 ^' ]0 C0 {
else die(res);//测试函数执行结果分析/ O" w) Z( K/ g( M
- X. t2 f* l9 }* }- B
// Unregister a work area before discard it ) [: t5 D1 L) M5 ^4 G) R" s f_mount(0, NULL);//卸载FATFS,就是释放FATFS结构体所占空间& c' z8 c0 Q, [ [4 v
} 2 _* j9 i0 F! \5 T0 b: O* v: ?
void Test_f_read(void)//读文件的数据,如果没有此文件则返回错误1 N6 O6 t5 |6 i7 V
{5 R) D& F0 w! U- z
FATFS fs; // Work area (file system object) for logical drive # D4 j6 [4 ^# d/ C1 v FIL fsrc; // file objects' W2 s' f9 B. }9 `4 ~- Y& i/ N$ B: ]
BYTE buffer[512]; // file copy buffer " ?$ t. u2 A4 u! C# { FRESULT res; // FatFs function common result code / _3 k3 |5 j7 H K# I6 J UINT br; // File R count ' n0 X5 d+ E r8 e u16 i; + O3 |0 u% f% A B 8 M7 `, T5 d0 p( b9 C
" O, Y' F2 p9 e9 b. c/ u# u char path[20]; ) }( V# q& Z; S8 I$ b7 L1 D3 o+ y1 t9 k* A
//检测磁盘是否插好 % X% }; C/ v9 L+ O6 j if( disk_detect_OK()==FALSE ) return;% p8 C5 N" K, S3 g4 k! r0 _
7 M' j/ K6 f0 `0 O/ A7 R
// Register a work area for logical drive 0+ g6 L) D9 B t0 m
f_mount(0, &fs);, Z. O* ~7 G9 B y0 p# o
5 x! c/ H6 m& Z* B+ ` printf("\r\nread file:>"); , k* u( q% \3 q8 @9 Y! @3 v3 q USART_Scanf_Name(path);//通过串口输入文件路径名/dir/file.txt或者0:dir/file.txt或者0:/dir/file.txt # e! l1 o: o9 P) i" V6 c S8 ~ . Q1 z6 \6 a% f# c! z0 s //Open source file) L V0 c `- a1 V) x/ D
res = f_open(&fsrc, path, FA_OPEN_EXISTING | FA_READ);//打开存在的文件,如果没有则返回错误# t2 B0 y% I; m& x5 W
die(res); . l( \2 ^3 L7 \8 O N5 l6 c5 s & G ]3 v0 S% P" \7 N6 n/ J J- X9 ~ //buffer空间设大一点,会提高读的速度。 2 H9 r9 M& b+ E( h //如果文件实际大小512byte, 5 B. v' u: v) u2 J- y //设为buffer[512]时,只需要循坏一次,如果设为buffer[1],需要循坏512次。 3 f& B. n. _" X, h0 n //下面两行主要是去除1s误差。 % Q; g. T( i+ H5 l; K8 f( }/ q. F& `- v$ o
for (;;) $ X: D! S6 U2 g, k {3 y' H" M1 m4 E5 k
for(i=0;i<sizeof(buffer);i++) buffer[i]='\0';//清除缓存 8 Y$ D B8 I5 |+ U! {2 d0 ?; a- L* W) C0 n, ]
res = f_read(&fsrc, buffer, sizeof(buffer), &br);& M+ k; x' B1 M, f/ ^2 {
if (res ||(br == 0)) break; // error or eof 0 g `" Y% A2 j1 V$ z
& f! v6 y6 P" Y( D! L1 w printf("%s",buffer); 3 }/ V9 D! x; r/ X! E }. w+ u; @. a4 r% I/ P: w; b! E
# r: I; _: W3 N9 ?9 v* h3 G
6 \* P" Z% S5 o- v' j
// Close all files; r( T: p& _ k& n1 E1 {1 C, ?
f_close(&fsrc);0 t1 q' {6 G9 i7 x
// Unregister a work area before discard it* {8 y9 ?( g) A& L( P
f_mount(0, NULL);- p- K4 a% v) L! h J3 |
} 9 ]9 {( ^' J+ b- `1 s' R 6 q# q8 t. ] ?" ?7 Yvoid Test_f_write(void)//写数据到文件,如果没有此文件则创建文件+ y1 u# H) _ q: ^; b, s
{" O5 W# j0 n5 r! ?+ [+ E4 m. Q
FATFS fs; // Work area (file system object) for logical drive- W* D7 i- Y" }2 i6 |2 c
FRESULT res; // FatFs function common result code* }; L: P9 P6 U5 h( K1 S% Z
FIL Make_file; 7 ^8 x* c8 Z( |0 J9 N. e* A char file_name[20];( C7 P8 B1 p1 f7 B/ K/ K6 w
char Storage_buffer[] ="0";; t$ e' N; s9 @% ?! V
/ j1 k- a' x$ C9 |6 |5 t
UINT bw; ) s) l P' F2 r$ o8 b0 ? //检测磁盘是否插好 0 H/ T3 z/ s; M4 u' I2 M5 e5 o n if( disk_detect_OK()==FALSE ) return; : [* U+ K: _# ^, k printf("\r\n inaert_ok:>");5 P5 }3 G2 t( I$ H
// Register a work area for logical drive 0" I7 ~0 S6 I' w
f_mount(0, &fs); 3 _1 S" C9 g: X J" w2 [% z9 v$ V* T4 I9 `8 g
printf("\r\n Make file Name:>"); 5 U0 e0 \6 X/ @, c& c) M* {4 P USART_Scanf_Name(file_name);//通过串口输入源文件路径名/dir/file.txt或者0:dir/file.txt或者0:/dir/file.txt& O% e, m) S3 Z/ `1 K
E! @- t; c/ `: x, e res = f_open(&Make_file, file_name, FA_OPEN_ALWAYS | FA_WRITE); //可写方式打开 没有文件则创建 0 |2 z3 k0 P Z1 q$ u3 I
printf("\r\n open_ok:>"); ; `! ~" A6 I1 U$ x/ Y die(res);4 s2 U" D$ ?# P6 X+ d( @
res = f_lseek(&Make_file, Make_file.fsize); //指针移到文件最后 i+ T" }: @5 p6 |# R% l- u printf("\r\n seek_ok:>");! X; L, ]) l1 Q; G" d* x/ V" b
die(res); 8 l8 }5 a7 w0 V$ Y res = f_write(&Make_file, Storage_buffer, (sizeof (Storage_buffer))-1 , &bw); //每次需要写入的数据字节数,去掉最后的\0所以-1 1 R. z. R$ U% W4 u
printf("\r\n write_ok:>"); ! f' k6 U' h4 q. O die(res); ; S% `0 C" h/ J& H3 u D res = f_lseek(&Make_file, Make_file.fsize); //指针移到文件最后 [$ {' M+ V9 W+ t f_close(&Make_file);//关闭文件 7 y9 h4 P9 g1 v$ Y N% z printf("\r\n close_ok:>"); * n# B" h) E {' A2 F2 u2 e* v. W, {
printf("\r\n写文件测试OK!\r\n");. u2 I' F; g/ m' }. h3 W* |8 K7 r- ]
; ~2 |5 [* _; k# }. R* O% m- }
// Unregister a work area before discard it . G; h8 S# T/ b( N. o. P f_mount(0, NULL); ; r5 _6 ]( x; c8 K} 4 m1 K& C$ D+ U5 U ) h. W/ Z5 P. H# T" ^- X//The f_read function reads data from a file.3 \8 ]1 o' W. n8 B: L, r
//在RAM里面调试这个程序的时候,总出现莫名其妙的错误,最后怀疑是堆寨溢出了,证明果然是这样 ' z" L+ N- S: k5 l1 P6 S3 I4 M' Z& j//把Stack_Size EQU 0x00000400 改为 Stack_Size EQU 0x00000800就正常了4 N2 Z$ a e7 S: t' b: J
//所以以后要特别注意这个问题。 # X. A6 ~" W( T; b! x1 f 7 [9 [, q9 j) g8 W# a, I, @7 Uu8 StrToData(u8 * data, u8 len)/ u1 ]1 h' |, h
{' h* z3 g4 i3 p* ~. L
u8 ltemp;4 x8 u; ]6 {$ B, B# e# w
if(len == 1) 6 Y* ~4 e9 @& g) f+ l6 V { 9 Z: {7 h# W1 k$ m ltemp = data[0]-0x30;8 h1 h. l$ n2 O! F; |1 ]
: p- b6 J* U) P2 k# s: z }# p8 @5 ^( A7 l6 F9 W
else if(len == 2) ' W" X; t& d3 m% ?/ }- L { - C( ]( E8 p3 o' X ltemp = (data[0]-0x30)*10 + (data[1]-0x30); - K- S! t% U* r5 w5 j) Y% L, ]: f9 X# V: `& L$ ~! x/ d
} + m2 L/ [# h0 w //else if(len == 3) / e/ D9 B, ]; ~/ g; C3 e! s5 C //ltemp = (data[0]-0x30)*100 + (data[1]-0x30)*10 + [data[2] - 0x30];* T7 O7 ]! d4 b. t7 }( H: Q6 a
' j9 z) [- e. x/ } w+ r" f: Q
return ltemp; ; B4 W" f1 C+ q; U3 G * u8 f: y" b, S& H6 Q& L0 Q
} 3 d0 P) ]3 T5 q6 O 7 [; x& Z: c5 g + `1 u* ~' Z) z& b#endif @( Y- P% r; J& l( x' Y
5 ^+ ]8 ?$ K, _0 ?' \
$ {3 U. Y/ |8 E7 H: n
/*# R0 H+ Y' E. j- Q) z, r
int main(void) + ~. n E( D8 Z- Q( q* V: P{ ( H* X( _8 ^( L& L$ R' M///////////////////////////////////////////////////////////8 D2 B/ S3 j* N. Z$ k$ G
UART1GPIO_config();//串口IO口配置 * J% E& e3 A! s2 v6 C. L" lUSART1_config();//串口初始化波特率为19200 - s! s/ n$ V q7 V( e$ t//UART1NVIC_config();//配置中断 7 a5 h `) C1 a/ N4 G///////////////////////////////////////////////////////////. e! v9 A! q- C y! O
SDCard_SpiInit();//SD卡的IO口及SPI模块初始化,PA2插入检测(H—>L)A3 CD_CS片选;PA5 SCK;PA6 MISO;PA7 MOSI;低速模式 ; d& I$ C1 p! y4 K//SD_Init();//SD卡初始化,如果使用的FATFS则可以不用这句,因为FATFS在打开文件等操作时已经调用了它* q3 b9 B* {/ s- ^, C6 P
Test_f_getfree();//获取SD卡的容量和剩余容量 / `5 Z4 x- C3 ITest_f_read();//SD卡读文件测试2 B* }7 v, o) w2 L& }) d* C
Test_f_write();//SD卡写文件测试7 `! B5 q# D7 X9 A+ K' G
/////////////////////////////////////////////////////////// - B6 Z* I( S& B+ m+ N while (1)2 [, _4 e. V( D. H* F8 I
{ 2 S' m9 l' ^ R, M1 x' j //printf("好的"); 5 H8 t/ ]3 O) v" q* B2 u }! S. H! T, T; \# ]5 U0 P
}*/ 6 m. a( f/ P/ `( d2 v3 J0 a//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ; X! x; E) z. e, N# r4 X) nFRESULT Test_f_mkfs(BYTE drv)//对卡进行格式化,驱动器号一般为0 ' Y, G' Q/ Q9 Y9 D{ : l, b, v+ V2 O6 {6 x( s& x" A FATFS fs; // Work area (file system object) for logical drive5 Z* K1 D' T" T( t7 x+ ~7 r6 ]' d
FRESULT res; // FatFs function common result code + H& K0 |; Q1 {* g% y1 c: Y$ H* `, _! o& M4 S
//检测磁盘是否插好. R! ^: b% P0 I9 _% \
//if(disk_detect_OK()==FALSE ) return ; # K& o' b( B# U0 D2 J/ D //printf("\r\n inaert_ok:>"); & c* F a: j4 R // Register a work area for logical drive 0! D" m3 e' p$ ^
f_mount(drv, &fs); . A! N: f ]) h$ M% } res=f_mkfs(drv, 0, 0);/* Create a file system on the drive 在驱动器创建一个文件系统(驱动器号,分区规则(0:FDISK, 1:SFD),分配的单元大小)*/ 3 `3 Z4 C& C4 b, u# Q //die(res); / n9 V& f9 e! Y6 @* |6 V f_mount(0, NULL); A' z: w {7 x
return res;, c3 u9 D* Y" c* o* O: `
}- E2 m& y% U! A% v, A
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// . E: Z0 i( S' ^ R, {0 rFRESULT Test_f_mkdir(const TCHAR* path)//创建一个新目录,输入目录的路径Test_f_mkdir("/dir");只能一级一级的建立目录 ' K" N1 B) S* c& i! D4 Y{ 8 |; L; x& j, c) [ FATFS fs; // Work area (file system object) for logical drive ; ^6 \! @7 j& y; C% z x, F FRESULT res; // FatFs function common result code . R1 s4 Y* v* J3 Z+ @- h S 3 f9 Y* _5 N6 g3 a' n+ A4 u //检测磁盘是否插好 - r1 C7 S$ n2 y+ |3 e1 X //if(disk_detect_OK()==FALSE ) return ;; q0 Q8 u" D `
//printf("\r\n inaert_ok:>"); 2 W( ^* }+ X) G q, w4 Y // Register a work area for logical drive 0 , D) F/ I2 `5 b* y2 A0 g: O f_mount(0, &fs); 2 d- j6 j. Q/ p* y# J% z& ~ res=f_mkdir(path);//创建一个新目录+ I2 s1 e3 S m, X
//die(res);" O; a9 `- `- Z* l
f_mount(0, NULL);# Y% S/ t! @- k+ m' P: \
return res; 7 V9 M/ G/ R1 j2 {}) o/ _' G; P6 r" P2 ^# c
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 6 }% G! {" i m m! }5 P& [4 ~FRESULT Test_f_deldir(const TCHAR* path)//删除一个目录,输入目录的路径;目录里的内容是空的才能删除Test_f_deldir("/dir"); 5 y# m8 @2 r' ^) B
{" p( f* c) C: d3 o, m2 A
FATFS fs; // Work area (file system object) for logical drive $ R7 w* A- r" v/ g //DIR dir;3 e% M3 D# \8 {5 t1 O! [" W. U
FRESULT res; // FatFs function common result code& e4 v* u: X3 m2 a% c
6 ~% G* ^/ P( O4 s; H* F# w
//检测磁盘是否插好" K5 s' K3 j1 `6 g( _$ o
//if(disk_detect_OK()==FALSE ) return ; : l7 l, K9 q( s; ~7 V2 ?+ D& R0 Q' L6 C //printf("\r\n inaert_ok:>");3 U; n6 H& u+ A7 f1 S( n" _
// Register a work area for logical drive 0& h$ \0 q! ?. ^
f_mount(0, &fs); 7 [* [: Y( l7 J9 r; ]3 b8 i //f_opendir (&dir,path); + ^8 |6 N9 _" p2 v/ S res=f_unlink(path);//删除一个目录 , d# V6 m4 K! A2 _, n //die(res);& P% ^$ {: |4 j9 E' h
f_mount(0, NULL);+ e* `5 c& L3 `! @2 R5 B
return res; 3 t/ s" [% Y: ?}% i# D8 ]* @' m! T. i
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// : c6 k" R: j% @/ F. |# P+ }FRESULT Test_f_readdir(const TCHAR* path,char (*filename)[13])//获取目录中的文件,输入目录的路径;输出文件名和文件夹名Test_f_readdir("/DIR",name);char name[5][13] , X7 e, b. B* a7 X# s
{5 G: N# ^8 R$ ~
FATFS fs; // Work area (file system object) for logical drive) H6 {& c! f! ~5 C! E
DIR dir;. Z' u, I- h- n3 M a
FILINFO finf; * q. c1 O! \1 D, K9 v; W FRESULT res; // FatFs function common result code ) ^" ]" e3 d# ^/ D8 ^/ I2 B6 ^9 T1 ^* ?, h! q
//检测磁盘是否插好 T. o7 O/ K4 W# V& {
//if(disk_detect_OK()==FALSE ) return ; * z; h' u$ X3 L //printf("\r\n inaert_ok:>");/ R ?4 I- G3 b. O) o
// Register a work area for logical drive 0 ( _/ a6 M! r6 o f_mount(0, &fs); 6 m% ?4 x% O2 n4 {" X) i f_opendir (&dir,path);' E+ G: y' u5 C# V2 I; M1 Z
* f. q4 O: ~; u0 P9 @7 e( T. t
while(((res=f_readdir(&dir,&finf))==FR_OK)&&(finf.fname[0]))//获取目录中的文件 0 `- r+ ^9 U$ r4 c/ f
{strcpy(*(filename++),finf.fname);4 b( ?9 C( C' g6 p; Y8 P2 T
//printf("%s",finf.fname);3 ~0 }) q8 p8 P3 H
}9 F8 o/ w% {$ G
//die(res); + ]) F$ g0 G8 u# m8 s S f_mount(0, NULL); / i( X4 L+ T( P: i7 b return res; 2 d- E: t1 \3 d& ?, `# W. _+ q: L3 u" m} . Y A5 U& N. u' X, j////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////" v5 n; k- O: B" N! s4 L; H) U' @5 \( m
FRESULT Test_f_creat(const TCHAR* path)//建立文件,输入文件路径和文件名 6 H6 E" A& U8 S- ]{+ m; `, J" R/ o! i( r3 m
FATFS fs; // Work area (file system object) for logical drive/ J( O0 Z" d7 O. k" s
FIL file;7 F& @( `/ j# A" z7 v# L9 ]
FRESULT res; // FatFs function common result code w w' e, M) R. ~- \* U; s0 |3 J: a/ S' l
//检测磁盘是否插好, | V2 F- D. l: A% ~
//if(disk_detect_OK()==FALSE ) return ; 2 o" \" c/ x1 f //printf("\r\n inaert_ok:>"); % u/ B1 w6 R5 s! O' `9 v // Register a work area for logical drive 0" v/ a$ j* w& a( q* H; u
f_mount(0, &fs);# M4 N3 }6 p& H9 |0 |5 x+ i
res=f_open(&file,path,FA_CREATE_NEW); //创建一个新文件。如果文件已存在,则创建失败//FA_CREATE_NEW创建一个新文件。如果文件已存在,则创建失败。 ' U, @" p' c( {, j5 Z/ O //FA_CREATE_ALWAYS //创建一个新文件。如果文件已存在,则它将被截断并覆盖。1 F7 K" n3 V( b8 T# Q
//FA_OPEN_ALWAYS //如果文件存在,则打开;否则,创建一个新文件。4 M- B4 e; y# R; h; j
//die(res);) g9 I2 W2 T- q, J4 @
f_close(&file);//关闭文件 `& n1 W; I5 a$ O5 `, [ f_mount(0, NULL); . g3 G; K" m; ~ return res;$ H: e; `2 m h9 u" y2 C) q3 x; C
} ' C d; J5 a. }: ?& j" f. N////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////& ?0 L2 K/ c" l- m- N, l
FRESULT Test_f_delfile(const TCHAR* path)//删除一个文件,输入文件的路径;Test_f_delfile("/dir"); |, g/ v h+ j{ . D( }) v4 S, ]3 A FATFS fs; // Work area (file system object) for logical drive 4 N7 v P# G( j5 u1 E3 a //DIR dir;2 Y, r' ]5 \5 S; G
FRESULT res; // FatFs function common result code ; U! a: Y! G0 q7 Y @. [- C ' W+ \3 l, V' i //检测磁盘是否插好$ |; Q: g; m; K& Z1 S8 n( O, T
//if(disk_detect_OK()==FALSE ) return ; m0 B, Y! U+ k4 Z5 n4 ? //printf("\r\n inaert_ok:>");7 V5 d$ d) D6 \! Q& M S. j
// Register a work area for logical drive 0 ! @: c) u" y3 A" u! @' w4 @' v, x+ v f_mount(0, &fs); / k( u' k: W' w, ~2 | //f_opendir (&dir,path); 5 W) }5 y0 A; K res=f_unlink(path);//删除一个文件 4 {( q# {; Y0 ?# ?! R% ~ //die(res); # u# L3 P4 B, p4 d/ [ `, m f_mount(0, NULL);3 \) N3 c0 U- h, y
return res; * s" `% C$ `* o4 p" G; ?} . ^+ F( F- b( q0 d% F/ r& ?////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////- h1 v& q# b5 b7 S
FRESULT Test_f_readfile(const TCHAR* path,char *buff,DWORD ofs,UINT strl)//读文件的数据,如果没有此文件则返回错误;输入文件的路径名,内容缓存,读取开始偏移指针,读取的字节数 9 M8 U0 C* a7 u8 `5 p5 V{ //Test_f_readfile("/dir/r.txt",str,0,sizeof(strr)); : d2 T% G. V9 o3 M! D3 }2 s) M5 d FATFS fs; // Work area (file system object) for logical drive. j8 B$ H: I, C/ E
FIL file; // file objects) `" {4 R. U, I5 N& T; M
FRESULT res; // FatFs function common result code ; N7 U0 m4 U7 O W& s) e5 H$ i4 X: O* R/ o UINT br; // File R count 文件读回的字节计数* G8 H, ~! V3 x9 K& r0 v
//u16 i;8 V) |6 [; d/ y: }1 k" z4 @
//检测磁盘是否插好 3 K. ?9 g, w# Q0 I7 M- G! R //if( disk_detect_OK()==FALSE ) return; * n) z& R, t. g ?; ?* r // Register a work area for logical drive 09 I+ i/ f( V+ l5 \' [9 Q+ Q. j2 {
//for(i=0;i<sizeof(buff);i++) buff[i]='\0';3 i# B+ ]1 X8 i' Q
f_mount(0, &fs); I' N% C7 o9 |4 z* }
//Open source file r; n2 `# `/ z5 a) \* \5 f1 `" R
res = f_open(&file, path, FA_OPEN_EXISTING | FA_READ);//打开存在的文件,如果没有则返回错误6 `. M4 S0 o: W
//die(res); - e: I5 u5 k8 M8 L/ U! u res = f_lseek(&file,ofs); //指针移到文件ofs个字节处 7 T+ ^2 S& ^$ O6 Q- l; ? //buffer空间设大一点,会提高读的速度。& Y# a& Q% Q9 T- b: \7 F& L: I
//如果文件实际大小512byte,& l, y. A, ]& s3 D D4 H( ]
//设为buffer[512]时,只需要循坏一次,如果设为buffer[1],需要循坏512次。' O5 R( z, \& z0 o8 l. X
//for (;;) 2 R+ T6 o* ^: v- r0 S) ?% a" P' n- ^# q, h { * g/ C3 g" H) A' `! L! t //for(i=0;i<sizeof(buff);i++) buff[i]='\0';//清除缓存' [! U( z; A; d' ?/ X
$ j9 |5 ~, d! G8 T2 @$ U res = f_read(&file, buff, strl, &br);8 m! n* S- V0 p6 B8 r; O6 D
//if (res ||(br == 0)) break; // error or eof如果错误或者到文件末尾则退出0 G6 e/ p: F1 B& s, Y3 \; z3 i
$ s# n$ S4 B( u& g //printf("%s",buff); * y. F0 w3 Y+ F$ E } " w0 o4 X$ K6 w0 M( \
// Close all files5 {4 H0 T) a/ M4 b. e
f_close(&file); 4 I" m$ U! z! ` // Unregister a work area before discard it . g. ^& m2 n0 U W* l( l f_mount(0, NULL); 3 L3 b3 R0 S( |+ |& ?+ Z2 s3 \( L return res; ' X4 t9 Q* K w+ s& n. `+ a% E X} $ m' _" h- I- S% a t- _//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 8 e) w" \6 u- L! p6 N' zFRESULT Test_f_writefile(const TCHAR* path,char *buff,DWORD ofs,UINT strl)//写数据到文件,如果没有此文件则创建文件;输入文件的路径名,内容缓存,写开始偏移指针,写的字节数 V0 I D! K. s5 L{ //Test_f_writefile("/dir/r.txt",strw,0,strlen(strw)); 1 l. a$ i b! \# a2 P- d- T7 i FATFS fs; // Work area (file system object) for logical drive8 }1 K% {) q: U6 V
FRESULT res; // FatFs function common result code: [2 d8 V: T3 Y0 O" F
FIL file; , B1 p# J) {/ @0 T% ]9 ^2 P; k7 B UINT bw; //文件写入的字节计数 6 I- |- I. X+ C //检测磁盘是否插好 {# u6 {% a% S, N6 d( d //if( disk_detect_OK()==FALSE ) return;: e( h" k0 E1 q) q/ K
// Register a work area for logical drive 0 : o4 u* [0 Z& n7 g$ G9 V f_mount(0, &fs); " [; C: {: R, H. ~/ T7 ` res = f_open(&file, path, FA_OPEN_ALWAYS | FA_WRITE); //可写方式打开 没有文件则创建 / j" r) i% Y2 n1 Q0 }# R# a/ E
//die(res);; \2 [0 E6 F* p8 L( d' ^8 H8 k
res = f_lseek(&file, ofs); //指针移到文件ofs处;输入file.fsize指针移到文件最后 . x- V& }: c; }; r5 {, J
//die(res);: P& P# s& b- I x9 I& u* c+ G
res = f_write(&file, buff, strl, &bw); //每次需要写入的数据字节数;如果btr为strlen(buff)则写入所有的字符' R- Q# O8 z) P1 v$ N: X2 z
//die(res); Y! O! K3 X1 e //res = f_lseek(&file, Make_file.fsize); //指针移到文件最后,一边再一次的写入 6 I1 t+ R7 d; Q. k! u: ^3 }
f_close(&file);//关闭文件 2 \ ^/ F1 q9 x3 f+ {1 L // Unregister a work area before discard it7 o, W* g" Y c" u; l& Z
f_mount(0, NULL); ; C) m6 T8 o2 N return res; + Y. K4 g( `4 f9 r3 L0 x9 @} 1 S0 \- O0 s! W//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 4 R3 t/ H) n6 D5 R1 [FRESULT Test_f_getfreem(DWORD *freem)//获取卡的剩余容量单位为M 0 d8 z0 d0 j8 C# d+ S6 X% I, P+ G, m{ ' q9 S0 \3 Q4 [( P FATFS fs;4 P, |6 E% p8 @1 |4 v
FATFS *pfs;# Y( _1 T9 _$ c/ ]( v
FRESULT res; // FatFs function common result code * ~/ s1 p5 K: W! e- U- L# g: f/ c //检测磁盘是否插好 + j5 i- E A) V: S! ~, {$ O& H //if( disk_detect_OK()==FALSE ) return; 8 Y" o5 o( U, [6 o" h4 L5 J // Register a work area for logical drive 0! g6 z* J' H% l: J
pfs=&fs;//指向2 k0 A2 I6 z' C O( o5 e% y+ s+ \
f_mount(0, &fs);//安装FATFS,就是给FATFS分配空间 0 c8 L2 _4 n& F% j) w' C; C5 F6 Q // Get free clusters 1 p ^* A1 B8 W; Q. ]# U7 M0 ^ res = f_getfree("/",freem,&pfs);//必须是根目录,默认磁盘0;"/"或者"0:/", `; `& D( c- A! G
//die(res);& h/ C* Y+ N1 m& s, f" ?3 S
if ( res==FR_OK ) . x# |2 t9 z' Z
{6 Y1 Z: Z- s1 l
// Get free space 5 N5 q# X" @' ^% U5 i. \0 L& v //printf("\r\n%d MB total disk space.\r\n%d MB available on the disk.\r\n", 2 [7 {4 |& X2 L6 T' R //(DWORD)(pfs->n_fatent - 2) * (pfs->csize) /2/1024,//总的磁盘空间M =(总簇数-2)*每簇的扇区数/2/1024=可用簇数*每簇的扇区数/2/1024% h: g% j/ i0 Q$ o
//(*freem)*(pfs->csize)/2/1024);//空闲的磁盘空间M=剩余簇数*每簇的扇区数/2/1024 ; @! e, E5 y6 V3 g *freem=((*freem)*pfs->csize)/2/1024; / w( |2 G: ?+ N0 y }: q" }* D" Q) z$ L) G
//else die(res);//测试函数执行结果分析5 c3 _: h+ P% Z6 r
// Unregister a work area before discard it# g1 d$ `5 P; G4 T' v( [9 L
f_mount(0, NULL);//卸载FATFS,就是释放FATFS结构体所占空间/ E9 e Z, ^' R% ~( u
return res;4 Z1 N1 I9 I9 L0 m4 f
} 3 t# q& h7 U% m v3 M2 S5 _0 F; k3 E5 R
7 I+ C: y' `# _5 W. l( b2 L2 B! V
: E. U9 ?2 U$ M# I9 o2 U
/ Feb 26,'06 R0.00 Prototype. : s# X; m/ k- r, X: J1 o# F/ ? |: t/% v& f% E# K# f. H6 E8 m& T
/ Apr 29,'06 R0.01 First stable version. 0 _( f0 ?2 m" n6 `4 L: P/ ; K4 B+ F1 a$ {/ Jun 01,'06 R0.02 Added FAT12 support., b( T9 ~1 ~: W9 G
/ Removed unbuffered mode. # ]! K, }9 p3 Z, _$ Y. u' \- h/ Fixed a problem on small (<32M) partition. 1 f0 }2 E% m" d; @+ c/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). . Z! m" M/ a/ [' t' K/ - ]3 Z4 u1 } T7 s/ Sep 22,'06 R0.03 Added f_rename()./ q' d+ w& Q9 ?* B( ?3 x& W7 J3 {: d
/ Changed option _FS_MINIMUM to _FS_MINIMIZE. 5 H5 i# s4 x- v6 Q f H/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast.3 Q9 O2 m6 n5 r1 l( g2 O$ {
/ Fixed f_mkdir() creates incorrect directory on FAT32.. B3 y# O& r `# r, S% C9 A$ K
/ ' G* v! T, r$ @! y- f' a/ Feb 04,'07 R0.04 Supported multiple drive system.' b3 {( i8 z7 V0 m) E5 X& }1 A
/ Changed some interfaces for multiple drive system.6 b" V( M' W4 v6 U+ ?8 Z
/ Changed f_mountdrv() to f_mount(). ( P8 h# \8 W& G, q) h4 g+ j/ Added f_mkfs().$ X8 l$ v" v% }' ~) E# G
/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. 2 ~8 L' L, H, L$ c/ Added a capability of extending file size to f_lseek(). 4 D& _3 o& {% l$ t# u/ Added minimization level 3.3 U9 }' t/ E) _% T0 i- H
/ Fixed an endian sensitive code in f_mkfs().& z/ a4 p/ u! w- v% \
/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. # P4 X' D- V, a" w, F0 Y/ Added FSInfo support.; f3 A3 Y! a9 M, M' u
/ Fixed DBCS name can result FR_INVALID_NAME., O P" {; i* s1 E# } j' W
/ Fixed short seek (<= csize) collapses the file object. . w% w. `+ K$ O) ~2 H, N$ w/ + A' H& ?6 ~- V8 T/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). : ?% ?6 h1 ?0 f3 u: c/ Fixed f_mkfs() on FAT32 creates incorrect FSInfo. ) l$ {3 s: ]. ~* [1 k/ Fixed f_mkdir() on FAT32 creates incorrect directory.) s+ C5 k/ {$ `% j7 f
/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). 5 Y! Y4 l, Q$ u1 O! e& v) `/ Fixed off by one error at FAT sub-type determination.0 d1 j3 A K3 |+ Q
/ Fixed btr in f_read() can be mistruncated. : Z* _7 t f$ w' r/ Fixed cached sector is not flushed when create and close without write.1 {0 H) i3 {1 l( E; j" @) e
/. H0 s% a! {& J+ ^+ S2 f
/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). $ @: }3 W+ R- Q! z- Y: X. `/ Improved performance of f_lseek() on moving to the same or following cluster.3 N/ m# t4 }& N& \
/& c U2 W2 S. O$ n
/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY) 0 n% c: F1 V# V! Z7 ?/ Added long file name feature. 0 M0 C z: f$ W, N x) \/ Added multiple code page feature. 3 b3 z) G7 E. c/ Added re-entrancy for multitask operation. Y1 R1 t$ T! c/ Added auto cluster size selection to f_mkfs(). % J$ ?5 ?; s9 T1 `- Q4 W/ Added rewind option to f_readdir(). 7 M# t. v1 j, Q% G/ Changed result code of critical errors. $ b# P. y3 o Q8 b& s, [, o- i0 U$ r/ Renamed string functions to avoid name collision. 2 p8 }3 l2 l& ^: ]5 x/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. 1 w6 _& _; X v- }/ Added multiple sector size feature.$ Z1 ^- s0 i+ u
/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. * j8 x7 X% ]2 n2 K/ Fixed wrong cache control in f_lseek(). 0 w$ {; O+ v: {- N |+ Q5 H( r5 _/ Added relative path feature. $ @0 o( P. X6 h- m; U. u/ Added f_chdir() and f_chdrive(). ; b& ` N8 P* Q4 m/ Added proper case conversion to extended char." K! U+ A% c4 _+ n8 i& @) Q
/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. , N7 k7 z f1 ~4 Y+ K) K: @6 N/ Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH. 2 R; h9 [- v; Y6 y' A$ `; w/ Fixed name matching error on the 13 char boundary. / W- s2 u( x/ y' ]* m/ r/ Added a configuration option, _LFN_UNICODE. - ?, u9 |5 k1 _/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.5 k( q3 V7 C" o: T8 y; O" t. x
/ 4 R S/ Z! e- Y4 Q1 f- e4 ~6 j/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3) ! X: `( c/ z+ Q1 G% U, q/ Added file lock feature. (_FS_SHARE) + Q( P, V, F8 [9 w* m/ Added fast seek feature. (_USE_FASTSEEK)- |+ A5 B4 q1 g
/ Changed some types on the API, XCHAR->TCHAR.$ m/ ~, y' C( J9 C3 q
/ Changed fname member in the FILINFO structure on Unicode cfg. + z: ?+ d$ j. I5 z& F) g/ String functions support UTF-8 encoding files on Unicode cfg. 5 i7 p. t/ m; N8 W$ o* v/ Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2) 6 D8 U( w( t$ `$ ^. D6 L1 c" O/ Added sector erase feature. (_USE_ERASE) - h& Z5 c* b- _7 g& `: S/ Moved file lock semaphore table from fs object to the bss./ f( `3 L$ @) W1 }3 B/ i
/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.2 z! L. F# ^* q' j* V$ u/ O
/ Fixed f_mkfs() creates wrong FAT32 volume.# }0 g: Z4 H9 N5 g
/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().* }! d6 X- Y1 s
/ f_lseek() reports required table size on creating CLMP. # C6 W G2 W" s/ Y7 J4 s# |: J/ Extended format syntax of f_printf function. 3 d1 w2 i: o8 G1 P/ Ignores duplicated directory separators in given path names. / ?* q/ d# R& l8 j/. X5 b- _" d" a+ \& N$ Q
/ Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature. " h; e- w: L6 ?6 ^0 @/ Added f_fdisk(). (_MULTI_PARTITION = 2)# ~ ^8 h, L8 z m+ f/ x& v' ^
/---------------------------------------------------------------------------*/. o8 Q) }$ P$ u