Configure FatFs for 256 page size

Hello All,

I am planning to port FatFs on the IS25LP064A flash drive to communicate with my STM32H573ii over SPI. The FreeRTOS is running on STM32H573ii.

According to the IS25LP064A datasheet, the maximum page size is 256 bytes. The total size of the flash drive is 8 Mbyte.

1] Could you help me set the following parameters in FatFs?

GET_SECTOR_COUNT = 32768 (8 Mbyte / 256 bytes)


Do I need to set the value of FF_MIN_SS since my maximum page size is 256 bytes?

FF_MIN_SS = 256

2] As per the datasheet, the erase block size is 4 Kbyte.

GET_BLOCK_SIZE = 16 (4 Kbyte / 256 bytes)

So Could you help me to find out the values of above parameters?

Are the parameter macros you have part of the FAT file system library or a block device layer between the FS library and an IS25LP064A flash driver that is in turn using the SPI interface driver? I did not see any such macros in the FreeRTOS-Plus-FAT Configuration page (TCP/IP stack configuration parameters).

Knowing what block storage driver you’re using will help answering your question.

Thanks for replay,

The FAT file system library and FreeRTOS, I am using is provided by STMicroelectronics.

These parameters are part of block device layer. The user has to define disk_ioctl() function under Diskio_drvTypeDef structure in ff_gen_drv.h file.
These parameters are part of disc_ioctl().
(Sorry, coping link is not allowed to me).

I am planning to write a block storage driver which will communicate with IS25LP064A over SPI bus.

Ugh. How old are those versions? Last time I looked the FatFS version was so old that the API didn’t match any documentation I could find. I would jettison those and download current releases.

FatFs is not ideal for use with FreeRTOS. It has some support for “reentrancy”, but it lacks sufficient locking (and/or thread specific context) to make operations like f_mkdir , f_chdir and f_getcwd thread safe. You could look at FreeRTOS-Plus-FAT instead.

I wonder if your block storage driver could emulate 512 byte blocks by dealing with pairs of 256 byte blocks under the covers.

Another one to consider is littlefs. It has no problem with small block sizes, but it doesn’t scale well to huge memories. It would probably work fine on 8 Mbyte.

1] It seems that you’ll need to set FF_MIN_SS = 256. Note - this is not a valid sector size per FatFs documentation so you may have additional work to get this functional.

2] The docs state “Retrieves erase block size in unit of sector”. Your math is right.

A few things that you need to do in a block driver for flash where you want a page size that is smaller than the erase sector size:

  • Create at least one buffer that is the size of an erase sector; it’s better to have multiple, especially for multithreaded access, also having one that always contains the active portion of the FAT for the file system will speed things up
  • Read a whole erase sector at a time an keep track of what sector is in each buffer; any time you read a sector into a buffer, mark the buffer as clean
  • When the application writes a block (or page):
    • Calculate the flash erase sector number that the block belongs to and the offset into the sector where the block begins
    • Find the sector buffer (think of it as a disk cache) with a current copy of the erase sector the block resides in
      • if no sector buffer contains the affected erase sector, read the required erase sector into a buffer and mark that buffer with the erase sector it now contains; select that sector buffer
      • if a sector buffer contains a copy of the affected erase sector, select that sector buffer
    • Copy the block data from the applications buffer to the selected sector buffer starting at the offset calculated earlier and mark the buffer as ‘dirty’
    • Erase the sector in flash (hold your breath because data can be lost if something goes wrong before the next step completes)
    • Write the data from the selected sector buffer back to the location in flash just erased (on completion of this operation, you can breath again), mark the selected buffer as ‘clean’

When I’ve done this, I have included the option (either compile-time or driver setting, depending on the platform) to only erase flash sectors and write ‘dirty’ sector buffers when they’re “cast out” due to running out of available sector buffers or when the “commit” API function is called. This has the benefit of reducing wear on the flash device. This “commit” API was done by the application around the virtual FS driver.

I have found that FAT is not well suited for NOR Flash, the allocation table (FAT) gets updated very often when doing writes to files, and this really reduces the lifetime of the device.