• Linux 下 Nand Flash 驱动说明


     注册 driver_register

    通过 module_init(s3c2410_nand_init);注册 Nand Flash 驱动. 在 s3c2410_nand_init ()中通过 driver_register()注册

    s3c2410_nand_driver 驱动程序,如下所示:

    static struct device_driver s3c2410_nand_driver = {

    .name          = "s3c2410-nand",

    .bus           = &platform_bus_type, /* 在 drivers/base/platform.c 中定义 */

    .probe         = s3c2410_nand_probe,

    .remove        = s3c2410_nand_remove,

    };

    探测设备 probe

    在注册的 Nand Flash 驱动程序中, probe 方法为 s3c2410_nand_probe(). s3c2410_nand_probe()再调用 s3c24xx_nand_probe(). 在该函数中, 把*info 作为 Nand Flash 驱动的私有数据结构, 并通过 dev_set_drvdata(dev, info)把*info 保存在*device 的*driver_data 字段中.然后通过 clk_get(dev, "nand")获取 Nand Flash 的时钟资 源, clk_use(info->clk)增加时钟资源的使用计数, clk_enable(info->clk)开启资源.填写*info 的其它字段, 其中包括:

    1. 通过 request_mem_region()为 Nand Flash 寄存器区申请 I/O 内存地址空间区,并通过 ioremap()把它映射到虚 拟地址空间.
      1. 调用 s3c2410_nand_inithw()初始化 Nand Flash 控制器. 3.  为 mtd 设备分配设备信息的存储空间.

    4. 对当前 mtd 设备,调用 s3c2410_nand_init_chip()进行初始化.

    5. 对当前 mtd 设备, 调用 nand_scan()检测 Nand Flash 芯片, nand_scan()函数在 drivers/mtd/nand/nand_base.c 中 定义.该函数的作用是初始化 struct nand_chip 中一些方法, 并从 Nand Flash 中读取芯片 ID, 并初始化 struct mtd_info 中的方法.

    6.  对当前 mtd 设备,加入其分区信息.

    7. 如果还有更多 mtd 设备,到 4 执行.

      初始化 Nand Flash 控制器

    s3c2410_nand_inithw()函数会初始化 Nand Flash 控制器, 通过设置 Nand Flash 控制寄存器(S3C2410_NFCONF)来

    完成, 这里最重要的是根据 S3C2410 的 PCLK 计算出 tacls, twrph0 以及 twrph1 值.

    移除设备

    s3c2410_nand_remove()当设备被移除时,被 device 核心驱动调用.它完成的主要工作如下:

    1. 把*device 的*driver_data 字段置空.

    2. 释放 mtd 设备信息. 3. 释放 clk 资源.

    4. 通过 iounmap()取消映地址空间. 5. 释放申请的 I/O 内存资源.

    6. 释放设备私有数据*info 的空间.

        Nand Flash 芯片初始化

    s3c2410_nand_init_chip()初始化 struct nand_chip 中的一些主要字段以及方法.其中主要包括的方法有:

    1. s3c2410_nand_hwcontrol(); 硬件控制

    2. s3c2410_nand_devready(); 设备是否准备好

    1. s3c2410_nand_write_buf(); 写一个 buffer 到 nand flash
    2. s3c2410_nand_read_buf(); 读一个 buffer 到 nand flash 5. s3c2410_nand_select_chip(); 选择操作芯片

    如果支持 ECC 硬件校验,还设置如下方法:

    1. s3c2410_nand_correct_data(); 通过 ECC 码校正数据
    2. s3c2410_nand_enable_hwecc(); 开启硬件 ECC 检查
    3. s3c2410_nand_calculate_ecc(); 计算 ECC 码

    Nand Flash

    当对 nand flash 的设备文件(nand flash 在/dev 下对应的文件)执行系统调用 read(),或在某个文件系统中对该 设备进行读操作时. 会调用 struct mtd_info 中的 read 方法,他们缺省调用函数为 nand_read(),在 drivers/mtd/nand/nand_base.c 中定义.nand_read()调用 nand_do_read_ecc(),执行读操作. 在 nand_do_read_ecc()函数中,主要完成如下几项工作:

    1. 会调用在 nand flash 驱动中对 struct nand_chip 重载的 select_chip 方法,即 s3c2410_nand_select_chip()选择要操作的 MTD 芯片.
    2. 会调用在 struct nand_chip 中系统缺省的方法 cmdfunc 发送读命令到 nand flash.
    3. 会调用在 nand flash 驱动中对 struct nand_chip 重载的 read_buf(),即 s3c2410_nand_read_buf() 从 Nand Flash 的控制器的数据寄存器中读出数据.
    4. 如果有必要的话,会调用在 nand flash 驱动中对 struct nand_chip 重载的 enable_hwecc,correct_data 以及 calculate_ecc 方法,进行数据 ECC 校验。

     写 Nand Flash

    当对 nand flash 的设备文件(nand flash 在/dev 下对应的文件)执行系统调用 write(),或在某个文件系统中对该设备 进行读操作时, 会调用 struct mtd_info 中 write 方法,他们缺省调用函数为 nand_write(),这两个函数在 drivers/mtd/nand/nand_base.c 中定义. nand_write()调用 nand_write_ecc(),执行写操作.在 nand_do_write_ecc()函数中,主要完成如下几项工作:

      1. 会调用在 nand flash 驱动中对 struct nand_chip 重载的 select_chip 方法,即 s3c2410_nand_select_chip()选择要操作的 MTD 芯片.
      2. 调用 nand_write_page()写一个页.
      3. 在 nand_write_page()中,会调用在 struct nand_chip 中系统缺省的方法 cmdfunc 发送写命令 到 nand flash.
      4. 在 nand_write_page()中,会调用在 nand flash 驱动中对 struct nand_chip 重载的 write_buf(),即 s3c2410_nand_write_buf()从 Nand Flash 的控制器的数据寄存器中写入数据.
      5. 在 nand_write_page()中,会调用在 nand flash 驱动中对 struct nand_chip 重载 waitfunc 方法, 该方法调用系统缺省函数 nand_wait(),该方法获取操作状态,并等待 nand flash 操作完成.等 待操作完成,是调用 nand flash 驱动中对 struct nand_chip 中重载的 dev_ready 方法,即 s3c2410_nand_devready()函数.
  • 相关阅读:
    ubuntu12.04.2上利用cmake安装opencv2.4.6
    微软无线鼠标3500滚轮问题
    Linux 安装 Tomcat
    Linux 安装 MySQL
    Linux 安装 JDK
    Linux 安装 Redis 及踩坑
    IDEA Git 撤销push(回退到指定版本)
    【Java】Ajax实现级联城市
    node.js更换镜像源
    【Java】数据库连接池的简单使用
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11106264.html
Copyright © 2020-2023  润新知