查看: 2108|回复: 0

零死角玩转stm32-高级篇之FatFs (Rev-R0.09)

[复制链接]
  • TA的每日心情
    慵懒
    2015-5-29 12:01
  • 签到天数: 11 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2013-8-5 17:46:56 | 显示全部楼层 |阅读模式
    分享到:
     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卡硬件原理图:


       2.2 实验简介
    本实验是在上一讲《SDIO(4bit + DMA)》的基础上讲解的,只有上一讲的实验成功了,文件系统才能跑起来。有关卡的底层的初始化,这里不再详述,这里着重讲解文件系统的移植和文件系统的应用。这个文档是更新版本,采用的文件系统的版本是目前最新的 R0.09。 文件系统的源码可以从fatfs官网下载https://elm-chan.org/fsw/ff/00index_e.html
    2.3 FatFS文件系统简介
    FAFFS是面向小型嵌入式系统的一种通用的FAT文件系统。FATFS完全是由AISI C语言编写并且完全独立于底层的I/O介质。因此它可以很容易地不加修改地移植到其他的处理器当中,如8051、PIC、AVR、SH、Z80、H8、ARM等。FATFS支持FAT12、FAT16、FAT32等格式,所以我们利用前面写好的SDIO驱动,把FATFS文件系统代码移植到工程之中,就可以利用文件系统的各种函数,对已格式化的SD卡进行读写文件了。
    本实验是将FATFS移植到野火STM32开发板中,CPU为STM32F103VET6,是采用ARM公司最新内核ARMV7的一款单片机。
    2.4 移植前的工作
    2.4.1 分析FATFS的目录结构
    在移植FATFS文件系统之前,我们先要到FAT的官网获取源码,版本为R0.07C。解压之后可看到里面有 doc 和 src 这两个文件夹。doc 文件夹里面是一些使用文档, src 里面是文件系统的源码。

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

    其中 en 和 ja 这两个文件夹里面是编译好的html文档,讲的是FATFS里面各个函数的使用方法,这些函数就如LINUX下的系统调用,是封装得非常好的函数,利用这些函数我们就可以操作我们的MicroSD卡了。有关具体的函数我们在用到的时候再讲解。这两个文件夹的唯一区别就是 en 文件夹下的文档是英文的,ja 文件夹下的是日文的。偏偏就是没中文的,真狗血呀。00index_e.html是一些关于FATFS的英文简介,updates.txt是FATFS的更新信息,至于其他几个文件可以不看。
    打开 src 文件夹,可看到如下目录:

    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文件夹下,如下截图:

    然后并回到MDK界面下将diskio.c 、ff.c 这两个文件添加到USER目录下,如
    下截图:

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

    好嘞,下面我们开始编译,这时会出现如下错误:

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

    stm32f10x.h

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

    意思是说在diskio.h、ff.c中 BOOL 、FALSE、TRUE没定义。刚刚才把人家注释掉了,不报错才怪。
    解决方法如下:
    1、将integer.h中有关BOOL的那句注释掉,注释掉也没太大关系,因为注释掉的不会怎么用到:

    2、在ff.c文件的开头重新定义一个布尔变量,取名为 bool,与stm32f10x.h中的名字一样:

    同时在 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(" %s ", buffer);将数据打印到电脑的超级终端。
    最后调用f_close(&fsrc);关闭文件。当被打开的文件操作完成之后都要调用f_close();将它关闭,就像一块动态分配的内存在用完之后都要调用free()来将它释放。
    这里涉及到了FATFS文件系统库函数的操作,如果你学过LINUX系统调用的话,操作这些函数将是非常简单,没有学过的话也没太大的关系,因为FATFS源码目录doc这个文件夹中提供了每个应用函数的用法,如 f_mount():

    2.7 实验现象
    将野火STM32开发板供电(DC5V),插上JLINK,插上串口线(两头都是母的交叉线),插上MicroSD卡( 野火用的是1G,4G的也已经测试通过 ),打开超级终端,配置超级终端为115200 8-N-1,将编译好的程序下载到开发板,即可看到超级终端打印出如下信息:
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-3-29 19:40 , Processed in 0.115749 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.