首先我这个版本用的比较老,是R0.04b的(通过查看版本历史,是在2007.05.05发布的),现在(2012..06)看到网站上http://elm-chan.org/fsw/ff/00index_e.html发布的R0.09(Sep 06,'11发布),但是这些不是主要问题,弄明白怎么用这个接口才是主要的;
到这里下载本文中的移植及测试程序:http://download.csdn.net/detail/dijkstar/4402353,做格式化实验f_mkfs时,一定要拿U盘来实验!!
FatFs是一个FAT文件系统接口,自己去作者网站上阅读资料吧。下面主要实现几个底层打开、读写物理磁盘的函数即可,来看diskio.c程序:
#include "diskio.h"
#include <windows.h>
#include <Winioctl.h>
static HANDLE hDevice = NULL;
static DSTATUS DiskStatus; //初始话磁盘状态为未初始化
/*
磁盘初始化
*/
DSTATUS disk_initialize(
BYTE Drive /* 磁盘号*/
)
{
// TODO: Add your control notification handler code here
hDevice = CreateFile("\\\\.\\I:",
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL
);
if (hDevice == INVALID_HANDLE_VALUE)
{
DiskStatus = STA_NOINIT;
return DiskStatus;
}
return 0;
}
/*
磁盘状态读取
in:none
*/
DSTATUS disk_status (
BYTE Drive /* 磁盘号*/
)
{
return DiskStatus;
}
/*
读磁盘
out :RES_OK (0) 成功读取数据
RES_ERROR 操作过程有错误发生
RES_PARERR 参数错误
RES_NOTRDY 磁盘没有初始化
*/
DRESULT disk_read (
BYTE Drive, /* 磁盘号 */
BYTE* Buffer, /* 读取数据缓存 */
DWORD SectorNumber, /* 扇区号*/
BYTE SectorCount /* 扇区数 */
)
{
DWORD bytesread = 0;
SetFilePointer (hDevice, SectorNumber*512, 0, FILE_BEGIN);
ReadFile (hDevice, Buffer, SectorCount*512, &bytesread, NULL);
return RES_OK;
}
DRESULT disk_write (
BYTE Drive, /* 磁盘号 */
const BYTE* Buffer, /* 读取数据缓存 */
DWORD SectorNumber, /* 扇区号*/
BYTE SectorCount /* 扇区数 */
)
{
DWORD bytesread = 0;
SetFilePointer (hDevice, SectorNumber*512, 0, FILE_BEGIN);
WriteFile (hDevice, Buffer, SectorCount*512, &bytesread, NULL);
return RES_OK;
}
DRESULT disk_ioctl (
BYTE Drive, /* 磁盘号 */
BYTE Command, /* 命令 */
void* Buffer /* 缓冲区 */
)
{
DISK_GEOMETRY dg;
DWORD ret = 0;
switch(Command)
{
case GET_SECTOR_COUNT:
DeviceIoControl(hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL, // lpInBuffer
0, // nInBufferSize
&dg,
sizeof(DISK_GEOMETRY),
&ret,
NULL
);
*(int *)Buffer = dg.Cylinders.LowPart * dg.TracksPerCylinder * dg.SectorsPerTrack;//返回扇区个数
break;
case GET_SECTOR_SIZE:
*(int *)Buffer = 512;//win平台上的扇区为512,直接返回
}
return RES_OK;
}
DWORD get_fattime (void)
{
return 0;
}
// int main(void)
// {
// unsigned char DataBuffer[512];
// unsigned char DataBuffer2[512] = {0};
//
// int i;
// unsigned char Result = 0;
// Result = disk_initialize (
// 0 /* 磁盘号*/
// );
// for(i = 0; i < 512; i++)
// {
// DataBuffer[i] = i;
// }
// if(!Result)
// {
// disk_write(0,DataBuffer,5,1);
// for(i = 0; i < 512; i++)
// {
// DataBuffer[i] = 0;
// }
//
// disk_read(0,DataBuffer2,5,1);
// }
// }
这就是全部的移植工作了,在disk_read里面打开U盘(插上U盘,看看出现的盘符,替换上面的“I”),都是在win平台上打开磁盘、读写物理扇区的现成代码,不多说了,都很简单和直观;
测试和使用部分在Test.c中,包括:文件拷贝、建立文件、改名、建立目录、格式化等等:
void main()
{
FATFS fs; // Work area (file system object) for logical drive
// Register a work area to logical drive 0
f_mount(0, &fs);
// CopyFile();
// ScanFiles("DIR");
// GetFree();
// MakeDir();
// ChMod();
// ReName();
FormatDisk();
// Unregister a work area before discard it
f_mount(0, NULL);
}
这个移植的主要目的,是通过这样一个接口,使用vc这样的强大而方便的调试工具,深入到FAT内部中去,跟踪FatFs的内部实现,为未来构造个人的专用文件系统而准备。