nand flash驱动分析

来源:互联网 发布:淘宝买家订单信用清洗 编辑:程序博客网 时间:2024/05/19 03:46

板子上使用的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_mtdlist_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_infoinfo->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_chipinfo->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);

0 0
原创粉丝点击