1 nand flash的操作

目的:读地址A的数据,把数据B写到地址A。

问1. 原理图上NAND FLASH和S3C2440之间只有数据线,怎么传输地址?
答1.在DATA0~DATA7上既传输数据,又传输地址,当ALE为高电平时传输的是地址。

问2. 从NAND FLASH芯片手册可知,要操作NAND FLASH需要先发出命令
     怎么传入命令?
答2.在DATA0~DATA7上既传输数据,又传输地址,也传输命令
     当ALE为高电平时传输的是地址,
     当CLE为高电平时传输的是命令
     当ALE和CLE都为低电平时传输的是数据
问3. 数据线既接到NAND FLASH,也接到NOR FLASH,还接到SDRAM、DM9000等等,那么怎么避免干扰?
答3. 这些设备,要访问之必须"选中",没有选中的芯片不会工作,相当于没接一样。(内存控制器)
问4. 假设烧写NAND FLASH,把命令、地址、数据发给它之后,
     NAND FLASH肯定不可能瞬间完成烧写的,怎么判断烧写完成?
答4. 通过状态引脚RnB来判断:它为高电平表示就绪,它为低电平表示正忙

问5. 怎么操作NAND FLASH呢?
答5. 根据NAND FLASH的芯片手册,一般的过程是:
     发出命令
     发出地址
     发出数据/读数据

2 分析nand flash的启动过程

搜"S3C24XX NAND Driver"
S3c2410.c (drivers\mtd\nand)

s3c2410_nand_inithw
s3c2410_nand_init_chip
nand_scan  // 根据nand_chip的底层操作函数识别NAND FLASH,构造mtd_info
    nand_scan_ident
        nand_set_defaults
            if (!chip->select_chip)
                chip->select_chip = nand_select_chip; // 默认值不适用

if (chip->cmdfunc == NULL)
                chip->cmdfunc = nand_command;
                                    chip->cmd_ctrl(mtd, command, ctrl);
            if (!chip->read_byte)
                chip->read_byte = nand_read_byte;
                                    readb(chip->IO_ADDR_R);
            if (chip->waitfunc == NULL)
                chip->waitfunc = nand_wait;
                                    chip->dev_ready
        
        
        nand_get_flash_type
            chip->select_chip(mtd, 0);
            chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
            *maf_id = chip->read_byte(mtd);
            dev_id = chip->read_byte(mtd);
    nand_scan_tail
            mtd->erase = nand_erase;
            mtd->read = nand_read;
            mtd->write = nand_write;
s3c2410_nand_add_partition
    add_mtd_partitions
        add_mtd_device
            list_for_each(this, &mtd_notifiers) { // 问. mtd_notifiers在哪设置
                                                  // 答. drivers/mtd/mtdchar.c,mtd_blkdev.c调用register_mtd_user
                struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
                not->add(mtd);
                // mtd_notify_add  和 blktrans_notify_add
                先看字符设备的mtd_notify_add
                        class_device_create
                        class_device_create
                再看块设备的blktrans_notify_add
                    list_for_each(this, &blktrans_majors) { // 问. blktrans_majors在哪设置
                                                            // 答. drivers\mtd\mdblock.c或mtdblock_ro.c   register_mtd_blktrans
                        struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);              
                        tr->add_mtd(tr, mtd);
                                mtdblock_add_mtd (drivers\mtd\mdblock.c)
                                    add_mtd_blktrans_dev
                                        alloc_disk
                                        gd->queue = tr->blkcore_priv->rq; // tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
                                        add_disk

3 nand flash驱动程序框架

(1)分配一个nand_chip/mtd_info结构体

(2)设置

(3)硬件相关的操作

(4)使用nand_scan/add_mtd_partitions

4 写代码

参考drivers\mtd\nand\s3c2410.c

  1. /*参考drivers\mtd\nand\at91_nand.c*/
  2.  
  3. #include <linux/module.h>
  4. #include <linux/types.h>
  5. #include <linux/init.h>
  6. #include <linux/kernel.h>
  7. #include <linux/string.h>
  8. #include <linux/ioport.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/delay.h>
  11. #include <linux/err.h>
  12. #include <linux/slab.h>
  13. #include <linux/clk.h>
  14.  
  15. #include <linux/mtd/mtd.h>
  16. #include <linux/mtd/nand.h>
  17. #include <linux/mtd/nand_ecc.h>
  18. #include <linux/mtd/partitions.h>
  19.  
  20. #include <asm/io.h>
  21.  
  22. #include <asm/arch/regs-nand.h>
  23. #include <asm/arch/nand.h>
  24.  
  25. struct s3c_nand_regs {
  26. unsigned long nfconf ;
  27. unsigned long nfcont ;
  28. unsigned long nfcmd ;
  29. unsigned long nfaddr ;
  30. unsigned long nfdata ;
  31. unsigned long nfeccd0 ;
  32. unsigned long nfeccd1 ;
  33. unsigned long nfeccd ;
  34. unsigned long nfstat ;
  35. unsigned long nfestat0;
  36. unsigned long nfestat1;
  37. unsigned long nfmecc0 ;
  38. unsigned long nfmecc1 ;
  39. unsigned long nfsecc ;
  40. unsigned long nfsblk ;
  41. unsigned long nfeblk ;
  42. };
  43.  
  44. static struct mtd_info *s3c_mtd;
  45. static struct nand_chip *s3c_nand;
  46.  
  47. static struct mtd_partition s3c_nand_parts[] = {
  48. [] = {
  49. .name = "bootloader",
  50. .size = 0x00040000,
  51. .offset = ,
  52. },
  53. [] = {
  54. .name = "params",
  55. .offset = MTDPART_OFS_APPEND,
  56. .size = 0x00020000,
  57. },
  58. [] = {
  59. .name = "kernel",
  60. .offset = MTDPART_OFS_APPEND,
  61. .size = 0x00200000,
  62. },
  63. [] = {
  64. .name = "root",
  65. .offset = MTDPART_OFS_APPEND,
  66. .size = MTDPART_SIZ_FULL,
  67. }
  68. };
  69.  
  70. static void s3c2440_select_chip(struct mtd_info *mtd, int chipnr)
  71. {
  72. if (chipnr == -)
  73. {
  74. /* 取消选中: NFCONT[1]设为1 */
  75. s3c_nand_regs->nfcont |= (<<);
  76. }
  77. else
  78. {
  79. /* 选中: NFCONT[1]设为0 */
  80. s3c_nand_regs->nfcont &= ~(<<);
  81. }
  82. }
  83.  
  84. static void s3c2440_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
  85. {
  86. if (ctrl & NAND_CLE)
  87. {
  88. /* 发命令: NFCMMD=dat */
  89. s3c_nand_regs->nfcmd = dat;
  90. }
  91. else
  92. {
  93. /* 发地址: NFADDR=dat */
  94. s3c_nand_regs->nfaddr = dat;
  95. }
  96. }
  97.  
  98. static int s3c2440_dev_ready(struct mtd_info *mtd)
  99. {
  100. return (s3c_nand_regs->nfstat & (<<));
  101. }
  102.  
  103. static int s3c_nand_init(void)
  104. {
  105. struct clk *clk;
  106. s3c_nand = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
  107.  
  108. s3c_nand_regs = ioremap(0x4E000000, sizeof(struct s3c_nand_regs));
  109.  
  110. s3c_nand->select_chip = s3c2440_select_chip;
  111. s3c_nand->cmd_ctrl = s3c2440_cmd_ctrl;
  112. s3c_nand->IO_ADDR_R = &s3c_nand_regs->nfdata;
  113. s3c_nand->IO_ADDR_W = &s3c_nand_regs->nfdata;
  114. s3c_nand->dev_ready = s3c2440_dev_ready;
  115. s3c_nand->ecc.mode = NAND_ECC_SOFT;//enable ECC
  116.  
  117. clk = clk_get(NULL, "nand");
  118. clk_enable(clk);
  119.  
  120. #define TACLS 0
  121. #define TWRPH0 1
  122. #define TWRPH1 0
  123. s3c_nand_regs->nfconf = (TACLS<<) | (TWRPH0<<) | (TWRPH1<<);
  124. s3c_nand_regs->nfcont = (<<) | (<<);
  125.  
  126. s3c_mtd = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
  127. s3c_mtd->owner = THIS_MODULE;
  128. s3c_mtd->priv = s3c_nand;
  129. nand_scan(s3c_mtd, );//识别nand falsh,构造mtd_info
  130.  
  131. add_mtd_partitions(s3c_mtd, s3c_nand_parts,);
  132.  
  133. return ;
  134. }
  135.  
  136. static void s3c_nand_exit(void)
  137. {
  138. del_mtd_partitions(s3c_mtd);
  139. kfree(s3c_mtd);
  140. iounmap(s3c_nand_regs);
  141. kfree(s3c_nand);
  142. }
  143.  
  144. module_init(s3c_nand_init);
  145. module_exit(s3c_nand_exit);
  146.  
  147. MODULE_LICENSE("GPL");

s3c_nand.c

驱动09.nand flash的更多相关文章

  1. STM32学习笔记——FSMC 驱动大容量NAND FLASH [复制链接]

    本文原创于观海听涛,原作者版权所有,转载请注明出处. 近几天开发项目需要用到STM32驱动NAND FLASH,但由于开发板例程以及固件库是用于小页(512B),我要用到的FLASH为1G bit的大 ...

  2. 块设备驱动之NAND FLASH驱动程序

    转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/25240909 一.框架总结 watermark/2/text/aHR0cDov ...

  3. 十八、Nand Flash驱动和Nor Flash驱动

    在读者学习本章之前,最好了解Nand Flash读写过程和操作,可以参考:Nand Flash裸机操作. 一开始想在本章写eMMC框架和设备驱动,但是没有找到关于eMMC设备驱动具体写法,所以本章仍继 ...

  4. linux nand flash常用命令

    使用命令前用cat /proc/mtd 查看一下mtdchar字符设备:或者用ls -l /dev/mtd*#cat /proc/mtddev:    size   erasesize  namemt ...

  5. 嵌入式Linux驱动学习之路(二十三)NAND FLASH驱动程序

    NAND FLASH是一个存储芯片. 在芯片上的DATA0-DATA7上既能传输数据也能传输地址. 当ALE为高电平时传输的是地址. 当CLE为高电平时传输的是命令. 当ALE和CLE都为低电平时传输 ...

  6. Smart210学习记录----nand flash驱动

    [详解]如何编写Linux下Nand Flash驱动  :http://www.cnblogs.com/linux-rookie/articles/3016990.html 当读写文件请求到来的时候, ...

  7. nuc900 nand flash mtd 驱动

    nuc900 nand flash mtd 驱动,请参考! /* * Copyright © 2009 Nuvoton technology corporation. * * Wan ZongShun ...

  8. Tiny6410之NAND FLASH驱动

    一.NAND FLASH的特点 S3C6410的NAND FLASH控制器有如下特点 1.自导入模式:复位后,引导代码被送入到8KB的STEPPINGSTONE中,引导代码移动完毕,引导代码将在STE ...

  9. Nand Flash驱动(实现初始化以及读操作)

    简单制作一个Nand Flash驱动(只需要初始化Flash以及读Flash) 打开2440芯片手册,K9F2G08U0M芯片手册(因为2440中Nand Flash是用的256MB(2Gb)内存,8 ...

随机推荐

  1. How to write own add-in for SSMS 2012 (Final release version)

    原文 How to write own add-in for SSMS 2012 (Final release version) Reading internet forums I have noti ...

  2. C#编程实践--字符串反转

    朴素反转 朴素解法,倒序遍历,字符串拼接,字符串性能低下,在长度已知的前提可以使用char数组代替 public static string NaiveReverse(string text) { s ...

  3. html5 canvas+js实现ps钢笔抠图

    html5 canvas+js实现ps钢笔抠图 1. 项目要求需要用js实现photoshop中钢笔抠图功能,就用了近三四天的时间去解决它,最终还是基本上把他实现了. 做的过程中走了不少弯路,最终一同 ...

  4. 在Idea中调试ant应用

    Ant调试 Ant调试 ant 是一种非常方便的打包,部署的工具,通过ant,可以一键构建整个项目,虽然MVN也支持这种功能,但是MVN混杂了package管理的功能,并且不是很自由,学习成本比较高. ...

  5. RMAN duplicate from active 时遭遇 ORA-17627 ORA-12154

    最近在从活动数据库进行异机克隆时碰到了ORA-17629,ORA-17627,ORA-12154的错误,起初以为是一个Bug呢.Oracle Bug着实太多了,已经成了习惯性思维了.汗!错误提示是无法 ...

  6. Asp.net MVC4.0(net4.5) 部署到window server 2003上的解决方案

    Asp.net MVC4.0(net4.5) 部署到window server 2003上的解决方案 最近做了一个Web项目,也没多想就用了Asp.net MVC4.0 ,MVC4.0默认的目标fra ...

  7. 一个简单的Garbage Collector的实现

    一个简单的Garbage Collector的实现 前言: 最近看了google的工程师写的一个非常简单的垃圾收集器,大概200多行C代码,感叹大牛总能够把复杂的东西通过很简单的语言和代码表达出来.为 ...

  8. C#算两个时间段相差的时间

    在数据中经常算两个时间差或者在某个时间段的内容 在数据库中设计表字段类型的时候设计为varchar类型,然后进行可以再Sql语句中书写>=或者<=这样的进行比较就可以查询出某个时间段的内容 ...

  9. ASP.NET交互Rest服务接口(Jquery的Get与Post方式)

    ASP.NET交互Rest服务接口(Jquery的Get与Post方式) 本文将通过一个简单的实例,介绍如何创建一个Rest服务接口,以及通过JQUERY去对它进行调用;主要采取两种方式分别为Get跟 ...

  10. 大IT公司笔试

    都是一些非常非常基础的题,是我最近参加各大IT公司笔试后靠记忆记下来的,经过整理献给与我一样参加各大IT校园招聘的同学们,纯考Java基础功底,老手们就不用进来了,免得笑话我们这些未出校门的孩纸们,但 ...