fatfs移植和使用(在SPI_FLASH上建立文件系统)
2017-09-19 17:55
513 查看
文件系统对于嵌入式系统的重要性是不言而喻的,有了文件系统管理数据和外设变得方便许多,同时简化了应用的开发。今天我们来以在SPI_FLASH上建立文件系统为例,看看FATFS文件系统怎么移植和使用。
需要准备的材料有:
(1)FATFS文件系统源码(点此下载最新FATFS源码)。
(2)单片机平台一个(内存大一些更好)。
(3)SPI_FLASH芯片一个(如:W25Q32)。
FATFS是一个通用的嵌入式文件系统,对不同的平台支持很好,大到硬盘、U盘、存储卡,小到spi_flash芯片甚至单片机内部FLASH都可以使用FATFS。今天我们就在一个4M大小的SPI_FLASH( W25Q32 )上建立一个文件系统,主控制器是飞思卡尔K60单片机。在做文件系统移植前,你需要把操作SPI_FLASH的驱动调通,能读写SPI_FLASH就可以了。
step 0.1:下载最新的FATFS源码,当前版本:R0.13。
step 0.2 解压缩新下载的FATFS源码,看看里面都是些什么文件。如下图所示,红色框是移植FATFS所必须的文件,蓝色框内的文件是可选的移植文件。
diskio.c个diskio.h是和存储器读写控制相关的驱动接口,比如SPI_FLASH的读写函数接口,都要映射到这里面。必须的文件
ff.h和ff.h是FATFS的核心文件,必须的文件
ffconf.h是FATFS的配置文件,用来裁剪FATFS,必须的文件
integer.h是FATFS所用到的数据类型定义,用以兼容不同字长CPU,必须的文件
ffsystem.c是一些关于在带操作系统平台中,使用的示例,可选文件
ffunicode.c是万国码编码文件,文件里主要是大数组定义,假如你需要让文件名支持中文就需要这个文件,这个文件会使代码空间急剧变大,可选文件
step 0.3 本次FATFS移植未使用操作系统,文件系统支持中文路径和名称,所以需要ff.c、ff.h、ffconf.h、diskio.c、diskio.h、ffunicode.c和integer.h这六个文件添加到工程中即可。如下图:
step 1.0 修改ffconf.h文件,来裁剪我们的FATFS,通过宏开关来去掉不用的功能,来精简文件系统。想知道每个宏的功能?(点击这里)
需要注意的是:由于我们此次移植支持了中文路径和名称,所以这个要设置这个宏 #define FF_CODE_PAGE936 /*936代表 简体中文*/
step 1.1 修改diskio.c 来映射我们的存储器读写控制接口,如下:
要修改的文件就这么多了,其他文件直接使用,不用改动。
step2.0 下面写个测试函数,来测测我们移植成功 了没有。
说的比较浅显,大家有问题或建议欢迎留言。over
需要准备的材料有:
(1)FATFS文件系统源码(点此下载最新FATFS源码)。
(2)单片机平台一个(内存大一些更好)。
(3)SPI_FLASH芯片一个(如:W25Q32)。
FATFS是一个通用的嵌入式文件系统,对不同的平台支持很好,大到硬盘、U盘、存储卡,小到spi_flash芯片甚至单片机内部FLASH都可以使用FATFS。今天我们就在一个4M大小的SPI_FLASH( W25Q32 )上建立一个文件系统,主控制器是飞思卡尔K60单片机。在做文件系统移植前,你需要把操作SPI_FLASH的驱动调通,能读写SPI_FLASH就可以了。
step 0.1:下载最新的FATFS源码,当前版本:R0.13。
step 0.2 解压缩新下载的FATFS源码,看看里面都是些什么文件。如下图所示,红色框是移植FATFS所必须的文件,蓝色框内的文件是可选的移植文件。
diskio.c个diskio.h是和存储器读写控制相关的驱动接口,比如SPI_FLASH的读写函数接口,都要映射到这里面。必须的文件
ff.h和ff.h是FATFS的核心文件,必须的文件
ffconf.h是FATFS的配置文件,用来裁剪FATFS,必须的文件
integer.h是FATFS所用到的数据类型定义,用以兼容不同字长CPU,必须的文件
ffsystem.c是一些关于在带操作系统平台中,使用的示例,可选文件
ffunicode.c是万国码编码文件,文件里主要是大数组定义,假如你需要让文件名支持中文就需要这个文件,这个文件会使代码空间急剧变大,可选文件
step 0.3 本次FATFS移植未使用操作系统,文件系统支持中文路径和名称,所以需要ff.c、ff.h、ffconf.h、diskio.c、diskio.h、ffunicode.c和integer.h这六个文件添加到工程中即可。如下图:
step 1.0 修改ffconf.h文件,来裁剪我们的FATFS,通过宏开关来去掉不用的功能,来精简文件系统。想知道每个宏的功能?(点击这里)
需要注意的是:由于我们此次移植支持了中文路径和名称,所以这个要设置这个宏 #define FF_CODE_PAGE936 /*936代表 简体中文*/
step 1.1 修改diskio.c 来映射我们的存储器读写控制接口,如下:
/*-----------------------------------------------------------------------*/ /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */ /*-----------------------------------------------------------------------*/ /* 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 modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ #include "diskio.h"/* FatFs lower layer API */ #include "w25qxx.h" #include "debug.h" #define DISKIO_DEBUG 1 #if defined DISKIO_DEBUG&&(DISKIO_DEBUG) #define diskio_printf uart_printf #else #define diskio_printf(a,...) #endif /* Definitions of physical drive number for each drive */ #define SPI_FLASH0/* Example: Map Ramdisk to physical drive 0 */ /*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ DSTATUS disk_status ( BYTE pdrv/* Physical drive nmuber to identify the drive */ ) { if(pdrv == SPI_FLASH) { return RES_OK; //直接返回OK即可 } else { diskio_printf("!!!disk_status ERR\r\n"); return RES_PARERR; } } /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ DSTATUS disk_initialize ( BYTE pdrv/* Physical drive nmuber to identify the drive */ ) { if(pdrv == SPI_FLASH) { w25qxx_init();//初始化 spi flash return RES_OK; } else { diskio_printf("!!!disk_initialize ERR\r\n"); return RES_PARERR; } } /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ DRESULT disk_read ( BYTE pdrv,/* Physical drive nmuber to identify the drive */ BYTE *buff,/* Data buffer to store read data */ DWORD sector,/* Start sector in LBA */ UINT count/* Number of sectors to read */ ) { DRESULT res; //uart_printf("disk_read---sector:%d,count:%d\r\n",sector,count); if(pdrv == SPI_FLASH) { res = FS_SpiFlash_Read(buff,sector,count);//spi flash的读接口,注意函数参数类型一致性 return res; } else { diskio_printf("!!!disk_read ERR\r\n"); return RES_PARERR; } } /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ DRESULT disk_write ( BYTE pdrv,/* Phy 4000 sical drive nmuber to identify the drive */ const BYTE *buff,/* Data to be written */ DWORD sector,/* Start sector in LBA */ UINT count/* Number of sectors to write */ ) { DRESULT res; if(pdrv == SPI_FLASH) { res = FS_SpiFlash_Write((uint8_t *)buff,sector,count);//spi flash的写接口,注意函数参数类型一致性 return res; } else { diskio_printf("!!!disk_write ERR\r\n"); return RES_PARERR; } } /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ DRESULT disk_ioctl ( BYTE pdrv,/* Physical drive nmuber (0..) */ BYTE cmd,/* Control code */ void *buff/* Buffer to send/receive control data */ ) { if (pdrv == SPI_FLASH) { switch (cmd) { case CTRL_SYNC: return RES_OK; /* 扇区数量 1024*1024*1024 =4 (MB) */ case GET_SECTOR_COUNT: *(DWORD * )buff = 1024;//W25Q32 有1024个大小为4k bytes 的扇区 return RES_OK; /* 扇区大小 */ case GET_SECTOR_SIZE : *(WORD * )buff = 4096;//spi flash的扇区大小是 4K Bytes return RES_OK; /*块大小 */ case GET_BLOCK_SIZE : *(DWORD * )buff = 1; return RES_OK; default: return RES_PARERR; } } else { diskio_printf("!!!disk_ioctl ERR\r\n"); return RES_PARERR; } }
DWORD get_fattime(void) { DWORD time; /* 返回当前时间戳 */ //暂不添加时间获取,需要的话就把RTC数据传入这里
return 0;
}
要修改的文件就这么多了,其他文件直接使用,不用改动。
step2.0 下面写个测试函数,来测测我们移植成功 了没有。
void fs_test(void)step2.1 Congratulations!!!瞧, 我们成功了,尽情享用文件系统带来的便利吧。
{
FATFS fs; /* Filesystem object */
FIL fil; /* File object */
FRESULT res; /* API result code */
UINT bw; /* Bytes written */
BYTE work[FF_MAX_SS]; /* Work area (larger is better for processing time) */
BYTE mm[50];
UINT i;
uart_printf("文件系统测试开始:\r\n");
/* 格式化文件系统 */
res = f_mkfs("0:", FM_ANY, 0, work, sizeof work);//"0:"是卷标,来自于 #define SPI_FLASH0
if (res)
{
uart_printf("文件系统格式化失败.\r\n");
return ;
}
else
{
uart_printf("文件系统格式化成功.\r\n");
}
/* 挂载文件系统 */
res = f_mount(&fs, "0:", 0);
if (res)
{
uart_printf("文件系统挂载失败.\r\n");
}
else
{
uart_printf("文件系统挂载成功.\r\n");
}
/* Create a file as new */
res = f_open(&fil, "0:/测试文件.txt", FA_CREATE_NEW|FA_WRITE|FA_READ);
if (res)
{
uart_printf("打开文件失败.\r\n");
}
else
{
uart_printf("打开文件成功.\r\n");
}
/* Write a message */
res = f_write(&fil, "Hello,World!", 12, &bw);
//uart_printf("res write:%d\r\n",res);
if (bw == 12)
{
uart_printf("写文件成功!\r\n");
}
else
{
uart_printf("写文件失败!\r\n");
}
res = f_size(&fil);
uart_printf("文件大小:%d Bytes.\r\n",res);
memset(mm,0x0,50);
f_lseek(&fil,0);
res = f_read(&fil,mm,12,&i);
if (res == FR_OK)
{
uart_printf("读文件成功!\r\n");
uart_printf("读到数据长度:%d Bytes.\r\n",i);
}
else
{
uart_printf("读文件失败!\r\n");
}
uart_printf("读到如下数据:\r\n");
buff_print((char *)mm,12);
/* Close the file */
f_close(&fil);
/*卸载文件系统*/
f_mount(0, "0:", 0);
uart_printf("文件系统测试完毕.\r\n");
说的比较浅显,大家有问题或建议欢迎留言。over
相关文章推荐
- 一种易于移植和使用的文件系统FatFs Moule
- Hi3531用SPI FLASH启动 使用Nand做文件系统
- STM32例程之FATFS文件系统(SPI方式)移植笔记(源码下载)
- Hi3531用SPI FLASH启动 使用Nand做文件系统 分类: HI3531 2013-08-28 10:26 884人阅读 评论(0) 收藏
- Hi3531用SPI FLASH启动 使用Nand做文件系统
- LPC1768 SPI模式下SD卡FatFs文件系统移植
- Hi3531用SPI FLASH启动 使用Nand做文件系统
- 转一篇比较详细介绍FatFs文件系统移植的文章
- 为STM32移植FATFS,读取SD卡上FAT12/16/32文件系统
- linux-2.6.21内核中建立jffs2文件系统(mtd分区的使用)
- 转一篇比较详细介绍FatFs文件系统移植的文章
- Fatfs文件系统分析(4)-FATFS文件系统移植笔记
- 介绍FatFs文件系统移植的文章
- 转一篇比较详细介绍FatFs文件系统移植的文章
- 介绍FatFs文件系统移植的文章
- FatFS文件系统详解-附移植建议
- fatfs文件系统移植
- FatFs文件系统的移植
- linux 2.6.24.4及根文件系统在S3C2410上的移植(使用4.3.2编译器支持eabi)(基于GEC2410)
- 在pc机上移植fatfs文件系统(windows/linux) (二)