1. 程式人生 > >linux 裝置驅動 nand驅動框架

linux 裝置驅動 nand驅動框架

nand 裝置驅動(一)架構

使用mini2440 - nand

1. nand硬體

1.1 資源

LDATD0~7資料線和地址線是複用的,都是8位

既可以傳輸資料(命令或者資料), 也可以傳送地址訊號

訊號說明:

CLE: 命令鎖存, 高表示cmd

ALE: 地址鎖存, 高表示地址

CE :片選,低有效

R/B:狀態: 低電平表示busy, 高電平表示idle, 

RE:讀使能, 

WE:

 

命令集:

 

1.2 硬體操作

 讀ID命令字90, 時序如下:

 

 

2. kernel-nand驅動結構

開發板上電後有輸出:

S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=3, 30ns Twrph0=7 70ns, Twrph1=3 30ns
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks

搜尋“S3C24XX NAND Driver”
s3c2410.c (drivers\mtd\nand)

呼叫關係
s3c2410_nand_init
    s3c2440_nand_driver
        s3c2440_nand_probe
            s3c24xx_nand_probe
                s3c2410_nand_inithw
                s3c2410_nand_init_chip
                nand_scan
                s3c2410_nand_add_partition

在s3c2410_nand_init_chip

s3c2410_nand_init_chip
    struct nand_chip *chip = &nmtd->chip;
    chip->write_buf    = s3c2410_nand_write_buf;
    chip->read_buf     = s3c2410_nand_read_buf;
    chip->select_chip  = s3c2410_nand_select_chip;
    chip->cmd_ctrl  = s3c2440_nand_hwcontrol;
    chip
->dev_ready = s3c2440_nand_devready; chip->IO_ADDR_R = chip->IO_ADDR_W; nmtd->info = info; nmtd->mtd.priv = chip; nmtd->mtd.owner = THIS_MODULE;

再看nand_scan          // 在檔案nand_base.c

nand_scan
nand_scan_ident
        nand_set_defaults(chip, busw);                    // 設定預設引數, 如果s3c2410_nand_init_chip設定了就用設定的函式
        nand_get_flash_type                               // Get the flash and manufacturer id
            /* Select the device */
            chip->select_chip(mtd, 0);
        
            /* Send the command for reading device ID */
            chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); // 傳送0x90,即讀ID
        
            /* Read manufacturer and device IDs */
            *maf_id = chip->read_byte(mtd);                 // 讀廠商ID
            dev_id = chip->read_byte(mtd);                  // 讀裝置ID
            
            輸出“NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)”
            printk(KERN_INFO "NAND device: Manufacturer ID:"
               " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
               dev_id, nand_manuf_ids[maf_idx].name, mtd->name);
               // nand_flash_ids 表示{NAND_MFR_SAMSUNG, "Samsung"},
           
        chip->select_chip(mtd, i); 
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);    // 發命令/資料

最後s3c2410_nand_add_partition

add_mtd_partitions
        mtd_table[i] = mtd;          // mtd_table是全域性陣列
        list_for_each(this, &mtd_notifiers) {
        mtd_notifiers是一個連結串列head, 在mtdcore.c (drivers\mtd)裡面新增
            register_mtd_user      // mtdchar.c (drivers\mtd) 和mtd_blkdevs.c (drivers\mtd)呼叫,分別是字元裝置和塊裝置

 

3. nand驅動編寫

從上面分析看出,編寫nand flash驅動主要有:
3.1 定義nand_chip *chip
3.2 設定
3.3 註冊

搜尋nand_scan可以看到很多例子
參考:s3c2410.c 和at91_nand.c (drivers\mtd\nand)