免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5563 | 回复: 5
打印 上一主题 下一主题

[驱动] 急,怎么读nandflash中的一块 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-20 22:43 |只看该作者 |倒序浏览
本帖最后由 forch 于 2011-09-20 23:51 编辑

有一块数据存储在0x4000000开始10M空间里,在驱动程序里怎么读出来?这一块没有分区。如果分区要怎么读,不分区怎么读?
arm-s3c2440+linux-2.6.26?  flash为k9f1208
用了好几种方法要么OOP错误,要么读不出来,帮忙···

论坛徽章:
2
水瓶座
日期:2013-09-04 15:09:57白羊座
日期:2014-04-17 16:48:13
2 [报告]
发表于 2011-09-21 10:40 |只看该作者
问题说清楚啊。

是在uboot里面读,还是内核里面读,还是用户层程序要读?

论坛徽章:
0
3 [报告]
发表于 2011-09-21 19:54 |只看该作者
问题说清楚啊。

是在uboot里面读,还是内核里面读,还是用户层程序要读?
l2y3n2 发表于 2011-09-21 10:40



    大哥,我说了再驱动程序里读啊,在应用里读也可以。
在驱动里读想直接操作寄存器读;
在应用里估计只能使用MTD来读吧,不过怎么定位到具体的地址?

论坛徽章:
0
4 [报告]
发表于 2011-09-21 21:59 |只看该作者
本帖最后由 forch 于 2011-09-22 00:11 编辑
  1. [root@forch /proc]# cat iomem
  2. 30000000-31ffffff : System RAM
  3.   3002a000-3035efff : Kernel text
  4.   30360000-303ab927 : Kernel data
  5. 49000000-490fffff : s3c2410-ohci
  6.   49000000-490fffff : ohci_hcd
  7. 4e000000-4e0fffff : s3c2440-nand
  8.   4e000000-4e0fffff : s3c2440-nand
  9. 50000000-50003fff : s3c2440-uart.0
  10.   50000000-500000ff : s3c2440-uart
  11. 50004000-50007fff : s3c2440-uart.1
  12.   50004000-500040ff : s3c2440-uart
  13. 50008000-5000bfff : s3c2440-uart.2
  14.   50008000-500080ff : s3c2440-uart
  15. [root@forch /proc]#
复制代码
开机后可以看到nand IO内存的相关信息如上,4e000000就是nand寄存器的开始地址,使用ioremap返回错误,先注销IO内存重新申请就可以ioremap成功,到底怎么把数据读出来呢?
s3c2410和s3c2440 nand 寄存器定义在内核头文件include\asm-arm\plat-s3c\regs-nand.h中
  1. #define S3C2410_NFREG(x) (x)
  2. #define S3C2410_NFCONF S3C2410_NFREG(0x00)
  3. #define S3C2410_NFCMD S3C2410_NFREG(0x04)
  4. #define S3C2410_NFADDR S3C2410_NFREG(0x08)
  5. #define S3C2410_NFDATA S3C2410_NFREG(0x0C)
复制代码
这个函数有问题吗?这样运行不会死机,数据似乎就没有读正确

  1. int nand_read_page_2626(unsigned char *buf, unsigned long addr)
  2. {
  3.         struct resource *res;
  4.         int size;
  5.         unsigned long cfg=0;
  6. //         unsigned char buf[1024]={0};
  7.         int len=512;
  8.         int cmd=0;
  9.        
  10.         cfg=0;
  11.        
  12.         // 直接释放内存IO
  13.         release_mem_region(S3C2410_PA_NAND,S3C24XX_SZ_NAND);
  14.         // 申请IO内存
  15.         res=request_mem_region(S3C2410_PA_NAND,S3C24XX_SZ_NAND,"lcm_fgw_t1");//
  16.         if (res==NULL)
  17.         {
  18.                 printk("request_mem_region fail \n");
  19.                 printk("release_mem_region \n");
  20.                 release_mem_region(S3C2410_PA_NAND,S3C24XX_SZ_NAND);
  21.                 return -1;
  22.         }
  23.        
  24.         // 重映射IO内存
  25.         res->start = S3C2410_PA_NAND;
  26.         size = S3C24XX_SZ_NAND;
  27.         regs = ioremap(res->start, size);
  28.         if (regs == NULL) {
  29.                 printk("cannot reserve register region\n");
  30.                 return -2;
  31.         }
  32.         printk("ready to nandrw \n");
  33.         mdelay(500);
  34.        
  35.         // 操作IO内存

  36.         printk("nandll_read_page addr=%#x \n",(int)addr);
  37.         // 操作IO内存开始

  38. //         printk("nandll_read_page addr=%#x \n",(int)addr);
  39.         // (NFCONT &= ~(1 << 1))
  40.         cmd=readb(regs + S3C2440_NFCONT);
  41.         cmd &= ~(1 << 1);
  42.         writeb(cmd,regs + S3C2440_NFCONT);

  43.         // (NFSTAT |= (1 << 2))
  44.         cmd=readb(regs + S3C2440_NFSTAT);
  45.         cmd |= (1 << 2);
  46.         writeb(cmd,regs + S3C2440_NFSTAT);

  47.         // NFCMMD = 0;
  48.         cmd = 0;
  49.         writeb(cmd,regs + S3C2440_NFCMD);

  50.         /* Write Address */
  51.         //         NFADDR = addr & 0xff;
  52.         cmd =addr & 0xff;
  53.         writeb(cmd,regs + S3C2440_NFADDR);
  54.         cmd = (addr >> 9) & 0xff;
  55.         writeb(cmd,regs + S3C2440_NFADDR);
  56.         //         NFADDR = (addr >> 9) & 0xff;
  57.         cmd = (addr >> 17) & 0xff;
  58.         writeb(cmd,regs + S3C2440_NFADDR);
  59.         //         NFADDR = (addr >> 17) & 0xff;
  60.         cmd = (addr >> 25) & 0xff;
  61.         writeb(cmd,regs + S3C2440_NFADDR);
  62.         //         NFADDR = (addr >> 25) & 0xff;

  63.         // { while(!(NFSTAT & 0x4));
  64.         while(!( readb(regs + S3C2440_NFSTAT) & 0x4));

  65. //         for(i=0; i < 512/4; i++)
  66. //         {
  67. //                 *ptr16 = NFDATA32;
  68. //                 ptr16++;
  69. //         }
  70.         readsl(regs + S3C2440_NFDATA, buf, len / 4);

  71.         // (NFCONT |= (1 << 1))
  72.         cmd=readb(regs + S3C2440_NFCONT);
  73.         cmd |= (1 << 1);
  74.         writeb(cmd,regs + S3C2440_NFCONT);
  75.        
  76.         // 操作IO内存结束
  77.        
  78.         // 解除重映射IO内存
  79.         if (regs != NULL)
  80.         {
  81.                 iounmap(regs);
  82.                 regs = NULL;
  83.         }
  84.        
  85.        
  86.         // 释放IO内存
  87.         release_mem_region(S3C2410_PA_NAND,S3C24XX_SZ_NAND);
  88.        
  89.         return 0;
  90. }
复制代码

论坛徽章:
2
水瓶座
日期:2013-09-04 15:09:57白羊座
日期:2014-04-17 16:48:13
5 [报告]
发表于 2011-09-22 09:38 |只看该作者
能改动内核的话,直接把那块flash分个区,然后用户层开mtd设备读取不是更方便么。

不能改的话,用户层吧nand控制器那些寄存器手动map出来,然后对照手册操作吧。
具体操作我也不是很熟悉,要去看nand flash操作手册和你的SoC的datasheet

论坛徽章:
0
6 [报告]
发表于 2011-09-22 10:19 |只看该作者
能改动内核的话,直接把那块flash分个区,然后用户层开mtd设备读取不是更方便么。

不能改的话,用户层吧 ...
l2y3n2 发表于 2011-09-22 09:38



    用的自己写得4楼的代码,昨天晚上没调通,早上重新调了一遍就可以了,奇怪---不过搞定就好。
有空用分区的方法试一下。还是谢谢你了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP