3 ms·
> We want our driver a bit smarter than that; it should first check whether it's possible to write the bytes directly. In other words, we want to ensure that ev
by scoutt 6y ago
> We want our driver a bit smarter than that; it should first check whether it's possible to write the bytes directly. In other words, we want to ensure that every 1 in our intended write is also a 1 in the target space.
Is this standard practice? Everyone knows that one should write only on previously erased units (sectors/blocks/pages/whatever). Maybe it's just for the sake of the example, but I think it's kind of insane to produce a routine to check for EVERY BIT and see if it's 1 AND if we can fit whatever we want to write. What are the chances one can overwrite (for example) a string TWICE?
- toast0 6y agoI didn't read enough of the post to get the context, but... You might often want to write less than a full block. In that case, if you always erase, you have to read the full block to ram, make your change, then erase, then write the full block. If you write byte by byte, that's a lot of erase cycles. So you add a check to see if the bytes you want to write are already in the erased state. But it's not much more work to check if the desired state is attainable instead of just if the current state is erased. Isn't it just if Current & New == New?
- jlokier 6y agoThat area full of 1s might not be really erased, though, if power was removed or the device reset during an erase cycle before. Those would be partially-charged cells, and should be erased properly before writing, lest you start getting temperamental read errors later. But repeatedly erasing blocks just to add a byte will wear out the block, as well as take a long time as you point out. I think the solution to these two constraints is filesystem-like book-keeping of which regions are in which states.
- __cuervo 6y agoThat's a risk, yes. For our use case, there is very strict error checking/firmware signature verification on every process involving the flash, so the corruption case is always handled gracefully, leading to a full erase anyway.
- kahlonel 6y agoIt is not a standard practice. You do want to verify your write though by reading the written blocks back.
- __cuervo 6y agoHey! Author here :) This is a very good question, and you're right that I should've expanded on my rationale as this is not standard practice at all. There are some particularities of the data we're writing that make this case more common than usual, and in any case the time spent in the bit masking routine is negligible compared to the flash erase time, so it works out well (keep in mind that the `all()` consumer will short-circuit as soon as two bits differ, so in the general case it's cheap, and in the erased case it isn't too different from verifying every byte is 0xFF). We're also really, really strongly optimizing for flash life above speed, as this code is meant to run very rarely for FOTA upgrades. For a general purpose storage flash driver, I'd definitely erase every sector.