零死角玩转stm32-高级篇之FatFs

零死角玩转stm32-高级篇之FatFs (Rev-R0.09)
2013年08月05日  ⁄ 教程  ⁄ 评论数 1 ⁄ 被围观 1,579+

 2、FatFs (Rev-R0.09)

   2.1 实验描述及工程文件清单

实验描述:MicroSD卡文件系统 FATFS R0.07C 测试实验。在MicroSD卡里面创建一个DEMO.TXT文本文件,在文件里面写入字符串“感谢您选用野火STM32开发板 !然后通过串口将这些内容打印在电脑的超级终端上。这个更新版本的代码增加了简体中文和长文件名的支持,采用SDIO的4bit+DMA模式。并图解了文件系统移植的全部过程。

硬件连接:PC12-SDIO-CLK:CLK PC10-SDIO-D2 :DATA2 PC11-SDIO-D3:CD/DATA3PD2-SDIO-CMD :CMDPC8-SDIO-D0:DATA0 PC9-SDIO-D1:DATA1

用到的库文件:startup/start_stm32f10x_hd.cCMSIS/core_cm3.cCMSIS/system_stm32f10x.cFWlib/stm32f10x_gpio.cFWlib/stm32f10x_rcc.cFWlib/stm32f10x_usart.cFWlib/ stm32f10x_sdio.cFWlib/ stm32f10x_dma.cFWlib/ misc.c

用户编写的文件:USER/main.cUSER/stm32f10x_it.cUSER/usart1.cUSER/ sdio_sdcard.c

文件系统文件: ff9/diskio.cff9/ff.cff9/cc936.c

 

 

野火STM32开发板 MicroSD卡硬件原理图:

 

打开 doc 文件夹,可看到如下文件目录:

option 文件夹下是一些可选的外部c文件,包含了多语言支持需要用到的文件和转换函数。

00readme.txt 说明了当前目录下 diskio.c 、diskio.h、ff.c、ff.h、integer.h的功用、涉及了FATFS的版权问题( 是自由软件 ),还讲到了FATFS的版本更新信息。

integer.h:是一些数值类型定义

diskio.c : 底层磁盘的操作函数,这些函数需要用户自己实现

ff.c : 独立于底层介质操作文件的函数,完全由ANSI C编写

cc936.c :简体中文支持所需要添加的文件,包含了简体中文的GBK和转换函数。

只要添加进来就行,这个文件不需要修改。

ffconf.h:这个头文件包含了对文件系统的各种配置,如需要支持简体中文要把_CODE_PAGE 的宏改成936并把上面的cc936.c文件加入到工程之中

建议阅读这些源码的顺序为:integer.h -> diskio.c -> ff.c 。

关于具体源码的分析不是我能力所及呀,大家就自己研究吧。我的主要工作是带领大家把这个文件系统移植到我们的开发板上,让这个文件系统先跑起来,这样才是硬道理呀。文件系统工作起来了的话,源码的分析那自然是大家的活啦。

2.5 开始移植

首先我们要获取一个完全没有修改过的文件系统源码,然后在 10-MicroSD卡这个文件夹下的实验代码下移植,这个实验代码实现的是卡的底层的块操作。注意,我们在移植这个文件系统的过程中会尽量保持文件系统源码的纯净,尽量做到在修改最少量的源码的情况下移植成功。

首先将 integer.h、diskio.h、diskio.c、ff.h、ff.c添加到工程目录下的USER文件夹下,如下截图:

因为我们要用到这两个c文件,所以我们在main.c中将这两个c文件对应的头文件diskio.h 、ff.h 包含进来,如下截图:

意思是说 FALSE 跟 TRUE这两个变量已经定义过了,为什么会出现这个错误呢?因为在 integer.h和我们的M3库头文件stm32f10x.h中都定义了这两个变量,所以就产生了重复定义:

integer.h

怎么解决呢,很简单,只要搞掉一个即可,但要去掉哪个呢?我们考虑到外面的M3库很多文件都包含了stm32f10x.h这个头文件,假如是修改stm32f10x.h的话工作量会非常大,鉴于此就只能委屈integer.h了,修改如下,将它注释掉:

意思是说在diskio.h、ff.c中 BOOL 、FALSE、TRUE没定义。刚刚才把人家注释掉了,不报错才怪。

解决方法如下:

1、将integer.h中有关BOOL的那句注释掉,注释掉也没太大关系,因为注释掉的不会怎么用到:

同时在 ff.c的第585行做如下修改:

到这里我们算是把文件系统移植成功了,接下来的任务就是调用文件系统的函数来操作我们的卡了。其实这里的移植是非常非常简单的,要是你学过LINUX的话,那里面的UBOOT移植,系统移植,那才叫人头疼,就光是目录里面的文件夹都几千个,更别说是找到要修改的源代码了,刚接触的话绝对叫你吐血,就连下载个交叉编译器都涉及到移植。

2.6实验代码分析

FATFS是独立于底层介质的应用函数库,对底层介质的操作都要交给用户去实现,其仅仅是提供了一个函数接口而已,函数为空,要用户添加代码。

这几个函数的原型如下,在diskio.c中定义:

/* Inidialize a Drive */

DSTATUS disk_initialize (

BYTE drv       /* Physical drive nmuber (0..) */

)

/* Return Disk Status  */

DSTATUS disk_status (

BYTE drv    /* Physical drive nmuber (0..) */

)

/* Read Sector(s) */

DRESULT disk_read (

BYTE drv,   /* Physical drive nmuber (0..) */

BYTE *buff, /* Data buffer to store read data */

DWORD sector,   /* Sector address (LBA) */

BYTE count  /* Number of sectors to read (1..255) */

)

/* Write Sector(s) */

#if _READONLY == 0

DRESULT disk_write (

BYTE drv,            /* Physical drive nmuber (0..) */

const BYTE *buff,   /* Data to be written */

DWORD sector,       /* Sector address (LBA) */

BYTE count      /* Number of sectors to write (1..255) */

)

/* Miscellaneous Functions                                               */

DRESULT disk_ioctl (

BYTE drv,   /* Physical drive nmuber (0..) */

BYTE ctrl,  /* Control code */

void *buff  /* Buffer to send/receive control data */

)

这些函数都是操作底层介质的函数,都需要用户自己实现,然后FATFS的应用函数就可以调用这些函数来操作我们的卡了。关于这些底层介质函数是如何实现的,请参考源码,这里就不贴出来了。

在diskio.c的最后我们还得提供了获取时间的函数,因为ff.c中调用了这个函数,而FATFS库又没有给出这个函数的原型,所以需要用户实现,不然会编译出错,函数体为空即可(也可以为它加载STM32的RTC驱动):

实现好底层介质的操作函数之后,我们就可以回到应用层了,下面我们从main函数开始看起。有关系统初始化和串口初始化这部分请参考前面的教程,这里不再详述。

首先我们调用函数disk_initialize( 0 ); 将我们的底层硬件初始化好,这一步非常重要,如果不成功的话,接下来什么都干不了。

f_open( &fsrc , "0:/Demo.TXT" , FA_CREATE_NEW | FA_WRITE); 将在刚刚开辟的工作区的盘符0下打开一个名为Demo.TXT的文件,以只写的方式打开,如果文件不存在的话则创建这个文件。并将Demo.TXT这个文件关联到 fsrc 这个结构指针,以后我们操作文件就是通过这个结构指针来完成的。

f_write(&fsrc, textFileBuffer, sizeof(textFileBuffer), &br); 将缓冲区的数据写到刚刚打开的Demo.TXT文件中。写完之后调用f_close(&fsrc);。关闭文件,

f_open(&fsrc, "0:/Demo.TXT", FA_OPEN_EXISTING | FA_READ);以只读的方式打开刚刚的文件。

f_read( &fsrc, buffer, sizeof(buffer), &br ); 将文件的内容读到缓冲区,然后调用printf("\r\n %s ", buffer);将数据打印到电脑的超级终端。

最后调用f_close(&fsrc);关闭文件。当被打开的文件操作完成之后都要调用f_close();将它关闭,就像一块动态分配的内存在用完之后都要调用free()来将它释放。

这里涉及到了FATFS文件系统库函数的操作,如果你学过LINUX系统调用的话,操作这些函数将是非常简单,没有学过的话也没太大的关系,因为FATFS源码目录doc这个文件夹中提供了每个应用函数的用法,如 f_mount():

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值