Adapting FatFs Generic File System Module for CodeVision
ChaN has published a pretty amazing generic FAT file system - as he says
FatFs is a generic FAT file system module for small embedded systems. The FatFs is written in compliance with ANSI C and completely
separated from the disk I/O layer. Therefore it is independent of hardware architecture. It can be incorporated into low cost
microcontrollers, such as AVR, 8051, PIC, ARM, Z80, 68k and etc..., without any change.
Here are a few (unessential) tweaks that I use with the CodeVisionAVR V2 compiler.
Tweaking Notes
These notes apply to the current (6-79-2011) version of FsFAT (R0.09) and CodeVisionAVR (V2.05.3a). They only cover changes to the ff.h and ff.c files as the other files are highly dependant on the hardware you use.
Changes to ff.h:
- Place integer.h and ff.h in an include file directory to suit your directory structure
- Around line 24
- Change the file reference to "integer.h" to <integer.h>
- Add #include <ctype.h>
- Add #include <string.h>
- Around line 340
- Add #pragma library ff.lib
These changes and additions look line this:
… line 25ish
#include <integer.h> /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#include <ctype.h>
#include <string.h>
… line 340ish
#pragma library ff.lib
#ifdef __cplusplus
}
#endif
#endif /* _FATFS */
Changes to ff.c:
- Rename ff.c to ff.lib and place in a library file directory, again, to suit your directory structure
- Around line 90
- Change the #include delimters to < and >
- Add the code below to ensure char is promoted to int
- Around line 350
- Comment out the 3 macros and replace with defines to use the ctype library
- Around line 520
- Comment out the 4 functions and replace with defines to use the string library
- Around line 4000 (end of file)
- Add the code below to restore the char promotion setting
These changes and additions look line this:
… line 90ish
#include <ff.h> /* FatFs configurations and declarations */
#include <diskio.h> /* Declarations of low level disk I/O functions */
#ifdef _PROMOTE_CHAR_TO_INT_OFF_
#define PROMOTE_OFF
#endif
#pragma promotechar+ // added to ensure correct arithmetic in places
… line 350ish
#define IsUpper isupper
#define IsLower islower
#define IsDigit isdigit
//#define IsUpper(c) (((c)>='A')&&((c)<='Z'))
//#define IsLower(c) (((c)>='a')&&((c)<='z'))
//#define IsDigit(c) (((c)>='0')&&((c)<='9'))
… line 520ish
#define mem_cpy memcpy
#define mem_set memset
#define mem_cmp memcmp
#define chk_chr strchr
#if 0
/* Copy memory to memory */
static
void mem_cpy (void* dst, const void* src, UINT cnt) {
… line 375ish
return *str;
}
#endif
… line 4000ish (actually end of file)
#ifdef PROMOTE_OFF
#pragma promotechar-
#endif
Obviously these are just tweaks and most of them are not absolutely necessary:
- You don't have to change the file delimiters if the original names suits your file structure.
- You don't have to make it into a library
- You don't have to refer to the ctype and string libraries but use the internal functions and macros (the advantage is probably a small saving in flash)
- You don't have to use the char promotion additions if you are compiling the project with promotion on. However, be warned that FsFAT MUST be compiled with promotion on for some of the fat arithmetic to produce the correct results.
Going slightly further…
I did a little more to suit myself that you might consider:
- I renamed integer.h to chan.h to avoid a clash with (or having to rename or merge with) another integer.h
- I renamed the configuration file to ff_cfg.h as it suits my file naming convention
- I renamed ff files to myff to avoid a clash with the Codevision filenames (myff.h, myff.c, myff_cfg.h)
- I put a comment line
// GSM
next to each change so I could find them again - I wanted access to the volume label, so I put comments into the following (commented out code in underline):
… line 1400ish
#else /* Non LFN configuration */
if (/*!(dir[DIR_Attr] & AM_VOL) &&*/ !mem_cmp(dir, dj->fn, 11))
/* Is it a valid entry? */
break;
#endif
res = dir_next(dj, 0); /* Next entry */
… line 1450ish
#else /* Non LFN configuration */
if (c != 0xE5 && (_FS_RPATH || c != '.') /* && !(dir[DIR_Attr] & AM_VOL)*/)
/* Is it a valid entry? */
break;
#endif
res = dir_next(dj, 0); /* Next entry */
if (res != FR_OK) break;
}
Afterword
I have only tested these changes in a limited fashion - for example I have not used long filenames. However, I have used the module with CodeVisionAVR with some pretty large projects (by my standards) with complete success.
The FatFs module is not mine - all credit and honour goes to ChaN.