[转载]STM32CubeMX配置文件系统FATFS
* B# a' S" j! v$ c% Fhttp://www.waveshare.net/study/article-657-1.html
; ~ w1 Q6 P8 L3 [; t(出处:微雪课堂)3 z( F3 F/ o! u2 N0 _
FATFS简介
) e& @. \2 u2 }2 P2 {6 m* I- H! \) r O- M. X
FatFS是一个为小型嵌入式系统设计的通用FAT(File Allocation Table)文件系统模块。FatFs 的编写遵循ANSI C,并且完全与磁盘I/O层分开。它可以被嵌入到低成本的微控制器中,如AVR, 8051, PIC, ARM等等。兼容Windows文件系统。. ~6 {6 [/ c; e; N$ o1 i
关于FATFS文件系统的API函数介绍,底层移植接口和例程等可以查到FATFS官网。
@ e3 n/ O8 H4 L" D. k
; a) M2 M/ ~6 k% m2 wFATFS官网:http://elm-chan.org/fsw/ff/00index_e.html
& {. k$ I5 ^0 y9 J, L; {/ }" @6 k& s' w9 k$ b
* w3 o9 T0 p# T; c3 t- z6 J
结合STM32cubeMX软件移植FATFS文件系统非常简单。本章程序在上一章SDMMC工程的基础上修改,复制串口SDMMC的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。在中间件中选择SD卡,在SD上建立文件系统。
a( C, A' t }
: Z8 M" d0 F6 W# v8 k
' k$ Q/ Z8 s3 T8 H8 y, N7 G 在FATFS配置中选择简体中文字GBK编码支持中文,使能长文件名,缓存存储在堆(STACK)中。8 x7 G+ E3 O, d
( W6 x S. c( u ] 点击菜单栏中Project->Setting修改堆的大小,堆设置为0x1000。(注意:由于刚才设置长文件名动态缓存存储在堆中,故需要增大堆大小,如果不修改则程序运行时堆会生成溢出,程序进入硬件错误中断(HardFault),死循环)。
% {6 y/ J' j1 V; _3 w
1 E; q/ q, Q; E' C2 D/ t( ^ 生成报告以及代码,编译程序。在fatfs.c文件中可以看到FATFS初始化函数。在bsp_drver_sd.c文件中可以看到SD卡的板级操作函数,包括SD初始化,读写擦除块操作函数。在sd_diskio.c文件中可以看到FATFS文件系统移植的底层操作函数。
8 I% \* @: |% L% V$ n
; k5 k y+ \) `% k8 q5 P$ P$ P. s
删除上一章SDMMC的应用程序。在main.c文件前添加变量。fs为文件系统工作区,fil为文件对象结构的指针。rtext/wtext分别为读写缓存,bytesread/byteswritten分别存储读写的字节数。filename存储文件名(FATFS文件系统配置时使能了长文件名,最长255字节,若不支持长文件名,则文件名最多8个字节)。
( o2 l/ k1 A, _" b( q2 }/ H, {- /* USER CODE BEGIN PV */4 _" [# e0 i2 J4 P) I7 ~, z
- /* Private variables ---------------------------------------------------------*/0 ~ Q, P7 y3 s
- FATFS fs; // Work area (file system object) for logical drive3 J# |7 _# \& r+ b
- FIL fil; // file objects
" h2 k) o/ R O -
) A: W0 i0 N& @& k - uint32_t byteswritten; /* File write counts */
% ^2 k; Z7 B+ S - uint32_t bytesread; /* File read counts */
$ q& n4 B' B. p - uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */% ?2 y V# W, E# I; P9 Z
- uint8_t rtext[100]; /* File read buffers */' v4 y3 m* O3 z7 ?$ Y; |
- char filename[] = "STM32cube.txt";* p2 P. E! t! G8 K7 V1 _; v
- /* USER CODE END PV */
/ E8 n4 W0 ^1 v9 D V6 w$ i
复制代码 在main函数中添加应用程序。程序中首先注册一个文件系统对象,然后新建STM32cube.txt文件,将数据写文件中再读出来,判断文件系统是否工作正常。: m# L1 r4 k% k9 F( E9 q% @! B
- /* USER CODE BEGIN 2 */
" B$ d, }4 b: A5 ~: g$ l - printf("\r\n ****** FatFs Example ******\r\n\r\n");# r& U K3 X+ H$ k" Y ]; O2 \8 ~
- ; A1 X. q v' T" I0 L
- /*##-1- Register the file system object to the FatFs module ##############*/2 V( S6 J/ I9 U
- retSD = f_mount(&fs, "", 0);
9 m+ @2 S9 U# C4 E - if(retSD)- @6 j9 f: a: i; z5 A
- {
. t$ d6 s+ d; z! z' O: I4 Y& f6 i - printf(" mount error : %d \r\n",retSD);
2 K) h/ y9 d5 ~9 N - Error_Handler();; l7 T" ?6 t8 n' D% F; ~+ v
- }+ c" U, Z+ }/ k' K5 F' z
- else
( v2 e/ B2 I5 ^9 y! u - printf(" mount sucess!!! \r\n");
! y* h% G: D( w -
& y B& h- A3 J0 h+ y: P* p - /*##-2- Create and Open new text file objects with write access ######*/7 P: }8 A* g3 ~1 B# L$ u* S5 e$ O
- retSD = f_open(&fil, filename, FA_CREATE_ALWAYS | FA_WRITE);; y. G; t& o' O. u! q1 O
- if(retSD)
6 w- p6 u" h( I2 \& v - printf(" open file error : %d\r\n",retSD);
$ t7 w& d: G; f! p - else
8 L/ e' |/ f: c. D2 g# B - printf(" open file sucess!!! \r\n");
6 ]$ p+ n* ], s5 z: T5 l; |9 f -
! C" k8 m, }8 p" X8 P. i - /*##-3- Write data to the text files ###############################*/* _5 k% k$ [0 f8 D$ o
- retSD = f_write(&fil, wtext, sizeof(wtext), (void *)&byteswritten);6 p& m8 Y% r6 b$ y# v! Y
- if(retSD)
. Y x( \0 W" n0 b- S# V - printf(" write file error : %d\r\n",retSD);1 a; f. \: u# j3 @, _) F4 U
- else6 c! E4 P4 ~1 z4 Y
- {
7 e2 V9 }4 j, A" h$ \; ~/ a - printf(" write file sucess!!! \r\n");
' T6 [- x( v% N - printf(" write Data : %s\r\n",wtext);, k' ] z- X7 r
- }
7 L1 ^4 B/ i, |/ v! a -
- I" ^* D: Z1 g: `4 d% A - /*##-4- Close the open text files ################################*/
4 F% Y& J: f7 R! } - retSD = f_close(&fil);6 A$ N% r2 h/ w; K! G, T- C0 L; J
- if(retSD)0 r, V+ z1 ? F- o, Y5 }2 \6 P p2 N
- printf(" close error : %d\r\n",retSD);
0 d% _" s4 _; N - else
J C. p+ a2 v1 S - printf(" close sucess!!! \r\n");
* l+ W3 j5 t+ }3 d3 }! c -
$ z4 G9 t- o) ~" J$ l( j r+ V - /*##-5- Open the text files object with read access ##############*/% @# T2 L0 \$ X2 U
- retSD = f_open(&fil, filename, FA_READ);9 ~ V: W5 {2 m) a& f
- if(retSD)$ D& h0 |/ V y! C4 g; f
- printf(" open file error : %d\r\n",retSD);
# \" A& d; J5 c* G - else! V4 Z, a( E( @5 Q1 L" Y2 t
- printf(" open file sucess!!! \r\n");
0 n7 V* j% E( G2 M! G -
$ S1 @6 ?& b# K0 K: q% X6 | - /*##-6- Read data from the text files ##########################*/
W+ i3 [( M" h( ]& _ - retSD = f_read(&fil, rtext, sizeof(rtext), (UINT*)&bytesread);
6 p" F3 I% c* t O - if(retSD)" X D1 T5 f3 }
- printf(" read error!!! %d\r\n",retSD);
+ q) I; G# f; D) V- `: I& H$ V - else4 J9 `. w/ n7 S, s$ d
- {
7 F0 F- O6 Y; q9 P6 I - printf(" read sucess!!! \r\n");
$ L& N( s3 y, E. P) t - printf(" read Data : %s\r\n",rtext);
, G, S. f, v( e, r" z - }8 m/ X. v0 x/ f
-
, A% s+ Y2 a- K1 R) W8 U) M3 \3 x - /*##-7- Close the open text files ############################*/
+ [4 l$ G7 C- k& N - retSD = f_close(&fil);
& n# O- n t' }0 m e# Q# i - if(retSD) & |, ~$ H0 U3 T4 `* ^
- printf(" close error!!! %d\r\n",retSD);- _" s% F$ M% I% P" V& m: z; {3 O
- else
+ t- M; }! n, c w G; Y - printf(" close sucess!!! \r\n");
# y9 a) @. b" F - 5 h. c+ X3 H2 M, _/ t3 y
- /*##-8- Compare read data with the expected data ############*/
+ m/ d% k3 b$ g4 q0 {" ? - if(bytesread == byteswritten)
2 ?$ I* L* N# N: J2 K - {
3 W3 x! u/ S- V% e - printf(" FatFs is working well!!!\r\n");% p1 {- Q/ W+ {6 g; u# V
- }
0 b7 {! \2 ~% E - /* USER CODE END 2 */
复制代码 在main.c文件后面添加错误处理函数。
$ J* k5 o/ i2 n+ R- /* USER CODE BEGIN 4 */
* g+ e2 D5 n# I, C. E* u6 D - static void Error_Handler(void)
- z: I, I' F5 e* E3 k( c9 A2 T. n& Q - {! ~! T) a! C1 w+ X
- printf("something wrong ....\r\n");
& T6 h: I+ m/ f6 N$ @ - /* User may add here some code to deal with this error */
! |% y' i# c3 ^1 { - while(1)
( o, m/ |0 o* m6 r - {; ], x+ X2 M7 ?+ p. P% @: P
- }3 W* d) \/ [& d* Y- j, `' W/ R8 ?
- }
/ ]7 O) k$ j7 i9 D - /* USER CODE END 4 */
复制代码 在main.c文件前面添加错误处理函数声明。
; }4 i d" A' {, z- U- /* USER CODE BEGIN PFP */* Z2 g; S8 P" n9 {
- /* Private function prototypes -----------------------------------------------*/
% I+ C, ^! y* y/ J& z - static void Error_Handler(void);8 i# S$ J: F+ S# ?( J
- /* USER CODE END PFP */
复制代码 编译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。: S+ P) ~+ w w( ~' U7 w+ U
" d7 A! v7 S. G1 L! N$ B4 a下载简介一下FATFS的几个操作函数。. R- h9 n- A0 ]4 {; a5 b
1.f_mount- W4 M8 r1 Y$ q4 ~$ g) k. k
在FatFs模块上注册、注销一个工作区(文件系统对象)。' W) m- O' }7 K0 |: m
- FRESULT f_mount (
# _9 n% e+ W6 m# o- g - FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/' @0 L. _! F3 e6 n) s) v
- const TCHAR* path, /* Logical drive number to be mounted/unmounted */
& {5 p6 T( _: a+ z - BYTE opt /* 0:Do not mount (delayed mount), 1:Mount immediately */
6 h0 |1 w( g& K7 `1 g6 x - )
复制代码 参数4 [4 [. @, x, a, b9 J5 V% G
fs 工作区(文件系统对象)指针7 k8 O, c4 Q, |- e
path 注册/注销工作区的逻辑驱动器号8 y9 v* z" k5 n& q' H
opt 注册或注销选项
8 v& `" z8 n2 d8 b+ ?1 @ n* r4 O7 q& u8 j! g5 f9 u
+ u4 }2 L [ w/ X0 ^6 b m9 k5 B
0 B) x# t. I! k3 q6 K9 j2 h# n, M
( h1 n) C3 x- O% L7 O; ^ W
2.f_open: w/ I2 E( T% u$ c* X$ J
创建/打开一个文件对象 K& n1 f) U4 j# E5 d
- FRESULT f_open (
) V2 h" l9 L i) {6 l5 o! q - FIL* fp, /* Pointer to the blank file object */' W7 Y/ \4 _ j8 ~5 q8 Z
- const TCHAR* path, /* Pointer to the file name */
; @8 v, d8 Z/ n7 u - BYTE mode /* Access mode and file open mode flags */
% o* O$ Y) x" F. e% _+ P - )
复制代码 fp 将被创建的文件对象结构的指针
- r- i G% {# M$ ?0 |path 文件名指针,指定将创建或打开的文件名
6 X% l- S x' T# Zmode 访问类型和打开方法,由一下标准的一个组合指定的。
* F! G+ f4 I, _$ X, K. u$ i5 V: x2 i) m7 n) V5 s o6 H& D
' e/ ` U* K' v; A% i8 d: S模式 描述 3 l% v; S% u0 r! }4 G
FA_READ 指定读访问对象。可以从文件中读取数据。 与FA_WRITE 结 合可以进行读写访问。 ; W. h6 @ c* `) v$ D# i) e
FA_WRITE 指定写访问对象。可以向文件中写入数据。与FA_READ 结合 可以进行读写访问。 ; Y n) {) k9 b
FA_OPEN_EXISTING 打开文件。如果文件不存在,则打开失败。(默认)
/ w# ~4 w% B9 S/ ~8 vFA_OPEN_ALWAYS 如果文件存在,则打开;否则,创建一个新文件。 ) l+ O |/ u0 M% U
FA_CREATE_NEW 创建一个新文件。如果文件已存在,则创建失败。
( L" r' |- r% b: T P! U" nFA_CREATE_ALWAYS 创建一个新文件。如果文件已存在,则它将被截断并覆盖。
9 f# D* n- [& k# [/ o+ `+ T- r& M$ ^# _' T* d# u; ?! Z
3 K, L5 j- q" J) v3.f_close
& Y: l* I+ b0 l3 K关闭一个打开的文件; o: c$ r: Y S* e: S1 H7 d
- FRESULT f_close (
' W, m2 U3 s8 v/ ^# o$ z3 _( G - FIL *fp /* Pointer to the file object to be closed */
7 |/ {$ v% ]0 L% Q7 O; N i! j - )
复制代码 fp 指向将被关闭的已打开的文件对象结构的指针。- y1 r- z \: |" x
: ?- r9 R3 i( c! Z. E- U- j, ?
& @/ x( m9 t# i. Y6 A4.f_read4 q7 F i$ }7 v2 b" T* H
从一个打开的文件中读取数据$ n) n% r8 q Z/ Q4 g) p" N& n
- FRESULT f_read (+ S7 N9 c: T/ x" ?
- FIL* fp, /* Pointer to the file object */
# h1 a8 S5 c n' T$ M. D - void* buff, /* Pointer to data buffer */; Z* N0 L/ |4 {- z3 o! b X C' x
- UINT btr, /* Number of bytes to read */# g, @8 j' D9 X. q, R, F9 c6 }+ }
- UINT* br /* Pointer to number of bytes read */
8 F4 d8 w; f$ k/ F9 f w - )
复制代码 fp 指向将被读取的已打开的文件对象结构的指针) E- W6 l3 Y# ~! C4 d
' N2 Z) R; ? Y+ L0 l% O
buff 指向存储读取数据的缓冲区的指针; k, Y! Q. ?7 k/ ^1 \) i, r
btr 要读取的字节数' Z0 J5 q# o( O4 P8 ]4 h$ ~9 Q0 m
br 指向返回已读取字节数的UINT变量的指针,返回为实际读取的字节数。& Z6 c$ N9 O5 j2 h1 q# C' u
7 G3 ~- J, ?. `* t9 s4 M. c) R3 s1 t! Q3 E, A, U; p w! e5 S
5.f_write3 e) B& u6 o! w0 T6 R8 K
写入数据到一个已打开的文件
% Y+ l9 y6 S7 y# g- FRESULT f_write (
' {+ u8 ?# D: R/ F - FIL* fp, /* Pointer to the file object */0 ~( m+ E+ l& t7 M# }" M
- const void *buff, /* Pointer to the data to be written */
. Z8 ]% a$ m3 T/ f3 I6 t5 @ - UINT btw, /* Number of bytes to write */% n( j; y+ a$ }. p* a! G
- UINT* bw /* Pointer to number of bytes written */8 }& ]4 X$ B# E# V4 e$ A$ f
- )
复制代码 fp 指向将被写入的已打开的文件对象结构的指针
3 ], ]8 S# L* j, K2 E2 H3 x! ^% z" L% t7 r- j
buff 指向存储写入数据的缓冲区的指针2 u. W; p' Z( ]
btr 要写入的字节数" N% s6 u% o3 b; f5 m* z
br 指向返回已写入字节数的UINT变量的指针,返回为实际写入的字节数。 D; C! \3 q: v' w' Q; L2 s
2 J3 p8 ~, A6 u! l4 f' b/ b
. P+ h( i) u) _, s8 D) V5 }0 {& Y另外FatFs还有很多API操作函数,在这里不再作详细的介绍,详细信息请查看FatFs文件系统官网。& S; a! D+ N; F' Z( d: m$ |5 O5 `
4 x6 s9 U- y. E5 ]% k( n9 H) e1 n- u4 b
6 J( [# n" Y* @: o6 g4 l: W$ s T/ |! `0 o6 z: {+ k/ `3 k
3 D) k8 D& h% ^) s' r9 B7 H" f4 H: n0 w6 j
d0 u1 ]! ^6 M& i$ [/ Q* x7 w1 g& S9 W8 O! M
|