`
mmdev
  • 浏览: 12956357 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

在pc机上移植fatfs文件系统(windows/linux) (一)

 
阅读更多

开始我的技术生涯~

哈哈,老大给我分配了一个以前都没接触到的任务。在PC机上移植fatfs文件系统。以前我认为的移植是调用底层提供的API接口,在PC机上模拟,测试通过后再移植到目标板上。这次的移植竟然是移植到PC机上。

我的开始考虑到的硬件基础:文件系统要在硬件存储介质上运行,例如u盘啊、SD卡啊。那这次没有硬件设备,怎么模拟呢。diskio.c是和底层硬件相关的文件。解决方案是用创建一个具有一定大小的文件来作为存储载体。

开始有了一点思路。我就开始了人生的第一次移植。

fatfs下载地址:http://elm-chan.org/fsw/ff/00index_e.html 工作后,搜索引擎就从百度转到了谷歌。嵌入式的很多重要资料都是外文文献。难堪啊,还好有谷歌浏览器,可以翻译网页~~ 强大 哈哈。

我用的是fatfs 0.08b 最新版。 0.08b版本多了几个API接口。并且前辈们反映移植遇到的问题 解决了。

下到了源代码


有2个文件夹。doc 里面我没仔细看。 src里面就是源代码 了。

diskio.c是自己写的。是一些贴近底层硬件的函数。

我看了CSDN里面一些前辈关于移植fatfs的资料。首先第一步就是配置ffconf.h

fatfs有2个版本。一个是tiny版本。这个版本适合比较小的RAM,eg:单片机。我用的是正常版。#define_FS_TINY 0/* 0:Normal or 1:Tiny */

因为 移植后要测试读与写是否匹配,所以设置为读写功能。#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */

#define _FS_MINIMIZE 3/* 0 to 3 */ 我用了全部功能,因为没要求要裁剪。这个具体实现以后再慢慢琢磨。

#define _USE_MKFS1 /* 0:Disable or 1:Enable */ 如果是在PC机上模拟,这个必须设置成1.因为这个参数,我搞了1天。下面再详述。

#define _CODE_PAGE 936 简体中文

#define _MAX_SS512 /* 512, 1024, 2048 or 4096 */ 一个扇区512字节

#define _USE_ERASE1 /* 0:Disable or 1:Enable */ 具备擦除功能,这个功能 我目前还没测试过。

#define _WORD_ACCESS 0/* 0 or 1 */

配置好ffconf.h,就可以开始写diskio.c了。

DSTATUS disk_initialize(BYTE drv)
{
return 0;
}

这个函数是用来初始化disk的。 因为这里没有硬件,所以直接return 0.
DSTATUS disk_status(BYTE drv)

这个函数嘛,是用来获取硬件状态的。我用文件模拟,就随便写了,可以正常打开就返回Ok,否则就返回错误代码

DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, BYTE count)
{
FILE *fp = NULL;
DWORD ulSeek = 0;
unsigned long nRead = 0;
int nSeekRes = 0;
DRESULT res = RES_OK;


if (drv || !count)
{
//Only support a single disk operation
//count is not equal to 0, otherwise parameter error
printf("param err!\n");
return RES_PARERR;
}


if((fp=fopen(DISKNAME, "r+")) == NULL)
{
printf("disk no ready!\n");
return RES_NOTRDY;
}


ulSeek = sector*512;


if(((nSeekRes = fseek(fp, ulSeek, SEEK_SET)) == 0) && ((nRead = fread((void *)buff, _MAX_SS, count, fp)) != 0))
{
printf("read disk OK!\n");
}
else
{
printf("Out of range Or ...\n");
res = RES_ERROR;
}
fclose(fp);

return res;
}

disk_read 是用来读取扇区数据的。可以偏移访问。开始的时候忘记单位了,ulSeek = sector,后来经过永都提醒,才注意到这个错误。不然调用格式化函数的时候一直不能正常返回。读取都是数量级扇区读取的。

disk_write和disk_read函数大同小异,这里不多描述了。

disk_ioctl,开始的时候我直接return 0。到后来需要调用格式化函数,那就必须实现disk_ioctl功能了。0.08b版本目前支持以下5种命令。

#define CTRL_SYNC 0/* Flush disk cache (for write functions) */
#define GET_SECTOR_COUNT 1/* Get media size (for only f_mkfs()) */
#define GET_SECTOR_SIZE 2/* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
#define GET_BLOCK_SIZE 3/* Get erase block size (for only f_mkfs()) */
#define CTRL_ERASE_SECTOR 4/* Force erased a block of sectors (for only _USE_ERASE) */

*(DWORD*)buff = (128-1)*32;

GET_SECTOR_COUNT 用来读取扇区个数的。我创建存储载体的思想是这样的sector=512字节。

今天就先写到这。明天继续。~

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics