主题 : linux下写nor flash的问题 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 1053
精华: 0
发帖: 4
金钱: 40 两
威望: 13 点
综合积分: 8 分
注册时间: 2008-07-13
最后登录: 2009-06-05
楼主  发表于: 2009-05-13 23:37

 linux下写nor flash的问题

小弟今天尝试着着学习写nor flash的驱动程序,测试的时候发现,读数据是没有问题的,而写数据则总是写不进去。
看AM29lv160db芯片资料上说对特定地址写数据的时候就是采用
向aaa地址写入aa
向555地址写入55
向aaa地址写入a0
然后向目的地址写目的数据
我就是这么来写的,但是测试程序测试显示根本没写进去。
测试程序的逻辑
打开norflash
读出基地址base_addr 开始的0~15字节,存入original_data数组中
然后向这些地址写入flash_data的数据
然后读出
再将original_data写回
。谁能帮我解决一下,我怀疑是写norflash的时序不对?
先谢谢了。
串行口发送回来的数据如下:
Open nor_drv successful!                                                        
/**************read test***********************Trying to vfree() nonexistent vm)
Badness in __vunmap at mm/vmalloc.c:308                                        
Trying to vfree() nonexistent vm area (c480a000)                                
Badness in __vunmap at mm/vmalloc.c:308                                        
***/                                                                            
[e] = 0                                                                        
[d] = 0                                                                        
[c] = 0                                                                        
= 0                                                                        
[a] = 0                                                                        
[9] = 0                                                                        
[8] = 0                                                                        
[7] = 0                                                                        
[6] = 0                                                                        
[5] = 0                                                                        
[4] = 0                                                                        
[3] = 0                                                                        
[2] = 0                                                                        
[1] = 0                                                                        
[0] = 0                                                                        
/***************write test***********************/                              
flash_data[0] = 0                                                              
flash_data[1] = 1                                                              
flash_data[2] = 2                                                              
flash_data[3] = 3                                                              
flash_data[4] = 4                                                              
flash_data[5] = 5                                                              
flash_data[6] = 6                                                              
flash_data[7] = 7                                                              
flash_data[8] = 8                                                              
flash_data[9] = 9                                                              
flash_data[10] = a                                                              
flash_data[11] = b                                                              
flash_data[12] = c                                                              
flash_data[13] = d                                                              
flash_data[14] = e                                                              
flash_data[15] = f                                                              
flash_data[0] = 0                                                              
flash_data[1] = 1                                                              
flash_data[2] = 2                                                              
flash_data[3] = 3                                                              
flash_data[4] = 4                                                              
flash_data[5] = 5                                                              
flash_data[6] = 6                                                              
flash_data[7] = 7                                                              
flash_data[8] = 8                                                              
flash_data[9] = 9                                                              
flash_data[10] = a                                                              
flash_data[11] = b                                                              
flash_data[12] = c                                                              
flash_data[13] = d                                                              
flash_data[14] = e                                                              
flash_data[15] = f                                                              
/**************read test**************************/                            
[e] = 0                                                                        
[d] = 0                                                                        
[c] = 0                                                                        
= 0                                                                        
[a] = 0                                                                        
[9] = 0                                                                        
[8] = 0                                                                        
[7] = 0                                                                        
[6] = 0                                                                        
[5] = 0                                                                        
[4] = 0                                                                        
[3] = 0                                                                        
[2] = 0                                                                        
[1] = 0                                                                        
[0] = 0
测试程序如下:
#include <stdio.h>

#include <stdlib.h> //system

#include <fcntl.h>

#include <errno.h>

#include <unistd.h>



#include <sys/ioctl.h>

#define DEVICE_NODE     "/dev/nor"

#define    READ_IN    0

#define    WRITE_OUT    1

#define    CPU_RESET    3



        



int main(int argc,char *argv[ ])

{

    int    fd;

    int i;

    int count;

    unsigned int capacity;

    unsigned long addr,arg;

    unsigned    int    data;

    unsigned    int    cmd=0xff;

    unsigned char original_data[1024];

    unsigned char flash_data[1024];

    unsigned char write_buffer[1024];

    fd=open(DEVICE_NODE,O_RDWR);

    

    if(fd<0)

    {

        perror("Can not open device!!!\n");

        exit(1);

    }

    printf("/**************read test**************************/\n");

    count = read(fd, original_data, 15);

    for(i = count - 1; i >= 0; i--)

    {

        printf("[%x] = %x\n", i, original_data);

    }

    printf("/***************write test***********************/\n");

    for(i = 0; i <= 15; i++)

    {

        write_buffer = i;

        printf("flash_data[%d] = %x\n", i, write_buffer);

    }

    count = write(fd, write_buffer, 15);

    for(i = 0; i <= 15; i++)

    {

        printf("flash_data[%d] = %x\n", i, write_buffer);

    }

    

    printf("/**************read test**************************/\n");

    count = read(fd, flash_data, count);

    for(i = count - 1; i >= 0; i--)

    {

        printf("[%x] = %x\n", i, flash_data);

    }

    

    count = write(fd, original_data, 15);

/**    printf("capacity: ... ");

    scanf("%d", &capacity);

    printf("capacity is %d M.\nstart read the nor flash\n", capacity);

    

    for(i = 0; i < capacity; i++)

    {    

        for(addr = 0; addr < 0x80000; addr++){

            arg=((unsigned long)0<<24)+((i * 0x80000 + addr) &0x00ffffff);

            ioctl(fd,0,arg);

        }

    }

*/

/*

    printf("cmd: ");

    scanf("%d",&cmd);

    printf("cmd is %d\n",cmd);

    switch(cmd)

    {

        case    READ_IN:

            printf("read!\n");

            printf("address: ");

            scanf("%lx",&addr);

            arg=((unsigned long)cmd<<24)+(addr&0x00ffffff);

            ioctl(fd,0,arg);

            break;

        case    WRITE_OUT:

            printf("write!\n");

            printf("address: ");

            scanf("%lx",&addr);

            arg=((unsigned long)cmd<<24)+(addr&0x00ffffff);

            printf("data: ");

            scanf("%x",&data);

            if(data>0xffff)

            {

                printf("Data too long!\n");

                return    1;

            }    

            ioctl(fd,data,arg);

            break;

        case    CPU_RESET:

            printf("Cpu reset!\n");

            arg=((unsigned    long)cmd<<24);

            ioctl(fd,0,arg);

            break;

        default:

            printf("Wrong Command!\n");

            break;

        }            

*/        

    close(fd);

    return 0;

}


驱动程序如下:
#include     <linux/config.h>
#include     <linux/module.h>
#include     <linux/moduleparam.h>

#include     <linux/mman.h>
#include     <linux/vmalloc.h>
#include     <asm/pgalloc.h>
#include     <linux/pagemap.h>
#include     <linux/rmap.h>
#include     <linux/mm.h>
#include     <linux/init.h>
#include     <linux/kernel.h>   /* DPRINTK() */
#include     <linux/slab.h>     /* kmalloc() */
#include     <linux/fs.h>       /* everything... */
#include     <linux/errno.h>    /* error codes */
#include     <linux/types.h>    /* size_t */
#include     <linux/proc_fs.h>
#include     <linux/delay.h>
#include     <asm/io.h>
#include     <linux/seq_file.h>
#include     <linux/cdev.h>
#include     <asm/uaccess.h>    /* copy_*_user */
#include     <linux/interrupt.h>
#include     <asm/arch/irqs.h>



#define PRINTK printk

#define DEVICE_CAPACITY 0X100000    /*QQ2440V3有 2M nor_flash*/


unsigned long base_addr = 0x14000;/*测试程序为了不引起nor flash内部原来的程序,从1M开始的地方进行测试,看是否好用*/
int nor_major  =  240;    


int nor_minor =   0;


int nor_nr_devs = 1;



struct cdev *nor_cdev;        //×Ö·ûÉ豞µÄœÚµã

dev_t nor_dev ;            //Çý¶¯É豞ºÅµÄœÚµã



static    int    nor_open(struct    inode    *inode,struct    file    *file);

static    int    nor_ioctl(struct    inode    *inode,struct    file    *file,unsigned        int    cmd,unsigned    long    arg);

ssize_t read(struct file *file, char __user *buf,
                         size_t len, loff_t *ppos);
ssize_t write(struct file *file, const char __user *buf,
                          size_t len, loff_t *ppos);

static struct file_operations nor_fops = {
    .owner    =    THIS_MODULE,
    .open    =    nor_open,
    .ioctl    =     nor_ioctl,
    .read      =     read,
    .write     =    write,
};


static    int nor_open(struct    inode    *inode,struct    file    *file)

{

    

    try_module_get(THIS_MODULE);

    PRINTK("Open nor_drv successful!\n");



    return    0;

}



unsigned    short    read_data(unsigned long    addr)

{

    unsigned    long    v_addr;

    unsigned    short data;

    v_addr=(unsigned long)ioremap(addr,4);

    data=*((volatile    unsigned    short*)v_addr);

    iounmap((void*)v_addr);

    return    data;

}    


ssize_t read(struct file *file, char __user *buf,
                         size_t len, loff_t *ppos)
{
    size_t count = 0;
    unsigned long v_addr;
    for(count = 0; (count <= DEVICE_CAPACITY) && (count < len); count ++)
    {
        v_addr=(unsigned long)ioremap(base_addr + count,1);

        copy_to_user(buf + count, ((volatile    unsigned    short*)v_addr), 1);
        iounmap(v_addr);
    }
    return count;
}


ssize_t write(struct file *file, const char __user *buf,
                          size_t len, loff_t *ppos){

    unsigned        long    v_addr[4];
    size_t count;
        int     i;
        //printk("[0x%08lx] = %04x\n",addr,data);
        v_addr[0]=(unsigned long)ioremap(0x00000aaa,4);
            v_addr[1]=(unsigned long)ioremap(0x00000555,4);
            v_addr[2]=(unsigned long)ioremap(0x00000aaa,4);
      for(count = 0; count < len; count++)
    {
            v_addr[3]=(unsigned long)ioremap(base_addr+count,4);
            *((volatile     unsigned        short*)v_addr[0])=0xaa;
            *((volatile     unsigned        short*)v_addr[1])=0x55;
            *((volatile     unsigned        short*)v_addr[2])=0xa0;
            copy_from_user((volatile unsigned short *)v_addr[3], &(buf[count]), 1);
//        *((volatile     unsigned        short*)v_addr[3])=data;
                iounmap((void*)v_addr[3]);
    }
        for(i=0;i<4;i++)
        {
                iounmap((void*)v_addr);
        }
    return count;
}
    

        

static    int    nor_ioctl(struct    inode    *inode,struct    file    *file,unsigned        int    cmd,unsigned    long    arg)

{

    unsigned    short data;

    data=read_data(arg);

    printk("[%x] = %d\n",arg, data);

}    









static int __init nor_init(void)

{

    int    result,err;

    if(nor_major)

    {

        nor_dev=MKDEV(nor_major,nor_minor);        //²úÉúÉ豞œÚµã

        //²ÎÊýÊÇÖ÷É豞ºÅºÍŽÓÉ豞ºÅ|·µ»ØÉ豞œÚµã

        result=register_chrdev_region(nor_dev,1,"nor");    //×¢²áÉ豞

           //²ÎÊýÊÇÉ豞œÚµã£¬É豞Êý£¬É豞Ãû|·µ»Øœá¹û

    }

    else

    {

        result=alloc_chrdev_region(&nor_dev,nor_minor,1,"nor");    //¶¯Ì¬²úÉúÉ豞œÚµã

        //²ÎÊýÊÇÉ豞œÚµãµÄÖžÕ룬ŽÓÉ豞ºÅ£¬É豞Êý£¬É豞Ãû|·µ»Øœá¹û

        nor_major=MAJOR(nor_dev);        //²ÎÊýÊÇÉ豞œÚµã|·µ»ØÖ÷É豞ºÅ

    }

    if(result<0)

    {

        PRINTK(KERN_ERR " nor: Can not get major %d!\n",nor_major);

        return -1;

        }    



         nor_cdev=cdev_alloc();        //²úÉú×Ö·ûÉ豞œÚµã

         if(nor_cdev!=NULL)

         {

             cdev_init(nor_cdev, &nor_fops);        //³õÊŒ»¯×Ö·ûÉ豞œÚµã

            //²ÎÊýÊÇ×Ö·ûÉ豞œÚµã£¬ÎÄŒþ²Ù×÷

            nor_cdev->ops=&nor_fops;

            nor_cdev->owner=THIS_MODULE;

            err=cdev_add(nor_cdev,nor_dev,1);    //ÌíŒÓ×Ö·ûÉ豞µœÉ豞œÚµã

            //²ÎÊýÊÇ×Ö·ûÉ豞œÚµã£¬É豞œÚµã£¬É豞Êý|·µ»ØŽíÎó



            if(err)

            {

            PRINTK(KERN_NOTICE " ERROR: %d adding nor_cdev!\n",err);

            }

            else

            {

                PRINTK(" Adding nor_cdev successful!\n");

            }    

        }

        else

        {

            PRINTK(KERN_ERR "Register nor_cdev error!\n");

            return    -1;

        }
        devfs_mk_cdev(MKDEV(nor_major, nor_minor), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, "nor");

            return    0;

}            



static    void    __exit    nor_cleanup(void)

{
    devfs_remove("nor");

    unregister_chrdev_region(nor_dev,1);        //Ð¶ÔØÇý¶¯@²ÎÊýÊÇÉ豞Çý¶¯œÚµã
    

    PRINTK("Unregister    Successful!\n");

}    



module_init(nor_init);

module_exit(nor_cleanup);



MODULE_AUTHOR("ELVIS");

MODULE_DESCRIPTION("ELVIS's norflash driver");

MODULE_LICENSE("GPL");