zoukankan      html  css  js  c++  java
  • 驱动10.nor flash

    1 比较nor/nand flash

                   NOR                                  NAND
    接口:    RAM-Like,引脚多                 引脚少,复用
    容量:  小 1M 2M 3M               大:128M 256M G
    读:        简单                                   复杂
    写:        发出特定命令 慢               发出特定命令 快
    价格:    贵                                         便宜
    特点:    无位反转、坏块                 位反转、坏块                                              
                    关键重要的程序         大数据、容忍可以出错的程序
    xip            可以                                 不可以

    2 使用UBOOT体验NOR FLASH的操作(开发板设为NOR启动,进入UBOOT)

     1 1. 读数据
     2 md.b 0 
     3 
     4 2. 读ID
     5 NOR手册上:
     6 往地址555H写AAH
     7 往地址2AAH写55H
     8 往地址555H写90H
     9 读0地址得到厂家ID: C2H
    10 读1地址得到设备ID: 22DAH或225BH
    11 退出读ID状态: 给任意地址写F0H
    12 
    13 2440的A1接到NOR的A0,所以2440发出(555h<<1), NOR才能收到555h这个地址
    14 UBOOT怎么操作?
    15 
    16 往地址AAAH写AAH                      mw.w aaa aa
    17 往地址554写55H                       mw.w 554 55
    18 往地址AAAH写90H                      mw.w aaa 90
    19 读0地址得到厂家ID: C2H               md.w 0 1
    20 读2地址得到设备ID: 22DAH或225BH      md.w 2 1
    21 退出读ID状态:                        mw.w 0 f0
    22 
    23 3. NOR有两种规范, jedec, cfi(common flash interface)
    24    读取CFI信息
    25 
    26 NOR手册:   
    27 进入CFI模式    往55H写入98H
    28 读数据:        读10H得到0051
    29                读11H得到0052
    30                读12H得到0059
    31                读27H得到容量
    32 
    33 2440的A1接到NOR的A0,所以2440发出(555h<<1), NOR才能收到555h这个地址
    34 UBOOT怎么操作?
    35 进入CFI模式    往AAH写入98H            mw.w aa 98
    36 读数据:        读20H得到0051           md.w 20 1
    37                读22H得到0052           md.w 22 1
    38                读24H得到0059           md.w 24 1
    39                读4EH得到容量           md.w 4e 1
    40                退出CFI模式             mw.w 0 f0
    41 
    42 4. 写数据: 在地址0x100000写入0x1234
    43 md.w 100000 1     // 得到ffff
    44 mw.w 100000 1234
    45 md.w 100000 1     // 还是ffff
    46 
    47 NOR手册:
    48 往地址555H写AAH 
    49 往地址2AAH写55H 
    50 往地址555H写A0H 
    51 往地址PA写PD
    52 
    53 2440的A1接到NOR的A0,所以2440发出(555h<<1), NOR才能收到555h这个地址
    54 UBOOT怎么操作?
    55 往地址AAAH写AAH               mw.w aaa aa
    56 往地址554H写55H               mw.w 554 55
    57 往地址AAAH写A0H               mw.w aaa a0
    58 往地址0x100000写1234h         mw.w 100000 1234
    使用uboot体验nor flash的读写

    3 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    

    4 写代码

     1 /*
     2  * 参考 driversmtdmapsphysmap.c
     3  */
     4 
     5 #include <linux/module.h>
     6 #include <linux/types.h>
     7 #include <linux/kernel.h>
     8 #include <linux/init.h>
     9 #include <linux/slab.h>
    10 #include <linux/device.h>
    11 #include <linux/platform_device.h>
    12 #include <linux/mtd/mtd.h>
    13 #include <linux/mtd/map.h>
    14 #include <linux/mtd/partitions.h>
    15 #include <asm/io.h>
    16 
    17 static struct map_info *s3c_nor_map;
    18 static struct mtd_info *s3c_nor_mtd;
    19 
    20 static struct mtd_partition s3c_nor_parts[] = {
    21     [0] = {
    22         .name   = "bootloader_nor",
    23         .size   = 0x00040000,
    24         .offset    = 0,
    25     },
    26     [1] = {
    27         .name   = "root_nor",
    28         .offset = MTDPART_OFS_APPEND,
    29         .size   = MTDPART_SIZ_FULL,
    30     }
    31 };
    32 
    33 
    34 static int s3c_nor_init(void)
    35 {
    36     /* 1. 分配map_info结构体 */
    37     s3c_nor_map = kzalloc(sizeof(struct map_info), GFP_KERNEL);;
    38     
    39     /* 2. 设置: 物理基地址(phys), 大小(size), 位宽(bankwidth), 虚拟基地址(virt) */
    40     s3c_nor_map->name = "s3c_nor";
    41     s3c_nor_map->phys = 0;
    42     s3c_nor_map->size = 0x1000000; /* >= NOR的真正大小 */
    43     s3c_nor_map->bankwidth = 2;
    44     s3c_nor_map->virt = ioremap(s3c_nor_map->phys, s3c_nor_map->size);
    45 
    46     simple_map_init(s3c_nor_map);
    47     
    48     /* 3. 使用: 调用NOR FLASH协议层提供的函数来识别 */
    49     printk("use cfi_probe
    ");
    50     s3c_nor_mtd = do_map_probe("cfi_probe", s3c_nor_map);
    51     if (!s3c_nor_mtd)
    52     {
    53         printk("use jedec_probe
    ");
    54         s3c_nor_mtd = do_map_probe("jedec_probe", s3c_nor_map);
    55     }
    56 
    57     if (!s3c_nor_mtd)
    58     {        
    59         iounmap(s3c_nor_map->virt);
    60         kfree(s3c_nor_map);
    61         return -EIO;
    62     }
    63     
    64     /* 4. add_mtd_partitions */
    65     add_mtd_partitions(s3c_nor_mtd, s3c_nor_parts, 2);
    66     
    67     return 0;
    68 }
    69 
    70 static void s3c_nor_exit(void)
    71 {
    72     del_mtd_partitions(s3c_nor_mtd);
    73     iounmap(s3c_nor_map->virt);
    74     kfree(s3c_nor_map);
    75 }
    76 
    77 module_init(s3c_nor_init);
    78 module_exit(s3c_nor_exit);
    79 
    80 MODULE_LICENSE("GPL");
    View Code
     1 测试1:通过配置内核支持NOR FLASH
     2 1. make menuconfig
     3 -> Device Drivers
     4   -> Memory Technology Device (MTD) support
     5     -> Mapping drivers for chip access
     6     <M> CFI Flash device in physical memory map
     7     (0x0) Physical start address of flash mapping  // 物理基地址
     8     (0x1000000) Physical length of flash mapping   // 长度
     9     (2)   Bank width in octets (NEW)               // 位宽
    10     
    11 2. make modules
    12    cp drivers/mtd/maps/physmap.ko /work/nfs_root/first_fs
    13 3. 启动开发板
    14    ls /dev/mtd*
    15    insmod physmap.ko
    16    ls /dev/mtd*
    17    cat /proc/mtd
    18 
    19 测试2: 使用自己写的驱动程序:
    20 
    21 1. ls /dev/mtd*
    22 2. insmod s3c_nor.ko
    23 3. ls /dev/mtd*
    24 4. 格式化: flash_eraseall -j /dev/mtd1
    25 5. mount -t jffs2 /dev/mtdblock1 /mnt
    26    在/mnt目录下操作文件
    测试方法
  • 相关阅读:
    LeetCode 226. Invert Binary Tree
    LeetCode 221. Maximal Square
    LeetCode 217. Contains Duplicate
    LeetCode 206. Reverse Linked List
    LeetCode 213. House Robber II
    LeetCode 198. House Robber
    LeetCode 188. Best Time to Buy and Sell Stock IV (stock problem)
    LeetCode 171. Excel Sheet Column Number
    LeetCode 169. Majority Element
    运维工程师常见面试题
  • 原文地址:https://www.cnblogs.com/Lwd-linux/p/6284111.html
Copyright © 2011-2022 走看看