I need to implement a block abstraction layer for SPI NAND flash. I'd like to know if Reliance Edge has any solutions for interfacing with serial flash devices, such as SPI NAND MT29F2G01ABAGDWB.
Thanks in advance!
While Reliance Edge itself does not have a sample block abstraction layer example for SPI NAND flash, Tuxera does have a commercial product offering called Reliance EdgeNand that might be of interest, if you are eventually looking for a commercially viable solution. If so, please take a look here, and let us know if you have questions!
I've obtained a third-party SPINAND driver, just so I could test quickly if my appication would be possible. I'm having trouble to format and mount Reliance Edge.
I can already write big chunks of raw bytes into the memory and read it afterwards with no conflict or byte errors, all with SPINAND IC ECC module enabled. But somehow, when "passing through" Reliance Edge's system, "red_format()" seems to work fine, when "red_mount()" fails at its first read attempt, trying to read what I think is the Master Block at the first block address.
The SPINAND driver shows: "internal ECC error reading page 0x200". With '0x200' beeing the offset sector configured at redconf.c.
This doesn't happen if I do my "raw read/write" test.
Could anyone help me with this?
-Reliance Edge v2.2
-Sector size is matching the page size of the NAND flash memory (2048).
-The number of sectors is properly defined by the Config Utility to fit the volume.
-The READ/WRITE test was made with 3000 bytes at multiple addresses.
I will ask my engineering team to comment, but a question:
How does your sample SPI NAND driver do any physical to logical translation of addresses being written? I.E. is it complex enough to be able to rewrite a "sector" of data somewhere else on the flash when overwriting a sector, or is it using some sort of erase, then reprogram for a given page that is being rewritten (1 to 1 mapping of "NAND pages" to "Sectors")? The fact that the NAND flash is reporting an ECC error makes it seem like perhaps the page was programmed with some data, and then reprogrammed with additional data without being erased first - is this possible? While I do not believe you would want to use a erase/write scheme for a shipping product (if you were interrupted after an erase, but before a write, you could use your entire file system), as long as the erase is completing, and the data is being rewritten, I would not expect the part to report an ECC error.
Can we also assume that the read that is reporting the ECC failure is returning invalid data (or not data at all)?
Again, let me ask the team for a bit of advice, but if you can explain how the driver is handing the writing of new sectors (and how the sectors are getting erased), that would be helpful.
[ed. note: email@example.com last edited this post 6 months, 4 weeks ago.]
Our engineer offered the following comments:
red_format() writes the master block twice, so if your “third-party SPINAND driver” isn’t an FTL that is capable of logical-to-physical remapping, then the master block ECC will be junk after format, and in general the file system is not going to work.
As our first reply said, Reliance EdgeNAND would be a good fit for what you need. The chip that you mentioned in your first post (MT29F2G01ABAGDWB) is supported out-of-the-box by Reliance EdgeNAND.
Please feel free to ask additional questions via this forum, or you can email directly to firstname.lastname@example.org
I'm very interested in Reliance EdgeNAND, since it fully supports the Micron chip. As I said before, I'm currently looking for simple solutions to validate my application, than I can think about it commercially.
Thanks for the tip about the FTL, I didn't realize it had such an importance. That ECC error does make sense, since it was writing the master block twice with no logical-to-physical convertion.
I was able to find a FTL API called "Dhara" and it seems to work fine, since I was able to write and read multiple logical sectors through its public API functions.
However, Reliance Edge is now unable to format the system. In the middle of the red_format() process, after a few "writings", there is one "reading" by RedBufferGet() that fails. It tries to obtain the second logical sector previously written, the one that follow master block, chronologically. (in my case 0x203)
The system reaches CRITICAL ASSERT after failing "BufferIsValid()".
I wonder if this is some sort of block/sector size misconfiguration. Any ideas what that might be?
Thanks again, I really appreciate the support!
Our team reports that they do have some experience with Dhara. When we were benchmarking Reliance EdgeNAND, FatFs+Dhara was among the alternative solutions that were tested. We have never tried using Dhara with Reliance Edge, but it should work. (For a production deployment, we would still recommend using Reliance EdgeNAND rather than RE+Dhara. We believe Dhara has some design flaws that could result in unreliability, particularly in the event of power interruption in the middle of program or erase. And we believe Reliance EdgeNAND would be faster, too.)
>>However, Reliance Edge is now unable to format the system. In the middle of the red_format() process, after a few "writings", there is one "reading" by RedBufferGet() that fails. It tries to obtain the second logical sector previously written, the one that follow master block, chronologically. (in my case 0x203)
The system reaches CRITICAL ASSERT after failing "BufferIsValid()".
Previously, you had said that sector 0x200 was the master block. In that case, sectors 0x201 and 0x202 are the metaroots, and sector 0x203 is the first imap (free-space bitmap) block. That imap block is written during format and it can be later read from disk while creating the root directory inode. If BufferIsValid() is failing, then no errors were reported when reading the block but it had incorrect data – either the signature was wrong or the CRC was wrong. Most likely, this means the data wasn’t correctly programmed when that block was written. If you have the ability to debug, or add debug printfs, then perhaps you could examine the contents of the buffer which is failing BufferIsValid(): is it mostly correct with only a few bit errors, or is it totally wrong? That should provide some hints on what went wrong during the program.
>> I wonder if this is some sort of block/sector size misconfiguration. Any ideas what that might be?
Maybe, but we don’t think so. Just in case, could you provide your redconf.[ch] configuration, along with the values being used to initialize struct dhara_nand. You can send to email@example.com
This is just speculation on our part, but it’s more likely that there’s a problem in the “glue code” – either in the osbdev.c that is being used to glue together Reliance Edge and Dhara, or in the dhara_nand_*() APIs being used to glue together Dhara and the low-level SPI NAND driver. It may be possible for us to review this code, if you are able to send it.
Thanks! I'll be in touch soon providing more details about the code and the "redconf.h" file.
It is likely that there is a problem with the "glue code", but since I was already able to write and read through Dhara directly it's probably not related to the SPI NAND driver.
I think I'm not writing sectors properly through my "osbdev.c" functions. I did put a debug log at that point you have pointed out and got this:
"red_debug: uMetaFlags = 0x8008 | ulSignature = 0xFFFFFFFF | buf.ulCRC = 0xFFFFFFFF"
So it seems pretty clear to me something is wrong with my "Reliance Edge - Dhara" interface.
My implementation of the "osbdev.c" functions are pretty straight forward, passing the logical sector (ullSectorStart) directly to Dhara's API such as "dhara_map_*()". The only thing I had to do it's a loop to write/read one sector at a time, maybe there is something wrong at this point. Is it correct to assume that Dhara only works with one sector at a time?
Just a quick update, I was doing a "dhara_map_sync()" every time "RedOsBDevFlush()" was called, but when I commented this section the previous problem got solved and now its reading that 0x203 sector correctly.
The problem now seems to be around Dhara's map itself, since its occurring an error at reading master block when mounting. When trying to read, the physical page is not the same as written before. I wonder if removing "dhara_map_sync()" has anything related to it.
If I don't resume Dhara's map by calling dhara_map_resume(), Reliance Edge can format and mount as usual. Of course that it doesn't do Wear Levelling this way, which can indicate that maybe there is something wrong with my "glue code" between Dhara and this SPI NAND driver, but not related to write and read operations.
[ed. note: firstname.lastname@example.org last edited this post 6 months, 3 weeks ago.]