6
\$\begingroup\$

I'm working on a data logger application using a MSP430F5529 running at 2 MHz and a SD card using FatFs. The SPI interface is already running at maximum frequency.

However I am seeing very erratic performance: even with an empty SD card, file creation times start getting slower, to the point that having 100 files in the card sometimes takes almost 10 seconds. In this plot it becomes visible that:

enter image description here

I tried with a few different SD cards to the same results. What to do besides increasing frequency?

My FatFs configuration (ffconf.h) is

#define _FS_TINY        1    /* 0:Normal or 1:Tiny */
#define _FS_READONLY    0   /* 0:Read/Write or 1:Read only */

#define _FS_MINIMIZE    0   /* 0 to 3 */

/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
#define _USE_STRFUNC    2   /* 0:Disable or 1/2:Enable */


/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
#define _USE_MKFS       1   /* 0:Disable or 1:Enable */

#define _USE_FORWARD    1   /* 0:Disable or 1:Enable */
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */

/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
#define _USE_FASTSEEK   1   /* 0:Disable or 1:Enable */

/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
/  Incorrect setting of the code page can cause a file open failure. */
#define _CODE_PAGE  850 // CP850 used for Portuguese

#define _USE_LFN    1       /* 0 to 3 */
#define _MAX_LFN    255     /* Maximum LFN length to handle (12 to 255) */

/* The _USE_LFN option switches the LFN support.
/
/   0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
/   1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
/   2: Enable LFN with dynamic working buffer on the STACK.
/   3: Enable LFN with dynamic working buffer on the HEAP.
/
/  The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
/  Unicode handling functions ff_convert() and ff_wtoupper() must be added
/  to the project. When enable to use heap, memory control functions
/  ff_memalloc() and ff_memfree() must be added to the project. */


#define _LFN_UNICODE    0   /* 0:ANSI/OEM or 1:Unicode */

/* The _FS_RPATH option configures relative path feature.
/
/   0: Disable relative path feature and remove related functions.
/   1: Enable relative path. f_chdrive() and f_chdir() are available.
/   2: f_getcwd() is available in addition to 1.
/
/  Note that output of the f_readdir fnction is affected by this option. */
#define _FS_RPATH       2   /* 0 to 2 */



/*---------------------------------------------------------------------------/
/ Physical Drive Configurations
/----------------------------------------------------------------------------*/
#define _VOLUMES    1 /* No de volumes a ser usado */

/* 512, 1024, 2048 or 4096 */
/* Maximum sector size to be handled.
/  Always set 512 for memory card and hard disk but a larger value may be
/  required for on-board flash memory, floppy disk and optical disk.
/  When _MAX_SS is larger than 512, it configures FatFs to variable sector size
/  and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
#define _MAX_SS     512     /* 512, 1024, 2048 or 4096 */

#define _MULTI_PARTITION    0   /* 0:Single partition, 1/2:Enable multiple partition */

/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
/  should be added to the disk_ioctl functio. */
#define _USE_ERASE  0   /* 0:Disable or 1:Enable */


/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
/  option defines which access method is used to the word data on the FAT volume.
/
/   0: Byte-by-byte access.
/   1: Word access. Do not choose this unless following condition is met.
/
/  When the byte order on the memory is big-endian or address miss-aligned word
/  access results incorrect behavior, the _WORD_ACCESS must be set to 0.
/  If it is not the case, the value can also be set to 1 to improve the
/  performance and code size.
*/
#define _WORD_ACCESS    0   /* 0 or 1 */


#define _FS_REENTRANT   0       /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT     1000    /* Timeout period in unit of time ticks */
#define _SYNC_t         HANDLE  /* O/S dependent type of sync object. 
                                e.g. HANDLE, OS_EVENT*, ID and etc.. */

#define _FS_SHARE   0   /* 0:Disable or >=1:Enable */

#endif /* _FFCONFIG */
\$\endgroup\$
  • \$\begingroup\$ Change filesystems. \$\endgroup\$ – Ignacio Vazquez-Abrams Jan 9 '14 at 16:42
  • \$\begingroup\$ which FatFs settings are you using? \$\endgroup\$ – markrages Jan 9 '14 at 16:58
  • \$\begingroup\$ @markrages updated my question with my fatfs settings (ffconf.h). \$\endgroup\$ – Renan Jan 9 '14 at 17:06
  • \$\begingroup\$ Does this code have a read cache at all? Otherwise your search for free space is going to be the time consuming thing. But you may not have space for a read cache. \$\endgroup\$ – pjc50 Jan 9 '14 at 17:08
4
\$\begingroup\$

You are using _FS_TINY. From the documentation:

The disadvantage of the tiny buffer configuration is: the FAT data cached in the sector buffer will be lost by file data transfer and it must be reloaded at every cluster boundary.

So your micro is spending a lot of time reloading FAT information instead of cacheing it.

If you can spare the memory, try the _FS_TINY=0 configuration.

\$\endgroup\$
  • \$\begingroup\$ If writes are going on, are there implications for reliability in the face of a crash or the card being pulled out? \$\endgroup\$ – Kaz Jan 9 '14 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.