• NOR Flash驱动


     

    驱动程序

    1 /*
    2 * 参考:
    3 * .linux-2.6.22.6driversmtddevicesmtdram.c
    4 * .linux-2.6.22.6driversmtdmapsphysmap.c
    5 */
    6 #include <linux/module.h>
    7 #include <linux/types.h>
    8 #include <linux/kernel.h>
    9 #include <linux/init.h>
    10 #include <linux/slab.h>
    11 #include <linux/device.h>
    12 #include <linux/platform_device.h>
    13 #include <linux/mtd/mtd.h>
    14 #include <linux/mtd/map.h>
    15 #include <linux/mtd/partitions.h>
    16 #include <linux/mtd/physmap.h>
    17 #include <asm/io.h>
    18
    19
    20 static struct map_info *nor_map;
    21 static struct mtd_info *nor_mtd;
    22
    23
    24 //分区信息
    25 static struct mtd_partition nor_parts[] = {
    26         [0] = {
    27                 .name         = "bootloader_nor",                        
    28                 .size         = 0x00040000,                        
    29                 .offset = 0,                                        /* offset within the master MTD space */
    30         },
    31
    32         [1] = {
    33                 .name         = "root_nor",                                
    34                 .offset = MTDPART_OFS_APPEND,        //紧跟着上一个分区的大小
    35                 .size         = MTDPART_SIZ_FULL,                
    36         },
    37 };
    38
    39
    40
    41 /* 1 出入口函数 */
    42 static int __init nor_init(void)
    43 {
    44         /* 2 分配map_info结构体 */
    45         nor_map = kmalloc(sizeof(struct map_info), GFP_KERNEL);
    46         /******** 2 end ********/
    47
    48
    49         /* 3 设置:物理基地址(phys)、大小(size)、位宽(bankwidth)、虚拟基地址(virt) */
    50         nor_map->name = "nor";
    51         nor_map->phys = 0;
    52         nor_map->size = 1000000;        //16M,大于nor的实际大小
    53         nor_map->bankwidth = 2;
    54         nor_map->virt = ioremap(nor_map->phys, nor_map->size);
    55
    56         simple_map_init(nor_map);
    57         /******** 3 end ********/
    58
    59
    60         /* 4 使用:调用Nor Flash协议层提供的函数来识别 */
    61         printk("use cfi_probe ");
    62         nor_mtd = do_map_probe("cfi_probe", nor_map);
    63         if (!nor_mtd)
    64         {
    65                 printk("use jedec_probe ");
    66                 nor_mtd = do_map_probe("jedec_probe", nor_map);
    67         }
    68         
    69         if (!nor_mtd)
    70         {
    71                 printk("fail ");
    72                 iounmap(nor_map->virt);
    73                 kfree(nor_map);
    74                 kfree(nor_mtd);
    75                 return -EIO;
    76         }
    77         /******** 4 end ********/
    78
    79         /* 5 添加分区:add_mtd_partison */
    80         add_mtd_partitions(nor_mtd, nor_parts, 2);
    81         /******** 5 end ********/
    82         return 0;
    83 }
    84
    85
    86 static void __exit nor_exit(void)
    87 {
    88         iounmap(nor_map->virt);
    89         kfree(nor_map);
    90         kfree(nor_mtd);
    91         del_mtd_partitions(nor_mtd);
    92         return;
    93 }
    94
    95 module_init(nor_init);
    96 module_exit(nor_exit);
    97
    98 MODULE_LICENSE("GPL");
    99 /******** 1 end ********/

       

       

    调试

    测试1:通过配置内核支持NOR FLASH

    1. make menuconfig

    -> Device Drivers

    -> Memory Technology Device (MTD) support

    -> Mapping drivers for chip access

    <M> CFI Flash device in physical memory map

    (0x0) Physical start address of flash mapping // 物理基地址

    (0x1000000) Physical length of flash mapping // 长度

    (2) Bank width in octets (NEW) // 位宽

     

    2. make modules

    cp drivers/mtd/maps/physmap.ko /work/nfs_root/first_fs

    3. 启动开发板

    ls /dev/mtd*

    insmod physmap.ko

    ls /dev/mtd*

    cat /proc/mtd

       

    测试2: 使用自己写的驱动程序:

    1. ls /dev/mtd*

    2. insmod s3c_nor.ko

    3. ls /dev/mtd*

    4. 格式化: flash_eraseall -j /dev/mtd1

    5. mount -t jffs2 /dev/mtdblock1 /mnt

    在/mnt目录下操作文件

     

     

    NOR FLASH识别过程:

    do_map_probe("cfi_probe", s3c_nor_map);

    drv = get_mtd_chip_driver(name)

    ret = drv->probe(map); // cfi_probe.c

    cfi_probe

    mtd_do_chip_probe(map, &cfi_chip_probe);

    cfi = genprobe_ident_chips(map, cp);

    genprobe_new_chip(map, cp, &cfi)

    cp->probe_chip(map, 0, NULL, cfi)

    cfi_probe_chip

    // 进入CFI模式

    cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);

    // 看是否能读出"QRY"

    qry_present(map,base,cfi)

    .....

     

    do_map_probe("jedec_probe", s3c_nor_map);

    drv = get_mtd_chip_driver(name)

    ret = drv->probe(map); // jedec_probe

    jedec_probe

    mtd_do_chip_probe(map, &jedec_chip_probe);

    genprobe_ident_chips(map, cp);

    genprobe_new_chip(map, cp, &cfi)

    cp->probe_chip(map, 0, NULL, cfi)

    jedec_probe_chip

    // 解锁

    cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);

    cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, cfi->device_type, NULL);

     

    // 读ID命令

    cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);

     

    // 得到厂家ID,设备ID

    cfi->mfr = jedec_read_mfr(map, base, cfi);

    cfi->id = jedec_read_id(map, base, cfi);

     

    // 和数组比较

    jedec_table

  • 相关阅读:
    0114 Handler(一)
    0110Activity布局初步2+0111布局初步3
    0108 Activity的生命周期(二)+显示文本的几种方法+调用发送短信(Intent)
    消除超级连接虚线
    ASP.NET数据绑定(转载)
    ASP.NET实现数字签名(转载)
    datatable插入数据库(转载)
    JavaScript(转载)
    Jquery插件按开发学习笔记(一)
    js判断浏览器\屏幕分辨率(转载)
  • 原文地址:https://www.cnblogs.com/lilto/p/11878027.html
Copyright © 2020-2023  润新知