美文网首页
nor flash设备驱动程序

nor flash设备驱动程序

作者: sgy1993 | 来源:发表于2017-08-11 22:35 被阅读0次

    为什么要把cpu的地址ADDR1连接到nor的A0上面
    cpu读取时认为一个地址对应一个字节,而nor flash一个地址对应两字节,如果直连的话就会存在一个问题,cpu读0,nor返回0地址两字节的低字节,cpu读1时,nor返回1地址两字节的低字节,这样显然是有问题的
    但是按照原理图就没有问题了
    cpu读0,nor返回0地址两字节的低字节,cpu读1时,nor返回0地址两字节的高字节,因为00,01,addr1都是0,同样10,11都对应nor的1地址,因为addr0不接,怎么变都无所谓这样就相当于cpu连续两个地址对应nor的一个地址。
    由于这样的特性,cpu如果发出地址0xa0,10100000,addr0没有接,对应nor flash地址1010000,hex:0x50.

    nor flash 原理图

    nor有两种规范jedec,cfi
    通用的
    1.进入cfi模式
    2.查找进入cfi模式后的后续操作

    读取厂家ID
    1.555写入aa mw.w 0xaaa 0xaa
    2.2aa写入55 mw.w 0x554 0x55
    3.555写入90 mw.w 0xaaa 0x90
    4.读取x00得到0xc2.厂家id,注意这里是两个字节为一个device id,高位在高地址

    进入cfi模式
    1.55写入98 mw.w aa 0x98
    2.读取10


    cfi指令集 flash 驱动程序框架

    程序源码do_map_probe函数是识别nor flash的函数,厂家id,设备id,容量等信息

    /*
     * 参考 drivers\mtd\maps\physmap.c
     */
    
    #include <linux/module.h>
    #include <linux/types.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/slab.h>
    #include <linux/device.h>
    #include <linux/platform_device.h>
    #include <linux/mtd/mtd.h>
    #include <linux/mtd/map.h>
    #include <linux/mtd/partitions.h>
    #include <asm/io.h>
    
    static struct mtd_info *nor_mtd = NULL;
    
    static struct map_info *my_map_info = NULL;
    static struct mtd_partition my_partions[] = {
        [0] = {
            .name = "bootloader",
            .size = 0x80000,
            .offset = 0,
        },
        [1] = {
            .name = "root",
            .size = MTDPART_SIZ_FULL,
            .offset = MTDPART_OFS_APPEND,
        },
    }; 
    static int s3c_nor_init(void)
    {
        int err = 0;
        /*
            1.分配一个map_info结构体,设置
        */
    
        my_map_info = kzalloc(sizeof(struct map_info), GFP_KERNEL);
        if (!my_map_info) {
            printk("error alloc my_map_info\n");
            return -ENOMEM;
        }
    
        
        my_map_info->name = "my_nor";
        my_map_info->phys = 0x0;
        my_map_info->size = 0x100000;
        my_map_info->bankwidth = 2;
    
        //映射地址空间,大小需要比nor flash大一点
    
        my_map_info->virt = ioremap(my_map_info->phys,my_map_info->size);
        if (!(my_map_info->virt)) {
            printk("Error ioremap\n");
            iounmap(my_map_info->virt);
            return -ENOMEM;
        }
    
        
        simple_map_init(my_map_info);
    
        //分配一个mtd_info结构体
        nor_mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
        
        if (!nor_mtd) {
            printk("error alloc nor_mtd\n");
            iounmap(my_map_info->virt);
            return -ENOMEM;
        }
        nor_mtd = do_map_probe("cfi_probe", my_map_info);
        
        if (!nor_mtd) {
            printk("error do_map_probe\n");
            iounmap(my_map_info->virt);
            kfree(my_map_info);
            kfree(nor_mtd);
            return -ENOMEM;
        }
        err = add_mtd_partitions(nor_mtd, my_partions, 2);
        if (err) {
            printk("func:%s, line:%d\n", 
                __func__, __LINE__);
            return -1;
        }
        return 0;
    }
    
    static void s3c_nor_exit(void)
    {
        int err = 0;
        
        iounmap(my_map_info->virt);
        kfree(my_map_info);
        kfree(nor_mtd);
        err = del_mtd_partitions(nor_mtd);
        if (!err) {
            
        printk("func:%s, line:%d, del mtd failed!\n", 
            __func__, __LINE__);
        }
    }
    
    module_init(s3c_nor_init);
    module_exit(s3c_nor_exit);
    
    MODULE_LICENSE("GPL");
    

    相关文章

      网友评论

          本文标题:nor flash设备驱动程序

          本文链接:https://www.haomeiwen.com/subject/fgarrxtx.html