STM32的FATFS文件系统移植的debug过程

对于FATFS文件系统的移植,正点原子已经有比较完整的移植视频和相应源码。因此关于FATFS内部诸如diskio.c、ff.c和ffconf.h等文件的功能和修改这里就不再详述。博主在这里主要共享一下自己debug的一些过程(主要是针对FR_NO_FILESYSTEM),希望能让网友们在移植过程中少走一些弯路。

首先,对于移植FATFS,必经的几个步骤我还是再这里概述一下。
1. 移植好官方提供的.c和.h文件。(详情参照正点原子)
2. 编写diskio.c的硬件连接部分代码。
3. 配置好ffconf.h内部的控制用宏变量。
4. 编写好内存管理部分。这一块最开始我也没多大注意,但是十分必要。最简单的表述就是,你要把一个数据块写到SD卡中,你先得在内存中开辟一块空间来存放这些数据才行。

其次,博主描述一下自己遇到的第一个BUG。在f_mount挂载SD卡的时候,通过串口观察该函数的FREASULT型返回值,观察到的始终都是error 13: FR_NO_FILESYSTEM。为了弄清楚这个BUG的来源,我们最好弄清楚SD卡的文件结构以及FATFS文件系统本身的工作原理。

SD卡的文件结构:
在f_mount之前,博主先在PC机上格式化SD卡为FAT32格式。对于SD卡等存储介质,我们需要了解,它一般都有两个地址,一个是物理地址一个是逻辑地址,逻辑地址往往是物理地址基础上加一个偏移量,即逻辑地址零 = 物理地址零 + 偏移。
考虑已格式化为FAT32格式后,在物理地址零处的最初是的512个字节是MBR(Master Boot Record),即主引导记录。其中的前446个字节为引导代码,我们这里不做详解。接下来的64个字节为分区表,其中16个字节为一组总共四组,每一个组都描述了一个分区,最后两个字节为固定的末尾签名,0x55、0xAA。

物理扇区0处

物理扇区0处

我们可以看到在0x01BE处开始到0x01CD处的16个字节指示了一个分区。对于这16个字节,我们所需要知道的主要是以该16个字节距起始处偏移0x08个字节处为起始的四个字节表示的是跳转量。即从这个物理地址的0扇区到达逻辑地址的0扇区的偏移量(单位为扇区)。这里我们可以看到这个偏移量为0x0000_00E3。
于是我们到这个偏移量的扇区去看,就可以看到我们逻辑扇区0处的数据。也就是DBR(Dos Boot Record)Dos引导记录。这一块的引导记录与我们FATFS文件系统能否正常工作密切相关。

逻辑扇区0处

逻辑扇区0处

第一张图是从物理扇区打开看到的效果,第二张图是从逻辑扇区打开看到的效果。具体这一块数据的详细解释将在下面与FATFS内部的文件系统结构体FATFS struct结合在一起解释。

除此之外我们还需要知道的两大块是。对于FAT32,它从DBR开始,间隔若干扇区后会有一个根目录(Directory),在该根目录后间隔若干扇区后会有一个存储数据起始处。知道这点后,我们就可以开启下面的讨论了。

FATFS工作原理
首先我们需要熟悉结构体FATFS,FIL和DIR的具体含义。在我的理解里,FATFS结构体记录的主要是和FATFS文件系统本身相关的一些参数;FIL主要记录的是和特定文件有关的参数;DIR记录的是和目录有关的参数。
下面我们重点讨论一下FATFS的内部变量的含义。

typedef struct {
    BYTE    fs_type;        /* FAT sub-type (0:Not mounted) */
    BYTE    drv;            /* Physical drive number */
    BYTE    csize;          /* Sectors per cluster (1,2,4...128)簇的大小,一般一个簇 = 八个扇区;给文件分配簇的时候一次分配三个簇 */
    BYTE    n_fats;         /* Number of FAT copies (1 or 2) */
    BYTE    wflag;          /* win[] flag (b0:dirty) */
    BYTE    fsi_flag;       /* FSINFO flags (b7:disabled, b0:dirty) */
    WORD    id;             /* File system mount ID */
    WORD    n_rootdir;      /* Number of root directory entries (FAT12/16) */
#if _MAX_SS != _MIN_SS
    WORD    ssize;          /* Bytes per sector (512, 1024, 2048 or 4096) */
#endif
#if _FS_REENTRANT
    _SYNC_t sobj;           /* Identifier of sync object */
#endif
#if !_FS_READONLY
    DWORD   last_clust;     /* Last allocated cluster 最后写入的一个文件的最后一个簇的簇地址,这里标志的是下一个文件写进来的时候应该写在哪个位置上*/
    DWORD   free_clust;     /* Number of free clusters 这里标志的是该文件系统管理下还剩下多少个可用簇*/
#endif
#if _FS_RPATH
    DWORD   cdir;           /* Current directory start cluster (0:root) */
#endif
    DWORD   n_fatent;       /* Number of FAT entries, = number of clusters + 2 */
    DWORD   fsize;          /* Sectors per FAT 一个FAT分区共有多少个扇区*/
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
声明:该设计资料来自啊德Blog文章,希望给需要的朋友带来帮助。 一、序言 经常在网上、群里看到很多人问关于STM32FATFS文件系统移植的问题,刚好自己最近也在调试这个程序,为了让大家少走弯路,我把我的调试过程和方法也贡献给大家。 二、FATFS简介 FatFs Module是一种完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。 三、移植准备 1、FATFS源代码的获取,可以到官网下载:https://elm-chan.org/fsw/ff/00index_e.html最新版本是R0.09版本,我们就移植这个版本的。 2、解压文件会得到两个文件夹,一个是doc文件夹,这里是FATFS的一些使用文档和说明,以后在文件编程的时候可以查看该文档。另一个是src文件夹,里面就是我们所要的源文件。 3、建立一个STM32的工程,为方便调试,我们应重载printf()底层函数实现串口打印输出。可以参考已经建立好的printf()打印输出工程:https://www.viewtool.com/bbs/foru ... d=77&extra=page=1(或者“相关附件”下载) 四、开始移植 在已经建立好的工程目录User文件夹下新建两个文件夹,FATFS_V0.09和SPI_SD_Card,FATFS_V0.09用于存放FATFS源文件,SPI_SD_Card用于存放SPI的驱动文件。 将ff.c添加到工程文件夹中,并新建diskio.c文件,在diskio.c文件中实现五个函数: DSTATUS disk_initialize (BYTE);//SD卡的初始化 DSTATUS disk_status (BYTE);//获取SD卡的状态,这里可以不用管 DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);//从SD卡读取数据 DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);//将数据写入SD卡,若该文件系统为只读文件系统则不用实现该函数 DRESULT disk_ioctl (BYTE, BYTE, void*);//获取SD卡文件系统相关信息 如截图: FATFS初始化函数: FATFS状态获取函数: FATFS底层读数据函数: 注意:更多相关代码下载,见“相关附件”下载

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值