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