经过充分的研究,发现fatfs文件系统移植的比较简单!因为代码都已经被别人做好了!我们只需把io层稍稍做个处理就ok了;
至于sd卡的驱动请看我这篇博客:http://blog.csdn.net/ieczw/article/details/17378475
移植是以这个驱动为前提的!!
http://elm-chan.org/fsw/ff/00index_e.html
这个网站发布了所有版本的文件fatfs文件系统,我这次下载最新版的http://elm-chan.org/fsw/ff/ff9a.zip
直接解压,里面有两个文件,一个是src,另一个是doc;
把src放到自己的工程目录下面,并添加。首先看看00Readme.txt,我们主要是关注这些东西
FILES ffconf.h Configuration file for FatFs module. ff.h Common include file for FatFs and application module. ff.c FatFs module. diskio.h Common include file for FatFs and disk I/O module. diskio.c An example of glue function to attach existing disk I/O module to FatFs. integer.h Integer type definitions for FatFs. option Optional external functions. Low level disk I/O module is not included in this archive because the FatFs module is only a generic file system layer and not depend on any specific storage device. You have to provide a low level disk I/O module that written to control your storage device.
所以我们主要修改的是diskio.c
DSTATUS disk_initialize (BYTE pdrv); DSTATUS disk_status (BYTE pdrv); DRESULT disk_read (BYTE pdrv, BYTE*buff, DWORD sector, BYTE count); DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, BYTE count); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
我们需要改的是这几个底层io函数,按照下面的修改,我想大家应该能懂!
/*-----------------------------------------------------------------------*/ /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2012 */ /*-----------------------------------------------------------------------*/ /* If a working storage control module is available, it should be */ /* attached to the FatFs via a glue function rather than modifying it. */ /* This is an example of glue functions to attach various exsisting */ /* storage control module to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ #include "diskio.h" /* FatFs lower layer API */ #include "stm32_eval_sdio_sd.h" /* Definitions of physical drive number for each media */ #define ATA 0 #define MMC 1 #define USB 2 #define SECTOR_SIZE 512U /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ DSTATUS disk_initialize ( BYTE drv /* Physical drive nmuber (0..) */ ) { return SD_Init(); } /*-----------------------------------------------------------------------*/ /* Return Disk Status */ DSTATUS disk_status ( BYTE drv /* Physical drive nmuber (0..) */ ) { return SD_GetStatus(); } /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ 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) */ ) { return (DRESULT)SD_ReadBlock(buff,sector << 9 ,count); } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ #if _READONLY == 0 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) */ ) { return (DRESULT)SD_WriteBlock((uint8_t *)buff,sector << 9 ,count); } #endif /* _READONLY */ /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ DRESULT disk_ioctl ( BYTE drv, /* Physical drive nmuber (0..) */ BYTE ctrl, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { return RES_OK; } unsigned short get_fattime(void){ return 0; }
这些修改完后,如果你直接编译会出现如下错误:
..\fatfs\cc936.c(11): error: #35: #error directive: This file is not needed in current configuration. Remove from the project.
找到cc936.c,他的头文件是这样定义的
/*------------------------------------------------------------------------*/ /* Unicode - OEM code bidirectional converter (C)ChaN, 2009 */ /* */ /* CP936 (Simplified Chinese GBK) */ /*------------------------------------------------------------------------*/ #include "../ff.h" #if !_USE_LFN || _CODE_PAGE != 936 #error This file is not needed in current configuration. Remove from the project. #endif
他是找不到USE_LFN或者_CODE_PAGE !=936
那么可能头文件处理问题,大家应该发现问题了,把头文件修改下:#include "ff.h"
为什么要用936的呢?大家看ffconf.h,有这么一段注释
/*---------------------------------------------------------------------------/ / Locale and Namespace Configurations /----------------------------------------------------------------------------*/ #define _CODE_PAGE 936 /* The _CODE_PAGE specifies the OEM code page to be used on the target system. / Incorrect setting of the code page can cause a file open failure. / / 932 - Japanese Shift-JIS (DBCS, OEM, Windows) / 936 - Simplified Chinese GBK (DBCS, OEM, Windows) / 949 - Korean (DBCS, OEM, Windows) / 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) / 1250 - Central Europe (Windows) / 1251 - Cyrillic (Windows) / 1252 - Latin 1 (Windows) / 1253 - Greek (Windows) / 1254 - Turkish (Windows) / 1255 - Hebrew (Windows) / 1256 - Arabic (Windows) / 1257 - Baltic (Windows) / 1258 - Vietnam (OEM, Windows) / 437 - U.S. (OEM) / 720 - Arabic (OEM) / 737 - Greek (OEM) / 775 - Baltic (OEM) / 850 - Multilingual Latin 1 (OEM) / 858 - Multilingual Latin 1 + Euro (OEM) / 852 - Latin 2 (OEM) / 855 - Cyrillic (OEM) / 866 - Russian (OEM) / 857 - Turkish (OEM) / 862 - Hebrew (OEM) / 874 - Thai (OEM, Windows) / 1 - ASCII only (Valid for non LFN cfg.) */
所以,因为我们是中国人,所以我们要用936!哈哈。。。
然后编译又出现另一个问题:
..\output\stm32.axf: Error: L6218E: Undefined symbol get_fattime (referred from ff.o).
这个我们需要自己添加,我在上面修改diskio.c的时候已经添加了。
这些做完之后,也算移植玩了,简单吧,至于如何使用,我们还是看下载网页:http://elm-chan.org/fsw/ff/00index_e.html
或者双击doc/目录下的00index_e.html
Application Interface FatFs module provides following functions to the applications. In other words, this list describes what FatFs can do to access the FAT volumes. f_open - Open/Create a file f_close - Close an open file f_read - Read file f_write - Write file f_lseek - Move read/write pointer, Expand file size f_truncate - Truncate file size f_sync - Flush cached data f_forward - Forward file data to the stream f_stat - Check existance of a file or sub-directory f_opendir - Open a directory f_closedir - Close an open directory f_readdir - Read a directory item f_mkdir - Create a sub-directory f_unlink - Remove a file or sub-directory f_chmod - Change attribute f_utime - Change timestamp f_rename - Rename/Move a file or sub-directory f_chdir - Change current directory f_chdrive - Change current drive f_getcwd - Retrieve the current directory f_getfree - Get free clusters f_getlabel - Get volume label f_setlabel - Set volume label f_mount - Register/Unregister a work area f_mkfs - Create a file system on the drive f_fdisk - Divide a physical drive f_gets - Read a string f_putc - Write a character f_puts - Write a string f_printf - Write a formatted string f_tell - Get current read/write pointer f_eof - Test for end-of-file on a file f_size - Get size of a file f_error - Test for an error on a file
里面对每个函数都做了说明,这样就有点像linux操作系统里面的文件io操作了。
我们可以任意点击去一个函数,里面都有例程,我们可以用这些例程来测试下
/* Read a text file and display it */ FATFS FatFs; /* Work area (file system object) for logical drive */ int main (void) { FIL fil; /* File object */ char line[82]; /* Line buffer */ FRESULT fr; /* FatFs return code */ /* Register work area to the default drive */ f_mount(&FatFs, "", 0); /* Open a text file */ fr = f_open(&fil, "message.txt", FA_READ); if (fr) return (int)fr; /* Read all lines and display it */ while (f_gets(line, sizeof line, &fil)) printf(line); /* Close the file */ f_close(&fil); return 0; }
好,基于STM32的fatfs文件系统移植就到这里了!!!!
147520657