Analysis of the implementation principle of nandflash device driven bottom based on MTD (III.)

Source: Internet
Author: User

Reprint Address: http://blog.csdn.net/eilianlau/article/details/6962693

Very said: I suddenly found in the writing of these NAND-driven article, I have been in rewriting other people's blog ... It doesn't really matter, and I think it's not just a good way to learn, why, because when I look at his blog, I understand a little bit, and then when I write it myself. Learn a little more about this stuff. Oh copy is also divided into grades

Five, the hardware time series to the software code evolution process to the NAND_BASE.C part code Analysis

The file is located in </linux2.6.35/dricer/mtd/nand/nand_base.c>

Or put the NAND-read hardware sequence diagram in the following figure:

①: This stage, is read the command first cycle, send the command for 0x00.
②: This stage, in turn, send the column address, about these row address, the column address and so how is calculated, the following content
will be explained in detail.
③: This phase is to send the corresponding row address
④: This stage is the command to send a read command for the second cycle 2nd cycle, 0x30
⑤: This phase is the wait time, waiting for the Nand flash hardware to prepare the corresponding data for subsequent reading.
⑥: At this stage, it's just a little bit of reading out the data you need.
MTD reads the data by Nand_read, and then calls Nand_do_read_ops, which is the body of the function as follows:

static int nand_do_read_ops (struct mtd_info *mtd, loff_t from,
struct Mtd_oob_ops *ops)
{
/*** here omit part of the code **/

。。。。。。。。。。。。。。

while (1) {
/****** omitted ****/

.。。。。。。。。。。。。。。。

if (likely (Sndcmd)) {/* #define NAND_CMD_READ0 0*/

/*1) * * * * Read the data must first send the corresponding read page command ******/

Chip->cmdfunc (MTD, nand_cmd_read0, 0x00, page);
Sndcmd = 0;
}

* Now read the page into the buffer * *
if (unlikely (Ops->mode = = Mtd_oob_raw))
ret = Chip->ecc.read_page_raw (MTD, Chip,
Bufpoi, page);
else if (!aligned && nand_subpage_read (Chip) &&!oob)
ret = Chip->ecc.read_subpage (MTD, Chip, col, Bytes, bufpoi);
Else

/****** Execute here read_page function to read the corresponding data ******/

ret = Chip->ecc.read_page (MTD, Chip, Bufpoi,
page);
if (Ret < 0)
Break

/* Transfer not aligned data */
if (!aligned) {
if (! Nand_subpage_read (Chip) &&!oob)
Chip->pagebuf = RealPage;
memcpy (buf, chip->buffers->databuf + col, bytes);
}

buf + = bytes;
。。。。。。。。。。。。。。。。。。

if (mtd->ecc_stats.failed-stats.failed)
return-ebadmsg;

Return mtd->ecc_stats.corrected-stats.corrected? -euclean:0;
}

The above code does not need us to implement, using the MTD layer of custom code on the line ...

Analysis of NAND_COMMAND_LP

static void Nand_command_lp (struct mtd_info *mtd, unsigned int command,
int column, int page_addr)
{
Register struct Nand_chip *chip = mtd->priv;

/* Emulate Nand_cmd_readoob * *
if (Command = = Nand_cmd_readoob) {
Column + = mtd->writesize;
command = nand_cmd_read0;
}

/* Command Latch Cycle * *

/* Here is the first cycle to send read command 1st Cycle command, that is, 0x00, corresponding to the above steps in the ①*/

Chip->cmd_ctrl (MTD, Command & 0xFF,
Nand_nce | nand_cle | Nand_ctrl_change);

if (column!=-1 | | page_addr!=-1) {
int CTRL = Nand_ctrl_change | Nand_nce | Nand_ale;

/* Serially Input address * *
if (column!=-1) {
/* Adjust columns for bit buswidth * *
if (Chip->options & nand_buswidth_16)
Column >>= 1;

/* Send two column addresses, corresponding to the ②*/in the above steps

Chip->cmd_ctrl (MTD, column, ctrl);/* Send column address 1*/
CTRL &= ~nand_ctrl_change;
Chip->cmd_ctrl (MTD, column >> 8, CTRL);/* Send column address 2*/
}
if (page_addr!=-1) {

/* Next is to send three row, row address, corresponding to the above steps in the ②*/

Chip->cmd_ctrl (MTD, PAGE_ADDR, ctrl); * Send line address 1*/
Chip->cmd_ctrl (MTD, page_addr >> 8,/* send row address 2*/
Nand_nce | Nand_ale);
/* One more address cycle for devices > 128MiB * *
if (Chip->chipsize > (128 << 20))
Chip->cmd_ctrl (MTD, page_addr >> 16,/* send row address 3*/
Nand_nce | Nand_ale);
}
}
Chip->cmd_ctrl (MTD, Nand_cmd_none, Nand_nce | Nand_ctrl_change);

/*
* Program and Erase have their own busy handlers
* Status, sequential in, and deplete1 need no delay
*/
Switch (command) {
。。。。。。。。。。。。。
Return
/*** Reset **/
Case Nand_cmd_reset:
if (Chip->dev_ready)
Break
Udelay (Chip->chip_delay);
Chip->cmd_ctrl (MTD, Nand_cmd_status,
Nand_nce | nand_cle | Nand_ctrl_change);
Chip->cmd_ctrl (MTD, Nand_cmd_none,
Nand_nce | Nand_ctrl_change);
while (!) ( Chip->read_byte (MTD) & Nand_status_ready));
Return
/* Read BUSY signal * *
Case Nand_cmd_rndout:
/* No ready/busy Check Necessary * *
Chip->cmd_ctrl (MTD, Nand_cmd_rndoutstart,
Nand_nce | nand_cle | Nand_ctrl_change);
Chip->cmd_ctrl (MTD, Nand_cmd_none,
Nand_nce | Nand_ctrl_change);
Return
/* Next send Read command of the second cycle 2nd Cycle command, that is, 0x30, corresponding to the above steps
In the ④*/
Case NAND_CMD_READ0:
Chip->cmd_ctrl (MTD, Nand_cmd_readstart,
Nand_nce | nand_cle | Nand_ctrl_change);
Chip->cmd_ctrl (MTD, Nand_cmd_none,
Nand_nce | Nand_ctrl_change);

/* This applies to read commands * *
Default
/*
* If we don ' t have access to the busy pin, we apply the given
* Command delay
*/
if (!chip->dev_ready) {
Udelay (Chip->chip_delay);
Return
}
}

* Apply This short delay always to ensure so we do wait TWB in
* Any machine. */

/* Here is the corresponding to the ④ in the TWB waiting time * *

Ndelay (100);
/* The next step is to wait a certain amount of time to make the NAND flash hardware ready for your
After reading, that corresponds to the steps ⑤*/
Nand_wait_ready (MTD);
}

There's one more step that's not implemented. That's the step ⑥. read out the data in 1.1.

NAND_READ_PAGE_HWECC Analysis

static int nand_read_page_hwecc (struct mtd_info *mtd, struct nand_chip, *chip,
uint8_t *buf, int page)
{
。。。。。。。。。。。。。。。。。。。。。。
for (i = 0; eccsteps eccsteps--, i + = eccbytes, p = = eccsize) {
Chip->ecc.hwctl (MTD, Nand_ecc_read);

/** This is the most important thing. Read the data from the NAND buffer ****/

Chip->read_buf (MTD, p, eccsize);
Chip->ecc.calculate (MTD, p, &ecc_calc[i]);
}



。。。。。。。。。。
return 0;
}

The read_buf above is really the function of reading the data, because different Nand Flash controller controllers are implemented in a different way, so this function must be implemented in your NAND flash drive, that is, the MTD layer, which can help us achieve, Can't achieve, that must be our own thing ... What is the next job? The interface between MTD's original device and the hardware driver layer. This is what we're going to really achieve.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.