【FatFs】基于STM32 SD卡移植FatFs文件系统

本文详细介绍了如何将FatFs文件系统移植到STM32的SD卡驱动上,包括下载FatFs源码、理解其组织架构、配置文件系统参数、修改diskio.c文件以适配SD卡驱动,以及实现实时时钟RTC。通过这些步骤,可以在STM32工程中实现对SD卡的读写和文件操作。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

相关文章

《【SDIO】SDIO、SD卡、FatFs文件系统相关文章索引》

1.前言

FatFs是一个通用的FAT/exFAT文件系统模块,用于小型嵌入式系统。它完全是由 ANSI C 语言编写并且完全独立于底层的 I/O 介质。因此它是独立于平台的,可以集成到资源有限的小型微控制器中,如8051、PIC、AVR、ARM、Z80、RX等。FatFs 支持 FAT12、FAT16、FAT32、exFAT 等格式,所以我们利用前面写好的 SD卡驱动,把 FatFs 文件系统代码移植到工程。

2.如何下载FatFs文件系统

FatFs 文件系统的源码可以从 fatfs 官网下载:
http://elm-chan.org/fsw/ff/00index_e.html
在这里插入图片描述
下面红色框标记出来的就是FatFs文件系统源码FatFs样例工程,如下:
在这里插入图片描述
下载如下:
在这里插入图片描述

3.FatFs文件系统的组织架构

在移植之前,我们需要对FatFs文件系统有一个大致认识。这样我们才知道哪些是可以直接移植,哪些是需要我们自己来实现的。下面显示的依赖关系图是带有FatFs模块的嵌入式系统的典型配置。绿色部分(Low Level Disk I/O Layer)FatFs文件系统不关心具体的实现,所以需要我们自己来实现它。
在这里插入图片描述
下面展示了单驱动系统多驱动系统,我们在实现了SD卡驱动之后,还需要实现一个实时时钟(RTC),它会在创建或者修改文件时会用到。如果需要同时支持U盘、SD卡、Nand Flash等,需要分别实现对应的驱动,然后挂载在不同的节点,这样FatFs就可以同时管理多个设备。
在这里插入图片描述
下表显示了根据配置选项需要哪些功能,如下:

Function Required when Note
disk_status
disk_initialize
disk_read
Always Disk I/O functions.
Samples available in ffsample.zip.
There are many implementations on the web.
disk_write
get_fattime
disk_ioctl (CTRL_SYNC)
FF_FS_READONLY == 0
disk_ioctl (GET_SECTOR_COUNT)
disk_ioctl (GET_BLOCK_SIZE)
FF_USE_MKFS == 1
disk_ioctl (GET_SECTOR_SIZE) FF_MAX_SS != FF_MIN_SS
disk_ioctl (CTRL_TRIM) FF_USE_TRIM == 1
ff_uni2oem
ff_oem2uni
ff_wtoupper
FF_USE_LFN != 0 Unicode support functions.
Add optional module ffunicode.c to the project.
ff_cre_syncobj
ff_del_syncobj
ff_req_grant
ff_rel_grant
FF_FS_REENTRANT == 1 O/S dependent functions.
Sample code is available in ffsystem.c.
ff_mem_alloc
ff_mem_free
FF_USE_LFN == 3

4.FatFs文件系统移植步骤

前面我们有实现基于STM32 SDIO SD卡读写测试程序,为移植 FatFs 方便,我们在该工程基础上添加 FatFs 组件,并修改 main 函数的用户程序即可。

  1. 将 FatFs 组件文件添加到工程中,视图如下:
    在这里插入图片描述
    2.将 FatFs 组件相关的头文件添加到工程,如下:
    在这里插入图片描述
    3.修改diskio.c文件,主要是将SD卡的初始化读写操作实时时钟RTC,添加到对应的位置。(备注:实时时钟RTC驱动未真正的实现,只是使用了固定假的时钟。
#include "main.h"
#include "ff.h"			/* Obtains integer types */
#include "diskio.h"		/* Declarations of disk functions */
#include "bsp_sdio_sd.h"

/* Definitions of physical drive number for each drive */
#define DEV_RAM		0	/* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC		1	/* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB		2	/* Example: Map USB MSD to physical drive 2 */

#define SD_BLOCKSIZE     512 

static volatile DSTATUS currStat = STA_NOINIT;	/* Physical drive status */
extern SD_CardInfo SDCardInfo;
/*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{
   
   
	DSTATUS stat = STA_NOINIT;
	//int result;

	switch (pdrv) {
   
   
	case DEV_RAM :
		break;
	case DEV_MMC :
		stat = currStat;
		break;
	case DEV_USB :
		break;
	}
	return stat;
}

/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
   
   
	DSTATUS stat = STA_NOINIT;

	switch (pdrv) {
   
   
	case DEV_RAM :
		break;
	case DEV_MMC :
		if(SD_Init()==SD_OK)
		{
   
   
			stat &= ~STA_NOINIT;
		}
		else 
		{
   
   
			stat = STA_NOINIT;
		}
		currStat = stat;
		break;
	case DEV_USB :
		break;
	}
	return stat;
}

/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	LBA_t sector,	/* Start sector in LBA */
	UINT count		/* Number of sectors to read */
)
{
   
   
	DRESULT res = RES_PARERR;
	SD_Error SD_state = SD_OK;

	if (!count) return RES_PARERR;					/* Check parameter */
	if (currStat & STA_NOINIT) return RES_NOTRDY;	/* Check if drive is ready */

	switch (pdrv) {
   
   
	case DEV_RAM :
		break;
		
	case DEV_MMC :
		if(count ==  1){
   
   
			SD_state = SD_ReadBlock(buff, sector*SD_BLOCKSIZE, SD_BLOCKSIZE);
		}else{
   
   
			SD_state

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值