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還沒有文件系統,即將進行格式化...\r\n");
  /* 格式化 */
  res_flash=f_mkfs("0:",0,0);

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

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM