FatFs是面向小型嵌入式系统的一种通用的FAT文件系统。它完全是由AISI C语言编写并且完全独立于底层的I/O介质。因此它可以很容易地不加修改地移植到其他的处理器当中,如8051、PIC、AVR、SH、Z80、H8、ARM等。FatFs支持FAT12、FAT16、FAT32等格式。
FatFs源码下载FatFs - Generic FAT Filesystem Module
下载下来后,目录结构由帮助文档(doc)和文件系统源码(src)构成:
打开源码我们会看到如下几个文件:
integer.h:文件中包含了一些数值类型定义。
diskio.c:包含底层存储介质的操作函数,这些函数需要用户自己实现,主要添加底层驱动函数。
ff.c:FatFs核心文件,文件管理的实现方法。该文件独立于底层介质操作文件的函数,利用这些函数实现文件的读写。(相当于C语言中的stdio.h)
ffconf.h:这个头文件包含了对FatFs功能配置的宏定义,通过修改这些宏定义就可以裁剪FatFs的功能。
在Xilinx平台MicroBlaze没有SD卡,所以我们只能以SPI的方式来进行移植。
移植步骤如下:
1.diskio.c中需要修改如下几个函数
1.
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case DEV_SPI :
result = spi_flash_status();
stat = RES_OK;
return stat;
case DEV_MMC :
return stat;
case DEV_USB :
return stat;
}
return STA_NOINIT;
}
2.
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case DEV_SPI :
result = spi_flash_init((u32)pdrv);
stat = RES_OK;
return stat;
case DEV_MMC :
return stat;
case DEV_USB :
return stat;
}
return STA_NOINIT;
}
3.
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;
int result;
switch (pdrv) {
case DEV_SPI :
sector+=1536;
result = spi_flash_read(sector*4096,count*4096,(u8*)buff);
res = RES_OK;
return res;
case DEV_MMC :
return res;
case DEV_USB :
return res;
}
return RES_PARERR;
}
4.
DRESULT disk_write (
BYTE pdrv, /* Physical 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;
int result;
switch (pdrv) {
case DEV_SPI :
sector += 1536;
spi_flash_sector_erase(sector*4096);
result = spi_flash_write(sector*4096,count*4096,(u8*)buff);
res = RES_OK;
return res;
case DEV_MMC :
return res;
case DEV_USB :
return res;
}
return RES_PARERR;
}
5.
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
int result;
switch (pdrv) {
case DEV_SPI:
switch(cmd)
{
case GET_SECTOR_COUNT:
*(DWORD *) buff = 512;
break;
case GET_SECTOR_SIZE:
*(DWORD *) buff = 4096;
break;
case GET_BLOCK_SIZE:
*(DWORD *) buff = 1;
break;
}
res = RES_OK;
return