STM32文件系统的移植

  首先介绍一下window中常见的文件系统格式,包括FAT32、NTFS、exFAT。

  我们嵌入式文件系统一般使用的是FAT格式。一般新的储存芯片(EEPROM、SD卡等)内部是没有文件系统的,他只是一个单纯的能储存数据的扇区而已,而我们需要格式化他们,才能让我们的文件系统认识这块芯片里的内容,并且管理他们。格式化其实就是在芯片中储存一个结构信息,可以理解成一个全局变量,然后文件系统就是靠这个结构去索引,修改我们文件系统中的文件。

  移植主要分3步:修改diskio.c文件(与硬件相关的底层接口);ffconf.c文件(修改相关的宏);格式化文件系统(如果已有文件系统可以不用格式化)

  首先下载FATFS文件系统的源码,可以到我的wp上下载:

  将源码的src目录拷贝到我们的工程中

  1.在工程中添加一个FATFS分组,并将ff.c,diskio.c添加到该分组中

  

  

  添加头文件路径 options terget.. -> C/C++ -> include Paths

  

  

  2.修改diskio.c文件,该文件是关于硬件的底层驱动,包含储存芯片的初始化、读写、状态等接口

  删除官方历程中包含的储存驱动头文件,添加自己的底层驱动

#include "diskio.h"        /* FatFs lower layer API */
//#include "usbdisk.h"    /* Example: Header file of existing USB MSD control module */
//#include "atadrive.h"    /* Example: Header file of existing ATA harddisk control module */
//#include "sdcard.h"        /* Example: Header file of existing MMC/SDC contorl module */

 #include "sdio_sdcard.h"  //SD卡驱动
 #include "SDram_file.h"

  修改状态文件系统获取硬件底层状态接口,我采取了一种简单粗暴的方式,直接返回OK,什么都不做

DSTATUS disk_status (
    BYTE pdrv        /* Physical drive nmuber to identify the drive */
)
{
    DSTATUS stat = RES_OK;

    switch (pdrv) {
    case ATA :
        return stat;

    case MMC :
        return stat;

    case USB :
        return stat;
    }
    return STA_NOINIT;
}

  初始化驱动

DSTATUS disk_initialize (
    BYTE pdrv                /* Physical drive nmuber to identify the drive */
)
{
    DSTATUS stat = RES_OK;

    switch (pdrv) {
    case ATA :
        SD_Init();    //SD卡初始化
        return stat;

    case MMC :
        return stat;

    case USB :
        return stat;
    }
    return STA_NOINIT;
}

  读写驱动,注意这里的读写都是对内存芯片的一个块进行操作的,所以底层读写接口也应该是整个内存块一起操作的,一般SD卡的块大小是512字节,一些储存芯片可能是4096个字节。

DRESULT disk_read (
    BYTE pdrv,        /* Physical drive nmuber to identify the drive */
    BYTE *buff,        /* Data buffer to store read data */
    DWORD sector,    /* Sector address in LBA */
    UINT count        /* Number of sectors to read */
)
{
    DRESULT res = RES_OK;

    switch (pdrv) {
    case ATA :
        SD_ReadDisk( buff, sector, count );
        return res;

    case MMC :
        return res;

    case USB :
        return res;
    }

    return RES_PARERR;
}


DRESULT disk_write (
    BYTE pdrv,            /* Physical drive nmuber to identify the drive */
    const BYTE *buff,    /* Data to be written */
    DWORD sector,        /* Sector address in LBA */
    UINT count            /* Number of sectors to write */
)
{
    DRESULT res = RES_OK;

    switch (pdrv) {
    case ATA :
        SD_WriteDisk(( u8* )buff, sector, count );
        return res;

    case MMC :
        return res;

    case USB :
        return res;
    }

    return RES_PARERR;
}

  最后还有一些其他的控制接口,比如获取SD卡块大小、容量等操作

DRESULT disk_ioctl (
    BYTE pdrv,        /* Physical drive nmuber (0..) */
    BYTE cmd,        /* Control code */
    void *buff        /* Buffer to send/receive control data */
)
{
    DRESULT res = RES_OK;
    int result;

    switch (pdrv) {
    case ATA :
        switch ( cmd )
        {
            case GET_SECTOR_SIZE:
                *( DWORD* )buff = 512;
                res = RES_OK;
                break;
            case GET_BLOCK_SIZE:
                *( WORD* )buff = SDCardInfo.CardBlockSize;
                res = RES_OK;
                break;
            case GET_SECTOR_COUNT:
                *( DWORD* )buff = SDCardInfo.CardCapacity / 512;
                res = RES_OK;
                break;
            default:
                res = RES_PARERR;
                break;
        }
        return res;

    case MMC :
        return res;

    case USB :
        return res;
    }

    return RES_PARERR;
}

//这个是获取时间戳,让文件系统可以记录文件操作的时间,这里我没有实现这个功能,所以直接返回0,必须定义这个,如果没有会报错
DWORD get_fattime( void )
{
    return 0;
}

  

  3.修改ffconf.h文件,改文件实现文件系统的配置和裁剪,这里有几个参数需要配置

#define _USE_MKFS 1      //是否支持格式化,我们默认0,我们要使能他
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */

#define _CODE_PAGE 936    //文件系统编码格式,我们选择中文编码

//是否使能长文件名,如果需要长文件名,这里改成2,并且需要在工程中添加cc936.c文件

#define _USE_LFN 0      
#define _MAX_LFN 255     //文件名长度

#define _VOLUMES 1      //设备数量

//内存块范围,一般SD卡为512字节,有的储存芯片一个块可能为4096个字节
#define _MIN_SS 512
#define _MAX_SS 4096

  

  4.最后在主程序中挂载这个卷,就可以使用我们熟悉的f_open、f_close....等功能了

FRESULT res_flash; 

/* 如果没有文件系统就格式化创建创建文件系统 */
if(f_mount(&fs,"0:",1) == FR_NO_FILESYSTEM)
{
  printf("》FLASH还没有文件系统,即将进行格式化... ");
  /* 格式化 */
  res_flash=f_mkfs("0:",0,0);

  if(res_flash == FR_OK)
  {
    printf("》FLASH已成功格式化文件系统。 ");
    /* 格式化后,先取消挂载 */
    res_flash = f_mount(NULL,"0:",1);
    /* 重新挂载 */
    res_flash = f_mount(&fs,"0:",1);
   }

}

原文地址:https://www.cnblogs.com/isyefeng/p/13425855.html