How to use a file system on a flash chip with 256KB erase sectors - filesystems

I have been asked to help out on an embedded firmware project where they are trying to mount a file system on an SPI flash chip (Cypress S25FL512S) with a 256KB (Kilo Byte) Erase sector size.
My past experience with file systems is that the file system has a block size upto 4Kbytes which is mapped onto erase sectors of 512bytes to 4Kbytes
The embedded controller is a small NXP device running at 180MHz with 512KBytes of RAM so I cannot even cache an erase sector. I note that the chip family does have pin compatible devices with smaller erase sectors.
My general question is how do you mount a file system with a block/cluster size that is smaller than the flash erase sector size? I've not been able to find any articles addressing this.

You can't do this in any sensible way. Your specification needs to be modified.
Possible solutions are:
Pick a flash/eeprom circuit with smaller erase size.
Pick a flash/eeprom with more memory and multiple segments, so that you can back-up the data in one segment while programming another.
Add a second flash circuit which mirrors the first one, erase one at a time and overwrite with contents of the other.
Pick a MCU with more RAM.
Backup the flash inside MCU flash (very slow and likely defeats the purpose of having external flash to begin with).

Related

How to get size of disk driver sector

Can get size of disk sector via the Linux API/ABI? It's about the quantum of I/O disk, normally it's equal 512 bytes, but others values can be too (usually multiple 512 bytes).
Also it should not confuse to size of logical block or to size of sector of a file system.
A block device is reflected as file in a file system of an UNIX (/dev/sda, /dev/sr etc.) It means, can open that file and make some manipulations to its content like with content of the corresponded block device.
So specifically the work to a true block device similar the work to a virtual hard disk (the .vhd format for instance).
But i don't know how to get size of sector in general case.
At moment i've single solution: get the maximal CHS address and size of hard drive, both action via BIOS. But i think, it's bad idea, because portability lost

FATFS porting on STM32F103 SPI Flash

I have ported FATFS for Free RTOS on STM32F103 SPI Flash of 32 Mbit. In a demo Application I have successfully created a file, written a file, and read back from the file. My requirement is like I have to store multiple files (images) in SPI flash and read it back when required.
I have the following conditions/queries.
I have set the Sector Size to 512 bytes, and block erase size for SPI flash is 4K. As in the SPI Flash, block needs to be erased before written. Do I need to keep track on whether a particular block is erased or not or its the file System who is managing this?
How can I verify that the sector, which I am writing in erased or not? What I am currently doing is, Erase the Complete Block for the sector, which I am going to write?
How can I make sure, The Block for SPI flash I am going to erase will not affect any Sector containing useful data?
Thanking in an Anticipation,
Regards,
AK
The simplest solution is to define the "cluster" size to 4K, the same as the page size of your flash. That mean each file, even if only 1 byte, takes 4K, which is 8 consecutive sectors of 512 bytes each.
As soon as you need to reserve one more cluster, when the file grow above 4096 bytes, you pick a free cluster, chain it to the FAT, and write the next byte.
For performance reason and to increase the durability of the flash, you should avoid to erase of flash sector when not needed. It is many order of magnitude faster to read then erasing. So, as you select a free cluster, you can start a loop to read each of the 8 sectors. As soon as you find even a single byte not equal to 0xFF, then you abort the loop and call the flash erase for that sector.
A further optimization is possible if the flash controller is able to perform the blank test directly. Such test could be done in a few microsecond while reading 8 sectors and looping to check each of the 4096 bytes is probably slower.

Can sector size of USB flash drive be changed?

i know the cluster size of a USB flash drive can be changed , can we change the sector size too ??
Sector size isn't a configurable parameter in ATA/SATA/SCSI/etc devices and, from my experience, USB flash drives implement one of these protocols. The sector size is reported by the device itself but, even if you could set it to something other than 512, you would likely run into a latent bug somewhere in a driver or file system package that assumed a sector size of 512.
There are real reasons for using a sector size like 512, for example, addressing of larger sectors can be done more quickly and efficiently (not just in time but in size/space as well). Throughput to these devices is also better with something like 512. Consider that, if you could set sector size to something like 16-bytes, you might have less wasted space with 16-byte sectors compared to having a number of half-full 512-byte sectors, but your throughput to the device would probably be worse. In fact, writing a single 16-byte sector would only be slightly faster than writing a single 512-byte sector. On the other hand, writing 32 16-byte sectors (to write a total of 512 bytes) would likely take longer than writing a single 512 byte sector simply due to the overhead associated with transferring multiple sectors.
I would suggest you buy a larger USB flash drive if you are worried about wasting space with 512-byte sectors.

Is there any way to write a few bytes to a disk sector without reading it first?

I've been experimenting with the performance of reading and writing files on Linux, specifically O_DIRECT, and I'm wondering, both at a hard drive level and the posix/Linux API level, is it possible to write only a few bytes to a sector, without destroying the rest of the sector, and without reading it first?
My experience with disk drives is that they expect data to be sent to them in entire sectors. So, basically, there's no way of writing less than an entire sector and if you wish to change the start of a sector without changing the end, you must read the whole sector, modify and write back. That is partly to do with how the disk head interacts with the platter (for physical disks anyway. In the case of flash drives, it's more likely to be with how small a chunk of the flash can be erased in one go).
In a portable way? Probably not.
In Linux and a few other Unix-like systems, you can open the block device for the drive, seek to a position (probably aligned to the sector size) and write some data to it, but I don't know what effect it would have on the remaining portion of that block.
Your best bet is to try it out on a virtual machine and see what happens. (Obviously, you'll have to have permission to write to the block device.)

Sectors written when over-writing a file?

Imagine there is a file of size 5 MB. I open it in write mode in C and then fill it up with junk data of exactly 5 MB. Will the same disk sectors previously used be overwritten or will the OS select new disk sectors for the new data?
It depends on the file system.
Classically, the answer would be 'yes, the same sectors would be overwritten with the new data'.
With journalled file systems, the answer might be different. With flash drive systems, the answer would almost certainly be 'no; new sectors will be written to avoid wearing out the currently written sectors'.
The filesystem could do anything it wishes. But any real file system will write the data back to the same sectors.
Image if it didn't. Every time your wrote to a file the file system would have to find a new free sector, write to that sector, then update the file system meta data for the file to point to the new sector. This would also cause horrible file fragmentation, because writing a single sector in the middle of your contiguous 5MB file would cause it to fragment. So it's much easier to just write back to the same sector.
The only exception I can think of is JFFS2 because it was designed to support wear leveling on flash.
Now the file system will write to the same sector, but the disk hardware could write anywhere it wants. In fact on SSD/flash drives the hardware, to handle wear leveling, is almost guaranteed to write the data to a different sector. But that is transparent to the OS/file system. (It's possible on hard drives as well due to sector sparing)

Resources