相关文章
《【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 函数的用户程序即可。
- 将 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

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

2354

被折叠的 条评论
为什么被折叠?



