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,只负责协议上需要发哪些数据,但并不关注怎么操作硬件才能分发成功。
底层驱动编写较为简单,分为3步
1:填充nand_chip成员,并挂接到mtd_info结构体,各个函数指针需要按照自己的硬件来实现。
2:nand_scan(&info->mtd, 1);
3:mtd_device_parse_register(&info->mtd, NULL, NULL, sets->partitions, sets->nr_partitions);
驱动采用了分层次的框架概念:
协议层(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);
相关文章推荐
- 嵌入式Linux裸机开发(二)——S5PV210启动过程分析
- Day01 准备工作
- 在s5pv210开发板上移植官方2101310版本的uboot
- platform设备驱动简介
- RC522在S5PV210处理器上的linux驱动调试(3)
- RC522在S5PV210处理器上的linux驱动调试(2)
- RC522在S5PV210处理器上的linux驱动调试(1)
- linux 中断处理(基于linux-3.7.2 arm linux)
- ARM引导过程(s5pv210)
- BL1校验和
- S5PV210启动过程详解
- SoC时钟系统简介
- S5PV210的时钟系统简介
- S5PV210时钟域详解
- S5PV210时钟体系框图详解
- 时钟设置的关键性寄存器
- S5PV210串行通信接口详解3
- S5PV210串行通信编程实战1
- uart stdio的移植3
- 串口实验烧录问题总结