免费注册 查看新帖 |

Chinaunix

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

读取NandFLASH只能读取4个字节 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-03 16:36 |只看该作者 |倒序浏览
1可用积分
read 实现:
static ssize_t phyaddr_read (struct file *fp, char __user *buf, size_t size, loff_t * loff)
{
    void __iomem *v_addr;
    ssize_t retval = 0;
    if (down_interruptible(&sem))//和semaphore有关的操作,暂时不讨论
        return -ERESTARTSYS;
                  
    v_addr = ioremap(PHYADDR_ADDR+addr_offset, 0x400);     //Don't know the means of 0x400 parameter  05/24

    printk("phyaddr_rw.c: read-phyaddr_read v_addr=0x%lX buf=0x%lX size=%ld\n",(long)v_addr, (long)buf, (long)size);
   
    if(copy_to_user(buf, v_addr, size))          //Jason 05/23/2006  
    {
           warn("copy failure");        
           retval= -EFAULT;
           goto out;
    }
    else
    {
        int i;
        char * tmp = (char*)v_addr;
        for(i=0;i<size;i++){
                printk("0x%02X ",tmp);
                if(i % 16==0)
                        printk("\n");
                }
        retval= size;
   }        

out:
        up(&sem);//semaphore处理
        return retval;
}


读取100个字节
0x7E
0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E
0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E
0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E
0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E
0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E
0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E
0x01 0x00 0xEB

读取20个字节
0x7E
0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E 0x01 0x00 0xEB 0x7E
0x01 0x00 0xEB

读取的位置我更换了很多,读出来的总是四个字节循环,而且这20个字节和100个字节物理地址差很远,小弟刚刚接触驱动各位大侠帮帮忙,小弟积分确实有点少,不好意思了,穷啊。

最佳答案

查看完整内容

使用端口读写函数 ioreadXX 在内核做个缓冲区读进来。nand的内容读写不是靠地址变化注意与Nor的区别!nand在一个地址上连续的读。copy_to_user不适用~

论坛徽章:
0
2 [报告]
发表于 2008-06-03 16:36 |只看该作者
使用端口读写函数 ioreadXX 在内核做个缓冲区读进来。
nand的内容读写不是靠地址变化注意与Nor的区别!
nand在一个地址上连续的读。
copy_to_user不适用~

论坛徽章:
0
3 [报告]
发表于 2008-06-03 17:18 |只看该作者

回复 #1 guoxin0110 的帖子

帮顶下...还没看过NANDFLASH的驱动....

论坛徽章:
0
4 [报告]
发表于 2008-06-05 14:59 |只看该作者

回复 #2 Roemer 的帖子

后来问题解决了,我直接操作NandFlash controller的寄存器来读取的参考了网上的一篇文档
http://hi.baidu.com/xydjh/blog/item/717cad54ffcf8e5dd1090682.html
代码如下
static ssize_t phyaddr_read (struct file *fp, char __user *buf, size_t size, loff_t * loff)
{
    void __iomem *v_addr;
    unsigned long  column_addr,page_address;
    ssize_t retval = 0;
    int nf_cmd=0;
   // int nf_addr;
    int i;
   char *tmp_buf=buf;
   unsigned short id;
    column_addr=(addr_offset+PHYADDR_ADDR)%512;        
    page_address=((addr_offset+PHYADDR_ADDR)>>9);

printk("phyaddr_rw.c: read-phyaddr=0x%lX\tcolumn_addr=0x%lX\tpage_address=0x%lX\tsize=%ld\n",
                                        PHYADDR_ADDR+addr_offset,
                                        (long)column_addr,
                                        (long)page_address,
                                        (long)size);
        //Enable Chip
    nand_chip_enable();
    id=nand_chip_getid();
                       
    if(column_addr >=256)
        nf_cmd=0x01;
    else
       nf_cmd=0x00;
    v_addr = ioremap(NFCMD, 4);
    __raw_writel(nf_cmd ,v_addr);
    iounmap(v_addr);

    v_addr = ioremap(NFADDR, 4);
    __raw_writel(column_addr&0xff ,v_addr);
    __raw_writel(page_address&0xff ,v_addr);
    __raw_writel((page_address>>&0xff ,v_addr);
    __raw_writel((page_address>>16)&0xff ,v_addr);
    iounmap(v_addr);

    v_addr = ioremap(NFDATA, 4);
    udelay(200);
    for(i=column_addr;i<column_addr+size;i++)
    {
      *tmp_buf++= __raw_readl(v_addr);
         //udelay(500);
        // printk("0x%02X ", __raw_readl(v_addr));
    }

    retval = size;
    //Disable Chip
    nand_chip_disable();
   
    return retval;
}

其中循环读取的那一块如果换成Roemer 老兄说的方法
    ioread8_rep(v_addr, tmpbuf,size);
    if(copy_to_user(buf, tmpbuf, size))
    {
         warn("copy failure";       
         retval= -EFAULT;
    }
是可以的,谢谢了啊。

论坛徽章:
0
5 [报告]
发表于 2008-06-05 15:09 |只看该作者

回复 #2 Roemer 的帖子

其实这样问题是解决了,但是我还是不明白kernel是怎么管理NandFlash的。我原本以为,系统已经给我虚拟好了Flash存储空间,我一旦调用copy_to_user(),就会替我做nand_chip_enable();发送读取flash命令,发送地址读取数据然后    nand_chip_disable(); 也就是说copy_to_user已经封装好了这些操作。如果这一系列的操作每次都要我来做的话,我也可以想象busybox的cp命令是不是也要做这样一些工作呢?这样是不是太麻烦,OS失去了意义呢?望高手解答!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP