//**** FAT文件系统移植 ****//*
1 下载文件系统 FATFS+R0.09.rar
2 将源码src的所有内容复制到工程下source\FatFs中. 重写以下3个文件即可
3 添加如下代码到工程,即如下结构:
bspeeprom.h [已经有了,需要的底层接口]
bspeeprom.c [已经有了]
FatFs\
ffconf.h *重写 FatFs 模块配置文件
ff.h FatFs 和应用模块公用的包含文件
ff.c FatFs 模块
diskio.h FatFs and disk I/O 模块公用的包含文件
diskio.c *重写
integer.h *重写 数据类型定义
option\ 可选的外部功能 */
/*****************************************************************************************
fat文件系统配置函数
文 件:ffconf.h
FatFs - FAT file system module configuration file R0.09 (C)ChaN, 2011
张永辉 2013年4月17日 整理
*****************************************************************************************/
#ifndef _FFCONF
//****************************************************************************************
#define _FFCONF 6502 //Revision ID
// Functions and Buffer Configurations
#define _FS_TINY 0 //==0:Normal 或==1:Tiny
//Tiny模式占用内存更小,每个文件占512字节。
//定义为1时,不能使用如下函数
//f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,f_truncate and useless f_getfree
#define _FS_READONLY 0 //0:Read/Write or 1:Read only
#define _FS_MINIMIZE 0 //0 to 3
// The _FS_MINIMIZE option defines minimization level to remove some functions.
// 0: Full function.
// 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
// are removed.
// 2: f_opendir and f_readdir are removed in addition to 1.
// 3: f_lseek is removed in addition to 2.
//使能字符串功能
#define _USE_STRFUNC 0 //0:Disable or 1-2:Enable
#define _USE_MKFS 1 //0:Disable or 1:Enable
// To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0
#define _USE_FORWARD 0 //0:Disable or 1:Enable
// To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1.
#define _USE_FASTSEEK 0 //0:Disable or 1:Enable
// To enable fast seek feature, set _USE_FASTSEEK to 1.
//使用语言 简体中文 代码会增加160K左右
#define _CODE_PAGE 1
// Incorrect setting of the code page can cause a file open failure.
// 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
// 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
// 1 - ASCII only (Valid for non LFN cfg.)
#define _USE_LFN 0 //==0\1\2\3
#define _MAX_LFN 64 //Maximum LFN length to handle (12 to 255)
// The _USE_LFN option switches the LFN support.
// 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
// 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
// 2: Enable LFN with dynamic working buffer on the STACK. 栈为工作区
// 3: Enable LFN with dynamic working buffer on the HEAP.
#define _LFN_UNICODE 0 //0:ANSI/OEM or 1:Unicode
#define _FS_RPATH 0 //0 to 2
//****************************************************************************************
// Physical Drive Configurations
#define _VOLUMES 1 //支持的逻辑卷数目 最大10个
#define _MAX_SS 512 //定义扇区大小,支持512, 1024, 2048 或 4096
//定义是否支持重入,使用 uCOS-II 时需要定义
#define _MULTI_PARTITION 0 //0:Single partition, 1/2:Enable multiple partition
//==0 each volume is bound to the same physical drive number and it can mount only first primaly partition.
//==1 When it is set to 1, each volume is tied to the partitions listed in VolToPart[]
#define _USE_ERASE 0 //0:Disable or 1:Enable
// To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
// should be added to the disk_ioctl functio.
//****************************************************************************************
// System Configurations
#define _WORD_ACCESS 0 //0 or 1
#define _FS_REENTRANT 0 //0:Disable or 1:Enable
#define _FS_TIMEOUT 1000 //定义超时周期,使用uCOS-II时需要定义
//定义 sync object.的类型,使用 uCOS-II 时需要定义
#define _SYNC_t HANDLE //O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc..
#define _FS_SHARE 0 //0:Disable or >=1:Enable
// To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
// defines how many files can be opened simultaneously.
//****************************************************************************************
#endif
/*****************************************************************************************
数据类型定义
文 件:integer.h
以下定义为在嵌入式平台而修改
*****************************************************************************************/
#ifndef _INTEGER
#define _INTEGER
//必须16位或更大
#ifndef INT
typedef int INT;
#endif
#ifndef UINT
typedef unsigned int UINT;
#endif
//必须8位
#ifndef CHAR
typedef char CHAR;
#endif
#ifndef UCHAR
typedef unsigned char UCHAR;
#endif
#ifndef BYTE
typedef unsigned char BYTE;
#endif
//必须16位
#ifndef SHORT
typedef short SHORT;
#endif
#ifndef USHORT
typedef unsigned short USHORT;
#endif
#ifndef WORD
typedef unsigned short WORD;
#endif
#ifndef WCHAR
typedef unsigned short WCHAR;
#endif
//必须32位
#ifndef LONG
typedef int LONG;
#endif
#ifndef ULONG
typedef unsigned int ULONG;
#endif
#ifndef DWORD
typedef unsigned int DWORD;
#endif
//其他地方需要的定义
#ifndef INT8U
typedef unsigned char INT8U;
#endif
#ifndef uint8
typedef unsigned char uint8;
#endif
//****************************************************************************************
#endif
/*****************************************************************************************
文 件:diskio.c
*****************************************************************************************/
#include "ffconf.h"
#include "integer.h"
#include "diskio.h"
#include "\embed\vs2008\bsp\bspeeprom.h"
DSTATUS Drv0Stat = STA_NOINIT; //磁盘状态
/*****************************************************************************************
功能: 函数初始化一个逻辑驱 动器为 读/ 写做 准备
入参:Drive指定要初始化的逻辑驱动器号,即盘符,应当取值 0~9
出参:函数返回一个磁盘状态作为结果
注意:应用程序不应调用此函数。如果需要重新初始化文件系统,可使用 f_mount 函数
*/
DSTATUS disk_initialize(BYTE Drive)
{
Drv0Stat |= STA_NOINIT;
switch (Drive)
{
//仅使用了盘符0 模拟EE
case 0 :
BspEePromInit(); //此函数,不能每次都清除EE的内容,否则会报文件系统不存在(经验)
Drv0Stat = 0; //成功
return Drv0Stat;
default:
return STA_NOINIT; //失败
}
return STA_NOINIT;
}
/*****************************************************************************************
功能:返回当前磁盘驱动器的状态
入参:Drive:指定要确认的逻辑驱动器号,即盘符,应当取值 0~9
出参:(磁盘状态返回下列标志的组合 FatFs只使用STA_NOINIT和STA_PROTECTED)
STA_NOINIT: 表明磁盘驱动未初始化,可能的 原因如下:
置位:系统复位,磁盘被移除和磁盘初始化函数失败;
清零:磁盘初始化函数成功
STA_NODISK: 表明驱动器中没有设备。
STA_PROTECTED: 表明设备被写保护。
*/
DSTATUS disk_status(BYTE Drive)
{
switch (Drive)
{
case 0 :
return Drv0Stat;
default:
return STA_NODISK; //失败
}
return STA_NOINIT;
}
/*****************************************************************************************
功能:从磁盘驱动器上读取扇区
入参: Drive: 指定逻辑驱动器号,即盘符,应当取值 0~9
Buffer: 指向存储读取数据字节数组的指针
SectorNumber: 指定起始扇区的逻辑块(LBA)上的地址
SectorCount: 指定要读取的扇区数,取值 1~128
出参: RES_OK(0): 函数成功
RES_ERROR: 读操作期间产生了任何错误且不能恢复它
RES_PARERR: 非法参数
RES_NOTRDY: 磁盘驱动器没有初始化
*/
DRESULT disk_read(BYTE Drive, BYTE* Buffer, DWORD SectorNumber, BYTE SectorCount)
{
INT8U ucRet;
if (Drv0Stat & STA_NOINIT)
{
return RES_NOTRDY;
} else if (!SectorCount)
{
return RES_PARERR;
}
switch(Drive)
{
case 0 :
ucRet = BspEePromSectorReads(Buffer,SectorNumber,SectorCount);
if (ucRet != 0x00)
{
return RES_ERROR;
} else
{
return RES_OK;
}
default:
return RES_PARERR;
}
return RES_PARERR;
}
/*****************************************************************************************
功能:向磁盘写入一个或多个扇区
入参:
Drive: 指定逻辑驱动器号,即盘符,应当取值 0~9
Buffer: 指向要写入字节数组的指针,
SectorNumber: 指定起始扇区的逻辑块(LBA)上的地址
SectorNumber: 指定要写入的扇区数,取值 1~128
出参:
RES_OK(0): 函数成功
RES_ERROR: 读操作期间产生了任何错误且不能恢复它
RES_WRPRT: 媒体被写保护
RES_PARERR: 非法参数
RES_NOTRDY: 磁盘驱动器没有初始化
注: FatFs 指定的内存地址并不总是字对齐的,如果硬件不支持不对齐的数据传输,函数里需要进行处理
*/
#if _READONLY == 0
DRESULT disk_write(BYTE Drive, const BYTE* Buffer, DWORD SectorNumber, BYTE SectorCount)
{
INT8U ucRet;
if (Drv0Stat & STA_NOINIT)
{
return RES_NOTRDY;
} else if (!SectorCount)
{
return RES_PARERR;
}
switch (Drive)
{
case 0 :
ucRet = BspEePromSectorWrites((BYTE*)Buffer,SectorNumber,SectorCount);
if (ucRet != 0x00)
{
return RES_ERROR;
}else
{
return RES_OK;
}
}
return RES_PARERR;
}
#endif
/*****************************************************************************************
功能:控制设备指定特性和除了读/写外的杂项功能
入参:
Drive: 指定逻辑驱动器号,即盘符,应当取值 0~9
Command: 指定命令代码
CTRL_SYNC: 确保磁盘驱动器已经完成了写处理,有一个写回缓存,立即刷新原扇区,只读配置下不适用此命令
GET_SECTOR_SIZE: 返回磁盘的扇区大小,只用于 f_mkfs()
GET_SECTOR_COUNT: 返回可利用的扇区数, _MAX_SS >= 1024 时可用
GET_BLOCK_SIZE: 获取擦除块大小,只用于 f_mkfs()
CTRL_ERASE_SECTOR: 强制擦除一块的扇区,_USE_ERASE >0 时可用
Buffer: 指向参数缓冲区的指针,取决于命令代码,不使用时,指定一个 NULL 指针
出参:
RES_OK(0): 函数成功
RES_ERROR: 读操作期间产生了任何错误且不能恢复它
RES_PARERR:非法参数
RES_NOTRDY:磁盘驱动器没有初始化
*/
DRESULT disk_ioctl(BYTE Drive, BYTE Command, void* Buffer)
{
if (Drv0Stat & STA_NOINIT)
{
return RES_NOTRDY;
}
switch (Drive)
{
case 0:
break;
default:
return RES_PARERR;
}
switch (Command)
{
case CTRL_SYNC:
return RES_OK;
case GET_SECTOR_SIZE: //扇区大小
*(DWORD*)Buffer = BspEePromSectorSizeGet();
return RES_OK;
case GET_SECTOR_COUNT: //扇区数
*(DWORD*)Buffer = BspEePromSectorConutGet();
return RES_OK;
case GET_BLOCK_SIZE: //块大小 要大于128
*(DWORD*)Buffer = BspEePromPageSizeGet();
return RES_OK;
case CTRL_ERASE_SECTOR: //扇区擦除
return RES_OK;
default:
return RES_PARERR;
}
return RES_PARERR;
}
/*****************************************************************************************
功能:函数必须返回一个合法的时间即使系统不支持实时时钟,
注 :如果返回 0,文件没有一个合法的时间,只读配置下无需此函数。
*/
DWORD get_fattime(void)
{
return ((2010UL-1980) << 25) /* Year = 2010 */
| (11UL << 21) /* Month = 11 */
| (2UL << 16) /* Day = 2 */
| (15U << 11) /* Hour = 15 */
| (0U << 5) /* Min = 0 */
| (0U >> 1) /* Sec = 0 */
;
}