您的位置:首页 > 其它

nand flash驱动分析

2016-06-30 10:47 323 查看
板子上使用的nand flash,其代码分布在driver/mtd/nand下面。

驱动采用了分层次的框架概念:

协议层(nand_base.c)

=================

底层驱动(s3c2410.c)

协议层:主要分布在nand_base.c,主要负责协议上的事情。

比如nand_get_flash_type中读取id,只负责协议上需要发哪些数据,但并不关注怎么操作硬件才能分发成功。

/* Read manufacturer and device IDs */
chip->select_chip(mtd, 0);
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
*maf_id = chip->read_byte(mtd);
*dev_id = chip->read_byte(mtd);
</pre><p></p><p>底层驱动:负责给协议层解释怎么才能正确的操作硬件分发数据,这个是和具体soc挂钩的。</p><p>驱动框架主要的接口函数为以下两个:</p><p>int nand_scan(struct mtd_info *mtd, int maxchips)</p><p>mtd_device_parse_register(&info->mtd, NULL, NULL, sets->partitions, sets->nr_partitions);</p><p></p><p>nand_scan:</p><p>主要的功能是nand_set_defaults和nand_get_flash_type</p><p>nand_set_defaults:</p><p><span style="white-space:pre"></span>如果底层驱动没有对一些方法设置,则使用默认函数,需要注意的是并不是所有的默认函数都是适用的。</p><p>nand_get_flash_type:</p><p><span style="white-space:pre"></span>通过读id的方式得到板载nand flash的容量,pagesize等等信息。</p><p></p><p>mtd_device_parse_register(&info->mtd, NULL, NULL, sets->partitions, sets->nr_partitions);</p><p>主要的功能是对sets->partitions表中的每一个分区分别注册一个字符设备和两个块设备。</p><p><pre name="code" class="cpp">mtd_device_parse_register(&info->mtd, NULL, NULL, sets->partitions, sets->nr_partitions);
err = add_mtd_partitions(mtd, real_parts, err);
add_mtd_device(&slave->mtd);
// 生成字符设备
if (device_register(&mtd->dev) != 0)
goto fail_added;
if (MTD_DEVT(i))
device_create(&mtd_class, mtd->dev.parent,
MTD_DEVT(i) + 1,
NULL, "mtd%dro", i);

/*
* not->add(mtd)最终将调用mtdblock_add_mtd两次,生成两个块设备
*/
list_for_each_entry(not, &mtd_notifiers, list)
not->add(mtd); // blktrans_notify_add将调用mtdblock_add_mtd
list_for_each_entry(tr, &blktrans_majors, list)
tr->add_mtd(tr, mtd);


底层驱动编写较为简单,分为3步

1:填充nand_chip成员,并挂接到mtd_info结构体,各个函数指针需要按照自己的硬件来实现。

static void s5pv210_mtd_chip_init(void)
{
// fill chip & mtd_info
info->chip.IO_ADDR_R 		= info->regs + S3C2440_NFDATA;
info->chip.IO_ADDR_W		= info->regs + S3C2440_NFDATA;
info->chip.cmd_ctrl 		= s5pv210_nand_hwcontrol;
info->chip.dev_ready 		= s5pv210_nand_devready;
info->chip.ecc.mode 		= NAND_ECC_SOFT;
info->chip.chip_delay 		= 20;
info->chip.read_buf 		= s5pv210_nand_read_buf;
info->chip.write_buf 		= s5pv210_nand_write_buf;
info->chip.select_chip		= s5pv210_nand_select_chip;

// link mtd_info & nand_chip
info->mtd.priv = &(info->chip);
info->mtd.owner = THIS_MODULE;
}


2:nand_scan(&info->mtd, 1);

3:mtd_device_parse_register(&info->mtd, NULL, NULL, sets->partitions, sets->nr_partitions);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息