This is the mail archive of the mailing list for the eCos project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Re: NAND technical review

Ross Younger wrote:
Jonathan Larmour wrote:
I think at first the ball is really in Ross/eCosCentric's court to give
the technical rationale for the decision, so I'd like to ask him first
to give his rationale and his own perspective of the comparison of the

Here goes with a comparison between the two in something close to their current states (my 26/08 push to bugzilla 1000770, and Rutger's r659). For brevity, I will refer to the two layers as "E" (eCosCentric) and "R" (Rutger) from time to time.

Note that this is only really a comparison of the two NAND layers. I have
not attempted to compare the two YAFFS porting layers, though I do mention
them in a couple of places where it seemed relevant.

BTW: I will be off-net tomorrow and all next week, so please don't think I
am ignoring the discussion...

(a) Partitions

E's application interface also provides logic implementing partitions.
That is to say, all access to a NAND array must be via a `partition';
the NAND layer sanity-checks whether the requested flash page or block
address is within the given partition. This is quite a lightweight
layer and hasn't added much overhead of either code footprint or
execution time.

The presence of partitions in E's model was controversial, as are its
fine details. Nevertheless, some notion of partitioning turns out to be
essential on some boards. In some recent work for a customer we identified
three separate regions of NAND: somewhere to put the boot loader (primary,
as booted by ROM, and RedBoot), somewhere for the application image itself
(perhaps FIS-like rather than a full filesystem), and a filesystem for the
application to use as it pleases.

R's interface does not have such a facility. It appears that, in the event that the flash is shared between two or more logical regions, it's up to higher-level code to be configured with the correct block ranges to use.

(b) Dynamic memory allocation

R's layer mandates the provision of malloc and free, or compatible
functions. These must be provided to the cyg_nand_init() call.

E's doesn't; instead it declares a small number of static buffers.

Andrew Lunn opined on 6/3/09 that R's requirement for malloc is not a major
issue because the memory needs of that layer are well-bounded; I think I
broadly agree, though the situation is not ideal in that it forces somebody
who wants to use a lean, mean eCos configuration to work around.

Also note that if you're going to run a full file system like YAFFS, you
can't avoid needing malloc, but in an application making simpler use of
NAND, it's an overhead that you may prefer to avoid.

3. Driver model --------------------------------------------------------

The major architectural difference between the two NAND layers is in their
driver models and the degree of abstraction enforced.

In Rutger's layer, controllers and chips are both formally abstracted. The
application talks to the Abstract NAND Chip, which has (hard-coded) the
basic sequences of commands, addresses and data required to talk to a NAND
chip. This layer talks to a controller driver, which provides the nuts and
bolts of reading and writing to the device. The chip driver is also called
by the ANC layer, and provides the really chip-specific parts.

The call flow looks something like this (best viewed in fixed-width font):

Application --(H)-> ANC --(L)-> Controller driver
                        \-(C)-> Chip driver

H: high-level interface (read page, program page, erase block; chip
L: low-level interface (read/write commands, addresses, data; query the busy
C: chip-specific details (chip init, parse ReadID, query factory-bad marker)

In eCosCentric's layer, a NAND driver is a single abstraction covering chip init and querying the factory-bad status as well as the high level functions (reading a page, etc). It is left to the driver to determine the sequence of commands to send. How the driver interacts with the device is considered to be a contract only between the driver and the relevant platform HAL, so is not formally abstracted by the NAND layer.

E's chip drivers are written as .inl files, intended to be included by the
relevant platform HALs by whichever source file provides the required
low-level functions. The lack of a formal abstraction is an attempt to
provide a leaner and meaner experience at runtime: the low-level functions
can be (and indeed are, so far) provided as static inlines.

The flow looks like this:

Application --(H1)-> NAND layer --(H2)-> NAND driver --(L*)-> Platform HAL

H1: high-level calls (read page, program page, erase block)
H2: high-level calls (as H1, plus device init and query factory-bad marker)
L*: low-level calls, like L above but not formally abstracted

The two models have pros and cons in both directions.

- As hinted at above, the static inline model of E's low-level access
functions is expected to turn out to have a lower function call (and,
generally, code size) overhead than R's.

- R's model shares the command sequence logic amongst all chips,
differentiating only between small- and large-page devices. (I do not know
whether this is correct for all current chips, though going forwards seems
less likely to be an issue as fully-ONFI-compliant chips become the norm.)
If multiple chips of different types are present in a build, E's model
potentially duplicates code (though this could be worked around; also, an
ONFI driver ought to be written).

- A corollary of arguably inconsequential import: R's model forces the synth
driver to emulate an entire NAND chip and its protocol. E's synth doesn't
need to.

- E's high-level driver interface makes it harder to add new functions
later, necessitating a change to that API (H2 above). R's does not; the
requisite logic would only need to be added to the ANC. It is not thought
that more than a handful such changes will ever be required, and it may be
possible to maintain backwards compatibility. (As a case in point, support
for hardware ECC is currently work-in-progress within eCosCentric, and does
require such a change, but now is not the right time to discuss that.)

Therefore we prefer R's model.

Is it possible that R's model follows better the "general" structure of drivers in eCos?
I mean: (I follow our CVS, could maybe differ from the final commit of Rutger to eCos)
1. with the low-level chip-specific code in /devs (devs/flash/arm/at91/[board] and devs/flash/arm/at91/nfc, and devs/flash/micron/nand)
2. with the "middleware" in /io (io/flash_nand/current/src and there /anc, /chip, /controller)
3. with the high-level code in /fs

Is it correct that R's abstraction makes it possible to add partitioning easily?
(because that is an interesting feature of E's implementation)

We also prefer R's model of course because we started with R's model and use it now.
It would perhaps be interesting to compare the complexities of drivers for
the two models, but it's not readily apparent how we would do that fairly.

Perhaps porting a driver from one NAND layer to the other would be a useful
exercise, and would also allow us to compare code sizes. Any suggestions or
(he says hopefully) volunteers? I've got a lot on my plate this month...
same for us, no time now - beginning of next year?

4. Feature/implementation differences ------------------------------------

(I don't consider these to be significant issues; whilst noteworthy, I don't
think they would take much effort to resolve.)

(a) Documentation

The two layers' documentation differ in their depth and layout; these are
difficult for me to compare objectively, and I would suggest that a fresh
pair of eyes compare them.

I can only offer the comment that I documented the E layer bearing in mind
what I considered to be missing from the R layer documentation: it was not
clear how the controller and chip layers inter-related, nor where to start
in creating a driver. (I also had a lot less experience of NAND chips then
than I do now, and what I need to know now is different from what a newbie

(b) Availability of drivers

R provides support for:
- One board: BlackFin EZ-Kit BF548 (which is not in anoncvs?)
- Two: also our "automatic announcement" board to store mp3's with an Atmel ARM9 AT91SAM9260 with 16MB of SDRAM.
- One chip: the ST Micro 0xG chip (large page, x8 and x16 present but
presumably only tested on the x8 chip on the BlackFin board?)
- Two: also the Micron MT29F2G08AACWP-ET:D 256MB 3V3 NAND FLASH (2kB page size, x8)
Because if this chip, Rutger adapted the hardware ECC controller code, because our chip uses more bits (for details, ask Stijn or Rutger).
- A synthetic controller/chip package
- A template for a GPIO-based controller (untested, intended as an example only)

I seem to remember rumours of the existence of a driver for a further
chip+board combination, but I haven't seen it.

E provides support for:
- Two boards: Embedded Artists LPC2468 (very well tested); STM3210E (largely
complete, based on work by Simon K; some enhancements planned)
- Two chips: Samsung K9 family (large page, only x8 done so far); ST-Micro
NANDxxxx3A (small page, x8) (based on work by Simon K)
- Synthetic target. This offers more features than R's: bad block injection,
logging, and a GUI interface via the synth I/O auxiliary.
- Further (customer-confidential) board ports.

(c) RedBoot support

E have added some commands for NAND operations and tested on the EA LPC2468
board. (YAFFS support works via the existing RB fileio layer; nothing really
needed to be done.)

(d) Degree of testing

There are presumably differences of coverage here; both E and R assert they
have carried out stress tests. Properly comparing the depth of the two would
be a job for fresh eyes.

E have:
- a handful of unit and functional tests of the NAND layer, and a benchmarker
- a number of YAFFS functional tests, one of which includes benchmarking,
and a further severe YAFFS stress test: these indirectly test the NAND
layer. (The latter has been run under the synth driver with bad-block
injection turned on, and has revealed some subtle bugs which we probably
wouldn't otherwise have caught.)
- the ability to run continual test cycles in their test farm
We have it very well tested, amongst others
- an automatic (continual) nand-flash test in a clima chamber
- stress tests: putting it full over and over again via FTP (both with af few big and many small files) and check the heap remaining:
* Put 25 files with a filesize of 10.000.000 bytes on the filesystem
* Put 2500 files with a filesize of 100.000 bytes on the filesystem
* Put 7000 files with a filesize of 10.000 bytes on the filesystem
Conclusion: storing smaller files needs more heap, but we still have plenty left with our 16MB
* Write a bundle of files over and over again on the filesystem. We put everytime 1000 files of 100.000 bytes filesize on the flash drive.
- used in the final mp3-player application

Kind regards,

5. Works in progress -----------------------------------------------------

I can of course only comment on eCosCentric's plans, but the following work
is in the pipeline:

* Expansion of the device interface to better allow efficient hardware ECC
support (in progress)
* Hardware ECC for the STM3210E board driver
* Performance tuning of software ECC and of NAND low-level drivers
* Partition addressing: make addressing relative to the start of the
partition, once and for all
* Simple raw NAND "filesystem" for use by RedBoot (see et seq; those
are the latest public mails but not the latest version of my thinking, which
I will update in due course)
* More RedBoot NAND utility commands
* Support for booting Linux off NAND and for sharing a (YAFFS) NAND-resident
* Part-page read support (would provide a big speed-up to parts of YAFFS2
inbandTags mode as needed by small-page devices like that on the STM3210E)



Embedded Software Engineer, eCosCentric Limited.
Barnwell House, Barnwell Drive, Cambridge CB5 8UU, UK.
Registered in England no. 4422071.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]