首先我这个版本用的比较老,是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); }