This is the mail archive of the
mailing list for the eCos project.
Re: NAND technical review
Jonathan Larmour wrote:
Hmm, I guess the key thing here is that in E's implementation most of
the complexity has been pushed into the lower layers; at least compared
to R's. R's has a more consistent interface through the layers. Albeit
at the expense of some rigidity and noticeable function overhead.
It's not likely E's will be able to easily share controller code, given
of course you don't know what chips, and so what chip driver APIs
they'll be connected to. But OTOH, maybe this isn't a big deal since a
lot of the controller-specific munging is likely to be platform-specific
anyway due to characteristics of the attached NAND (e.g. timings etc.)
and the only bits that would be sensibly shared would potentially happen
in the processor HAL anyway at startup time. What's left may not be that
much and isn't a problem in the platform HAL. However the likely
exception to that is hardware-assisted ECC. A semi-formal API for that
would be desirable.
This is the largest difference in design philosophy between E and R. Is
it OK if I expand?
NAND chips are all identical in their wire setup. They all have a data
'bus', and control lines to indicate whether what is on the bus is a
command, an address, or data.
NAND chips differ in how their command language works, but only so far.
What is on the market now is 'regular' large-page chips that all speak
the same command language, and small-page chips that have a somewhat
different command language. ONFI chips are large-page chips except in
interrogation at startup and in bad-block marking.
E.g. a page read for a large-page chip (my running example) looks like this:
. write a command 0x00 (READ_START)
. write address bytes of the page(+offset) to be read
. write a command 0x30 (READ_CONFIRM)
. read the data on the bus
. insofar as supported retrieve hw-calculated ECC
For small-page chips the sequence is different because a page's data is
read in multiple chunks, using READ_1_A (0x00), READ_1_B (0x01), and for
spare area READ_2 (0x05).
These 2 languages are all the variation there is for NAND chips (plus,
at another level, 2 timing values for read cycle and write cycle)! The
wide-ranging differences for devices for NAND are in the controllers.
How controllers work, is that they accept input like 'write a command of
value 0x..', 'write an address of value 0x.....', etc, and do their job
on the NAND chip's wires. They cannot really operate at a higher level,
if only because they must support both small-page and large-page chips
(and ONFI), and this is the level of common protocol for the chips.
So controller code has to bridge between API calls like page_read and
the interface of the controller as described above. R's implementation
presumes that a lot of the code to make this translation is generic: a
large-page read translates to the controller steps as given above in the
running example, in any controller implementation. Moreover, the generic
code handles spare layout: where in the spare is the application's spare
data folded, where is the ECC, where is the bad-block mark. OTOH, the
generic code has hooks for handling any ECC that the controller has
computed in hardware -- how ECC is supported in hardware varies across
controllers. But the way the ECC check is handled (case in point is
where a correctible bit error is flagged) is generic again.
So, lots of code can (and will) be shared across controller
implementations -- whether by code sharing or by code duplication.