1. 参考了 Q-sys的V2.35版本, 2个文件为 fswrap.h, fswarp.c
fswrap.h
-
#ifndef __FS_WRAP_H__
-
#define __FS_WRAP_H__
-
-
#define FS_size_t unsigned long /* 32 bit unsigned */
-
#define FS_u32 unsigned long /* 32 bit unsigned */
-
#define FS_i32 signed long /* 32 bit signed */
-
#define FS_u16 unsigned short /* 16 bit unsigned */
-
#define FS_i16 signed short /* 16 bit signed */
-
#define FS_i8 signed char /* 8 bit signed */
-
#define FS_u8 unsigned char /* 8 bit unsigned */
-
//#define NULL 0
-
-
typedef void FS_FILE;
-
typedef void FS_DIR;
-
-
typedef struct {
-
FS_u32 total_size;
-
FS_u32 free_size;
-
} _DISK_INFO;
-
-
/* Global constants*/
-
#define FS_SEEK_CUR 1
-
#define FS_SEEK_END 2
-
#define FS_SEEK_SET 0 /*文件开头*/
-
-
#ifndef _OPENDIR_TYPE_
-
#define _OPENDIR_TYPE_
-
-
typedef unsigned int size_t;
-
typedef short dev_t;
-
typedef unsigned int ino_t;
-
typedef unsigned int mode_t;
-
typedef unsigned short nlink_t;
-
typedef unsigned long off_t;
-
typedef unsigned short gid_t;
-
typedef unsigned short uid_t;
-
typedef int pid_t;
-
typedef int time_t;
-
-
struct stat {
-
mode_t st_mode; /* File mode */
-
ino_t st_ino; /* File serial number */
-
dev_t st_dev; /* ID of device containing file */
-
nlink_t st_nlink; /* Number of hard links */
-
uid_t st_uid; /* User ID of the file owner */
-
gid_t st_gid; /* Group ID of the file's group */
-
off_t st_size; /* File size (regular files only) */
-
time_t st_atime; /* Last access time */
-
time_t st_mtime; /* Last data modification time */
-
time_t st_ctime; /* Last file status change time */
-
};
-
-
#define NAME_MAX 63 /* domain */
-
struct dirent
-
{
-
char d_name[NAME_MAX+1];
-
unsigned int id; /* use for id file, and only valid when the */
-
mode_t st_mode; /* file mode */
-
int st_ctime; /* file create time */
-
-
-
/* size of d_name is zero */
-
/* now we needn't u_name, we save file name as utf8 */
-
//char u_name[NAME_MAX+1];
-
-
};
-
-
#define _IFMT 0170000 /* type of file */
-
#define _IFDIR 0040000 /* directory */
-
#define _IFCHR 0020000 /* character special */
-
#define _IFBLK 0060000 /* block special */
-
#define _IFREG 0100000 /* regular */
-
#define _IFLNK 0120000 /* symbolic link */
-
#define _IFSOCK 0140000 /* socket */
-
#define _IFIFO 0010000 /* fifo */
-
#define S_BLKSIZE 1024 /* size of a block */
-
#define S_ISUID 0004000 /* set user id on execution */
-
#define S_ISGID 0002000 /* set group id on execution */
-
-
#define S_ISBLK(m) (((m)&_IFMT) == _IFBLK)
-
#define S_ISCHR(m) (((m)&_IFMT) == _IFCHR)
-
#define S_ISDIR(m) (((m)&_IFMT) == _IFDIR)
-
#define S_ISFIFO(m) (((m)&_IFMT) == _IFIFO)
-
#define S_ISREG(m) (((m)&_IFMT) == _IFREG)
-
#define S_ISLNK(m) (((m)&_IFMT) == _IFLNK)
-
#define S_ISSOCK(m) (((m)&_IFMT) == _IFSOCK)
-
-
#endif
-
-
#ifndef _INC_TCHAR
-
#define _INC_TCHAR
-
typedef char TCHAR;
-
#define _T(x) x
-
#define _TEXT(x) x
-
#endif
-
-
#if 0
-
#ifndef FA_READ
-
#define FA_READ 0x01
-
#endif
-
-
#ifndef FA_OPEN_EXISTING
-
#define FA_OPEN_EXISTING 0x00
-
#endif
-
-
#ifndef FA_WRITE
-
#define FA_WRITE 0x02
-
#endif
-
-
#ifndef FA_CREATE_NEW
-
#define FA_CREATE_NEW 0x04
-
#endif
-
-
#ifndef FA_CREATE_ALWAYS
-
#define FA_CREATE_ALWAYS 0x08
-
#endif
-
-
#ifndef FA_OPEN_ALWAYS
-
#define FA_OPEN_ALWAYS 0x10
-
#endif
-
#endif
-
-
FS_FILE* FS_FOpen(const TCHAR *pFileName, const FS_i32 Mode);
-
FS_i32 FS_FClose(FS_FILE*pFile);
-
FS_size_t FS_FWrite(const void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile);
-
FS_size_t FS_FRead(void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile);
-
FS_i32 FS_FSeek(FS_FILE *pFile, FS_i32 Offset, FS_i32 Whence);
-
FS_i32 FS_FTell(FS_FILE *pFile);
-
-
FS_DIR *FS_OpenDir( const TCHAR *dirname );
-
struct dirent * FS_ReadDir( FS_DIR *dirp);
-
struct dirent * FS_ReadDir_IDX( FS_DIR *dirp,unsigned short idx);
-
void FS_RewindDir(FS_DIR *pDir);
-
FS_i32 FS_CloseDir( FS_DIR *dirp );
-
FS_i32 FS_Unlink(const TCHAR *Path);
-
FS_i32 FS_Stat(const TCHAR *path,struct stat *buf);
-
FS_i32 FS_Rename(const TCHAR *OldName,const TCHAR *NewName);
-
FS_i32 FS_Init(void);
-
FS_i32 FS_Exit(void);
-
-
FS_i32 GetDiskInfo(const TCHAR* Path,_DISK_INFO* info);
-
FS_i32 FS_FileCpy(const TCHAR*path1, const TCHAR*path2); //path1: souce file path2: destination file
-
FS_i32 FS_GetFileSize(FS_FILE *pFile);
-
-
-
//--- qiushui007, 自己习惯的写法
-
#define fs_init FS_Init
-
#define fs_exit FS_Exit
-
-
#define fs_fopen FS_FOpen
-
#define fs_fclose FS_FClose
-
#define fs_fwrite FS_FWrite
-
#define fs_fread FS_FRead
-
#define fs_fseek FS_FSeek
-
#define fs_ftell FS_FTell
-
-
#endif
fswrap.c
-
/************************************************************************
-
Project :
-
Module : file system api
-
File Name : fs_api.c
-
Author : dragon_zhang
-
Start Date : 2011.4.25
-
Language : C
-
Target :
-
Summary :
-
Change Notes : 2011.4.25 V1.0 creat file
-
**************************************************************************/
-
#include <string.h>
-
#include "ff.h"
-
#include "FsWrap.h"
-
#include "OS_Wrap.h"
-
-
#define DEBUGP //printf
-
-
static FATFS FileSystemArea[_VOLUMES]; /* Work area (file system object) for logical drives */
-
#if _USE_LFN
-
static WCHAR LenFileName[_MAX_LFN+1];
-
#endif
-
-
typedef struct {
-
FRESULT error;
-
union {
-
FIL file;
-
DIR dir;
-
}fs;
-
} _FS_PTR;
-
-
//--------------------------------------------------------------------
-
FS_i32 FS_Init(void)
-
{
-
#if 2
-
FS_i32 i = _VOLUMES;
-
-
for(i=0;i<_VOLUMES;i++) f_mount(i, &FileSystemArea[i]);
-
-
#else
-
f_mount(0, &FileSystemArea[0]);
-
#endif
-
-
return 0;
-
}
-
-
FS_i32 FS_Exit(void) {
-
-
FS_i32 i = _VOLUMES;
-
-
while(i--) f_mount(0, NULL);
-
-
return 0;
-
}
-
-
//---- 其余函数
-
FS_FILE* FS_FOpen(const TCHAR *pFileName, const FS_i32 Mode)
-
{
-
_FS_PTR * fp;
-
-
fp = (_FS_PTR*)Q_Mallco(sizeof(_FS_PTR));
-
memset((void*)fp,0,sizeof(_FS_PTR));
-
-
fp->error = f_open(&fp->fs.file,pFileName,Mode);
-
-
if(fp->error!=FR_OK)
-
{
-
Q_Free((void *)fp );
-
fp = 0;
-
}
-
-
return (FS_FILE*)fp;
-
}
-
-
FS_i32 FS_FClose(FS_FILE* pFile)
-
{
-
_FS_PTR * fp = (_FS_PTR *)pFile;
-
-
if (!pFile) return -1; /* No pointer to a FS_FILE structure */
-
-
fp->error = f_close(&fp->fs.file);
-
-
if(fp->error!=FR_OK) return -1;
-
-
Q_Free((void *)pFile);
-
-
return 0;
-
}
-
-
FS_size_t FS_FWrite(const void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile)
-
{
-
UINT i;
-
_FS_PTR * fp = (_FS_PTR *)pFile;
-
-
if (!pFile) return 0; /* No pointer to a FS_FILE structure */
-
-
fp->error = f_write(&fp->fs.file,pData,Size*N,&i);
-
-
if(fp->error!=FR_OK) return 0;
-
-
return i;
-
}
-
-
FS_size_t FS_FRead(void *pData, FS_size_t Size, FS_size_t N, FS_FILE *pFile)
-
{
-
UINT i=0;
-
_FS_PTR * fp = (_FS_PTR *)pFile;
-
-
if (!pFile) return 0; /* No pointer to a FS_FILE structure */
-
-
fp->error = f_read(&fp->fs.file,pData,Size*N,&i);
-
-
if(fp->error!=FR_OK) return 0;
-
-
return i;
-
}
-
-
FS_i32 FS_FSeek(FS_FILE *pFile, FS_i32 Offset, FS_i32 Whence)
-
{
-
FS_i32 value;
-
_FS_PTR * fp = (_FS_PTR *)pFile;
-
-
if (!pFile) return -1;
-
-
if(FS_SEEK_SET==Whence) value = 0;
-
else if(FS_SEEK_CUR==Whence) value = fp->fs.file.fptr;
-
else if(FS_SEEK_END==Whence) value = fp->fs.file.fsize;
-
else return -1;
-
-
fp->error = f_lseek(&fp->fs.file,value+Offset);
-
-
if(fp->error!=FR_OK) return -1;
-
-
return 0;
-
}
-
-
-
FS_i32 FS_FTell(FS_FILE *pFile)
-
{
-
_FS_PTR * fp = (_FS_PTR *)pFile;
-
-
if (!pFile) return -1;
-
-
return fp->fs.file.fptr;
-
}
-
-
FS_DIR *FS_OpenDir( const TCHAR *dirname )
-
{
-
_FS_PTR * dir;
-
-
dir = (_FS_PTR *)Q_Mallco(sizeof(_FS_PTR));
-
memset((void*)dir,0,sizeof(_FS_PTR));
-
-
dir->error= f_opendir(&dir->fs.dir,dirname);
-
-
if(dir->error!=FR_OK)
-
{
-
Q_Free((void *)dir );
-
dir= 0;
-
}
-
-
return (FS_DIR *)dir;
-
}
-
-
-
#if _MAX_LFN > (NAME_MAX/2)
-
#error " _MAX_LFN must less than NAME_MAX/2"
-
#endif
-
-
struct dirent * FS_ReadDir( FS_DIR *dirp)
-
{
-
_FS_PTR * dir = (_FS_PTR *) dirp;
-
-
FILINFO FileInfo;
-
static struct dirent ent;
-
char *fn;
-
#if _USE_LFN
-
FileInfo.lfname = (TCHAR*)LenFileName;
-
FileInfo.lfsize = sizeof(LenFileName);
-
#endif
-
-
ent.d_name[0]=0;
-
-
if (dirp == 0) {
-
return 0; /* Device not found */
-
}
-
-
dir->error = f_readdir (
-
&dir->fs.dir, /* Pointer to the open directory object */
-
&FileInfo /* Pointer to the file information structure */
-
);
-
-
if(dir->error!=FR_OK)
-
{
-
ent.d_name[0]=0;
-
ent.st_mode=0;
-
ent.id = 0;
-
ent.st_ctime = 0;
-
-
return 0;
-
}
-
-
#if _USE_LFN
-
fn = (char *)FileInfo.lfname;
-
#else
-
fn = (char *)FileInfo.fname;
-
#endif
-
-
if(FileInfo.fname[0] == 0) //end
-
ent.d_name[0]=0;
-
else
-
strcpy(ent.d_name,fn);
-
-
ent.st_mode = (FileInfo.fattrib & AM_DIR)?_IFDIR:0;
-
ent.id = FileInfo.fsize;
-
ent.st_ctime = FileInfo.ftime|(FileInfo.fdate<<16);
-
-
return &ent;
-
}
-
-
struct dirent * FS_ReadDir_IDX( FS_DIR *dirp,unsigned short idx)
-
{
-
_FS_PTR * dir = (_FS_PTR *) dirp;
-
-
FILINFO FileInfo;
-
static struct dirent ent;
-
char *fn;
-
#if _USE_LFN
-
FileInfo.lfname = (TCHAR*)LenFileName;
-
FileInfo.lfsize = sizeof(LenFileName);
-
#endif
-
-
ent.d_name[0]=0;
-
-
if (dirp == 0) {
-
return 0; /* Device not found */
-
}
-
-
dir->error = f_readdir (
-
&dir->fs.dir, /* Pointer to the open directory object */
-
0 /* Pointer to the file information structure */
-
);
-
-
for(;idx;idx--)
-
f_readdir_noinfo(&dir->fs.dir,&FileInfo);
-
-
dir->error = f_readdir (
-
&dir->fs.dir, /* Pointer to the open directory object */
-
&FileInfo /* Pointer to the file information structure */
-
);
-
-
if(dir->error!=FR_OK)
-
{
-
ent.d_name[0]=0;
-
ent.st_mode=0;
-
ent.id = 0;
-
ent.st_ctime = 0;
-
-
return 0;
-
}
-
-
#if _USE_LFN
-
fn = (char *)FileInfo.lfname;
-
#else
-
fn = (char *)FileInfo.fname;
-
#endif
-
-
if(FileInfo.fname[0] == 0) //end
-
ent.d_name[0]=0;
-
else
-
strcpy(ent.d_name,fn);
-
-
ent.st_mode = (FileInfo.fattrib & AM_DIR)?_IFDIR:0;
-
ent.id = FileInfo.fsize;
-
ent.st_ctime = FileInfo.ftime|(FileInfo.fdate<<16);
-
-
return &ent;
-
}
-
-
void FS_RewindDir(FS_DIR *dirp)
-
{
-
_FS_PTR * dir = (_FS_PTR *) dirp;
-
-
if (!dirp) return;
-
-
dir->fs.dir.index = 0;
-
}
-
-
FS_i32 FS_CloseDir( FS_DIR *dirp )
-
{
-
if(dirp == 0) return -1;
-
-
Q_Free((void *)dirp);
-
-
return 0;
-
}
-
-
FS_i32 FS_Unlink(const TCHAR *Path)
-
{
-
if(f_unlink(Path)!=FR_OK) return -1;
-
-
return 0;
-
}
-
-
FS_i32 FS_GetFileSize(FS_FILE *pFile)
-
{
-
_FS_PTR * fp = (_FS_PTR *)pFile;
-
-
return fp->fs.file.fsize;
-
}
-
-
FS_i32 FS_Stat(const TCHAR *path,struct stat *buf)
-
{
-
FRESULT res;
-
FILINFO stat;
-
#if _USE_LFN
-
stat.lfname = (TCHAR*)LenFileName;
-
stat.lfsize = sizeof(LenFileName);
-
#endif
-
-
res=f_stat(path,&stat);
-
-
if(res!=FR_OK)
-
{
-
buf->st_size = 0;
-
buf->st_mode = 0;
-
buf->st_mtime = 0;
-
return -1;
-
}
-
-
buf->st_size = stat.fsize;
-
buf->st_mode = (stat.fattrib & AM_DIR)?_IFDIR:0;
-
buf->st_mtime = stat.ftime|(stat.fdate<<16);
-
-
return 0;
-
}
-
-
FS_i32 FS_Rename(const TCHAR *OldName,const TCHAR *NewName)
-
{
-
FRESULT res ;
-
-
res =f_rename (OldName,NewName);
-
-
if(res!=FR_OK) return -1;
-
-
return 0;
-
}
-
-
#define COPY_FILE_BUFFER 512
-
FS_i32 FS_FileCpy(const TCHAR*path1, const TCHAR*path2) //path1: souce file path2: destination file
-
{
-
FS_FILE *src;
-
FS_FILE * dst;
-
FS_i32 read_size,write_size;
-
FS_i32 src_size, dst_size;
-
struct stat buf;
-
_DISK_INFO info;
-
FS_i8 *buffer;
-
-
if( !strcmp((const char *)path1, (const char *)path2) )
-
{
-
DEBUGP("ERROR:can not copy a file to itselfrn");
-
return 0;
-
}
-
-
if( -1 == FS_Stat( path1, &buf ) ) return 0;
-
-
src_size = buf.st_size;
-
-
if(GetDiskInfo(path2,&info)==-1)
-
{
-
DEBUGP("ERROR:getdiskinfo errrn");
-
return 0;
-
}
-
-
if(src_size > info.free_size)
-
{
-
DEBUGP("there is no enough space on the flash!nr");
-
return 0;
-
}
-
-
src = FS_FOpen(path1, FA_READ|FA_OPEN_EXISTING);
-
if(0 == src)
-
{
-
DEBUGP("ERROR:cannot open the source filern");
-
return 0;
-
}
-
-
dst = FS_FOpen(path2, FA_CREATE_ALWAYS|FA_WRITE);
-
if(0 == dst)
-
{
-
DEBUGP("ERROR:cannot create the distance filern");
-
FS_FClose(src);
-
return 0;
-
}
-
-
buffer=Q_Mallco(COPY_FILE_BUFFER);
-
-
do{
-
read_size = FS_FRead(buffer, COPY_FILE_BUFFER,1,src);
-
write_size = FS_FWrite(buffer, read_size,1,dst);
-
-
if(write_size < read_size)
-
{
-
DEBUGP("ERROR:file write errorrn");
-
Q_Free(buffer);
-
goto CP_FILE_ERROR;
-
}
-
}while(read_size == COPY_FILE_BUFFER);
-
-
Q_Free(buffer);
-
FS_FClose(src);
-
FS_FClose(dst);
-
-
if( -1 == FS_Stat( path2, &buf ) ) return 0;
-
-
dst_size = buf.st_size;
-
-
if(dst_size < src_size)
-
{
-
DEBUGP("there is an unkown flash operation during the copyfile!nr");
-
FS_Unlink(path2);
-
return 0;
-
}
-
-
return 1;
-
-
CP_FILE_ERROR:
-
FS_FClose(src);
-
FS_FClose(dst);
-
return 0;
-
}
-
-
FS_i32 GetDiskInfo(const TCHAR* Path,_DISK_INFO* info)
-
{
-
FATFS *fs;
-
DWORD fre_clust, tot_sect,fre_sect;
-
FRESULT res;
-
-
/* Get volume information and free clusters of drive 1 */
-
res = f_getfree(Path, &fre_clust, &fs);
-
if (res)
-
{
-
info->total_size = 0;
-
info->free_size = 0;
-
return -1;
-
}
-
/* Get total sectors and free sectors */
-
tot_sect = (fs->n_fatent - 2) * fs->csize;
-
fre_sect = fre_clust * fs->csize;
-
-
info->total_size = tot_sect *512;
-
info->free_size = fre_sect *512;
-
-
return 0;
-
}
2. 应用例程如下
-
u8 readfile(char *filename)
-
{
-
#if HAVE_FSWRAP
-
FS_FILE *fp;
-
-
#else
-
FATFS fs; // Work area (file system object) for logical drive
-
FIL fsrc, fdst; // file objects
-
FRESULT res; // FatFs function common result code
-
UINT br, bw; // File R/W count
-
#endif
-
-
u8 bytelen = 38, readlen, ty;
-
u8 buffer[50];
-
static u16 ustimes = 1;
-
-
memset(buffer, 0x00, sizeof(buffer));
-
-
#if HAVE_FSWRAP
-
fs_init();
-
-
fp = fs_fopen(filename, FA_OPEN_EXISTING | FA_READ);
-
if (fp == 0) {
-
display_status((char *)buffer);
-
fs_exit();
-
return(-1);
-
}
-
else {
-
DEBUGP("fopen OKrn!");
-
readlen = fs_fread(buffer, sizeof(char), bytelen, fp);
-
if (readlen != bytelen) {
-
display_status((char *)buffer);
-
fs_exit();
-
return(-2);
-
}
-
fs_fclose(fp);
-
}
-
fs_exit();
-
-
#else
-
f_mount(0, &fs);
-
-
res = f_open(&fsrc, filename, FA_OPEN_EXISTING | FA_READ);
-
if (res != FR_OK) {
-
sprintf((char *)buffer, "f_open Error: %d", res);
-
display_status((char *)buffer);
-
-
f_mount(0, NULL);
-
return(res);
-
}
-
-
f_lseek(&fsrc, 0);
-
res = f_read(&fsrc, buffer, bytelen, &br);
-
//if (res != FR_OK) {
-
if (br != bytelen) {
-
sprintf((char *)buffer, "f_read Error: %d", res);
-
display_status((char *)buffer);
-
-
f_mount(0, NULL);
-
return(res);
-
}
-
//ty = fsrc.fsize;
-
//f_lseek(&fsrc, ty);
-
//res = f_write(&fsrc, buffer, ByteLen, &bw);
-
-
f_close(&fsrc);
-
f_mount(0, NULL);
-
#endif
-
-
return SD_OK;
-
}
3. 移植参考
ff.c: 主要为底层协议, 配置文件为 ffconf.h,
diskio.c: 数据读取的驱动代码, 中间层, 为ff.c 服务. 至少完成disk_read和disk_write
sdcard.c: 底层的硬件驱动
每次读写时都调用 f_mount 可以支持热插拔. 带目录如: theme/f/common/btn/backp.bmp
//--- FatFs module application interface,
FRESULT f_mount (BYTE, FATFS*); //加载文件系统,BYTE参数是ID,后一个是文件系统定义。
FRESULT f_open (FIL*, const XCHAR*, BYTE); //打开文件,第一个参数是文件信息结构,第二个参数是文件名,第三是文件打开模式
FRESULT f_read (FIL*, void*, UINT, UINT*); //文件读取函数,参数1为文件对象(文件打开函数中得到),参数2为文件读取缓冲区,参数3为读取的字节数,参数4意义不清晰,等读到源代码就清楚了。
FRESULT f_write (FIL*, const void*, UINT, UINT*);//写文件,参数跟读差不多
FRESULT f_lseek (FIL*, DWORD); //移动文件的读写指针,参数2应该是移动的数目。
FRESULT f_close (FIL*); /* Close an open file object */
FRESULT f_opendir (DIR*, const XCHAR*); //打开目录,返回目录对象
FRESULT f_readdir (DIR*, FILINFO*); //读取目录,获得文件信息
FRESULT f_stat (const XCHAR*, FILINFO*); /* Get file status */
FRESULT f_getfree (const XCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
FRESULT f_truncate (FIL*); /* Truncate file */
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */将缓冲区数据写回文件
FRESULT f_unlink (const XCHAR*); //删除目录中的一个文件
FRESULT f_mkdir (const XCHAR*); /* Create a new directory */
FRESULT f_chmod (const XCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
FRESULT f_utime (const XCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
FRESULT f_rename (const XCHAR*, const XCHAR*); /* Rename/Move a file or directory */
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */ 这个函数还要提供一个回调函数。
FRESULT f_mkfs (BYTE, BYTE, WORD); /* Create a file system on the drive */
FRESULT f_chdir (const XCHAR*); /* Change current directory */改变当前目录
FRESULT f_chdrive (BYTE); /* Change current drive */
阅读(3317) | 评论(0) | 转发(0) |