From aa2baa87e9494c23b5f0a6616786db7fdf145eeb Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 23 Dec 2016 20:39:09 +1100 Subject: [PATCH 01/24] src: Remove diskio.c, it should be provided by user of the library. --- src/diskio.c | 225 --------------------------------------------------- 1 file changed, 225 deletions(-) delete mode 100644 src/diskio.c diff --git a/src/diskio.c b/src/diskio.c deleted file mode 100644 index c802e03..0000000 --- a/src/diskio.c +++ /dev/null @@ -1,225 +0,0 @@ -/*-----------------------------------------------------------------------*/ -/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */ -/*-----------------------------------------------------------------------*/ -/* If a working storage control module is available, it should be */ -/* attached to the FatFs via a glue function rather than modifying it. */ -/* This is an example of glue functions to attach various exsisting */ -/* storage control modules to the FatFs module with a defined API. */ -/*-----------------------------------------------------------------------*/ - -#include "diskio.h" /* FatFs lower layer API */ - -/* Definitions of physical drive number for each drive */ -#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ -#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ -#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ - - -/*-----------------------------------------------------------------------*/ -/* Get Drive Status */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_status ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat; - int result; - - switch (pdrv) { - case DEV_RAM : - result = RAM_disk_status(); - - // translate the reslut code here - - return stat; - - case DEV_MMC : - result = MMC_disk_status(); - - // translate the reslut code here - - return stat; - - case DEV_USB : - result = USB_disk_status(); - - // translate the reslut code here - - return stat; - } - return STA_NOINIT; -} - - - -/*-----------------------------------------------------------------------*/ -/* Inidialize a Drive */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat; - int result; - - switch (pdrv) { - case DEV_RAM : - result = RAM_disk_initialize(); - - // translate the reslut code here - - return stat; - - case DEV_MMC : - result = MMC_disk_initialize(); - - // translate the reslut code here - - return stat; - - case DEV_USB : - result = USB_disk_initialize(); - - // translate the reslut code here - - return stat; - } - return STA_NOINIT; -} - - - -/*-----------------------------------------------------------------------*/ -/* Read Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ -) -{ - DRESULT res; - int result; - - switch (pdrv) { - case DEV_RAM : - // translate the arguments here - - result = RAM_disk_read(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_MMC : - // translate the arguments here - - result = MMC_disk_read(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_USB : - // translate the arguments here - - result = USB_disk_read(buff, sector, count); - - // translate the reslut code here - - return res; - } - - return RES_PARERR; -} - - - -/*-----------------------------------------------------------------------*/ -/* Write Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ -) -{ - DRESULT res; - int result; - - switch (pdrv) { - case DEV_RAM : - // translate the arguments here - - result = RAM_disk_write(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_MMC : - // translate the arguments here - - result = MMC_disk_write(buff, sector, count); - - // translate the reslut code here - - return res; - - case DEV_USB : - // translate the arguments here - - result = USB_disk_write(buff, sector, count); - - // translate the reslut code here - - return res; - } - - return RES_PARERR; -} - - - -/*-----------------------------------------------------------------------*/ -/* Miscellaneous Functions */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ -) -{ - DRESULT res; - int result; - - switch (pdrv) { - case DEV_RAM : - - // Process of the command for the RAM drive - - return res; - - case DEV_MMC : - - // Process of the command for the MMC/SD card - - return res; - - case DEV_USB : - - // Process of the command the USB drive - - return res; - } - - return RES_PARERR; -} - From 54c4011ce8cc8f791cea21748cb650b76c87a314 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 4 Mar 2016 22:42:30 +0000 Subject: [PATCH 02/24] src: Remove need for integer.h, use stdint instead. --- src/diskio.h | 1 - src/ff.h | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/diskio.h b/src/diskio.h index 3c7cac9..a1941ba 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -9,7 +9,6 @@ extern "C" { #endif -#include "integer.h" /* Status of Disk Functions */ diff --git a/src/ff.h b/src/ff.h index 15cc35b..b6744fd 100644 --- a/src/ff.h +++ b/src/ff.h @@ -25,7 +25,27 @@ extern "C" { #endif -#include "integer.h" /* Basic integer types */ +#include + +/* This type MUST be 8-bit */ +typedef uint8_t BYTE; + +/* These types MUST be 16-bit */ +typedef int16_t SHORT; +typedef uint16_t WORD; +typedef uint16_t WCHAR; + +/* These types MUST be 16-bit or 32-bit */ +typedef int INT; +typedef unsigned int UINT; + +/* These types MUST be 32-bit */ +typedef int32_t LONG; +typedef uint32_t DWORD; + +/* This type MUST be 64-bit (Remove this for C89 compatibility) */ +typedef uint64_t QWORD; + #include "ffconf.h" /* FatFs configuration options */ #if _FATFS != _FFCONF From 187d6a6e91aa9fae56bc35c12ce65704059d1df4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 23 Dec 2016 20:38:45 +1100 Subject: [PATCH 03/24] src: Remove integer.h, it's no longer needed. --- src/integer.h | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 src/integer.h diff --git a/src/integer.h b/src/integer.h deleted file mode 100644 index 66d7e3b..0000000 --- a/src/integer.h +++ /dev/null @@ -1,38 +0,0 @@ -/*-------------------------------------------*/ -/* Integer type definitions for FatFs module */ -/*-------------------------------------------*/ - -#ifndef _FF_INTEGER -#define _FF_INTEGER - -#ifdef _WIN32 /* FatFs development platform */ - -#include -#include -typedef unsigned __int64 QWORD; - - -#else /* Embedded platform */ - -/* These types MUST be 16-bit or 32-bit */ -typedef int INT; -typedef unsigned int UINT; - -/* This type MUST be 8-bit */ -typedef unsigned char BYTE; - -/* These types MUST be 16-bit */ -typedef short SHORT; -typedef unsigned short WORD; -typedef unsigned short WCHAR; - -/* These types MUST be 32-bit */ -typedef long LONG; -typedef unsigned long DWORD; - -/* This type MUST be 64-bit (Remove this for C89 compatibility) */ -typedef unsigned long long QWORD; - -#endif - -#endif From 4b33737377e11e14740811dcfd822e4eafb63841 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 4 Mar 2016 22:43:29 +0000 Subject: [PATCH 04/24] src: Allow ffconf.h to be configurable, via FFCONF_H. --- src/ff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ff.h b/src/ff.h index b6744fd..1dc1e0c 100644 --- a/src/ff.h +++ b/src/ff.h @@ -46,7 +46,7 @@ typedef uint32_t DWORD; /* This type MUST be 64-bit (Remove this for C89 compatibility) */ typedef uint64_t QWORD; -#include "ffconf.h" /* FatFs configuration options */ +#include FFCONF_H /* FatFs configuration options */ #if _FATFS != _FFCONF #error Wrong configuration file (ffconf.h). From 231698c7b00ebb3f43410cbfb8ae90290f8a38bd Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 4 Mar 2016 22:54:02 +0000 Subject: [PATCH 05/24] src: Remove STRFUNC functions. --- src/ff.c | 312 ------------------------------------------------------- src/ff.h | 4 - 2 files changed, 316 deletions(-) diff --git a/src/ff.c b/src/ff.c index 88dbd37..b6c275a 100644 --- a/src/ff.c +++ b/src/ff.c @@ -5727,315 +5727,3 @@ FRESULT f_fdisk ( #endif /* _MULTI_PARTITION */ #endif /* _USE_MKFS && !_FS_READONLY */ - - - - -#if _USE_STRFUNC -/*-----------------------------------------------------------------------*/ -/* Get a string from the file */ -/*-----------------------------------------------------------------------*/ - -TCHAR* f_gets ( - TCHAR* buff, /* Pointer to the string buffer to read */ - int len, /* Size of string buffer (characters) */ - FIL* fp /* Pointer to the file object */ -) -{ - int n = 0; - TCHAR c, *p = buff; - BYTE s[2]; - UINT rc; - - - while (n < len - 1) { /* Read characters until buffer gets filled */ -#if _LFN_UNICODE -#if _STRF_ENCODE == 3 /* Read a character in UTF-8 */ - f_read(fp, s, 1, &rc); - if (rc != 1) break; - c = s[0]; - if (c >= 0x80) { - if (c < 0xC0) continue; /* Skip stray trailer */ - if (c < 0xE0) { /* Two-byte sequence */ - f_read(fp, s, 1, &rc); - if (rc != 1) break; - c = (c & 0x1F) << 6 | (s[0] & 0x3F); - if (c < 0x80) c = '?'; - } else { - if (c < 0xF0) { /* Three-byte sequence */ - f_read(fp, s, 2, &rc); - if (rc != 2) break; - c = c << 12 | (s[0] & 0x3F) << 6 | (s[1] & 0x3F); - if (c < 0x800) c = '?'; - } else { /* Reject four-byte sequence */ - c = '?'; - } - } - } -#elif _STRF_ENCODE == 2 /* Read a character in UTF-16BE */ - f_read(fp, s, 2, &rc); - if (rc != 2) break; - c = s[1] + (s[0] << 8); -#elif _STRF_ENCODE == 1 /* Read a character in UTF-16LE */ - f_read(fp, s, 2, &rc); - if (rc != 2) break; - c = s[0] + (s[1] << 8); -#else /* Read a character in ANSI/OEM */ - f_read(fp, s, 1, &rc); - if (rc != 1) break; - c = s[0]; - if (IsDBCS1(c)) { - f_read(fp, s, 1, &rc); - if (rc != 1) break; - c = (c << 8) + s[0]; - } - c = ff_convert(c, 1); /* OEM -> Unicode */ - if (!c) c = '?'; -#endif -#else /* Read a character without conversion */ - f_read(fp, s, 1, &rc); - if (rc != 1) break; - c = s[0]; -#endif - if (_USE_STRFUNC == 2 && c == '\r') continue; /* Strip '\r' */ - *p++ = c; - n++; - if (c == '\n') break; /* Break on EOL */ - } - *p = 0; - return n ? buff : 0; /* When no data read (eof or error), return with error. */ -} - - - - -#if !_FS_READONLY -#include -/*-----------------------------------------------------------------------*/ -/* Put a character to the file */ -/*-----------------------------------------------------------------------*/ - -typedef struct { - FIL *fp; /* Ptr to the writing file */ - int idx, nchr; /* Write index of buf[] (-1:error), number of chars written */ - BYTE buf[64]; /* Write buffer */ -} putbuff; - - -static -void putc_bfd ( /* Buffered write with code conversion */ - putbuff* pb, - TCHAR c -) -{ - UINT bw; - int i; - - - if (_USE_STRFUNC == 2 && c == '\n') { /* LF -> CRLF conversion */ - putc_bfd(pb, '\r'); - } - - i = pb->idx; /* Write index of pb->buf[] */ - if (i < 0) return; - -#if _LFN_UNICODE -#if _STRF_ENCODE == 3 /* Write a character in UTF-8 */ - if (c < 0x80) { /* 7-bit */ - pb->buf[i++] = (BYTE)c; - } else { - if (c < 0x800) { /* 11-bit */ - pb->buf[i++] = (BYTE)(0xC0 | c >> 6); - } else { /* 16-bit */ - pb->buf[i++] = (BYTE)(0xE0 | c >> 12); - pb->buf[i++] = (BYTE)(0x80 | (c >> 6 & 0x3F)); - } - pb->buf[i++] = (BYTE)(0x80 | (c & 0x3F)); - } -#elif _STRF_ENCODE == 2 /* Write a character in UTF-16BE */ - pb->buf[i++] = (BYTE)(c >> 8); - pb->buf[i++] = (BYTE)c; -#elif _STRF_ENCODE == 1 /* Write a character in UTF-16LE */ - pb->buf[i++] = (BYTE)c; - pb->buf[i++] = (BYTE)(c >> 8); -#else /* Write a character in ANSI/OEM */ - c = ff_convert(c, 0); /* Unicode -> OEM */ - if (!c) c = '?'; - if (c >= 0x100) - pb->buf[i++] = (BYTE)(c >> 8); - pb->buf[i++] = (BYTE)c; -#endif -#else /* Write a character without conversion */ - pb->buf[i++] = (BYTE)c; -#endif - - if (i >= (int)(sizeof pb->buf) - 3) { /* Write buffered characters to the file */ - f_write(pb->fp, pb->buf, (UINT)i, &bw); - i = (bw == (UINT)i) ? 0 : -1; - } - pb->idx = i; - pb->nchr++; -} - - -static -int putc_flush ( /* Flush left characters in the buffer */ - putbuff* pb -) -{ - UINT nw; - - if ( pb->idx >= 0 /* Flush buffered characters to the file */ - && f_write(pb->fp, pb->buf, (UINT)pb->idx, &nw) == FR_OK - && (UINT)pb->idx == nw) return pb->nchr; - return EOF; -} - - -static -void putc_init ( /* Initialize write buffer */ - putbuff* pb, - FIL* fp -) -{ - pb->fp = fp; - pb->nchr = pb->idx = 0; -} - - - -int f_putc ( - TCHAR c, /* A character to be output */ - FIL* fp /* Pointer to the file object */ -) -{ - putbuff pb; - - - putc_init(&pb, fp); - putc_bfd(&pb, c); /* Put the character */ - return putc_flush(&pb); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Put a string to the file */ -/*-----------------------------------------------------------------------*/ - -int f_puts ( - const TCHAR* str, /* Pointer to the string to be output */ - FIL* fp /* Pointer to the file object */ -) -{ - putbuff pb; - - - putc_init(&pb, fp); - while (*str) putc_bfd(&pb, *str++); /* Put the string */ - return putc_flush(&pb); -} - - - - -/*-----------------------------------------------------------------------*/ -/* Put a formatted string to the file */ -/*-----------------------------------------------------------------------*/ - -int f_printf ( - FIL* fp, /* Pointer to the file object */ - const TCHAR* fmt, /* Pointer to the format string */ - ... /* Optional arguments... */ -) -{ - va_list arp; - putbuff pb; - BYTE f, r; - UINT i, j, w; - DWORD v; - TCHAR c, d, str[32], *p; - - - putc_init(&pb, fp); - - va_start(arp, fmt); - - for (;;) { - c = *fmt++; - if (c == 0) break; /* End of string */ - if (c != '%') { /* Non escape character */ - putc_bfd(&pb, c); - continue; - } - w = f = 0; - c = *fmt++; - if (c == '0') { /* Flag: '0' padding */ - f = 1; c = *fmt++; - } else { - if (c == '-') { /* Flag: left justified */ - f = 2; c = *fmt++; - } - } - while (IsDigit(c)) { /* Precision */ - w = w * 10 + c - '0'; - c = *fmt++; - } - if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ - f |= 4; c = *fmt++; - } - if (!c) break; - d = c; - if (IsLower(d)) d -= 0x20; - switch (d) { /* Type is... */ - case 'S' : /* String */ - p = va_arg(arp, TCHAR*); - for (j = 0; p[j]; j++) ; - if (!(f & 2)) { - while (j++ < w) putc_bfd(&pb, ' '); - } - while (*p) putc_bfd(&pb, *p++); - while (j++ < w) putc_bfd(&pb, ' '); - continue; - case 'C' : /* Character */ - putc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue; - case 'B' : /* Binary */ - r = 2; break; - case 'O' : /* Octal */ - r = 8; break; - case 'D' : /* Signed decimal */ - case 'U' : /* Unsigned decimal */ - r = 10; break; - case 'X' : /* Hexdecimal */ - r = 16; break; - default: /* Unknown type (pass-through) */ - putc_bfd(&pb, c); continue; - } - - /* Get an argument and put it in numeral */ - v = (f & 4) ? (DWORD)va_arg(arp, long) : ((d == 'D') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int)); - if (d == 'D' && (v & 0x80000000)) { - v = 0 - v; - f |= 8; - } - i = 0; - do { - d = (TCHAR)(v % r); v /= r; - if (d > 9) d += (c == 'x') ? 0x27 : 0x07; - str[i++] = d + '0'; - } while (v && i < sizeof str / sizeof str[0]); - if (f & 8) str[i++] = '-'; - j = i; d = (f & 1) ? '0' : ' '; - while (!(f & 2) && j++ < w) putc_bfd(&pb, d); - do putc_bfd(&pb, str[--i]); while (i); - while (j++ < w) putc_bfd(&pb, d); - } - - va_end(arp); - - return putc_flush(&pb); -} - -#endif /* !_FS_READONLY */ -#endif /* _USE_STRFUNC */ diff --git a/src/ff.h b/src/ff.h index 1dc1e0c..ea6ca84 100644 --- a/src/ff.h +++ b/src/ff.h @@ -294,10 +294,6 @@ FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ -int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ -int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ -int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ -TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) #define f_error(fp) ((fp)->err) From 34749f7037a4bd0ab4798cefbe9c89a45e50bae8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 4 Mar 2016 23:19:49 +0000 Subject: [PATCH 06/24] src: Make disk_XXX functions take a block device as first argument. --- src/diskio.h | 10 +++++----- src/ff.c | 7 +++---- src/ff.h | 6 ++---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/diskio.h b/src/diskio.h index a1941ba..e70f831 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -28,11 +28,11 @@ typedef enum { /* Prototypes for disk control functions */ -DSTATUS disk_initialize (BYTE pdrv); -DSTATUS disk_status (BYTE pdrv); -DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); -DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); -DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); +DSTATUS disk_initialize (void *drv); +DSTATUS disk_status (void *drv); +DRESULT disk_read (void *drv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_write (void *drv, const BYTE* buff, DWORD sector, UINT count); +DRESULT disk_ioctl (void *drv, BYTE cmd, void* buff); /* Disk Status Bits (DSTATUS) */ diff --git a/src/ff.c b/src/ff.c index b6c275a..acb451d 100644 --- a/src/ff.c +++ b/src/ff.c @@ -2981,7 +2981,6 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */ fs->fs_type = 0; /* Clear the file system object */ - fs->drv = LD2PD(vol); /* Bind the logical drive and a physical drive */ stat = disk_initialize(fs->drv); /* Initialize the physical drive */ if (stat & STA_NOINIT) { /* Check if the initialization succeeded */ return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ @@ -5220,7 +5219,7 @@ FRESULT f_mkfs ( const UINT n_rootdir = 512; /* Number of root directory entries for FAT12/16 volume */ static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT12/16 volume (4Ks unit) */ static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */ - BYTE fmt, sys, *buf, *pte, pdrv, part; + BYTE fmt, sys, *buf, *pte, part; void *pdrv; WORD ss; DWORD szb_buf, sz_buf, sz_blk, n_clst, pau, sect, nsect, n; DWORD b_vol, b_fat, b_data; /* Base LBA for volume, fat, data */ @@ -5237,7 +5236,7 @@ FRESULT f_mkfs ( vol = get_ldnumber(&path); /* Get target logical drive */ if (vol < 0) return FR_INVALID_DRIVE; if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear mounted volume */ - pdrv = LD2PD(vol); /* Physical drive */ + pdrv = fs->drv; /* Physical drive */ part = LD2PT(vol); /* Partition (0:create as new, 1-4:get from partition table) */ /* Check physical drive status */ @@ -5665,7 +5664,7 @@ FRESULT f_mkfs ( /*-----------------------------------------------------------------------*/ FRESULT f_fdisk ( - BYTE pdrv, /* Physical drive number */ + void *pdrv, /* Physical drive number */ const DWORD* szt, /* Pointer to the size table for each partitions */ void* work /* Pointer to the working buffer */ ) diff --git a/src/ff.h b/src/ff.h index ea6ca84..6424a9c 100644 --- a/src/ff.h +++ b/src/ff.h @@ -62,11 +62,9 @@ typedef struct { BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ } PARTITION; extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ -#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ #define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ #else /* Single partition configuration */ -#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */ #define LD2PT(vol) 0 /* Find first valid partition or in SFD */ #endif @@ -110,8 +108,8 @@ typedef DWORD FSIZE_t; /* File system object structure (FATFS) */ typedef struct { + void *drv; // block device underlying this filesystem BYTE fs_type; /* File system type (0:N/A) */ - BYTE drv; /* Physical drive number */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] flag (b0:dirty) */ BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ @@ -293,7 +291,7 @@ FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ -FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ +FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) #define f_error(fp) ((fp)->err) From 9b2d96934cbcfb5be5f914cd7ddd6701bedb39f3 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 4 Mar 2016 23:58:27 +0000 Subject: [PATCH 07/24] src: Replace disk_initialize and disk_status with ioctl commands. --- src/diskio.h | 4 ++-- src/ff.c | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/diskio.h b/src/diskio.h index e70f831..eb51a9f 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -28,8 +28,6 @@ typedef enum { /* Prototypes for disk control functions */ -DSTATUS disk_initialize (void *drv); -DSTATUS disk_status (void *drv); DRESULT disk_read (void *drv, BYTE* buff, DWORD sector, UINT count); DRESULT disk_write (void *drv, const BYTE* buff, DWORD sector, UINT count); DRESULT disk_ioctl (void *drv, BYTE cmd, void* buff); @@ -50,6 +48,8 @@ DRESULT disk_ioctl (void *drv, BYTE cmd, void* buff); #define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ +#define IOCTL_INIT 5 +#define IOCTL_STATUS 6 /* Generic command (Not used by FatFs) */ #define CTRL_POWER 5 /* Get/Set power status */ diff --git a/src/ff.c b/src/ff.c index acb451d..075f8cd 100644 --- a/src/ff.c +++ b/src/ff.c @@ -2968,7 +2968,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */ if (fs->fs_type) { /* If the volume has been mounted */ - stat = disk_status(fs->drv); + disk_ioctl(fs->drv, IOCTL_STATUS, &stat); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ if (!_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */ return FR_WRITE_PROTECTED; @@ -2981,7 +2981,7 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */ fs->fs_type = 0; /* Clear the file system object */ - stat = disk_initialize(fs->drv); /* Initialize the physical drive */ + disk_ioctl(fs->drv, IOCTL_INIT, &stat); /* Initialize the physical drive */ if (stat & STA_NOINIT) { /* Check if the initialization succeeded */ return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ } @@ -3165,9 +3165,10 @@ FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ ) { FRESULT res; + DSTATUS stat; - if (!obj || !obj->fs || !obj->fs->fs_type || obj->fs->id != obj->id || (disk_status(obj->fs->drv) & STA_NOINIT)) { + if (!obj || !obj->fs || !obj->fs->fs_type || obj->fs->id != obj->id || disk_ioctl(obj->fs->drv, IOCTL_STATUS, &stat) != RES_OK || (stat & STA_NOINIT)) { *fs = 0; /* The object is invalid */ res = FR_INVALID_OBJECT; } else { @@ -5240,7 +5241,7 @@ FRESULT f_mkfs ( part = LD2PT(vol); /* Partition (0:create as new, 1-4:get from partition table) */ /* Check physical drive status */ - stat = disk_initialize(pdrv); + disk_ioctl(pdrv, IOCTL_INIT, &stat); if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK || !sz_blk || sz_blk > 32768 || (sz_blk & (sz_blk - 1))) sz_blk = 1; /* Erase block to align data area */ @@ -5675,7 +5676,7 @@ FRESULT f_fdisk ( DWORD sz_disk, sz_part, s_part; - stat = disk_initialize(pdrv); + disk_ioctl(pdrv, IOCTL_INIT, &stat); if (stat & STA_NOINIT) return FR_NOT_READY; if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR; From 6eb1b56fcd5ac2aa3a4aeaa1db62d8d1afb10888 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 5 Mar 2016 00:14:19 +0000 Subject: [PATCH 08/24] src: Make f_mkfs take a FATFS as argument instead of a path. --- src/ff.c | 15 ++++++--------- src/ff.h | 18 +++++++----------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/ff.c b/src/ff.c index 075f8cd..3868cca 100644 --- a/src/ff.c +++ b/src/ff.c @@ -2995,17 +2995,17 @@ FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ /* Find an FAT partition on the drive. Supports only generic partitioning, FDISK and SFD. */ bsect = 0; fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */ - if (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) { /* Not an FAT-VBR or forced partition number */ + if (fmt == 2 || (fmt < 2 && LD2PT(fs) != 0)) { /* Not an FAT-VBR or forced partition number */ for (i = 0; i < 4; i++) { /* Get partition offset */ pt = fs->win + (MBR_Table + i * SZ_PTE); br[i] = pt[PTE_System] ? ld_dword(pt + PTE_StLba) : 0; } - i = LD2PT(vol); /* Partition number: 0:auto, 1-4:forced */ + i = LD2PT(fs); /* Partition number: 0:auto, 1-4:forced */ if (i) i--; do { /* Find an FAT volume */ bsect = br[i]; fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */ - } while (!LD2PT(vol) && fmt >= 2 && ++i < 4); + } while (!LD2PT(fs) && fmt >= 2 && ++i < 4); } if (fmt == 4) return FR_DISK_ERR; /* An error occured in the disk I/O layer */ if (fmt >= 2) return FR_NO_FILESYSTEM; /* No FAT volume is found */ @@ -5209,7 +5209,7 @@ FRESULT f_forward ( /*-----------------------------------------------------------------------*/ FRESULT f_mkfs ( - const TCHAR* path, /* Logical drive number */ + FATFS *fs, BYTE opt, /* Format option */ DWORD au, /* Size of allocation unit [byte] */ void* work, /* Pointer to working buffer */ @@ -5226,7 +5226,6 @@ FRESULT f_mkfs ( DWORD b_vol, b_fat, b_data; /* Base LBA for volume, fat, data */ DWORD sz_vol, sz_rsv, sz_fat, sz_dir; /* Size for volume, fat, dir, data */ UINT i; - int vol; DSTATUS stat; #if _USE_TRIM || _FS_EXFAT DWORD tbl[3]; @@ -5234,11 +5233,9 @@ FRESULT f_mkfs ( /* Check mounted drive and clear work area */ - vol = get_ldnumber(&path); /* Get target logical drive */ - if (vol < 0) return FR_INVALID_DRIVE; - if (FatFs[vol]) FatFs[vol]->fs_type = 0; /* Clear mounted volume */ + fs->fs_type = 0; /* Clear mounted volume */ pdrv = fs->drv; /* Physical drive */ - part = LD2PT(vol); /* Partition (0:create as new, 1-4:get from partition table) */ + part = LD2PT(fs); /* Partition (0:create as new, 1-4:get from partition table) */ /* Check physical drive status */ disk_ioctl(pdrv, IOCTL_INIT, &stat); diff --git a/src/ff.h b/src/ff.h index 6424a9c..59a6393 100644 --- a/src/ff.h +++ b/src/ff.h @@ -56,17 +56,10 @@ typedef uint64_t QWORD; /* Definitions of volume management */ -#if _MULTI_PARTITION /* Multiple partition configuration */ -typedef struct { - BYTE pd; /* Physical drive number */ - BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ -} PARTITION; -extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ -#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ - +#if _MULTI_PARTITION /* Multiple partition configuration */ +#define LD2PT(fs) (fs->part) /* Get partition index */ #else /* Single partition configuration */ -#define LD2PT(vol) 0 /* Find first valid partition or in SFD */ - +#define LD2PT(fs) 0 /* Find first valid partition or in SFD */ #endif @@ -109,6 +102,9 @@ typedef DWORD FSIZE_t; typedef struct { void *drv; // block device underlying this filesystem +#if _MULTI_PARTITION /* Multiple partition configuration */ + BYTE part; // Partition: 0:Auto detect, 1-4:Forced partition +#endif BYTE fs_type; /* File system type (0:N/A) */ BYTE n_fats; /* Number of FATs (1 or 2) */ BYTE wflag; /* win[] flag (b0:dirty) */ @@ -290,7 +286,7 @@ FRESULT f_setlabel (const TCHAR* label); /* Set volum FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ -FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ +FRESULT f_mkfs (FATFS *fs, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) From 2e5494bcbada447fdf9b2af1a93a98d9c25b2fb8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 7 Mar 2016 13:41:20 +0000 Subject: [PATCH 09/24] src: Split out umount functionality from f_mount to new f_umount. --- src/ff.c | 24 ++++++++++++++++++------ src/ff.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/ff.c b/src/ff.c index 3868cca..22f6227 100644 --- a/src/ff.c +++ b/src/ff.c @@ -3195,7 +3195,7 @@ FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ /*-----------------------------------------------------------------------*/ FRESULT f_mount ( - FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/ + FATFS* fs, /* Pointer to the file system object to mount */ const TCHAR* path, /* Logical drive number to be mounted/unmounted */ BYTE opt /* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */ ) @@ -3221,21 +3221,33 @@ FRESULT f_mount ( cfs->fs_type = 0; /* Clear old fs object */ } - if (fs) { - fs->fs_type = 0; /* Clear new fs object */ + fs->fs_type = 0; /* Clear new fs object */ #if _FS_REENTRANT /* Create sync object for the new volume */ - if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; + if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; #endif - } FatFs[vol] = fs; /* Register new fs object */ - if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */ + if (opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */ res = find_volume(&path, &fs, 0); /* Force mounted the volume */ LEAVE_FF(fs, res); } +FRESULT f_umount ( + FATFS* fs /* Pointer to the file system object to unmount */ +) +{ +#if _FS_LOCK + clear_lock(fs); +#endif +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(fs->sobj)) return FR_INT_ERR; +#endif + fs->fs_type = 0; /* Clear old fs object */ + + return FR_OK; +} /*-----------------------------------------------------------------------*/ diff --git a/src/ff.h b/src/ff.h index 59a6393..2fa3a34 100644 --- a/src/ff.h +++ b/src/ff.h @@ -286,6 +286,7 @@ FRESULT f_setlabel (const TCHAR* label); /* Set volum FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ +FRESULT f_umount (FATFS* fs); /* Unmount a logical drive */ FRESULT f_mkfs (FATFS *fs, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ From 5d75698a4f7d148ef7b39843a6fa92a6d17c5ee0 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 7 Mar 2016 14:04:30 +0000 Subject: [PATCH 10/24] src: Make all necessary functions take FATFS* as first argument. This removes the global FatFs[] structure, being the list of mounted filesystems. Instead, just pass the desired FS to the function. --- src/ff.c | 103 +++++++++++++++++-------------------------------------- src/ff.h | 28 +++++++-------- 2 files changed, 45 insertions(+), 86 deletions(-) diff --git a/src/ff.c b/src/ff.c index 22f6227..d6db9cd 100644 --- a/src/ff.c +++ b/src/ff.c @@ -522,7 +522,6 @@ typedef struct { #if _VOLUMES < 1 || _VOLUMES > 9 #error Wrong _VOLUMES setting #endif -static FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */ static WORD Fsid; /* File system mount ID */ #if _FS_RPATH != 0 && _VOLUMES >= 2 @@ -2940,31 +2939,18 @@ BYTE check_fs ( /* 0:FAT, 1:exFAT, 2:Valid BS but not FAT, 3:Not a BS, 4:Disk er static FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ - const TCHAR** path, /* Pointer to pointer to the path name (drive number) */ - FATFS** rfs, /* Pointer to pointer to the found file system object */ + FATFS* fs, /* Pointer to the file system object */ BYTE mode /* !=0: Check write protection for write access */ ) { BYTE fmt, *pt; - int vol; DSTATUS stat; DWORD bsect, fasize, tsect, sysect, nclst, szbfat, br[4]; WORD nrsv; - FATFS *fs; UINT i; - /* Get logical drive number */ - *rfs = 0; - vol = get_ldnumber(path); - if (vol < 0) return FR_INVALID_DRIVE; - - /* Check if the file system object is valid or not */ - fs = FatFs[vol]; /* Get pointer to the file system object */ - if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ - ENTER_FF(fs); /* Lock the volume */ - *rfs = fs; /* Return pointer to the file system object */ mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */ if (fs->fs_type) { /* If the volume has been mounted */ @@ -3195,41 +3181,17 @@ FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */ /*-----------------------------------------------------------------------*/ FRESULT f_mount ( - FATFS* fs, /* Pointer to the file system object to mount */ - const TCHAR* path, /* Logical drive number to be mounted/unmounted */ - BYTE opt /* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */ + FATFS* fs /* Pointer to the file system object to mount */ ) { - FATFS *cfs; - int vol; FRESULT res; - const TCHAR *rp = path; - - - /* Get logical drive number */ - vol = get_ldnumber(&rp); - if (vol < 0) return FR_INVALID_DRIVE; - cfs = FatFs[vol]; /* Pointer to fs object */ - - if (cfs) { -#if _FS_LOCK != 0 - clear_lock(cfs); -#endif -#if _FS_REENTRANT /* Discard sync object of the current volume */ - if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR; -#endif - cfs->fs_type = 0; /* Clear old fs object */ - } fs->fs_type = 0; /* Clear new fs object */ #if _FS_REENTRANT /* Create sync object for the new volume */ if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; #endif - FatFs[vol] = fs; /* Register new fs object */ - - if (opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */ - res = find_volume(&path, &fs, 0); /* Force mounted the volume */ + res = find_volume(fs, 0); /* Force mounted the volume */ LEAVE_FF(fs, res); } @@ -3255,6 +3217,7 @@ FRESULT f_umount ( /*-----------------------------------------------------------------------*/ FRESULT f_open ( + FATFS *fs, FIL* fp, /* Pointer to the blank file object */ const TCHAR* path, /* Pointer to the file name */ BYTE mode /* Access mode and file open mode flags */ @@ -3262,7 +3225,6 @@ FRESULT f_open ( { FRESULT res; DIR dj; - FATFS *fs; #if !_FS_READONLY DWORD dw, cl, bcs, clst, sc; FSIZE_t ofs; @@ -3274,7 +3236,7 @@ FRESULT f_open ( /* Get logical drive */ mode &= _FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND | FA_SEEKEND; - res = find_volume(&path, &fs, mode); + res = find_volume(fs, mode); if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); @@ -3811,16 +3773,16 @@ FRESULT f_chdrive ( FRESULT f_chdir ( + FATFS *fs, const TCHAR* path /* Pointer to the directory path */ ) { FRESULT res; DIR dj; - FATFS *fs; DEF_NAMBUF /* Get logical drive */ - res = find_volume(&path, &fs, 0); + res = find_volume(fs, 0); if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); @@ -3863,13 +3825,13 @@ FRESULT f_chdir ( #if _FS_RPATH >= 2 FRESULT f_getcwd ( + FATFS *fs, TCHAR* buff, /* Pointer to the directory path */ UINT len /* Size of path */ ) { FRESULT res; DIR dj; - FATFS *fs; UINT i, n; DWORD ccl; TCHAR *tp; @@ -3879,7 +3841,7 @@ FRESULT f_getcwd ( *buff = 0; /* Get logical drive */ - res = find_volume((const TCHAR**)&buff, &fs, 0); /* Get current volume */ + res = find_volume(fs, 0); /* Get current volume */ if (res == FR_OK) { dj.obj.fs = fs; INIT_NAMBUF(fs); @@ -4097,12 +4059,12 @@ FRESULT f_lseek ( /*-----------------------------------------------------------------------*/ FRESULT f_opendir ( + FATFS *fs, DIR* dp, /* Pointer to directory object to create */ const TCHAR* path /* Pointer to the directory path */ ) { FRESULT res; - FATFS *fs; _FDID *obj; DEF_NAMBUF @@ -4111,7 +4073,7 @@ FRESULT f_opendir ( /* Get logical drive */ obj = &dp->obj; - res = find_volume(&path, &fs, 0); + res = find_volume(fs, 0); if (res == FR_OK) { obj->fs = fs; INIT_NAMBUF(fs); @@ -4288,6 +4250,7 @@ FRESULT f_findfirst ( /*-----------------------------------------------------------------------*/ FRESULT f_stat ( + FATFS *fs, const TCHAR* path, /* Pointer to the file path */ FILINFO* fno /* Pointer to file information to return */ ) @@ -4298,7 +4261,8 @@ FRESULT f_stat ( /* Get logical drive */ - res = find_volume(&path, &dj.obj.fs, 0); + res = find_volume(fs, 0); + dj.obj.fs = fs; if (res == FR_OK) { INIT_NAMBUF(dj.obj.fs); res = follow_path(&dj, path); /* Follow the file path */ @@ -4323,13 +4287,11 @@ FRESULT f_stat ( /*-----------------------------------------------------------------------*/ FRESULT f_getfree ( - const TCHAR* path, /* Path name of the logical drive number */ - DWORD* nclst, /* Pointer to a variable to return number of free clusters */ - FATFS** fatfs /* Pointer to return pointer to corresponding file system object */ + FATFS *fs, + DWORD* nclst /* Pointer to a variable to return number of free clusters */ ) { FRESULT res; - FATFS *fs; DWORD nfree, clst, sect, stat; UINT i; BYTE *p; @@ -4337,9 +4299,8 @@ FRESULT f_getfree ( /* Get logical drive */ - res = find_volume(&path, &fs, 0); + res = find_volume(fs, 0); if (res == FR_OK) { - *fatfs = fs; /* Return ptr to the fs object */ /* If free_clst is valid, return it without full cluster scan */ if (fs->free_clst <= fs->n_fatent - 2) { *nclst = fs->free_clst; @@ -4460,13 +4421,13 @@ FRESULT f_truncate ( /*-----------------------------------------------------------------------*/ FRESULT f_unlink ( + FATFS *fs, const TCHAR* path /* Pointer to the file or directory path */ ) { FRESULT res; DIR dj, sdj; DWORD dclst = 0; - FATFS *fs; #if _FS_EXFAT _FDID obj; #endif @@ -4474,7 +4435,7 @@ FRESULT f_unlink ( /* Get logical drive */ - res = find_volume(&path, &fs, FA_WRITE); + res = find_volume(fs, FA_WRITE); dj.obj.fs = fs; if (res == FR_OK) { INIT_NAMBUF(fs); @@ -4555,12 +4516,12 @@ FRESULT f_unlink ( /*-----------------------------------------------------------------------*/ FRESULT f_mkdir ( + FATFS *fs, const TCHAR* path /* Pointer to the directory path */ ) { FRESULT res; DIR dj; - FATFS *fs; BYTE *dir; UINT n; DWORD dsc, dcl, pcl, tm; @@ -4568,7 +4529,7 @@ FRESULT f_mkdir ( /* Get logical drive */ - res = find_volume(&path, &fs, FA_WRITE); + res = find_volume(fs, FA_WRITE); dj.obj.fs = fs; if (res == FR_OK) { INIT_NAMBUF(fs); @@ -4648,20 +4609,19 @@ FRESULT f_mkdir ( /*-----------------------------------------------------------------------*/ FRESULT f_rename ( + FATFS *fs, const TCHAR* path_old, /* Pointer to the object name to be renamed */ const TCHAR* path_new /* Pointer to the new name */ ) { FRESULT res; DIR djo, djn; - FATFS *fs; BYTE buf[_FS_EXFAT ? SZDIRE * 2 : 24], *dir; DWORD dw; DEF_NAMBUF - get_ldnumber(&path_new); /* Ignore drive number of new name */ - res = find_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */ + res = find_volume(fs, FA_WRITE); if (res == FR_OK) { djo.obj.fs = fs; INIT_NAMBUF(fs); @@ -4754,6 +4714,7 @@ FRESULT f_rename ( /*-----------------------------------------------------------------------*/ FRESULT f_chmod ( + FATFS *fs, const TCHAR* path, /* Pointer to the file path */ BYTE attr, /* Attribute bits */ BYTE mask /* Attribute mask to change */ @@ -4761,11 +4722,10 @@ FRESULT f_chmod ( { FRESULT res; DIR dj; - FATFS *fs; DEF_NAMBUF - res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ + res = find_volume(fs, FA_WRITE); /* Get logical drive */ dj.obj.fs = fs; if (res == FR_OK) { INIT_NAMBUF(fs); @@ -4799,17 +4759,17 @@ FRESULT f_chmod ( /*-----------------------------------------------------------------------*/ FRESULT f_utime ( + FATFS *fs, const TCHAR* path, /* Pointer to the file/directory name */ const FILINFO* fno /* Pointer to the time stamp to be set */ ) { FRESULT res; DIR dj; - FATFS *fs; DEF_NAMBUF - res = find_volume(&path, &fs, FA_WRITE); /* Get logical drive */ + res = find_volume(fs, FA_WRITE); /* Get logical drive */ dj.obj.fs = fs; if (res == FR_OK) { INIT_NAMBUF(fs); @@ -4844,21 +4804,20 @@ FRESULT f_utime ( /*-----------------------------------------------------------------------*/ FRESULT f_getlabel ( - const TCHAR* path, /* Path name of the logical drive number */ + FATFS *fs, TCHAR* label, /* Pointer to a buffer to return the volume label */ DWORD* vsn /* Pointer to a variable to return the volume serial number */ ) { FRESULT res; DIR dj; - FATFS *fs; UINT si, di; #if _LFN_UNICODE || _FS_EXFAT WCHAR w; #endif /* Get logical drive */ - res = find_volume(&path, &fs, 0); + res = find_volume(fs, 0); /* Get volume label */ if (res == FR_OK && label) { @@ -4933,12 +4892,12 @@ FRESULT f_getlabel ( /*-----------------------------------------------------------------------*/ FRESULT f_setlabel ( + FATFS *fs, const TCHAR* label /* Pointer to the volume label to set */ ) { FRESULT res; DIR dj; - FATFS *fs; BYTE dirvn[22]; UINT i, j, slen; WCHAR w; @@ -4946,7 +4905,7 @@ FRESULT f_setlabel ( /* Get logical drive */ - res = find_volume(&label, &fs, FA_WRITE); + res = find_volume(fs, FA_WRITE); if (res != FR_OK) LEAVE_FF(fs, res); dj.obj.fs = fs; diff --git a/src/ff.h b/src/ff.h index 2fa3a34..96ab456 100644 --- a/src/ff.h +++ b/src/ff.h @@ -259,33 +259,33 @@ typedef enum { /*--------------------------------------------------------------*/ /* FatFs module application interface */ -FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ +FRESULT f_open (FATFS *fs, FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ FRESULT f_close (FIL* fp); /* Close an open file object */ FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ FRESULT f_truncate (FIL* fp); /* Truncate the file */ FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ -FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ +FRESULT f_opendir (FATFS *fs, DIR* dp, const TCHAR* path); /* Open a directory */ FRESULT f_closedir (DIR* dp); /* Close an open directory */ FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ -FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ -FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ -FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ -FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ -FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ -FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ -FRESULT f_chdir (const TCHAR* path); /* Change current directory */ +FRESULT f_mkdir (FATFS *fs, const TCHAR* path); /* Create a sub directory */ +FRESULT f_unlink (FATFS *fs, const TCHAR* path); /* Delete an existing file or directory */ +FRESULT f_rename (FATFS *fs, const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ +FRESULT f_stat (FATFS *fs, const TCHAR* path, FILINFO* fno); /* Get file status */ +FRESULT f_chmod (FATFS *fs, const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ +FRESULT f_utime (FATFS *fs, const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ +FRESULT f_chdir (FATFS *fs, const TCHAR* path); /* Change current directory */ FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ -FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ -FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ -FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ -FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ +FRESULT f_getcwd (FATFS *fs, TCHAR* buff, UINT len); /* Get current directory */ +FRESULT f_getfree (FATFS *fs, DWORD* nclst); /* Get number of free clusters on the drive */ +FRESULT f_getlabel (FATFS *fs, TCHAR* label, DWORD* vsn); /* Get volume label */ +FRESULT f_setlabel (FATFS *fs, const TCHAR* label); /* Set volume label */ FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */ -FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ +FRESULT f_mount (FATFS* fs); /* Mount/Unmount a logical drive */ FRESULT f_umount (FATFS* fs); /* Unmount a logical drive */ FRESULT f_mkfs (FATFS *fs, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */ FRESULT f_fdisk (void *pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */ From 26d3da2e4546a858134e67b0c00bff7360f824fd Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 7 Mar 2016 14:10:14 +0000 Subject: [PATCH 11/24] src: Remove get_ldnumber, CurrVol and f_chdrive. --- src/ff.c | 88 -------------------------------------------------------- src/ff.h | 1 - 2 files changed, 89 deletions(-) diff --git a/src/ff.c b/src/ff.c index d6db9cd..e788ba8 100644 --- a/src/ff.c +++ b/src/ff.c @@ -524,10 +524,6 @@ typedef struct { #endif static WORD Fsid; /* File system mount ID */ -#if _FS_RPATH != 0 && _VOLUMES >= 2 -static BYTE CurrVol; /* Current drive */ -#endif - #if _FS_LOCK != 0 static FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */ #endif @@ -2844,67 +2840,6 @@ FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ -/*-----------------------------------------------------------------------*/ -/* Get logical drive number from path name */ -/*-----------------------------------------------------------------------*/ - -static -int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */ - const TCHAR** path /* Pointer to pointer to the path name */ -) -{ - const TCHAR *tp, *tt; - UINT i; - int vol = -1; -#if _STR_VOLUME_ID /* Find string drive id */ - static const char* const str[] = {_VOLUME_STRS}; - const char *sp; - char c; - TCHAR tc; -#endif - - - if (*path) { /* If the pointer is not a null */ - for (tt = *path; (UINT)*tt >= (_USE_LFN ? ' ' : '!') && *tt != ':'; tt++) ; /* Find ':' in the path */ - if (*tt == ':') { /* If a ':' is exist in the path name */ - tp = *path; - i = *tp++ - '0'; - if (i < 10 && tp == tt) { /* Is there a numeric drive id? */ - if (i < _VOLUMES) { /* If a drive id is found, get the value and strip it */ - vol = (int)i; - *path = ++tt; - } - } -#if _STR_VOLUME_ID - else { /* No numeric drive number, find string drive id */ - i = 0; tt++; - do { - sp = str[i]; tp = *path; - do { /* Compare a string drive id with path name */ - c = *sp++; tc = *tp++; - if (IsLower(tc)) tc -= 0x20; - } while (c && (TCHAR)c == tc); - } while ((c || tp != tt) && ++i < _VOLUMES); /* Repeat for each id until pattern match */ - if (i < _VOLUMES) { /* If a drive id is found, get the value and strip it */ - vol = (int)i; - *path = tt; - } - } -#endif - return vol; - } -#if _FS_RPATH != 0 && _VOLUMES >= 2 - vol = CurrVol; /* Current drive */ -#else - vol = 0; /* Drive 0 */ -#endif - } - return vol; -} - - - - /*-----------------------------------------------------------------------*/ /* Load a sector and check if it is an FAT boot sector */ /*-----------------------------------------------------------------------*/ @@ -3753,25 +3688,6 @@ FRESULT f_close ( /* Change Current Directory or Current Drive, Get Current Directory */ /*-----------------------------------------------------------------------*/ -#if _VOLUMES >= 2 -FRESULT f_chdrive ( - const TCHAR* path /* Drive number */ -) -{ - int vol; - - - /* Get logical drive number */ - vol = get_ldnumber(&path); - if (vol < 0) return FR_INVALID_DRIVE; - - CurrVol = (BYTE)vol; /* Set it as current volume */ - - return FR_OK; -} -#endif - - FRESULT f_chdir ( FATFS *fs, const TCHAR* path /* Pointer to the directory path */ @@ -3875,10 +3791,6 @@ FRESULT f_getcwd ( } tp = buff; if (res == FR_OK) { -#if _VOLUMES >= 2 - *tp++ = '0' + CurrVol; /* Put drive number */ - *tp++ = ':'; -#endif if (i == len) { /* Root-directory */ *tp++ = '/'; } else { /* Sub-directroy */ diff --git a/src/ff.h b/src/ff.h index 96ab456..1c426c4 100644 --- a/src/ff.h +++ b/src/ff.h @@ -278,7 +278,6 @@ FRESULT f_stat (FATFS *fs, const TCHAR* path, FILINFO* fno); /* Get file FRESULT f_chmod (FATFS *fs, const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ FRESULT f_utime (FATFS *fs, const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ FRESULT f_chdir (FATFS *fs, const TCHAR* path); /* Change current directory */ -FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ FRESULT f_getcwd (FATFS *fs, TCHAR* buff, UINT len); /* Get current directory */ FRESULT f_getfree (FATFS *fs, DWORD* nclst); /* Get number of free clusters on the drive */ FRESULT f_getlabel (FATFS *fs, TCHAR* label, DWORD* vsn); /* Get volume label */ From 818733072b8e2a09c9e85dd32efd9cedff955167 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Dec 2016 16:29:40 +1100 Subject: [PATCH 12/24] tests: Add functional test for fatfs functions. --- tests/.gitignore | 1 + tests/Makefile | 7 ++ tests/fatfs1.c | 226 ++++++++++++++++++++++++++++++++++++++++++++ tests/fatfs1.exp | 196 ++++++++++++++++++++++++++++++++++++++ tests/fatfs1_conf.h | 33 +++++++ tests/util.c | 50 ++++++++++ tests/util.h | 5 + 7 files changed, 518 insertions(+) create mode 100644 tests/.gitignore create mode 100644 tests/Makefile create mode 100644 tests/fatfs1.c create mode 100644 tests/fatfs1.exp create mode 100644 tests/fatfs1_conf.h create mode 100644 tests/util.c create mode 100644 tests/util.h diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..9f4f72b --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +fatfs1 diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..e1b9f58 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,7 @@ +all: fatfs1 + +fatfs1: ../src/ff.c ../src/option/ccsbcs.c util.c fatfs1.c + gcc -g -I.. -std=c99 -DFFCONF_H='"tests/fatfs1_conf.h"' $^ -o $@ + +test: fatfs1 + ./fatfs1 | diff - fatfs1.exp diff --git a/tests/fatfs1.c b/tests/fatfs1.c new file mode 100644 index 0000000..8db9098 --- /dev/null +++ b/tests/fatfs1.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include + +#include "tests/util.h" +#include "src/ff.h" +#include "src/diskio.h" + +#define NSEC (128) +#define SEC_SIZE (512) +static uint8_t ram_bdev[NSEC * SEC_SIZE]; + +struct _bdev_t { + int pdrv; +}; + +DRESULT disk_read(void *bdev_in, BYTE *buff, DWORD sector, UINT count) { + struct _bdev_t *bdev = bdev_in; + printf("disk_read(%d, %u, %u)\n", bdev->pdrv, sector, count); + memcpy(buff, ram_bdev + sector * SEC_SIZE, count * SEC_SIZE); + return RES_OK; +} + +static DWORD sector_no_hash = -1; +DRESULT disk_write(void *bdev_in, const BYTE *buff, DWORD sector, UINT count) { + struct _bdev_t *bdev = bdev_in; + printf("disk_write(%d, %u, %u, ", bdev->pdrv, sector, count); + if (sector == sector_no_hash) { + // some sectors have non-deterministic data + printf(""); + } else { + printf("0x%08x", hash_djb2(buff, count * SEC_SIZE)); + } + printf(")\n"); + memcpy(ram_bdev + sector * SEC_SIZE, buff, count * SEC_SIZE); + return RES_OK; +} + +DRESULT disk_ioctl(void *bdev_in, BYTE cmd, void *buff) { + struct _bdev_t *bdev = bdev_in; + printf("disk_ioctl(%d, %u)\n", bdev->pdrv, cmd); + switch (cmd) { + case CTRL_SYNC: break; + case GET_SECTOR_COUNT: *((DWORD*)buff) = NSEC; break; + case GET_SECTOR_SIZE: *((WORD*)buff) = SEC_SIZE; break; + case GET_BLOCK_SIZE: *((DWORD*)buff) = 1; break; + case IOCTL_INIT: *((DSTATUS*)buff) = 0; break; + case IOCTL_STATUS: *((DSTATUS*)buff) = 0; break; + default: assert(0); + } + return RES_OK; +} + +DWORD get_fattime(void) { + printf("get_fattime()\n"); + return 0; +} + +int main() { + struct _bdev_t bdev = {0}; + FATFS fatfs; + fatfs.drv = &bdev; + + printf("== MKFS ==\n"); + { + FRESULT res = f_mkfs(&fatfs, 1, 0); + printf("mkfs res=%d\n", res); + } + + printf("== MOUNT ==\n"); + { + FRESULT res = f_mount(&fatfs); + printf("mount res=%d\n", res); + } + + printf("== SET LABEL ==\n"); + { + FRESULT res = f_setlabel(&fatfs, "LABEL"); + printf("setlabel res=%d\n", res); + } + + printf("== GET LABEL ==\n"); + { + uint8_t buf[256]; + DWORD vsn; + FRESULT res = f_getlabel(&fatfs, (TCHAR*)buf, &vsn); + printf("getlabel res=%d label=%.12s vsn=%u\n", res, buf, vsn); + } + + printf("== FILE CREATION ==\n"); + { + FIL fp; + FRESULT res = f_open(&fatfs, &fp, "/test.txt", FA_WRITE | FA_CREATE_ALWAYS); + printf("open res=%d\n", res); + UINT n; + res = f_write(&fp, "test file\n", 10, &n); + printf("write res=%d n=%u\n", res, n); + sector_no_hash = 34; + res = f_close(&fp); + sector_no_hash = -1; + printf("close res=%d\n", res); + } + + printf("== FILE READ ==\n"); + { + FIL fp; + FRESULT res = f_open(&fatfs, &fp, "/test.txt", FA_READ); + printf("open res=%d\n", res); + uint8_t buf[100]; + UINT n; + res = f_read(&fp, buf, 100, &n); + printf("read res=%d n=%u\n", res, n); + hexdump(buf, n, 16); + res = f_close(&fp); + printf("close res=%d\n", res); + } + + printf("== STAT ==\n"); + { + FILINFO fno; + #if _USE_LFN + fno.lfname = NULL; + fno.lfsize = 0; + #endif + FRESULT res = f_stat(&fatfs, "/test.txt", &fno); + printf("stat res=%d size=%u date=%u time=%u attrib=%u\n", res, fno.fsize, fno.fdate, fno.ftime, fno.fattrib); + } + + printf("== FILE CREATION, LONG NAME AND LOTS OF DATA ==\n"); + { + FIL fp; + FRESULT res = f_open(&fatfs, &fp, "/filename-that-is-long.txt", FA_WRITE | FA_CREATE_ALWAYS); + printf("open res=%d\n", res); + UINT n; + for (int i = 0; i < 10; ++i) { + res = f_write(&fp, "More data for the test file. Need to have enough characters to fill more than one 512-byte sector.\n", 100, &n); + printf("write res=%d n=%u\n", res, n); + } + res = f_close(&fp); + printf("close res=%d\n", res); + } + + printf("== FILE SEEK AND READ ==\n"); + { + FIL fp; + FRESULT res = f_open(&fatfs, &fp, "/filename-that-is-long.txt", FA_READ); + printf("open res=%d\n", res); + res = f_lseek(&fp, 800); + printf("lseek res=%d\n", res); + printf("tell %d\n", f_tell(&fp)); + uint8_t buf[100]; + UINT n; + res = f_read(&fp, buf, 100, &n); + printf("read res=%d n=%u\n", res, n); + hexdump(buf, n, 16); + res = f_close(&fp); + printf("close res=%d\n", res); + } + + printf("== MKDIR ==\n"); + { + FRESULT res = f_mkdir(&fatfs, "/dir"); + printf("mkdir res=%d\n", res); + } + + printf("== DIRECTORY LISTING ==\n"); + { + DIR dp; + FRESULT res = f_opendir(&fatfs, &dp, "/"); + printf("opendir res=%d\n", res); + FILINFO fno; + #if _USE_LFN + char lfn[_MAX_LFN + 1]; + fno.lfname = lfn; + fno.lfsize = sizeof(lfn); + #endif + for (;;){ + res = f_readdir(&dp, &fno); + if (res != FR_OK || fno.fname[0] == 0) { + break; + } + #if _USE_LFN + // note: lfname is empty string if it fits in 12 chars in fname + printf("readdir res=%d size=%u name=/%s/ lname=/%s/\n", res, fno.fsize, fno.fname, fno.lfname); + #else + printf("readdir res=%d size=%u name=/%s/\n", res, fno.fsize, fno.fname); + #endif + } + res = f_closedir(&dp); + printf("closedir res=%d\n", res); + } + + printf("== RENAME FILE ==\n"); + { + FRESULT res = f_rename(&fatfs, "/test.txt", "/test2.txt"); + printf("unlink res=%d\n", res); + } + + printf("== UNLINK FILE ==\n"); + { + FRESULT res = f_unlink(&fatfs, "/test2.txt"); + printf("unlink res=%d\n", res); + } + + printf("== RENAME DIR ==\n"); + { + FRESULT res = f_rename(&fatfs, "/dir", "/dir2"); + printf("unlink res=%d\n", res); + } + + printf("== UNLINK DIR ==\n"); + { + FRESULT res = f_unlink(&fatfs, "/dir2"); + printf("unlink res=%d\n", res); + } + + printf("== FREE SPACE ==\n"); + { + DWORD nclst; + FRESULT res = f_getfree(&fatfs, &nclst); + printf("getfree res=%d nclst=%u\n", res, nclst); + } + + return 0; +} diff --git a/tests/fatfs1.exp b/tests/fatfs1.exp new file mode 100644 index 0000000..c74649c --- /dev/null +++ b/tests/fatfs1.exp @@ -0,0 +1,196 @@ +== MKFS == +disk_ioctl(0, 5) +disk_ioctl(0, 1) +disk_ioctl(0, 3) +get_fattime() +disk_write(0, 0, 1, 0x56c0aabe) +disk_write(0, 1, 1, 0x9ca634d5) +disk_write(0, 2, 1, 0x082d5505) +disk_write(0, 3, 1, 0x082d5505) +disk_write(0, 4, 1, 0x082d5505) +disk_write(0, 5, 1, 0x082d5505) +disk_write(0, 6, 1, 0x082d5505) +disk_write(0, 7, 1, 0x082d5505) +disk_write(0, 8, 1, 0x082d5505) +disk_write(0, 9, 1, 0x082d5505) +disk_write(0, 10, 1, 0x082d5505) +disk_write(0, 11, 1, 0x082d5505) +disk_write(0, 12, 1, 0x082d5505) +disk_write(0, 13, 1, 0x082d5505) +disk_write(0, 14, 1, 0x082d5505) +disk_write(0, 15, 1, 0x082d5505) +disk_write(0, 16, 1, 0x082d5505) +disk_write(0, 17, 1, 0x082d5505) +disk_write(0, 18, 1, 0x082d5505) +disk_write(0, 19, 1, 0x082d5505) +disk_write(0, 20, 1, 0x082d5505) +disk_write(0, 21, 1, 0x082d5505) +disk_write(0, 22, 1, 0x082d5505) +disk_write(0, 23, 1, 0x082d5505) +disk_write(0, 24, 1, 0x082d5505) +disk_write(0, 25, 1, 0x082d5505) +disk_write(0, 26, 1, 0x082d5505) +disk_write(0, 27, 1, 0x082d5505) +disk_write(0, 28, 1, 0x082d5505) +disk_write(0, 29, 1, 0x082d5505) +disk_write(0, 30, 1, 0x082d5505) +disk_write(0, 31, 1, 0x082d5505) +disk_write(0, 32, 1, 0x082d5505) +disk_write(0, 33, 1, 0x082d5505) +disk_ioctl(0, 0) +mkfs res=0 +== MOUNT == +disk_ioctl(0, 5) +disk_read(0, 0, 1) +mount res=0 +== SET LABEL == +disk_ioctl(0, 6) +disk_read(0, 2, 1) +get_fattime() +disk_write(0, 2, 1, 0x0d96b58b) +disk_ioctl(0, 0) +setlabel res=0 +== GET LABEL == +disk_ioctl(0, 6) +disk_read(0, 0, 1) +getlabel res=0 label=LABEL vsn=0 +== FILE CREATION == +disk_ioctl(0, 6) +disk_read(0, 2, 1) +get_fattime() +open res=0 +disk_ioctl(0, 6) +disk_write(0, 2, 1, 0x236a437d) +disk_read(0, 1, 1) +write res=0 n=10 +disk_ioctl(0, 6) +disk_write(0, 34, 1, ) +disk_write(0, 1, 1, 0x5343a9c5) +disk_read(0, 2, 1) +get_fattime() +disk_write(0, 2, 1, 0x6ae708d5) +disk_ioctl(0, 0) +disk_ioctl(0, 6) +close res=0 +== FILE READ == +disk_ioctl(0, 6) +open res=0 +disk_ioctl(0, 6) +disk_read(0, 34, 1) +read res=0 n=10 +0000 74 65 73 74 20 66 69 6c 65 0a test file. +disk_ioctl(0, 6) +disk_ioctl(0, 6) +close res=0 +== STAT == +disk_ioctl(0, 6) +stat res=0 size=10 date=0 time=0 attrib=32 +== FILE CREATION, LONG NAME AND LOTS OF DATA == +disk_ioctl(0, 6) +get_fattime() +open res=0 +disk_ioctl(0, 6) +disk_write(0, 2, 1, 0xf3dd04eb) +disk_read(0, 1, 1) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +disk_write(0, 35, 1, 0x4049ed30) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +write res=0 n=100 +disk_ioctl(0, 6) +disk_write(0, 36, 1, 0x37a6ca6c) +disk_write(0, 1, 1, 0x7f57e755) +disk_read(0, 2, 1) +get_fattime() +disk_write(0, 2, 1, 0xdd0a2fc3) +disk_ioctl(0, 0) +disk_ioctl(0, 6) +close res=0 +== FILE SEEK AND READ == +disk_ioctl(0, 6) +open res=0 +disk_ioctl(0, 6) +disk_read(0, 1, 1) +disk_read(0, 36, 1) +lseek res=0 +tell 800 +disk_ioctl(0, 6) +read res=0 n=100 +0000 4d 6f 72 65 20 64 61 74 61 20 66 6f 72 20 74 68 More data for th +0010 65 20 74 65 73 74 20 66 69 6c 65 2e 20 20 4e 65 e test file. Ne +0020 65 64 20 74 6f 20 68 61 76 65 20 65 6e 6f 75 67 ed to have enoug +0030 68 20 63 68 61 72 61 63 74 65 72 73 20 74 6f 20 h characters to +0040 66 69 6c 6c 20 6d 6f 72 65 20 74 68 61 6e 20 6f fill more than o +0050 6e 65 20 35 31 32 2d 62 79 74 65 20 73 65 63 74 ne 512-byte sect +0060 6f 72 2e 0a or.. +disk_ioctl(0, 6) +disk_ioctl(0, 6) +close res=0 +== MKDIR == +get_fattime() +disk_ioctl(0, 6) +disk_read(0, 2, 1) +disk_read(0, 1, 1) +disk_write(0, 1, 1, 0xa5c7187a) +disk_write(0, 37, 1, 0x2953772e) +disk_read(0, 2, 1) +disk_write(0, 2, 1, 0x55944b21) +disk_ioctl(0, 0) +mkdir res=0 +== DIRECTORY LISTING == +disk_ioctl(0, 6) +opendir res=0 +disk_ioctl(0, 6) +readdir res=0 size=10 name=/test.txt/ lname=// +disk_ioctl(0, 6) +readdir res=0 size=1000 name=/FILENA~1.TXT/ lname=/filename-that-is-long.txt/ +disk_ioctl(0, 6) +readdir res=0 size=0 name=/dir/ lname=// +disk_ioctl(0, 6) +disk_ioctl(0, 6) +closedir res=0 +== RENAME FILE == +disk_ioctl(0, 6) +disk_write(0, 2, 1, 0xccafbc76) +disk_ioctl(0, 0) +unlink res=0 +== UNLINK FILE == +disk_ioctl(0, 6) +disk_write(0, 2, 1, 0x76e9bdff) +disk_read(0, 1, 1) +disk_write(0, 1, 1, 0xd19f436a) +disk_ioctl(0, 0) +unlink res=0 +== RENAME DIR == +disk_ioctl(0, 6) +disk_read(0, 2, 1) +disk_write(0, 2, 1, 0x1ff9ac0d) +disk_ioctl(0, 0) +unlink res=0 +== UNLINK DIR == +disk_ioctl(0, 6) +disk_read(0, 37, 1) +disk_read(0, 2, 1) +disk_write(0, 2, 1, 0x6ae11ad8) +disk_read(0, 1, 1) +disk_write(0, 1, 1, 0x61648e45) +disk_ioctl(0, 0) +unlink res=0 +== FREE SPACE == +disk_ioctl(0, 6) +getfree res=0 nclst=92 diff --git a/tests/fatfs1_conf.h b/tests/fatfs1_conf.h new file mode 100644 index 0000000..b408e76 --- /dev/null +++ b/tests/fatfs1_conf.h @@ -0,0 +1,33 @@ +#define _FFCONF 64180 +#define _FS_READONLY 0 +#define _FS_MINIMIZE 0 +#define _USE_STRFUNC 0 +#define _USE_FIND 0 +#define _USE_MKFS 1 +#define _USE_FASTSEEK 0 +#define _USE_LABEL 1 +#define _USE_FORWARD 0 +#define _CODE_PAGE 437 +#define _USE_LFN 1 +#define _MAX_LFN 255 +#define _LFN_UNICODE 0 +#define _STRF_ENCODE 3 +#define _FS_RPATH 0 +#define _VOLUMES 1 +#define _STR_VOLUME_ID 0 +#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3" +#define _MULTI_PARTITION 0 +#define _MIN_SS 512 +#define _MAX_SS 512 +#define _USE_TRIM 0 +#define _FS_NOFSINFO 0 +#define _FS_TINY 0 +#define _FS_NORTC 0 +#define _NORTC_MON 1 +#define _NORTC_MDAY 1 +#define _NORTC_YEAR 2015 +#define _FS_LOCK 0 +#define _FS_REENTRANT 0 +#define _FS_TIMEOUT 1000 +#define _SYNC_t HANDLE +#define _WORD_ACCESS 0 diff --git a/tests/util.c b/tests/util.c new file mode 100644 index 0000000..c90db10 --- /dev/null +++ b/tests/util.c @@ -0,0 +1,50 @@ +#include +#include + +#include "util.h" + +void hexdump(const uint8_t *buf, size_t len, size_t width) { + for (size_t i = 0; i < len; i += width) { + printf("%04x ", i); + size_t j; + for (j = i; j < len && j < i + width; ++j) { + printf("%02x ", buf[j]); + } + for (; j < i + width; ++j) { + printf(" "); + } + for (j = i; j < len && j < i + width; ++j) { + int c = buf[j]; + if (c < 32 || c > 126) { + c = '.'; + } + printf("%c", c); + } + printf("\n"); + } +} + +uint32_t hash_djb2(const uint8_t *data, size_t len) { + // djb2 algorithm; see http://www.cse.yorku.ca/~oz/hash.html + uint32_t hash = 5381; + for (const uint8_t *top = data + len; data < top; data++) { + hash = ((hash << 5) + hash) ^ (*data); // hash * 33 ^ data + } + return hash; +} + +void hashdump(const uint8_t *data, size_t len, size_t block_size, size_t width) { + const uint8_t *top = data + len; + for (size_t i = 0; data < top;) { + size_t n = top - data; + if (n > block_size) { + n = block_size; + } + printf("%08x ", hash_djb2(data, n)); + i += 1; + data += n; + if (i % width == 0 || data >= top) { + printf("\n"); + } + } +} diff --git a/tests/util.h b/tests/util.h new file mode 100644 index 0000000..5226bfc --- /dev/null +++ b/tests/util.h @@ -0,0 +1,5 @@ +#pragma once + +void hexdump(const uint8_t *buf, size_t len, size_t width); +uint32_t hash_djb2(const uint8_t *data, size_t len); +void hashdump(const uint8_t *data, size_t len, size_t block_size, size_t width); From b77074a63d45591c6d06d340452a6d67925bf903 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Dec 2016 16:35:29 +1100 Subject: [PATCH 13/24] tests: Update fatfs1 test. --- tests/fatfs1.c | 11 +---------- tests/fatfs1.exp | 23 +++++++++++------------ tests/fatfs1_conf.h | 6 ++++-- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/tests/fatfs1.c b/tests/fatfs1.c index 8db9098..7350b96 100644 --- a/tests/fatfs1.c +++ b/tests/fatfs1.c @@ -119,10 +119,6 @@ int main() { printf("== STAT ==\n"); { FILINFO fno; - #if _USE_LFN - fno.lfname = NULL; - fno.lfsize = 0; - #endif FRESULT res = f_stat(&fatfs, "/test.txt", &fno); printf("stat res=%d size=%u date=%u time=%u attrib=%u\n", res, fno.fsize, fno.fdate, fno.ftime, fno.fattrib); } @@ -170,11 +166,6 @@ int main() { FRESULT res = f_opendir(&fatfs, &dp, "/"); printf("opendir res=%d\n", res); FILINFO fno; - #if _USE_LFN - char lfn[_MAX_LFN + 1]; - fno.lfname = lfn; - fno.lfsize = sizeof(lfn); - #endif for (;;){ res = f_readdir(&dp, &fno); if (res != FR_OK || fno.fname[0] == 0) { @@ -182,7 +173,7 @@ int main() { } #if _USE_LFN // note: lfname is empty string if it fits in 12 chars in fname - printf("readdir res=%d size=%u name=/%s/ lname=/%s/\n", res, fno.fsize, fno.fname, fno.lfname); + printf("readdir res=%d size=%u name=/%s/ lname=/%s/\n", res, fno.fsize, fno.altname, fno.fname); #else printf("readdir res=%d size=%u name=/%s/\n", res, fno.fsize, fno.fname); #endif diff --git a/tests/fatfs1.exp b/tests/fatfs1.exp index c74649c..c539ee2 100644 --- a/tests/fatfs1.exp +++ b/tests/fatfs1.exp @@ -46,7 +46,6 @@ mount res=0 == SET LABEL == disk_ioctl(0, 6) disk_read(0, 2, 1) -get_fattime() disk_write(0, 2, 1, 0x0d96b58b) disk_ioctl(0, 0) setlabel res=0 @@ -60,14 +59,14 @@ disk_read(0, 2, 1) get_fattime() open res=0 disk_ioctl(0, 6) -disk_write(0, 2, 1, 0x236a437d) +disk_write(0, 2, 1, 0xa8b3f35d) disk_read(0, 1, 1) write res=0 n=10 disk_ioctl(0, 6) disk_write(0, 34, 1, ) +get_fattime() disk_write(0, 1, 1, 0x5343a9c5) disk_read(0, 2, 1) -get_fattime() disk_write(0, 2, 1, 0x6ae708d5) disk_ioctl(0, 0) disk_ioctl(0, 6) @@ -90,7 +89,7 @@ disk_ioctl(0, 6) get_fattime() open res=0 disk_ioctl(0, 6) -disk_write(0, 2, 1, 0xf3dd04eb) +disk_write(0, 2, 1, 0xb1d034cb) disk_read(0, 1, 1) write res=0 n=100 disk_ioctl(0, 6) @@ -114,9 +113,9 @@ disk_ioctl(0, 6) write res=0 n=100 disk_ioctl(0, 6) disk_write(0, 36, 1, 0x37a6ca6c) +get_fattime() disk_write(0, 1, 1, 0x7f57e755) disk_read(0, 2, 1) -get_fattime() disk_write(0, 2, 1, 0xdd0a2fc3) disk_ioctl(0, 0) disk_ioctl(0, 6) @@ -142,11 +141,11 @@ disk_ioctl(0, 6) disk_ioctl(0, 6) close res=0 == MKDIR == -get_fattime() disk_ioctl(0, 6) disk_read(0, 2, 1) disk_read(0, 1, 1) disk_write(0, 1, 1, 0xa5c7187a) +get_fattime() disk_write(0, 37, 1, 0x2953772e) disk_read(0, 2, 1) disk_write(0, 2, 1, 0x55944b21) @@ -156,22 +155,22 @@ mkdir res=0 disk_ioctl(0, 6) opendir res=0 disk_ioctl(0, 6) -readdir res=0 size=10 name=/test.txt/ lname=// +readdir res=0 size=10 name=/TEST.TXT/ lname=/test.txt/ disk_ioctl(0, 6) readdir res=0 size=1000 name=/FILENA~1.TXT/ lname=/filename-that-is-long.txt/ disk_ioctl(0, 6) -readdir res=0 size=0 name=/dir/ lname=// +readdir res=0 size=0 name=/DIR/ lname=/dir/ disk_ioctl(0, 6) disk_ioctl(0, 6) closedir res=0 == RENAME FILE == disk_ioctl(0, 6) -disk_write(0, 2, 1, 0xccafbc76) +disk_write(0, 2, 1, 0xcdb1e73c) disk_ioctl(0, 0) unlink res=0 == UNLINK FILE == disk_ioctl(0, 6) -disk_write(0, 2, 1, 0x76e9bdff) +disk_write(0, 2, 1, 0x12c8992d) disk_read(0, 1, 1) disk_write(0, 1, 1, 0xd19f436a) disk_ioctl(0, 0) @@ -179,14 +178,14 @@ unlink res=0 == RENAME DIR == disk_ioctl(0, 6) disk_read(0, 2, 1) -disk_write(0, 2, 1, 0x1ff9ac0d) +disk_write(0, 2, 1, 0x2b759c33) disk_ioctl(0, 0) unlink res=0 == UNLINK DIR == disk_ioctl(0, 6) disk_read(0, 37, 1) disk_read(0, 2, 1) -disk_write(0, 2, 1, 0x6ae11ad8) +disk_write(0, 2, 1, 0x09922d72) disk_read(0, 1, 1) disk_write(0, 1, 1, 0x61648e45) disk_ioctl(0, 0) diff --git a/tests/fatfs1_conf.h b/tests/fatfs1_conf.h index b408e76..5c1ccc2 100644 --- a/tests/fatfs1_conf.h +++ b/tests/fatfs1_conf.h @@ -1,10 +1,12 @@ -#define _FFCONF 64180 +#define _FFCONF 88100 #define _FS_READONLY 0 #define _FS_MINIMIZE 0 #define _USE_STRFUNC 0 #define _USE_FIND 0 #define _USE_MKFS 1 #define _USE_FASTSEEK 0 +#define _USE_EXPAND 0 +#define _USE_CHMOD 1 #define _USE_LABEL 1 #define _USE_FORWARD 0 #define _CODE_PAGE 437 @@ -22,6 +24,7 @@ #define _USE_TRIM 0 #define _FS_NOFSINFO 0 #define _FS_TINY 0 +#define _FS_EXFAT 1 #define _FS_NORTC 0 #define _NORTC_MON 1 #define _NORTC_MDAY 1 @@ -30,4 +33,3 @@ #define _FS_REENTRANT 0 #define _FS_TIMEOUT 1000 #define _SYNC_t HANDLE -#define _WORD_ACCESS 0 From 61859abddb853813890120e7b46abd8b4f8f1b71 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 28 Dec 2016 16:40:31 +1100 Subject: [PATCH 14/24] tests: Update fatfs1 test. --- tests/fatfs1.c | 3 ++- tests/fatfs1.exp | 16 ++++++++-------- tests/fatfs1_conf.h | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/fatfs1.c b/tests/fatfs1.c index 7350b96..a8a8e29 100644 --- a/tests/fatfs1.c +++ b/tests/fatfs1.c @@ -64,7 +64,8 @@ int main() { printf("== MKFS ==\n"); { - FRESULT res = f_mkfs(&fatfs, 1, 0); + uint8_t buf[SEC_SIZE]; + FRESULT res = f_mkfs(&fatfs, FM_FAT | FM_SFD, 0, buf, sizeof(buf)); printf("mkfs res=%d\n", res); } diff --git a/tests/fatfs1.exp b/tests/fatfs1.exp index c539ee2..f70bd9c 100644 --- a/tests/fatfs1.exp +++ b/tests/fatfs1.exp @@ -1,10 +1,10 @@ == MKFS == disk_ioctl(0, 5) -disk_ioctl(0, 1) disk_ioctl(0, 3) +disk_ioctl(0, 1) get_fattime() -disk_write(0, 0, 1, 0x56c0aabe) -disk_write(0, 1, 1, 0x9ca634d5) +disk_write(0, 0, 1, 0x01c410b6) +disk_write(0, 1, 1, 0xd21511dd) disk_write(0, 2, 1, 0x082d5505) disk_write(0, 3, 1, 0x082d5505) disk_write(0, 4, 1, 0x082d5505) @@ -65,7 +65,7 @@ write res=0 n=10 disk_ioctl(0, 6) disk_write(0, 34, 1, ) get_fattime() -disk_write(0, 1, 1, 0x5343a9c5) +disk_write(0, 1, 1, 0x42bbc4cd) disk_read(0, 2, 1) disk_write(0, 2, 1, 0x6ae708d5) disk_ioctl(0, 0) @@ -114,7 +114,7 @@ write res=0 n=100 disk_ioctl(0, 6) disk_write(0, 36, 1, 0x37a6ca6c) get_fattime() -disk_write(0, 1, 1, 0x7f57e755) +disk_write(0, 1, 1, 0x2d32005d) disk_read(0, 2, 1) disk_write(0, 2, 1, 0xdd0a2fc3) disk_ioctl(0, 0) @@ -144,7 +144,7 @@ close res=0 disk_ioctl(0, 6) disk_read(0, 2, 1) disk_read(0, 1, 1) -disk_write(0, 1, 1, 0xa5c7187a) +disk_write(0, 1, 1, 0x867a0372) get_fattime() disk_write(0, 37, 1, 0x2953772e) disk_read(0, 2, 1) @@ -172,7 +172,7 @@ unlink res=0 disk_ioctl(0, 6) disk_write(0, 2, 1, 0x12c8992d) disk_read(0, 1, 1) -disk_write(0, 1, 1, 0xd19f436a) +disk_write(0, 1, 1, 0xf848f062) disk_ioctl(0, 0) unlink res=0 == RENAME DIR == @@ -187,7 +187,7 @@ disk_read(0, 37, 1) disk_read(0, 2, 1) disk_write(0, 2, 1, 0x09922d72) disk_read(0, 1, 1) -disk_write(0, 1, 1, 0x61648e45) +disk_write(0, 1, 1, 0x5535694d) disk_ioctl(0, 0) unlink res=0 == FREE SPACE == diff --git a/tests/fatfs1_conf.h b/tests/fatfs1_conf.h index 5c1ccc2..62ce3c3 100644 --- a/tests/fatfs1_conf.h +++ b/tests/fatfs1_conf.h @@ -1,4 +1,4 @@ -#define _FFCONF 88100 +#define _FFCONF 80186 #define _FS_READONLY 0 #define _FS_MINIMIZE 0 #define _USE_STRFUNC 0 From 52ce982234f131c56416c70723940c344f1b1853 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Jan 2017 17:40:20 +1100 Subject: [PATCH 15/24] src: Decrease minimum volume size down to 50 sectors. This seems to be the minimum that holds a FAT12 filesystem. --- src/ff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ff.c b/src/ff.c index e788ba8..624eef8 100644 --- a/src/ff.c +++ b/src/ff.c @@ -5156,7 +5156,7 @@ FRESULT f_mkfs ( if (sz_vol < b_vol) return FR_MKFS_ABORTED; sz_vol -= b_vol; /* Volume size */ } - if (sz_vol < 128) return FR_MKFS_ABORTED; /* Check if volume size is >=128s */ + if (sz_vol < 50) return FR_MKFS_ABORTED; /* Check if volume size is >=50s */ /* Pre-determine the FAT type */ do { From 85fff88c26e2f053b13a0aa714d36ce239db78d0 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 24 Jan 2017 23:19:50 +1100 Subject: [PATCH 16/24] tests: Update fatfs1 test. --- tests/fatfs1_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fatfs1_conf.h b/tests/fatfs1_conf.h index 62ce3c3..569d943 100644 --- a/tests/fatfs1_conf.h +++ b/tests/fatfs1_conf.h @@ -1,4 +1,4 @@ -#define _FFCONF 80186 +#define _FFCONF 68020 #define _FS_READONLY 0 #define _FS_MINIMIZE 0 #define _USE_STRFUNC 0 From f943743e0b3cc24522ab51e652befedcb49ace00 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 27 Jan 2017 12:46:07 +1100 Subject: [PATCH 17/24] src: Add short header to source files to describe and point to git repo. --- src/diskio.h | 4 ++++ src/ff.c | 4 ++++ src/ff.h | 4 ++++ src/ffconf.h | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/src/diskio.h b/src/diskio.h index eb51a9f..8deb68e 100644 --- a/src/diskio.h +++ b/src/diskio.h @@ -1,3 +1,7 @@ +/* This file is part of ooFatFs, a customised version of FatFs + * See https://github.com/micropython/oofatfs for details + */ + /*-----------------------------------------------------------------------/ / Low level disk interface modlue include file (C)ChaN, 2014 / /-----------------------------------------------------------------------*/ diff --git a/src/ff.c b/src/ff.c index 624eef8..d749280 100644 --- a/src/ff.c +++ b/src/ff.c @@ -1,3 +1,7 @@ +/* This file is part of ooFatFs, a customised version of FatFs + * See https://github.com/micropython/oofatfs for details + */ + /*----------------------------------------------------------------------------/ / FatFs - Generic FAT file system module R0.12b / /-----------------------------------------------------------------------------/ diff --git a/src/ff.h b/src/ff.h index 1c426c4..74f9fc9 100644 --- a/src/ff.h +++ b/src/ff.h @@ -1,3 +1,7 @@ +/* This file is part of ooFatFs, a customised version of FatFs + * See https://github.com/micropython/oofatfs for details + */ + /*----------------------------------------------------------------------------/ / FatFs - Generic FAT file system module R0.12b / /-----------------------------------------------------------------------------/ diff --git a/src/ffconf.h b/src/ffconf.h index 15ce0b9..af7d152 100644 --- a/src/ffconf.h +++ b/src/ffconf.h @@ -1,3 +1,7 @@ +/* This file is part of ooFatFs, a customised version of FatFs + * See https://github.com/micropython/oofatfs for details + */ + /*---------------------------------------------------------------------------/ / FatFs - FAT file system module configuration file /---------------------------------------------------------------------------*/ From a346ccec123c2e4d887e2751d64156208d03bff4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 27 Jan 2017 12:54:38 +1100 Subject: [PATCH 18/24] src: Use standrd, external memcpy/memset/memcmp functions. --- src/ff.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/src/ff.c b/src/ff.c index d749280..fca6c4f 100644 --- a/src/ff.c +++ b/src/ff.c @@ -22,6 +22,8 @@ /----------------------------------------------------------------------------*/ +#include + #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of device I/O functions */ @@ -676,37 +678,12 @@ void st_qword (BYTE* ptr, QWORD val) /* Store an 8-byte word in little-endian /* String functions */ /*-----------------------------------------------------------------------*/ -/* Copy memory to memory */ -static -void mem_cpy (void* dst, const void* src, UINT cnt) { - BYTE *d = (BYTE*)dst; - const BYTE *s = (const BYTE*)src; - - if (cnt) { - do *d++ = *s++; while (--cnt); - } -} - -/* Fill memory block */ -static -void mem_set (void* dst, int val, UINT cnt) { - BYTE *d = (BYTE*)dst; - - do *d++ = (BYTE)val; while (--cnt); -} - -/* Compare memory block */ -static -int mem_cmp (const void* dst, const void* src, UINT cnt) { /* ZR:same, NZ:different */ - const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; - int r = 0; - - do { - r = *d++ - *s++; - } while (--cnt && r == 0); - - return r; -} +// These were originally provided by the FatFs library but we use externally +// provided versions from C stdlib to (hopefully) reduce code size and use +// more efficient versions. +#define mem_cpy memcpy +#define mem_set memset +#define mem_cmp memcmp /* Check if chr is contained in the string */ static From 1e295b40550664bbaac18d95a4b6a58154464d31 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 27 Jan 2017 23:17:41 +1100 Subject: [PATCH 19/24] src: Use curly braces for empty for-loop body to silence compiler warn. --- src/ff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ff.c b/src/ff.c index fca6c4f..346f3df 100644 --- a/src/ff.c +++ b/src/ff.c @@ -4803,7 +4803,7 @@ FRESULT f_setlabel ( dj.obj.fs = fs; /* Get length of given volume label */ - for (slen = 0; (UINT)label[slen] >= ' '; slen++) ; /* Get name length */ + for (slen = 0; (UINT)label[slen] >= ' '; slen++) { } /* Get name length */ #if _FS_EXFAT if (fs->fs_type == FS_EXFAT) { /* On the exFAT volume */ From d14e78c44dc02f37ccd2e9ad76b8214f4d4ff137 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 30 Jan 2017 12:01:30 +1100 Subject: [PATCH 20/24] src: Make f_mount compile when _FS_REENTRANT is enabled. --- src/ff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ff.c b/src/ff.c index 346f3df..5637e71 100644 --- a/src/ff.c +++ b/src/ff.c @@ -3104,7 +3104,7 @@ FRESULT f_mount ( fs->fs_type = 0; /* Clear new fs object */ #if _FS_REENTRANT /* Create sync object for the new volume */ - if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; + if (!ff_cre_syncobj(fs, &fs->sobj)) return FR_INT_ERR; #endif res = find_volume(fs, 0); /* Force mounted the volume */ From fad030a0a921eefc10b4ab57f5d651b72b5432da Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 30 Jan 2017 12:02:24 +1100 Subject: [PATCH 21/24] src: Make f_sync compile when EXFAT is disabled, REENTRANT enabled. --- src/ff.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ff.c b/src/ff.c index 5637e71..747ea55 100644 --- a/src/ff.c +++ b/src/ff.c @@ -3562,7 +3562,9 @@ FRESULT f_sync ( FATFS *fs; DWORD tm; BYTE *dir; +#if _FS_EXFAT DEF_NAMBUF +#endif res = validate(&fp->obj, &fs); /* Check validity of the file object */ From 51d88acfabb92ab1d6ea53e8e356733be6c4adab Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 30 Jan 2017 12:03:54 +1100 Subject: [PATCH 22/24] src: Make ff_cre_syncobj take a FATFS* as first arg, instead of BYTE. --- src/ff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ff.h b/src/ff.h index 74f9fc9..c79b5bc 100644 --- a/src/ff.h +++ b/src/ff.h @@ -327,7 +327,7 @@ void ff_memfree (void* mblock); /* Free memory block */ /* Sync functions */ #if _FS_REENTRANT -int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */ +int ff_cre_syncobj (FATFS *fatfs, _SYNC_t* sobj); /* Create a sync object */ int ff_req_grant (_SYNC_t sobj); /* Lock sync object */ void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */ int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ From 6545af25ed11e1f694f63aefbff55306a3dc1847 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 30 Jan 2017 12:04:13 +1100 Subject: [PATCH 23/24] src: Rename DIR to FF_DIR, to not clash with POSIX declaration. --- src/ff.c | 2 ++ src/ff.h | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/ff.c b/src/ff.c index 747ea55..b098475 100644 --- a/src/ff.c +++ b/src/ff.c @@ -27,6 +27,8 @@ #include "ff.h" /* Declarations of FatFs API */ #include "diskio.h" /* Declarations of device I/O functions */ +// DIR has been renamed FF_DIR in the public API so it doesn't clash with POSIX +#define DIR FF_DIR /*-------------------------------------------------------------------------- diff --git a/src/ff.h b/src/ff.h index c79b5bc..068de11 100644 --- a/src/ff.h +++ b/src/ff.h @@ -197,7 +197,7 @@ typedef struct { -/* Directory object structure (DIR) */ +/* Directory object structure (FF_DIR) */ typedef struct { _FDID obj; /* Object identifier */ @@ -212,7 +212,7 @@ typedef struct { #if _USE_FIND const TCHAR* pat; /* Pointer to the name matching pattern */ #endif -} DIR; +} FF_DIR; @@ -270,11 +270,11 @@ FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write dat FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ FRESULT f_truncate (FIL* fp); /* Truncate the file */ FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ -FRESULT f_opendir (FATFS *fs, DIR* dp, const TCHAR* path); /* Open a directory */ -FRESULT f_closedir (DIR* dp); /* Close an open directory */ -FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ -FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ -FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ +FRESULT f_opendir (FATFS *fs, FF_DIR* dp, const TCHAR* path); /* Open a directory */ +FRESULT f_closedir (FF_DIR* dp); /* Close an open directory */ +FRESULT f_readdir (FF_DIR* dp, FILINFO* fno); /* Read a directory item */ +FRESULT f_findfirst (FF_DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ +FRESULT f_findnext (FF_DIR* dp, FILINFO* fno); /* Find next file */ FRESULT f_mkdir (FATFS *fs, const TCHAR* path); /* Create a sub directory */ FRESULT f_unlink (FATFS *fs, const TCHAR* path); /* Delete an existing file or directory */ FRESULT f_rename (FATFS *fs, const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ From 46fb53331e7a583c29a41d37ce4b53f2718597e5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 30 Jan 2017 12:04:49 +1100 Subject: [PATCH 24/24] tests: Fix fatfs1 test to work with new FF_DIR type. --- tests/fatfs1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fatfs1.c b/tests/fatfs1.c index a8a8e29..bf14ceb 100644 --- a/tests/fatfs1.c +++ b/tests/fatfs1.c @@ -163,7 +163,7 @@ int main() { printf("== DIRECTORY LISTING ==\n"); { - DIR dp; + FF_DIR dp; FRESULT res = f_opendir(&fatfs, &dp, "/"); printf("opendir res=%d\n", res); FILINFO fno;