fs: add fat filesystem support
This code is based on: http://elm-chan.org/fsw/ff/00index_e.html FatFs Generic FAT File System Module This patch offers a read/write implementation for barebox. The code does not exaclty match barebox coding style, but works nicely and should be ready to give it a try. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
9faae796be
commit
17e91068b1
|
@ -16,6 +16,8 @@ config FS_DEVFS
|
|||
default y
|
||||
prompt "devfs support"
|
||||
|
||||
source fs/fat/Kconfig
|
||||
|
||||
config PARTITION_NEED_MTD
|
||||
bool
|
||||
|
||||
|
|
|
@ -2,4 +2,5 @@ obj-$(CONFIG_FS_CRAMFS) += cramfs/
|
|||
obj-$(CONFIG_FS_RAMFS) += ramfs.o
|
||||
obj-y += devfs-core.o
|
||||
obj-$(CONFIG_FS_DEVFS) += devfs.o
|
||||
obj-$(CONFIG_FS_FAT) += fat/
|
||||
obj-y += fs.o
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
menuconfig FS_FAT
|
||||
bool
|
||||
prompt "FAT filesystem support"
|
||||
|
||||
if FS_FAT
|
||||
|
||||
config FS_FAT_WRITE
|
||||
bool
|
||||
prompt "FAT write support"
|
||||
|
||||
config FS_FAT_LFN
|
||||
bool
|
||||
prompt "Support long filenames"
|
||||
|
||||
endif
|
|
@ -0,0 +1 @@
|
|||
obj-y += ff.o fat.o
|
|
@ -0,0 +1,78 @@
|
|||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _DISKIO
|
||||
|
||||
#define _READONLY 0 /* 1: Remove write functions */
|
||||
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
int assign_drives (int, int);
|
||||
DSTATUS disk_initialize (FATFS *fatfs);
|
||||
DSTATUS disk_status (FATFS *fatfs);
|
||||
DRESULT disk_read (FATFS *fatfs, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (FATFS *fatfs, const BYTE*, DWORD, BYTE);
|
||||
#endif
|
||||
DRESULT disk_ioctl (FATFS *fatfs, BYTE, void*);
|
||||
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic command (defined for FatFs) */
|
||||
#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) */
|
||||
|
||||
/* Generic command */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
/* NAND specific ioctl command */
|
||||
#define NAND_FORMAT 30 /* Create physical format */
|
||||
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
|
@ -0,0 +1,434 @@
|
|||
/*
|
||||
* ramfs.c - a malloc based filesystem
|
||||
*
|
||||
* Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <driver.h>
|
||||
#include <init.h>
|
||||
#include <malloc.h>
|
||||
#include <fs.h>
|
||||
#include <command.h>
|
||||
#include <errno.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <xfuncs.h>
|
||||
#include <fcntl.h>
|
||||
#include "ff.h"
|
||||
#include "integer.h"
|
||||
#include "diskio.h"
|
||||
|
||||
struct fat_priv {
|
||||
struct cdev *cdev;
|
||||
FATFS fat;
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------*/
|
||||
|
||||
DRESULT disk_read(FATFS *fat, BYTE *buf, DWORD sector, BYTE count)
|
||||
{
|
||||
struct fat_priv *priv = fat->userdata;
|
||||
int ret;
|
||||
|
||||
debug("%s: sector: %ld count: %d\n", __func__, sector, count);
|
||||
|
||||
ret = cdev_read(priv->cdev, buf, count << 9, sector * 512, 0);
|
||||
if (ret != count << 9)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DRESULT disk_write(FATFS *fat, const BYTE *buf, DWORD sector, BYTE count)
|
||||
{
|
||||
struct fat_priv *priv = fat->userdata;
|
||||
int ret;
|
||||
|
||||
debug("%s: buf: %p sector: %ld count: %d\n",
|
||||
__func__, buf, sector, count);
|
||||
|
||||
ret = cdev_write(priv->cdev, buf, count << 9, sector * 512, 0);
|
||||
if (ret != count << 9)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DSTATUS disk_status(FATFS *fat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD get_fattime(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DRESULT disk_ioctl (FATFS *fat, BYTE command, void *buf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
WCHAR ff_convert(WCHAR src, UINT dir)
|
||||
{
|
||||
if (src <= 0x80)
|
||||
return src;
|
||||
else
|
||||
return '?';
|
||||
}
|
||||
|
||||
WCHAR ff_wtoupper(WCHAR chr)
|
||||
{
|
||||
if (chr <= 0x80)
|
||||
return toupper(chr);
|
||||
else
|
||||
return '?';
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------*/
|
||||
|
||||
#ifdef CONFIG_FS_FAT_WRITE
|
||||
static int fat_create(struct device_d *dev, const char *pathname, mode_t mode)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
FIL f_file;
|
||||
int ret;
|
||||
|
||||
ret = f_open(&priv->fat, &f_file, pathname, FA_OPEN_ALWAYS);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
f_close(&f_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_unlink(struct device_d *dev, const char *pathname)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
int ret;
|
||||
|
||||
ret = f_unlink(&priv->fat, pathname);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cdev_flush(priv->cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_mkdir(struct device_d *dev, const char *pathname)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
int ret;
|
||||
|
||||
ret = f_mkdir(&priv->fat, pathname);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cdev_flush(priv->cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_rmdir(struct device_d *dev, const char *pathname)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
int ret;
|
||||
|
||||
ret = f_unlink(&priv->fat, pathname);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cdev_flush(priv->cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_write(struct device_d *_dev, FILE *f, const void *buf, size_t insize)
|
||||
{
|
||||
FIL *f_file = f->inode;
|
||||
int outsize;
|
||||
int ret;
|
||||
|
||||
ret = f_write(f_file, buf, insize, &outsize);
|
||||
|
||||
debug("%s: %d %d %d %p\n", __func__, ret, insize, outsize, f_file);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!outsize)
|
||||
return -ENOSPC;
|
||||
|
||||
return outsize;
|
||||
}
|
||||
|
||||
static int fat_truncate(struct device_d *dev, FILE *f, ulong size)
|
||||
{
|
||||
FIL *f_file = f->inode;
|
||||
unsigned long lastofs;
|
||||
int ret;
|
||||
|
||||
lastofs = f_file->fptr;
|
||||
|
||||
ret = f_lseek(f_file, size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = f_truncate(f_file);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = f_lseek(f_file, lastofs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_FS_FAT_WRITE */
|
||||
|
||||
static int fat_open(struct device_d *dev, FILE *file, const char *filename)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
FIL *f_file;
|
||||
int ret;
|
||||
unsigned long flags = 0;
|
||||
|
||||
f_file = xzalloc(sizeof(*f_file));
|
||||
|
||||
switch (file->flags & O_ACCMODE) {
|
||||
case O_RDONLY:
|
||||
flags = FA_READ;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
flags = FA_WRITE;
|
||||
break;
|
||||
case O_RDWR:
|
||||
flags = FA_READ | FA_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = f_open(&priv->fat, f_file, filename, flags);
|
||||
if (ret) {
|
||||
free(f_file);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (file->flags & O_APPEND) {
|
||||
ret = f_lseek(f_file, f_file->fsize);
|
||||
}
|
||||
|
||||
file->inode = f_file;
|
||||
file->size = f_file->fsize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_close(struct device_d *dev, FILE *f)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
FIL *f_file = f->inode;
|
||||
|
||||
f_close(f_file);
|
||||
|
||||
free(f_file);
|
||||
|
||||
cdev_flush(priv->cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
|
||||
{
|
||||
int ret;
|
||||
FIL *f_file = f->inode;
|
||||
int outsize;
|
||||
|
||||
ret = f_read(f_file, buf, insize, &outsize);
|
||||
|
||||
debug("%s: %d %d %d %p\n", __func__, ret, insize, outsize, f_file);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return outsize;
|
||||
}
|
||||
|
||||
static off_t fat_lseek(struct device_d *dev, FILE *f, off_t pos)
|
||||
{
|
||||
FIL *f_file = f->inode;
|
||||
int ret;
|
||||
|
||||
ret = f_lseek(f_file, pos);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static DIR* fat_opendir(struct device_d *dev, const char *pathname)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
DIR *dir;
|
||||
FF_DIR *ff_dir;
|
||||
int ret;
|
||||
|
||||
debug("%s: %s\n", __func__, pathname);
|
||||
|
||||
ff_dir = xzalloc(sizeof(*ff_dir));
|
||||
if (pathname)
|
||||
ret = f_opendir(&priv->fat, ff_dir, pathname);
|
||||
else
|
||||
ret = f_opendir(&priv->fat, ff_dir, "/");
|
||||
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
dir = xzalloc(sizeof(*dir));
|
||||
|
||||
dir->priv = ff_dir;
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
static struct dirent* fat_readdir(struct device_d *dev, DIR *dir)
|
||||
{
|
||||
FF_DIR *ff_dir = dir->priv;
|
||||
FILINFO finfo;
|
||||
int ret;
|
||||
#ifdef CONFIG_FS_FAT_LFN
|
||||
char name[PATH_MAX];
|
||||
#endif
|
||||
memset(&finfo, 0, sizeof(finfo));
|
||||
#ifdef CONFIG_FS_FAT_LFN
|
||||
finfo.lfname = name;
|
||||
finfo.lfsize = PATH_MAX;
|
||||
#endif
|
||||
ret = f_readdir(ff_dir, &finfo);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
if (finfo.fname[0] == '\0')
|
||||
return NULL;
|
||||
|
||||
#ifdef CONFIG_FS_FAT_LFN
|
||||
if (*finfo.lfname)
|
||||
strcpy(dir->d.d_name, finfo.lfname);
|
||||
else
|
||||
#endif
|
||||
strcpy(dir->d.d_name, finfo.fname);
|
||||
|
||||
return &dir->d;
|
||||
}
|
||||
|
||||
static int fat_closedir(struct device_d *dev, DIR *dir)
|
||||
{
|
||||
FF_DIR *ff_dir = dir->priv;
|
||||
|
||||
free(ff_dir);
|
||||
free(dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_stat(struct device_d *dev, const char *filename, struct stat *s)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
FILINFO finfo;
|
||||
int ret;
|
||||
|
||||
ret = f_stat(&priv->fat, filename, &finfo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
s->st_size = finfo.fsize;
|
||||
s->st_mode = S_IRWXU | S_IRWXG | S_IRWXO;
|
||||
|
||||
if (finfo.fattrib & AM_DIR)
|
||||
s->st_mode |= S_IFDIR;
|
||||
else
|
||||
s->st_mode |= S_IFREG;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fat_probe(struct device_d *dev)
|
||||
{
|
||||
struct fs_device_d *fsdev = dev->type_data;
|
||||
struct fat_priv *priv = xzalloc(sizeof(struct fat_priv));
|
||||
char *backingstore = fsdev->backingstore;
|
||||
|
||||
dev->priv = priv;
|
||||
|
||||
if (!strncmp(backingstore , "/dev/", 5))
|
||||
backingstore += 5;
|
||||
|
||||
priv->cdev = cdev_open(backingstore, O_RDWR);
|
||||
if (!priv->cdev)
|
||||
return -EINVAL;
|
||||
|
||||
priv->fat.userdata = priv;
|
||||
f_mount(&priv->fat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fat_remove(struct device_d *dev)
|
||||
{
|
||||
struct fat_priv *priv = dev->priv;
|
||||
|
||||
cdev_close(priv->cdev);
|
||||
|
||||
free(dev->priv);
|
||||
}
|
||||
|
||||
static struct fs_driver_d fat_driver = {
|
||||
.open = fat_open,
|
||||
.close = fat_close,
|
||||
.read = fat_read,
|
||||
.lseek = fat_lseek,
|
||||
.opendir = fat_opendir,
|
||||
.readdir = fat_readdir,
|
||||
.closedir = fat_closedir,
|
||||
.stat = fat_stat,
|
||||
#ifdef CONFIG_FS_FAT_WRITE
|
||||
.create = fat_create,
|
||||
.unlink = fat_unlink,
|
||||
.mkdir = fat_mkdir,
|
||||
.rmdir = fat_rmdir,
|
||||
.write = fat_write,
|
||||
.truncate = fat_truncate,
|
||||
#endif
|
||||
.flags = 0,
|
||||
.drv = {
|
||||
.probe = fat_probe,
|
||||
.remove = fat_remove,
|
||||
.name = "fat",
|
||||
.type_data = &fat_driver,
|
||||
}
|
||||
};
|
||||
|
||||
static int fat_init(void)
|
||||
{
|
||||
return register_fs_driver(&fat_driver);
|
||||
}
|
||||
|
||||
coredevice_initcall(fat_init);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,239 @@
|
|||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.08b (C)ChaN, 2011
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2011, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 8237 /* Revision ID */
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#ifndef CONFIG_FS_FAT_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1,2) */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
WORD ssize; /* Bytes per sector (512,1024,2048,4096) */
|
||||
#endif
|
||||
#ifdef CONFIG_FS_FAT_WRITE
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector (FAT32) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
|
||||
void *userdata; /* User data, ff core does not touch this */
|
||||
struct list_head dirtylist;
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE pad1;
|
||||
DWORD fptr; /* File read/write pointer (0 on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File start cluster (0 when fsize==0) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#ifdef CONFIG_FS_FAT_WRITE
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
|
||||
#endif
|
||||
#if _FS_SHARE
|
||||
UINT lockid; /* File lock ID (index of file semaphore table) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File data read/write buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#ifdef CONFIG_FS_FAT_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} FF_DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
#ifdef CONFIG_FS_FAT_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
int f_mount (FATFS*); /* Mount/Unmount a logical drive */
|
||||
int f_open (FATFS*, FIL*, const TCHAR*, BYTE); /* Open or create a file */
|
||||
int f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
int f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
int f_close (FIL*); /* Close an open file object */
|
||||
int f_opendir (FATFS*, FF_DIR*, const TCHAR*); /* Open an existing directory */
|
||||
int f_readdir (FF_DIR*, FILINFO*); /* Read a directory item */
|
||||
int f_stat (FATFS*, const TCHAR*, FILINFO*); /* Get file status */
|
||||
int f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
int f_getfree (FATFS*, const TCHAR*, DWORD*); /* Get number of free clusters on the drive */
|
||||
int f_truncate (FIL*); /* Truncate file */
|
||||
int f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
int f_unlink (FATFS*, const TCHAR*); /* Delete an existing file or directory */
|
||||
int f_mkdir (FATFS*, const TCHAR*); /* Create a new directory */
|
||||
int f_chmod (FATFS*, const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
int f_utime (FATFS*, const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
int f_rename (FATFS*, const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
|
||||
int f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
int f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
int f_chdrive (BYTE); /* Change current drive */
|
||||
int f_chdir (const TCHAR*); /* Change current directory */
|
||||
int f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
int f_putc (TCHAR, FIL*); /* Put a character to the file */
|
||||
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
DWORD get_fattime (void);
|
||||
|
||||
/* Unicode support functions */
|
||||
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek function */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#define LD_WORD(ptr) get_unaligned_le16(ptr)
|
||||
#define LD_DWORD(ptr) get_unaligned_le32(ptr)
|
||||
#define ST_WORD(ptr,val) put_unaligned_le16(val, ptr)
|
||||
#define ST_DWORD(ptr,val) put_unaligned_le32(val, ptr)
|
||||
|
||||
#endif /* _FATFS */
|
|
@ -0,0 +1,145 @@
|
|||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.08b (C)ChaN, 2011
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 8237 /* Revision ID */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
|
||||
#define _USE_STRFUNC 0 /* 0:Disable or 1/2:Enable */
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 0 /* 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. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||
*/
|
||||
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
|
||||
#define ff_memalloc xzalloc
|
||||
#define ff_memfree free
|
||||
/* 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.
|
||||
/
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||
/ to the project. When enable to use heap, memory control functions
|
||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* To switch the character code set on FatFs API to Unicode,
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Physical Drive Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for on-board flash memory, floppy disk and optical disk.
|
||||
/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size
|
||||
/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
|
||||
|
||||
#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 */
|
||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
||||
/ option defines which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code size. */
|
||||
|
||||
|
||||
/* A header file that defines sync object types on the O/S, such as
|
||||
/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
|
||||
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#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 /* _FFCONFIG */
|
|
@ -0,0 +1,28 @@
|
|||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
#define _INTEGER
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue