NOR FLASH Driver

Publisher:阳关三迭Latest update time:2016-04-01 Source: eefocusKeywords:NOR  FLASH  driver Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
//
// Refer to 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 map_info *s3c_nor_map;
static struct mtd_info *s3c_nor_mtd;
 
static struct mtd_partition s3c_nor_parts[] = {
        [0] = {
        .name   = "bootloader_nor",
        .size   = 0x00040000,
                  .offset = 0,
         },
         [1] = {
        .name   = "root_nor",
        .offset = MTDPART_OFS_APPEND,
        .size   = MTDPART_SIZ_FULL,
         }
};
 
 
static int s3c_nor_init(void)
{
       // 1. Allocate map_info structure//
        s3c_nor_map = kzalloc(sizeof(struct map_info), GFP_KERNEL);;
       // 2. Settings: physical base address (phys), size (size), bankwidth (bankwidth), virtual base address (virt) //
        s3c_nor_map->name = "s3c_nor";
       s3c_nor_map->phys = 0;                  //When nor is started, the physical address is 0
       s3c_nor_map->size = 0x1000000;    // >= the actual size of NOR//
        s3c_nor_map->bankwidth = 2;        //16位
        s3c_nor_map->virt = ioremap(s3c_nor_map->phys, s3c_nor_map->size);
 
       simple_map_init(s3c_nor_map);      //Simple initialization
       // 3. Use: Call the function provided by the NOR FLASH protocol layer to identify //
        printk("use cfi_probe\n");
        s3c_nor_mtd = do_map_probe("cfi_probe", s3c_nor_map);
        if (!s3c_nor_mtd)
        {
                printk("use jedec_probe\n");
                s3c_nor_mtd = do_map_probe("jedec_probe", s3c_nor_map);
        }
 
       if (!s3c_nor_mtd)
       {
                iounmap(s3c_nor_map->virt);
                kfree(s3c_nor_map);
               return -EIO;
       }
        // 4. add_mtd_partitions //
        add_mtd_partitions(s3c_nor_mtd, s3c_nor_parts, 2);
        return 0;
}
 
static void s3c_nor_exit(void)
{
        del_mtd_partitions(s3c_nor_mtd);
       iounmap(s3c_nor_map->virt);
       kfree(s3c_nor_map);
}
 
module_init(s3c_nor_init);
module_exit(s3c_nor_exit);
 
MODULE_LICENSE("GPL");
=============================================================
Use UBOOT to experience the operation of NOR FLASH (the development board is set to NOR boot and enter UBOOT)
Use OpenJTAG to burn UBOOT to NOR FLASH first
 
1. Read data
md.b 0 
 
2. Read ID
NOR manual:
Write AAH to address 555H
Write 55H to address 2AAH
Write 90H to address 555H
Read address 0 to get the manufacturer ID: C2H
Read address 1 to get device ID: 22DAH or 225BH
Exit the read ID state: write F0H to any address
 
A1 of 2440 is connected to A0 of NOR, so 2440 sends (555h<<1), and NOR can receive the address 555h.
How to operate UBOOT?
 
Write AAH to address AAAH                      mw.w aaa aa
Write 55H to address 554                      mw.w 554 55
Write 90H to address AAAH                      mw.w aaa 90
Read address 0 to get the manufacturer ID: C2H              md.w 0 1
Read address 2 to get device ID: 22DAH or 225BH      md.w 2 1
Exit read ID state:                        mw.w 0 f0
 
3. NOR has two specifications, jedec and cfi (common flash interface)
   Read CFI information
 
NOR Manual:   
Enter CFI mode    and write 98H to 55H
Read data:        read 10H to get 0051
               Read 11H and get 0052
               Read 12H and get 0059
               Read 27H to get capacity
 
A1 of 2440 is connected to A0 of NOR, so 2440 sends (555h<<1), and NOR can receive the address 555h.
How to operate UBOOT?
Enter CFI mode    and write 98H to AAH            mw.w aa 98
Read data:        read 20H to get 0051          md.w 20 1
               Read 22H to get 0052          md.w 22 1
               Read 24H to get 0059          md.w 24 1
               Read 4EH to get the capacity          md.w 4e 1
               Exit CFI mode            mw.w 0 f0
 
4. Write data: Write 0x1234 at address 0x100000
md.w 100000 1    // get ffff
mw.w 100000 1234
md.w 100000 1    // Still ffff
 
NOR Manual:
Write AAH to address 555H 
Write 55H to address 2AAH 
Write A0H to address 555H 
Write PD to address PA
 
A1 of 2440 is connected to A0 of NOR, so 2440 sends (555h<<1), and NOR can receive the address 555h.
How to operate UBOOT?
Write AAH to address AAAH              mw.w aaa aa
Write 55H to address 554H              mw.w 554 55
Write A0H to address AAAH              mw.w aaa a0
Write 1234h to address 0x100000        mw.w 100000 1234
 
 
NOR FLASH driver framework
 
 
Test 1: Configure the kernel to support NOR FLASH
1. make menuconfig
-> Device Drivers
  -> Memory Technology Device (MTD) support
    -> Mapping drivers for chip access
    CFI Flash device in physical memory map 
   (0x0) Physical start address of flash mapping    // Physical base address
   (0x1000000) Physical length of flash mapping   // length
   (2)   Bank width in octets (NEW)                          // bit width
    
2. make modules
   cp drivers/mtd/maps/physmap.ko /work/nfs_root/first_fs
3. Start the development board
   ls /dev/mtd*
   insmod physmap.ko
   ls /dev/mtd*
   cat /proc/mtd
 
 
Test 2: Using a self-written driver:
 
1. ls /dev/mtd*
2. insmod s3c_nor.ko
3. ls /dev/mtd*
4. Formatting: 
   flash_eraseall -j /dev/mtd1                  //-j: indicates formatting into jffs2. Generally, NOR flash uses jffs2, and NAND flash uses yaffs
                                                                   //Use character device mtd1 when formatting
5. mount -t jffs2 /dev/mtdblock1 /mnt   //Use block device mtdblock1 when mounting
   Operate files in the /mnt directory
   
   
NOR FLASH identification process:
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
                                               // Enter CFI mode
                                                cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
                                               // See if "QRY" can be read
                                                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
           every_sample
                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
                                       // Unlock
                                        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);
                                        
                                       // Read ID command
                                        cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);                                      
                            
                                       // Get the manufacturer ID and device ID
                                        cfi->mfr = jedec_read_mfr(map, base, cfi);
                                        cfi->id = jedec_read_id(map, base, cfi);
                                        
                                       // Compare with array
                                       jederc_table     
 

Keywords:NOR  FLASH  driver Reference address:NOR FLASH Driver

Previous article:DMA operation driver
Next article:NAND FLASH Driver

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号