提交 b3cf2785 编写于 作者: P prife

1) elm fatfs can do mkfs without mounting first, 2) use new mkfs 3)change...

1) elm fatfs can do mkfs without mounting first, 2) use new mkfs 3)change linebreak in dfs_uffs.c to unix
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* 2012-07-26 aozima implement ff_memalloc and ff_memfree. * 2012-07-26 aozima implement ff_memalloc and ff_memfree.
* 2012-12-19 Bernard fixed the O_APPEND and lseek issue. * 2012-12-19 Bernard fixed the O_APPEND and lseek issue.
*/ */
#include <rtthread.h> #include <rtthread.h>
#include "ffconf.h" #include "ffconf.h"
#include "ff.h" #include "ff.h"
...@@ -30,667 +30,711 @@ static rt_device_t disk[_VOLUMES] = {0}; ...@@ -30,667 +30,711 @@ static rt_device_t disk[_VOLUMES] = {0};
static int elm_result_to_dfs(FRESULT result) static int elm_result_to_dfs(FRESULT result)
{ {
int status = DFS_STATUS_OK; int status = DFS_STATUS_OK;
switch (result) switch (result)
{ {
case FR_OK: case FR_OK:
break; break;
case FR_NO_FILE: case FR_NO_FILE:
case FR_NO_PATH: case FR_NO_PATH:
case FR_NO_FILESYSTEM: case FR_NO_FILESYSTEM:
status = -DFS_STATUS_ENOENT; status = -DFS_STATUS_ENOENT;
break; break;
case FR_INVALID_NAME: case FR_INVALID_NAME:
status = -DFS_STATUS_EINVAL; status = -DFS_STATUS_EINVAL;
break; break;
case FR_EXIST: case FR_EXIST:
case FR_INVALID_OBJECT: case FR_INVALID_OBJECT:
status = -DFS_STATUS_EEXIST; status = -DFS_STATUS_EEXIST;
break; break;
case FR_DISK_ERR: case FR_DISK_ERR:
case FR_NOT_READY: case FR_NOT_READY:
case FR_INT_ERR: case FR_INT_ERR:
status = -DFS_STATUS_EIO; status = -DFS_STATUS_EIO;
break; break;
case FR_WRITE_PROTECTED: case FR_WRITE_PROTECTED:
case FR_DENIED: case FR_DENIED:
status = -DFS_STATUS_EROFS; status = -DFS_STATUS_EROFS;
break; break;
case FR_MKFS_ABORTED: case FR_MKFS_ABORTED:
status = -DFS_STATUS_EINVAL; status = -DFS_STATUS_EINVAL;
break; break;
default: default:
status = -1; status = -1;
break; break;
} }
return status; return status;
}
/* results:
* -1, no space to install fatfs driver
* >= 0, there is an space to install fatfs driver
*/
static int get_disk(rt_device_t id)
{
int index;
for (index = 0; index < _VOLUMES; index ++)
{
if (disk[index] == id)
return index;
}
return -1;
} }
int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
{ {
FATFS *fat; FATFS *fat;
FRESULT result; FRESULT result;
BYTE index; int index;
/* handle RT-Thread device routine */ /* get an empty position */
for (index = 0; index < _VOLUMES; index ++) index = get_disk(RT_NULL);
{ if (index == -1)
if (disk[index] == RT_NULL) return -DFS_STATUS_ENOSPC;
{
break; /* save device */
} disk[index] = fs->dev_id;
}
if (index == _VOLUMES) fat = (FATFS *)rt_malloc(sizeof(FATFS));
return -DFS_STATUS_ENOSPC; if (fat == RT_NULL)
{
/* get device */ disk[index] = RT_NULL;
disk[index] = fs->dev_id; return -1;
}
fat = (FATFS *)rt_malloc(sizeof(FATFS));
if (fat == RT_NULL) /* mount fatfs, always 0 logic driver */
{ result = f_mount((BYTE)index, fat);
return -1; if (result == FR_OK)
} {
char drive[8];
/* mount fatfs, always 0 logic driver */ DIR *dir;
result = f_mount(index, fat);
if (result == FR_OK) rt_snprintf(drive, sizeof(drive), "%d:/", index);
{ dir = (DIR *)rt_malloc(sizeof(DIR));
char drive[8]; if (dir == RT_NULL)
DIR * dir; return -DFS_STATUS_ENOMEM;
rt_snprintf(drive, sizeof(drive), "%d:/", index); /* open the root directory to test whether the fatfs is valid */
dir = (DIR *)rt_malloc(sizeof(DIR)); result = f_opendir(dir, drive);
if (dir == RT_NULL) if (result != FR_OK)
return -DFS_STATUS_ENOMEM; goto __err;
/* open the root directory to test whether the fatfs is valid */ /* mount succeed! */
result = f_opendir(dir, drive); fs->data = fat;
if (result != FR_OK) rt_free(dir);
{ return 0;
rt_free(dir); }
return elm_result_to_dfs(result);
} __err:
rt_free(dir); disk[index] = RT_NULL;
rt_free(fat);
fs->data = fat; return elm_result_to_dfs(result);
}
else
{
rt_free(fat);
return elm_result_to_dfs(result);
}
return 0;
} }
int dfs_elm_unmount(struct dfs_filesystem *fs) int dfs_elm_unmount(struct dfs_filesystem *fs)
{ {
FATFS *fat; FATFS *fat;
FRESULT result; FRESULT result;
BYTE index; int index;
fat = (FATFS *)fs->data; fat = (FATFS *)fs->data;
RT_ASSERT(fat != RT_NULL); RT_ASSERT(fat != RT_NULL);
/* find the device index and then umount it */ /* find the device index and then umount it */
for (index = 0; index < _VOLUMES; index ++) index = get_disk(fs->dev_id);
{ if (index == -1) /* not found */
if (disk[index] == fs->dev_id) return -DFS_STATUS_ENOENT;
{
result = f_mount(index, RT_NULL); result = f_mount((BYTE)index, RT_NULL);
if (result != FR_OK)
if (result == FR_OK) return elm_result_to_dfs(result);
{
fs->data = RT_NULL; fs->data = RT_NULL;
disk[index] = RT_NULL; disk[index] = RT_NULL;
rt_free(fat); rt_free(fat);
return DFS_STATUS_OK;
} return DFS_STATUS_OK;
}
}
return -DFS_STATUS_ENOENT;
} }
int dfs_elm_mkfs(const char *device_name) int dfs_elm_mkfs(rt_device_t dev_id)
{ {
BYTE drv; #define FSM_STATUS_INIT 0
rt_device_t dev; #define FSM_STATUS_USE_TEMP_DRIVER 1
FRESULT result; FATFS *fat;
int flag;
/* find device name */ FRESULT result;
for (drv = 0; drv < _VOLUMES; drv ++) int index;
{
dev = disk[drv]; if (dev_id == RT_NULL)
if (dev != RT_NULL && rt_strncmp(dev->parent.name, device_name, RT_NAME_MAX) == 0) return -DFS_STATUS_EINVAL;
{
/* 1: no partition table */ /* if the device is already mounted, then just do mkfs to the drv,
/* 0: auto selection of cluster size */ * while if it is not mounted yet, then find an empty drive to do mkfs
result = f_mkfs(drv, 1, 0); */
if (result != FR_OK)
{ flag = FSM_STATUS_INIT;
rt_kprintf("format error\n"); index = get_disk(dev_id);
return elm_result_to_dfs(result); if (index == -1)
} {
/* not found the device id */
return DFS_STATUS_OK; index = get_disk(RT_NULL);
} if (index == -1)
} {
/* no space to store an temp driver */
/* can't find device driver */ rt_kprintf("sorry, there is no space to do mkfs! \n");
rt_kprintf("can not find device driver: %s\n", device_name); return -DFS_STATUS_ENOSPC;
return -DFS_STATUS_EIO; }
else
{
fat = rt_malloc(sizeof(FATFS));
if (fat == RT_NULL)
return -DFS_STATUS_ENOMEM;
flag = FSM_STATUS_USE_TEMP_DRIVER;
disk[index] = dev_id;
/* just fill the FatFs[vol] in ff.c, or mkfs will failded!
* consider this condition: you just umount the elm fat,
* then the space in FatFs[index] is released, and now do mkfs
* on the disk, you will get a failure. so we need f_mount here,
* just fill the FatFS[index] in elm fatfs to make mkfs work.
*/
f_mount((BYTE)index, fat);
}
}
/* 1: no partition table */
/* 0: auto selection of cluster size */
result = f_mkfs((BYTE)index, 1, 0);
/* check flag status, we need clear the temp driver stored in disk[] */
if (flag == FSM_STATUS_USE_TEMP_DRIVER)
{
rt_free(fat);
f_mount((BYTE)index, RT_NULL);
disk[index] = RT_NULL;
}
if (result != FR_OK)
{
rt_kprintf("format error\n");
return elm_result_to_dfs(result);
}
return DFS_STATUS_OK;
} }
int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf) int dfs_elm_statfs(struct dfs_filesystem *fs, struct statfs *buf)
{ {
FATFS *f; FATFS *f;
FRESULT res; FRESULT res;
char driver[4]; char driver[4];
DWORD fre_clust, fre_sect, tot_sect; DWORD fre_clust, fre_sect, tot_sect;
RT_ASSERT(fs != RT_NULL); RT_ASSERT(fs != RT_NULL);
RT_ASSERT(buf != RT_NULL); RT_ASSERT(buf != RT_NULL);
f = (FATFS *)fs->data; f = (FATFS *)fs->data;
rt_snprintf(driver, sizeof(driver), "%d:", f->drv); rt_snprintf(driver, sizeof(driver), "%d:", f->drv);
res = f_getfree(driver, &fre_clust, &f); res = f_getfree(driver, &fre_clust, &f);
if (res) if (res)
return elm_result_to_dfs(res); return elm_result_to_dfs(res);
/* Get total sectors and free sectors */ /* Get total sectors and free sectors */
tot_sect = (f->n_fatent - 2) * f->csize; tot_sect = (f->n_fatent - 2) * f->csize;
fre_sect = fre_clust * f->csize; fre_sect = fre_clust * f->csize;
buf->f_bfree = fre_sect; buf->f_bfree = fre_sect;
buf->f_blocks = tot_sect; buf->f_blocks = tot_sect;
#if _MAX_SS != 512 #if _MAX_SS != 512
buf->f_bsize = f->ssize; buf->f_bsize = f->ssize;
#else #else
buf->f_bsize = 512; buf->f_bsize = 512;
#endif #endif
return 0; return 0;
} }
int dfs_elm_open(struct dfs_fd *file) int dfs_elm_open(struct dfs_fd *file)
{ {
FIL *fd; FIL *fd;
BYTE mode; BYTE mode;
FRESULT result; FRESULT result;
char *drivers_fn; char *drivers_fn;
#if (_VOLUMES > 1) #if (_VOLUMES > 1)
int vol; int vol;
extern int elm_get_vol(FATFS *fat); extern int elm_get_vol(FATFS * fat);
/* add path for ELM FatFS driver support */ /* add path for ELM FatFS driver support */
vol = elm_get_vol((FATFS *)file->fs->data); vol = elm_get_vol((FATFS *)file->fs->data);
if (vol < 0) if (vol < 0)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
drivers_fn = rt_malloc(256); drivers_fn = rt_malloc(256);
if (drivers_fn == RT_NULL) if (drivers_fn == RT_NULL)
return -DFS_STATUS_ENOMEM; return -DFS_STATUS_ENOMEM;
rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->path); rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->path);
#else #else
drivers_fn = file->path; drivers_fn = file->path;
#endif #endif
if (file->flags & DFS_O_DIRECTORY) if (file->flags & DFS_O_DIRECTORY)
{ {
DIR *dir; DIR *dir;
if (file->flags & DFS_O_CREAT) if (file->flags & DFS_O_CREAT)
{ {
result = f_mkdir(drivers_fn); result = f_mkdir(drivers_fn);
if (result != FR_OK) if (result != FR_OK)
{ {
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_fn); rt_free(drivers_fn);
#endif #endif
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
} }
/* open directory */ /* open directory */
dir = (DIR *)rt_malloc(sizeof(DIR)); dir = (DIR *)rt_malloc(sizeof(DIR));
if (dir == RT_NULL) if (dir == RT_NULL)
{ {
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_fn); rt_free(drivers_fn);
#endif #endif
return -DFS_STATUS_ENOMEM; return -DFS_STATUS_ENOMEM;
} }
result = f_opendir(dir, drivers_fn); result = f_opendir(dir, drivers_fn);
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_fn); rt_free(drivers_fn);
#endif #endif
if (result != FR_OK) if (result != FR_OK)
{ {
rt_free(dir); rt_free(dir);
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
file->data = dir; file->data = dir;
return DFS_STATUS_OK; return DFS_STATUS_OK;
} }
else else
{ {
mode = FA_READ; mode = FA_READ;
if (file->flags & DFS_O_WRONLY) if (file->flags & DFS_O_WRONLY)
mode |= FA_WRITE; mode |= FA_WRITE;
if ((file->flags & DFS_O_ACCMODE) & DFS_O_RDWR) if ((file->flags & DFS_O_ACCMODE) & DFS_O_RDWR)
mode |= FA_WRITE; mode |= FA_WRITE;
/* Opens the file, if it is existing. If not, a new file is created. */ /* Opens the file, if it is existing. If not, a new file is created. */
if (file->flags & DFS_O_CREAT) if (file->flags & DFS_O_CREAT)
mode |= FA_OPEN_ALWAYS; mode |= FA_OPEN_ALWAYS;
/* Creates a new file. If the file is existing, it is truncated and overwritten. */ /* Creates a new file. If the file is existing, it is truncated and overwritten. */
if (file->flags & DFS_O_TRUNC) if (file->flags & DFS_O_TRUNC)
mode |= FA_CREATE_ALWAYS; mode |= FA_CREATE_ALWAYS;
/* Creates a new file. The function fails if the file is already existing. */ /* Creates a new file. The function fails if the file is already existing. */
if (file->flags & DFS_O_EXCL) if (file->flags & DFS_O_EXCL)
mode |= FA_CREATE_NEW; mode |= FA_CREATE_NEW;
/* allocate a fd */ /* allocate a fd */
fd = (FIL *)rt_malloc(sizeof(FIL)); fd = (FIL *)rt_malloc(sizeof(FIL));
if (fd == RT_NULL) if (fd == RT_NULL)
{ {
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_fn); rt_free(drivers_fn);
#endif #endif
return -DFS_STATUS_ENOMEM; return -DFS_STATUS_ENOMEM;
} }
result = f_open(fd, drivers_fn, mode); result = f_open(fd, drivers_fn, mode);
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_fn); rt_free(drivers_fn);
#endif #endif
if (result == FR_OK) if (result == FR_OK)
{ {
file->pos = fd->fptr; file->pos = fd->fptr;
file->size = fd->fsize; file->size = fd->fsize;
file->data = fd; file->data = fd;
if (file->flags & DFS_O_APPEND) if (file->flags & DFS_O_APPEND)
{ {
/* seek to the end of file */ /* seek to the end of file */
f_lseek(fd, fd->fsize); f_lseek(fd, fd->fsize);
file->pos = fd->fptr; file->pos = fd->fptr;
} }
} }
else else
{ {
/* open failed, return */ /* open failed, return */
rt_free(fd); rt_free(fd);
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
} }
return DFS_STATUS_OK; return DFS_STATUS_OK;
} }
int dfs_elm_close(struct dfs_fd *file) int dfs_elm_close(struct dfs_fd *file)
{ {
FRESULT result; FRESULT result;
result = FR_OK; result = FR_OK;
if (file->type == FT_DIRECTORY) if (file->type == FT_DIRECTORY)
{ {
DIR *dir; DIR *dir;
dir = (DIR *)(file->data); dir = (DIR *)(file->data);
RT_ASSERT(dir != RT_NULL); RT_ASSERT(dir != RT_NULL);
/* release memory */ /* release memory */
rt_free(dir); rt_free(dir);
} }
else if (file->type == FT_REGULAR) else if (file->type == FT_REGULAR)
{ {
FIL *fd; FIL *fd;
fd = (FIL *)(file->data); fd = (FIL *)(file->data);
RT_ASSERT(fd != RT_NULL); RT_ASSERT(fd != RT_NULL);
result = f_close(fd); result = f_close(fd);
if (result == FR_OK) if (result == FR_OK)
{ {
/* release memory */ /* release memory */
rt_free(fd); rt_free(fd);
} }
} }
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args) int dfs_elm_ioctl(struct dfs_fd *file, int cmd, void *args)
{ {
return -DFS_STATUS_ENOSYS; return -DFS_STATUS_ENOSYS;
} }
int dfs_elm_read(struct dfs_fd *file, void *buf, rt_size_t len) int dfs_elm_read(struct dfs_fd *file, void *buf, rt_size_t len)
{ {
FIL *fd; FIL *fd;
FRESULT result; FRESULT result;
UINT byte_read; UINT byte_read;
if (file->type == FT_DIRECTORY) if (file->type == FT_DIRECTORY)
{ {
return -DFS_STATUS_EISDIR; return -DFS_STATUS_EISDIR;
} }
fd = (FIL *)(file->data); fd = (FIL *)(file->data);
RT_ASSERT(fd != RT_NULL); RT_ASSERT(fd != RT_NULL);
result = f_read(fd, buf, len, &byte_read); result = f_read(fd, buf, len, &byte_read);
/* update position */ /* update position */
file->pos = fd->fptr; file->pos = fd->fptr;
if (result == FR_OK) if (result == FR_OK)
return byte_read; return byte_read;
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
int dfs_elm_write(struct dfs_fd *file, const void *buf, rt_size_t len) int dfs_elm_write(struct dfs_fd *file, const void *buf, rt_size_t len)
{ {
FIL *fd; FIL *fd;
FRESULT result; FRESULT result;
UINT byte_write; UINT byte_write;
if (file->type == FT_DIRECTORY) if (file->type == FT_DIRECTORY)
{ {
return -DFS_STATUS_EISDIR; return -DFS_STATUS_EISDIR;
} }
fd = (FIL *)(file->data); fd = (FIL *)(file->data);
RT_ASSERT(fd != RT_NULL); RT_ASSERT(fd != RT_NULL);
result = f_write(fd, buf, len, &byte_write); result = f_write(fd, buf, len, &byte_write);
/* update position and file size */ /* update position and file size */
file->pos = fd->fptr; file->pos = fd->fptr;
file->size = fd->fsize; file->size = fd->fsize;
if (result == FR_OK) if (result == FR_OK)
return byte_write; return byte_write;
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
int dfs_elm_flush(struct dfs_fd *file) int dfs_elm_flush(struct dfs_fd *file)
{ {
FIL *fd; FIL *fd;
FRESULT result; FRESULT result;
fd = (FIL *)(file->data); fd = (FIL *)(file->data);
RT_ASSERT(fd != RT_NULL); RT_ASSERT(fd != RT_NULL);
result = f_sync(fd); result = f_sync(fd);
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
int dfs_elm_lseek(struct dfs_fd *file, rt_off_t offset) int dfs_elm_lseek(struct dfs_fd *file, rt_off_t offset)
{ {
FRESULT result = FR_OK; FRESULT result = FR_OK;
if (file->type == FT_REGULAR) if (file->type == FT_REGULAR)
{ {
FIL *fd; FIL *fd;
/* regular file type */ /* regular file type */
fd = (FIL *)(file->data); fd = (FIL *)(file->data);
RT_ASSERT(fd != RT_NULL); RT_ASSERT(fd != RT_NULL);
result = f_lseek(fd, offset); result = f_lseek(fd, offset);
if (result == FR_OK) if (result == FR_OK)
{ {
/* return current position */ /* return current position */
file->pos = fd->fptr; file->pos = fd->fptr;
return fd->fptr; return fd->fptr;
} }
} }
else if (file->type == FT_DIRECTORY) else if (file->type == FT_DIRECTORY)
{ {
/* which is a directory */ /* which is a directory */
DIR *dir; DIR *dir;
dir = (DIR *)(file->data); dir = (DIR *)(file->data);
RT_ASSERT(dir != RT_NULL); RT_ASSERT(dir != RT_NULL);
result = f_seekdir(dir, offset / sizeof(struct dirent)); result = f_seekdir(dir, offset / sizeof(struct dirent));
if (result == FR_OK) if (result == FR_OK)
{ {
/* update file position */ /* update file position */
file->pos = offset; file->pos = offset;
return file->pos; return file->pos;
} }
} }
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count) int dfs_elm_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count)
{ {
DIR *dir; DIR *dir;
FILINFO fno; FILINFO fno;
FRESULT result; FRESULT result;
rt_uint32_t index; rt_uint32_t index;
struct dirent *d; struct dirent *d;
dir = (DIR *)(file->data); dir = (DIR *)(file->data);
RT_ASSERT(dir != RT_NULL); RT_ASSERT(dir != RT_NULL);
/* make integer count */ /* make integer count */
count = (count / sizeof(struct dirent)) * sizeof(struct dirent); count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
if (count == 0) if (count == 0)
return -DFS_STATUS_EINVAL; return -DFS_STATUS_EINVAL;
#if _USE_LFN #if _USE_LFN
/* allocate long file name */ /* allocate long file name */
fno.lfname = rt_malloc(256); fno.lfname = rt_malloc(256);
fno.lfsize = 256; fno.lfsize = 256;
#endif #endif
index = 0; index = 0;
while (1) while (1)
{ {
char *fn; char *fn;
d = dirp + index; d = dirp + index;
result = f_readdir(dir, &fno); result = f_readdir(dir, &fno);
if (result != FR_OK || fno.fname[0] == 0) if (result != FR_OK || fno.fname[0] == 0)
break; break;
#if _USE_LFN #if _USE_LFN
fn = *fno.lfname? fno.lfname : fno.fname; fn = *fno.lfname ? fno.lfname : fno.fname;
#else #else
fn = fno.fname; fn = fno.fname;
#endif #endif
d->d_type = DFS_DT_UNKNOWN; d->d_type = DFS_DT_UNKNOWN;
if (fno.fattrib & AM_DIR) if (fno.fattrib & AM_DIR)
d->d_type = DFS_DT_DIR; d->d_type = DFS_DT_DIR;
else else
d->d_type = DFS_DT_REG; d->d_type = DFS_DT_REG;
d->d_namlen = (rt_uint8_t)rt_strlen(fn); d->d_namlen = (rt_uint8_t)rt_strlen(fn);
d->d_reclen = (rt_uint16_t)sizeof(struct dirent); d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
rt_strncpy(d->d_name, fn, rt_strlen(fn) + 1); rt_strncpy(d->d_name, fn, rt_strlen(fn) + 1);
index ++; index ++;
if (index * sizeof(struct dirent) >= count) if (index * sizeof(struct dirent) >= count)
break; break;
} }
#if _USE_LFN #if _USE_LFN
rt_free(fno.lfname); rt_free(fno.lfname);
#endif #endif
if (index == 0) if (index == 0)
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
file->pos += index * sizeof(struct dirent); file->pos += index * sizeof(struct dirent);
return index * sizeof(struct dirent); return index * sizeof(struct dirent);
} }
int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path) int dfs_elm_unlink(struct dfs_filesystem *fs, const char *path)
{ {
FRESULT result; FRESULT result;
#if _VOLUMES > 1 #if _VOLUMES > 1
int vol; int vol;
char *drivers_fn; char *drivers_fn;
extern int elm_get_vol(FATFS *fat); extern int elm_get_vol(FATFS * fat);
/* add path for ELM FatFS driver support */ /* add path for ELM FatFS driver support */
vol = elm_get_vol((FATFS *)fs->data); vol = elm_get_vol((FATFS *)fs->data);
if (vol < 0) if (vol < 0)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
drivers_fn = rt_malloc(256); drivers_fn = rt_malloc(256);
if (drivers_fn == RT_NULL) if (drivers_fn == RT_NULL)
return -DFS_STATUS_ENOMEM; return -DFS_STATUS_ENOMEM;
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path); rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
#else #else
const char *drivers_fn; const char *drivers_fn;
drivers_fn = path; drivers_fn = path;
#endif #endif
result = f_unlink(drivers_fn); result = f_unlink(drivers_fn);
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_fn); rt_free(drivers_fn);
#endif #endif
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *newpath) int dfs_elm_rename(struct dfs_filesystem *fs, const char *oldpath, const char *newpath)
{ {
FRESULT result; FRESULT result;
#if _VOLUMES > 1 #if _VOLUMES > 1
char *drivers_oldfn; char *drivers_oldfn;
const char *drivers_newfn; const char *drivers_newfn;
int vol; int vol;
extern int elm_get_vol(FATFS *fat); extern int elm_get_vol(FATFS * fat);
/* add path for ELM FatFS driver support */ /* add path for ELM FatFS driver support */
vol = elm_get_vol((FATFS *)fs->data); vol = elm_get_vol((FATFS *)fs->data);
if (vol < 0) if (vol < 0)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
drivers_oldfn = rt_malloc(256); drivers_oldfn = rt_malloc(256);
if (drivers_oldfn == RT_NULL) if (drivers_oldfn == RT_NULL)
return -DFS_STATUS_ENOMEM; return -DFS_STATUS_ENOMEM;
drivers_newfn = newpath; drivers_newfn = newpath;
rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath); rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
#else #else
const char *drivers_oldfn, *drivers_newfn; const char *drivers_oldfn, *drivers_newfn;
drivers_oldfn = oldpath; drivers_oldfn = oldpath;
drivers_newfn = newpath; drivers_newfn = newpath;
#endif #endif
result = f_rename(drivers_oldfn, drivers_newfn); result = f_rename(drivers_oldfn, drivers_newfn);
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_oldfn); rt_free(drivers_oldfn);
#endif #endif
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st)
{ {
FILINFO file_info; FILINFO file_info;
FRESULT result; FRESULT result;
#if _VOLUMES > 1 #if _VOLUMES > 1
int vol; int vol;
char *drivers_fn; char *drivers_fn;
extern int elm_get_vol(FATFS *fat); extern int elm_get_vol(FATFS * fat);
/* add path for ELM FatFS driver support */ /* add path for ELM FatFS driver support */
vol = elm_get_vol((FATFS *)fs->data); vol = elm_get_vol((FATFS *)fs->data);
if (vol < 0) if (vol < 0)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
drivers_fn = rt_malloc(256); drivers_fn = rt_malloc(256);
if (drivers_fn == RT_NULL) if (drivers_fn == RT_NULL)
return -DFS_STATUS_ENOMEM; return -DFS_STATUS_ENOMEM;
rt_snprintf(drivers_fn, 256, "%d:%s", vol, path); rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
#else #else
const char *drivers_fn; const char *drivers_fn;
drivers_fn = path; drivers_fn = path;
#endif #endif
#if _USE_LFN #if _USE_LFN
/* allocate long file name */ /* allocate long file name */
file_info.lfname = rt_malloc(256); file_info.lfname = rt_malloc(256);
file_info.lfsize = 256; file_info.lfsize = 256;
#endif #endif
result = f_stat(drivers_fn, &file_info); result = f_stat(drivers_fn, &file_info);
#if _VOLUMES > 1 #if _VOLUMES > 1
rt_free(drivers_fn); rt_free(drivers_fn);
#endif #endif
if (result == FR_OK) if (result == FR_OK)
{ {
/* convert to dfs stat structure */ /* convert to dfs stat structure */
st->st_dev = 0; st->st_dev = 0;
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH | st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH; DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
if (file_info.fattrib & AM_DIR) if (file_info.fattrib & AM_DIR)
{ {
st->st_mode &= ~DFS_S_IFREG; st->st_mode &= ~DFS_S_IFREG;
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH; st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
} }
if (file_info.fattrib & AM_RDO) if (file_info.fattrib & AM_RDO)
st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH); st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH);
st->st_size = file_info.fsize; st->st_size = file_info.fsize;
st->st_mtime = file_info.ftime; st->st_mtime = file_info.ftime;
st->st_blksize = 512; st->st_blksize = 512;
} }
#if _USE_LFN #if _USE_LFN
rt_free(file_info.lfname); rt_free(file_info.lfname);
#endif #endif
return elm_result_to_dfs(result); return elm_result_to_dfs(result);
} }
static const struct dfs_filesystem_operation dfs_elm = static const struct dfs_filesystem_operation dfs_elm =
{ {
"elm", "elm",
DFS_FS_FLAG_DEFAULT, DFS_FS_FLAG_DEFAULT,
dfs_elm_mount, dfs_elm_mount,
dfs_elm_unmount, dfs_elm_unmount,
dfs_elm_mkfs, dfs_elm_mkfs,
dfs_elm_statfs, dfs_elm_statfs,
dfs_elm_open, dfs_elm_open,
dfs_elm_close, dfs_elm_close,
dfs_elm_ioctl, dfs_elm_ioctl,
dfs_elm_read, dfs_elm_read,
dfs_elm_write, dfs_elm_write,
dfs_elm_flush, dfs_elm_flush,
dfs_elm_lseek, dfs_elm_lseek,
dfs_elm_getdents, dfs_elm_getdents,
dfs_elm_unlink, dfs_elm_unlink,
dfs_elm_stat, dfs_elm_stat,
dfs_elm_rename, dfs_elm_rename,
}; };
int elm_init(void) int elm_init(void)
...@@ -698,7 +742,7 @@ int elm_init(void) ...@@ -698,7 +742,7 @@ int elm_init(void)
/* register fatfs file system */ /* register fatfs file system */
dfs_register(&dfs_elm); dfs_register(&dfs_elm);
return 0; return 0;
} }
/* /*
...@@ -709,97 +753,97 @@ int elm_init(void) ...@@ -709,97 +753,97 @@ int elm_init(void)
/* Initialize a Drive */ /* Initialize a Drive */
DSTATUS disk_initialize(BYTE drv) DSTATUS disk_initialize(BYTE drv)
{ {
return 0; return 0;
} }
/* Return Disk Status */ /* Return Disk Status */
DSTATUS disk_status(BYTE drv) DSTATUS disk_status(BYTE drv)
{ {
return 0; return 0;
} }
/* Read Sector(s) */ /* Read Sector(s) */
DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, BYTE count) DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, BYTE count)
{ {
rt_size_t result; rt_size_t result;
rt_device_t device = disk[drv]; rt_device_t device = disk[drv];
result = rt_device_read(device, sector, buff, count); result = rt_device_read(device, sector, buff, count);
if (result == count) if (result == count)
{ {
return RES_OK; return RES_OK;
} }
return RES_ERROR; return RES_ERROR;
} }
/* Write Sector(s) */ /* Write Sector(s) */
DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, BYTE count) DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, BYTE count)
{ {
rt_size_t result; rt_size_t result;
rt_device_t device = disk[drv]; rt_device_t device = disk[drv];
result = rt_device_write(device, sector, buff, count); result = rt_device_write(device, sector, buff, count);
if (result == count) if (result == count)
{ {
return RES_OK; return RES_OK;
} }
return RES_ERROR; return RES_ERROR;
} }
/* Miscellaneous Functions */ /* Miscellaneous Functions */
DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff) DRESULT disk_ioctl(BYTE drv, BYTE ctrl, void *buff)
{ {
rt_device_t device = disk[drv]; rt_device_t device = disk[drv];
if (device == RT_NULL) if (device == RT_NULL)
return RES_ERROR; return RES_ERROR;
if (ctrl == GET_SECTOR_COUNT) if (ctrl == GET_SECTOR_COUNT)
{ {
struct rt_device_blk_geometry geometry; struct rt_device_blk_geometry geometry;
rt_memset(&geometry, 0, sizeof(geometry)); rt_memset(&geometry, 0, sizeof(geometry));
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
*(DWORD *)buff = geometry.sector_count; *(DWORD *)buff = geometry.sector_count;
if (geometry.sector_count == 0) if (geometry.sector_count == 0)
return RES_ERROR; return RES_ERROR;
} }
else if (ctrl == GET_SECTOR_SIZE) else if (ctrl == GET_SECTOR_SIZE)
{ {
struct rt_device_blk_geometry geometry; struct rt_device_blk_geometry geometry;
rt_memset(&geometry, 0, sizeof(geometry)); rt_memset(&geometry, 0, sizeof(geometry));
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
*(WORD *)buff = (WORD)(geometry.bytes_per_sector); *(WORD *)buff = (WORD)(geometry.bytes_per_sector);
} }
else if (ctrl == GET_BLOCK_SIZE) /* Get erase block size in unit of sectors (DWORD) */ else if (ctrl == GET_BLOCK_SIZE) /* Get erase block size in unit of sectors (DWORD) */
{ {
struct rt_device_blk_geometry geometry; struct rt_device_blk_geometry geometry;
rt_memset(&geometry, 0, sizeof(geometry)); rt_memset(&geometry, 0, sizeof(geometry));
rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry); rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);
*(DWORD *)buff = geometry.block_size/geometry.bytes_per_sector; *(DWORD *)buff = geometry.block_size / geometry.bytes_per_sector;
} }
else if (ctrl == CTRL_SYNC) else if (ctrl == CTRL_SYNC)
{ {
rt_device_control(device, RT_DEVICE_CTRL_BLK_SYNC, RT_NULL); rt_device_control(device, RT_DEVICE_CTRL_BLK_SYNC, RT_NULL);
} }
else if (ctrl == CTRL_ERASE_SECTOR) else if (ctrl == CTRL_ERASE_SECTOR)
{ {
rt_device_control(device, RT_DEVICE_CTRL_BLK_ERASE, buff); rt_device_control(device, RT_DEVICE_CTRL_BLK_ERASE, buff);
} }
return RES_OK; return RES_OK;
} }
rt_time_t get_fattime(void) rt_time_t get_fattime(void)
{ {
return 0; return 0;
} }
#if _FS_REENTRANT #if _FS_REENTRANT
...@@ -821,7 +865,8 @@ int ff_cre_syncobj(BYTE drv, _SYNC_t *m) ...@@ -821,7 +865,8 @@ int ff_cre_syncobj(BYTE drv, _SYNC_t *m)
int ff_del_syncobj(_SYNC_t m) int ff_del_syncobj(_SYNC_t m)
{ {
rt_mutex_delete(m); if (m != RT_NULL)
rt_mutex_delete(m);
return RT_TRUE; return RT_TRUE;
} }
...@@ -829,14 +874,14 @@ int ff_del_syncobj(_SYNC_t m) ...@@ -829,14 +874,14 @@ int ff_del_syncobj(_SYNC_t m)
int ff_req_grant(_SYNC_t m) int ff_req_grant(_SYNC_t m)
{ {
if (rt_mutex_take(m, _FS_TIMEOUT) == RT_EOK) if (rt_mutex_take(m, _FS_TIMEOUT) == RT_EOK)
return RT_TRUE; return RT_TRUE;
return RT_FALSE; return RT_FALSE;
} }
void ff_rel_grant(_SYNC_t m) void ff_rel_grant(_SYNC_t m)
{ {
rt_mutex_release(m); rt_mutex_release(m);
} }
#endif #endif
...@@ -844,13 +889,13 @@ void ff_rel_grant(_SYNC_t m) ...@@ -844,13 +889,13 @@ void ff_rel_grant(_SYNC_t m)
/* Memory functions */ /* Memory functions */
#if _USE_LFN == 3 #if _USE_LFN == 3
/* Allocate memory block */ /* Allocate memory block */
void* ff_memalloc (UINT size) void *ff_memalloc(UINT size)
{ {
return rt_malloc(size); return rt_malloc(size);
} }
/* Free memory block */ /* Free memory block */
void ff_memfree (void* mem) void ff_memfree(void *mem)
{ {
rt_free(mem); rt_free(mem);
} }
......
...@@ -222,7 +222,7 @@ static int dfs_jffs2_unmount(struct dfs_filesystem* fs) ...@@ -222,7 +222,7 @@ static int dfs_jffs2_unmount(struct dfs_filesystem* fs)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
} }
static int dfs_jffs2_mkfs(const char* device_name) static int dfs_jffs2_mkfs(rt_device_t dev_id)
{ {
/* just erase all blocks on this nand partition */ /* just erase all blocks on this nand partition */
return -DFS_STATUS_ENOSYS; return -DFS_STATUS_ENOSYS;
......
...@@ -207,7 +207,7 @@ static int dfs_uffs_unmount(struct dfs_filesystem* fs) ...@@ -207,7 +207,7 @@ static int dfs_uffs_unmount(struct dfs_filesystem* fs)
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
} }
static int dfs_uffs_mkfs(const char* device_name) static int dfs_uffs_mkfs(rt_device_t dev_id)
{ {
rt_base_t index; rt_base_t index;
rt_uint32_t block; rt_uint32_t block;
...@@ -216,15 +216,13 @@ static int dfs_uffs_mkfs(const char* device_name) ...@@ -216,15 +216,13 @@ static int dfs_uffs_mkfs(const char* device_name)
/*1. find the device index */ /*1. find the device index */
for (index = 0; index < UFFS_DEVICE_MAX; index++) for (index = 0; index < UFFS_DEVICE_MAX; index++)
{ {
if (rt_strncmp(nand_part[index].dev->parent.parent.name, if (nand_part[index].dev == (struct rt_mtd_nand_device *)dev_id)
device_name, RT_NAME_MAX) == 0)
break; break;
} }
if (index == UFFS_DEVICE_MAX) if (index == UFFS_DEVICE_MAX)
{ {
/* can't find device driver */ /* can't find device driver */
rt_kprintf("can not find device driver: %s\n", device_name);
return -DFS_STATUS_ENOENT; return -DFS_STATUS_ENOENT;
} }
......
...@@ -35,7 +35,7 @@ struct dfs_filesystem_operation ...@@ -35,7 +35,7 @@ struct dfs_filesystem_operation
int (*unmount) (struct dfs_filesystem *fs); int (*unmount) (struct dfs_filesystem *fs);
/* make a file system */ /* make a file system */
int (*mkfs) (const char *device_name); int (*mkfs) (rt_device_t devid);
int (*statfs) (struct dfs_filesystem *fs, struct statfs *buf); int (*statfs) (struct dfs_filesystem *fs, struct statfs *buf);
int (*open) (struct dfs_fd *fd); int (*open) (struct dfs_fd *fd);
......
...@@ -424,6 +424,19 @@ err1: ...@@ -424,6 +424,19 @@ err1:
int dfs_mkfs(const char *fs_name, const char *device_name) int dfs_mkfs(const char *fs_name, const char *device_name)
{ {
int index; int index;
rt_device_t dev_id;
/* check device name, and it should not be NULL */
if (device_name == RT_NULL)
dev_id = RT_NULL;
else
dev_id = rt_device_find(device_name);
if (dev_id == RT_NULL)
{
rt_set_errno(-DFS_STATUS_ENODEV);
return -1;
}
/* lock file system */ /* lock file system */
dfs_lock(); dfs_lock();
...@@ -438,7 +451,7 @@ int dfs_mkfs(const char *fs_name, const char *device_name) ...@@ -438,7 +451,7 @@ int dfs_mkfs(const char *fs_name, const char *device_name)
dfs_unlock(); dfs_unlock();
if (ops->mkfs != RT_NULL) if (ops->mkfs != RT_NULL)
return ops->mkfs(device_name); return ops->mkfs(dev_id);
break; break;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册