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