From: batt Date: Thu, 21 May 2009 10:43:26 +0000 (+0000) Subject: Added kfile interface implementation for FatFS. X-Git-Tag: 2.2.0~275 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=b65e60edaa04a0d0bec335198d7cf2279f3a22ae;p=bertos.git Added kfile interface implementation for FatFS. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@2693 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/bertos/fs/fat.c b/bertos/fs/fat.c new file mode 100644 index 00000000..aca2fa30 --- /dev/null +++ b/bertos/fs/fat.c @@ -0,0 +1,150 @@ +/** + * \file + * + * + * \brief FatFS: kfile interface for FatFS module by ChaN. + * + * \version $Id$ + * + * \author Luca Ottaviano + * + */ + +#include "fat.h" + +static size_t fatfile_read(struct KFile *_fd, void *buf, size_t size) +{ + FatFile *fd = FATFILE_CAST(_fd); + UINT count; + fd->error_code = f_read(&fd->fat_file, buf, size, &count); + return count; +} + +static size_t fatfile_write(struct KFile *_fd, const void *buf, size_t size) +{ + FatFile *fd = FATFILE_CAST(_fd); + UINT count; + fd->error_code = f_write(&fd->fat_file, buf, size, &count); + return count; +} + +static int fatfile_close(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + fd->error_code = f_close(&fd->fat_file); + if (fd->error_code) + return EOF; + else + return 0; +} + +static kfile_off_t fatfile_seek(struct KFile *_fd, kfile_off_t offset, KSeekMode whence) +{ + /* clip at start-of-file + * don't clip at end-of-file when in write mode + */ + FatFile *fd = FATFILE_CAST(_fd); + DWORD lseek_offset; + switch (whence) + { + case KSM_SEEK_SET: + if (offset > 0) + lseek_offset = (DWORD) offset; + else + lseek_offset = 0; + break; + case KSM_SEEK_CUR: + if (offset > 0) + lseek_offset = fd->fat_file.fptr + (DWORD) offset; + else + { + if (fd->fat_file.fptr > (DWORD) (-offset)) + lseek_offset = fd->fat_file.fptr - (DWORD)(-offset); + else + lseek_offset = 0; + } + break; + case KSM_SEEK_END: + if (offset > 0) + lseek_offset = fd->fat_file.fsize + (DWORD) offset; + else + { + if (fd->fat_file.fsize > (DWORD) (-offset)) + lseek_offset = fd->fat_file.fsize + (DWORD) offset; + else + lseek_offset = 0; + } + break; + } + fd->error_code = f_lseek(&fd->fat_file, lseek_offset); + if ((fd->error_code) || (fd->fat_file.fptr != lseek_offset)) + return EOF; + else + /* TODO: this conversion may overflow */ + return (kfile_off_t)fd->fat_file.fptr; +} + +static int fatfile_flush(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + fd->error_code = f_sync(&fd->fat_file); + if (fd->error_code) + return EOF; + else + return 0; +} + +static int fatfile_error(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + return (int)fd->error_code; +} + +static void fatfile_clearerr(struct KFile *_fd) +{ + FatFile *fd = FATFILE_CAST(_fd); + fd->error_code = FR_OK; +} + +FRESULT fatfile_open(FatFile *file, const char *file_path, BYTE mode) +{ + file->fd._type = KFT_FATFILE; + file->fd.read = fatfile_read; + file->fd.write = fatfile_write; + file->fd.reopen = 0; + file->fd.close = fatfile_close; + file->fd.seek = fatfile_seek; + file->fd.flush = fatfile_flush; + file->fd.error = fatfile_error; + file->fd.clearerr = fatfile_clearerr; + return f_open(&file->fat_file, file_path, mode); +} + diff --git a/bertos/fs/fat.h b/bertos/fs/fat.h new file mode 100644 index 00000000..77d046ee --- /dev/null +++ b/bertos/fs/fat.h @@ -0,0 +1,67 @@ +/** + * \file + * + * + * \brief FatFS: kfile interface for FatFS module by ChaN. + * + * \version $Id$ + * + * \author Luca Ottaviano + * + */ +#ifndef FS_FAT_H +#define FS_FAT_H + +#include +#include "fatfs/src/ff.h" + +typedef struct FatFile +{ + KFile fd; + FIL fat_file; + FRESULT error_code; ///< error code for calls like kfile_read +} FatFile; + +#define KFT_FATFILE MAKE_ID('F', 'A', 'T', 'F') + +INLINE FatFile * FATFILE_CAST(KFile *fd) +{ + ASSERT(fd->_type == KFT_FATFILE); + return (FatFile *)fd; +} + +/** + * Initialize \a file and open \a file_path for reading. + */ +FRESULT fatfile_open(FatFile *file, const char *file_path, BYTE mode); + +#endif /* FS_FAT_H */ +