首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

STM32的FATFS文件系统移植笔记(1)

STM32的FATFS文件系统移植笔记(1)

一、序言
    经常在网上、群里看到很多人问关于STM32的FATFS文件系统移植的问题,刚好自己最近也在调试这个程序,为了让大家少走弯路,我把我的调试过程和方法也贡献给大家。

二、FATFS简介
    FatFs Module是一种完全免费开源的FAT文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准C语言编写,所以具有良好的硬件平台独立性,可以移植到8051、PIC、AVR、SH、Z80、H8、ARM等系列单片机上而只需做简单的修改。它支持FATl2、FATl6和FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对8位单片机和16位单片机做了优化。

三、移植准备
    1、FATFS源代码的获取,可以到官网下载:http://elm-chan.org/fsw/ff/00index_e.html 最新版本是R0.09版本,我们就移植这个版本的。
    2、解压文件会得到两个文件夹,一个是doc文件夹,这里是FATFS的一些使用文档和说明,以后在文件编程的时候可以查看该文档。另一个是src文件夹,里面就是我们所要的源文件。
    3、建立一个STM32的工程,为方便调试,我们应重载printf()底层函数实现串口打印输出。可以参考已经建立好的printf()打印输出工程:http://www.viewtool.com/bbs/foru ... d=77&extra=page%3D1
四、开始移植
    1、在已经建立好的工程目录User文件夹下新建两个文件夹,FATFS_V0.09和SPI_SD_Card,FATFS_V0.09用于存放FATFS源文件,SPI_SD_Card用于存放SPI的驱动文件。
    2、如图1将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卡文件系统相关信息
复制代码
<IGNORE_JS_OP>



图1
    3、初步实现以上五个函数
        FATFS初始化函数:

DSTATUS disk_initialize (
                BYTE drv                                /* Physical drive nmuber (0..) */
        )
        {
                switch (drv)
                {
                        case 0 :
                                return RES_OK;
                        case 1 :
                                return RES_OK;         
                        case 2 :
                                return RES_OK;         
                        case 3 :
                                return RES_OK;
                        default:
                                return STA_NOINIT;
                }
        }
复制代码
FATFS状态获取函数:

DSTATUS disk_status (
                BYTE drv                /* Physical drive nmuber (0..) */
        )
        {
                switch (drv)
                {
                        case 0 :
                                return RES_OK;
                        case 1 :
                                return RES_OK;
                        case 2 :
                                return RES_OK;
                        default:
                                return STA_NOINIT;
                }
        }
复制代码
FATFS底层读数据函数:

DRESULT disk_read (
                BYTE drv,                /* Physical drive nmuber (0..) */
                BYTE *buff,                /* Data buffer to store read data */
                DWORD sector,        /* Sector address (LBA) */
                BYTE count                /* Number of sectors to read (1..255) */
        )
        {
                if( !count )
                {   
                        return RES_PARERR;  /* count不能等于0,否则返回参数错误 */
                }
                switch (drv)
                {
                        case 0:
                            if(count==1)            /* 1个sector的读操作 */      
                            {   
                                        return RES_OK;   
                            }                                                
                            else                    /* 多个sector的读操作 */     
                            {  
                                        return RES_OK;
                            }                                                
                        case 1:
                            if(count==1)            /* 1个sector的读操作 */      
                            {   
                                        return RES_OK;   
                            }                                                
                            else                    /* 多个sector的读操作 */     
                            {  
                                        return RES_OK;
                            }
                        default:
                                return RES_ERROR;
                }
        }
复制代码
FATFS底层写数据函数:

DRESULT disk_write (
                BYTE drv,                        /* Physical drive nmuber (0..) */
                const BYTE *buff,                /* Data to be written */
                DWORD sector,                /* Sector address (LBA) */
                BYTE count                        /* Number of sectors to write (1..255) */
        )
        {
                if( !count )
                {   
                        return RES_PARERR;  /* count不能等于0,否则返回参数错误 */
                }
                switch (drv)
                {
                        case 0:
                            if(count==1)            /* 1个sector的写操作 */      
                            {   
                                        return RES_OK;
                            }                                                
                            else                    /* 多个sector的写操作 */   
                            {  
                                        return RES_OK;  
                            }                                                
                        case 1:
                            if(count==1)            /* 1个sector的写操作 */      
                            {  
                                        return RES_OK;
                            }                                                
                            else                    /* 多个sector的写操作 */   
                            {  
                                        return RES_OK;
                            }                                                

                        default:return RES_ERROR;
                }
        }
复制代码
FATFS磁盘控制函数:

DRESULT disk_ioctl (
                BYTE drv,                /* Physical drive nmuber (0..) */
                BYTE ctrl,                /* Control code */
                void *buff                /* Buffer to send/receive control data */
        )
        {
                if (drv==0)
                {   
                        switch (ctrl)
                        {
                                case CTRL_SYNC :
                                        return RES_OK;
                                case GET_SECTOR_COUNT :
                                return RES_OK;
                                case GET_BLOCK_SIZE :
                                return RES_OK;        
                                case CTRL_POWER :
                                        break;
                                case CTRL_LOCK :
                                        break;
                                case CTRL_EJECT :
                                        break;
                        /* MMC/SDC command */
                                case MMC_GET_TYPE :
                                        break;
                                case MMC_GET_CSD :
                                        break;
                                case MMC_GET_CID :
                                        break;
                                case MMC_GET_OCR :
                                        break;
                                case MMC_GET_SDSTAT :
                                        break;        
                        }
            }else if(drv==1){
                        switch (ctrl)
                        {
                                case CTRL_SYNC :
                                        return RES_OK;
                                case GET_SECTOR_COUNT :
                                return RES_OK;
                                case GET_SECTOR_SIZE :
                                        return RES_OK;
                                case GET_BLOCK_SIZE :
                                return RES_OK;        
                                case CTRL_POWER :
                                        break;
                                case CTRL_LOCK :
                                        break;
                                case CTRL_EJECT :
                                        break;
                        /* MMC/SDC command */
                                case MMC_GET_TYPE :
                                        break;
                                case MMC_GET_CSD :
                                        break;
                                case MMC_GET_CID :
                                        break;
                                case MMC_GET_OCR :
                                        break;
                                case MMC_GET_SDSTAT :
                                        break;        
                        }         
                }
                else{                                 
                        return RES_PARERR;  
                }
                return RES_PARERR;
        }
复制代码
以上函数都只是实现一个框架,并没有做实际的事情,下一步就需要把操作SD卡的程序填充在这个框架里面。
继承事业,薪火相传
返回列表