zoukankan      html  css  js  c++  java
  • U-BOOT 对 Nand Flash 命令的支持

    U-BOOT Nand Flash 命令的支持

    在 U­BOOT 下对 Nand Flash 的支持主要是在命令行下实现对 nand flash 的操作。对 nand flash 实现的命令 为:nand info、nand device、nand read、nand write、nand erease、nand bad。

    用到的主要数据结构有:struct nand_flash_dev、struct nand_chip。前者包括主要的芯片型号、存储容量、

    设备 ID、I/O 总线宽度等信息;后者是具体对 nand flash 进行操作时用到的信息。

    3.2.1 主要数据结构介绍

    1. struct nand_flash_dev 数据结构

    该数据结构在 include/linux/mtd/nand.h 中定义,在 include/linux/mtd/nand_ids.h 中赋初值。 struct nand_flash_dev {

    char *name;                       /* 芯片名称 */ int manufacture_id;     /* 厂商 ID    */ int model_id;        /* 模式 ID   */

    int chipshift;                       /*  Nand Flash 地址位数 */

    char page256;                    /* 表明是否时 256 字节一页。1:是;0:否。*/

    char pageadrlen;                /* 完成一次地址传送需要往 NFADDR 中传送几次。*/ unsigned long erasesize;  /* 一次块擦除可以擦除多少字节 */

    int bus16;                            /* 地址线是否是 16 位,1:是;0:否 */

    };

    1. struct nand_chip 数据结构

    该数据结构在 include/linux/mtd/nand.h 中定义. 该结构体定义出一个 Nand Flash 设备数组: struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];

    该数组在 nand_probe()中对其进行初始化.

    struct nand_chip {

    int

    page_shift;

    /*  Page 地址位数

    */

    u_char

    *data_buf;

    /* 本次读出的一页数据

    */

    u_char

    *data_cache;

    /* 读出的一页数据

    */

    int

    cache_page;

    /* 上次操作的页号

    */

    u_char   ecc_code_buf[6]; /* ECC 校验码          */ u_char   reserved[2];

    char ChipID;                        /* 芯片 ID 号            */

    struct Nand *chips;             /* Nand Flash 芯片列表, 表示支持几个芯片为一个设备*/ int chipshift;

    char* chips_name;            /* Nand Flash 芯片名称    */

    unsigned long erasesize;  /* 块擦写的大小          */

    unsigned long mfr;            /* 厂商 ID                                     */

    unsigned long id;                /* 模式 ID                                    */

    char* name;                       /* 设备名称              */

    int numchips;                     /* 有几块 Nand Flash 芯片  */

    char page256;                   /* 一页是 256 字节, 还是 512 字节 */ char pageadrlen;     /* 页地址的长度          */

    unsigned long IO_ADDR; /* 用于对 nand flash 进行寻址的地址值存放处 */ unsigned long totlen;                                          /* Nand Flash 总共大小      */

    uint oobblock;               /* 一页的大小。本款 nand flash 为 512                   */ uint oobsize;        /* spare array 大小。本款 nand flash 为 16                           */ uint eccsize;     /* ECC 大小 */

    int bus16;                       /* 地址线是否是 16 位,1:是;0:否       */

    };

    3.2.2 支持的命令函数说明

    1. nand info/nand device 功能:显示当前 nand flash 芯片信息。 函数调用关系如下(按先后顺序):

    static void nand_print(struct nand_chip *nand) ;

    1. nand erase 功能:擦除指定块上的数据。 函数调用关系如下(按先后顺序):

    int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);

    1. nand bad

    功能:显示坏块。 函数调用关系如下(按先后顺序):

    static void nand_print_bad(struct nand_chip* nand);

    int check_block (struct nand_chip *nand, unsigned long pos);

    1. nand read

    功能:读取 nand flash 信息到 SDRAM。

    函数调用关系如下(按先后顺序):

    int nand_rw (struct nand_chip* nand, int cmd,size_t start, size_t len, size_t * retlen, u_char * buf); static int nand_read_ecc(struct nand_chip *nand, size_t start, size_t len,

    size_t * retlen, u_char *buf, u_char *ecc_code);

    static void NanD_ReadBuf (struct nand_chip *nand, u_char * data_buf, int cntr); READ_NAND(adr);

    1. nand write

    功能:从 SDRAM 写数据到 nand flash 中。

    函数调用关系如下(按先后顺序):

    int nand_rw (struct nand_chip* nand, int cmd,size_t start, size_t len, size_t * retlen, u_char * buf); static int nand_write_ecc (struct nand_chip* nand, size_t to, size_t len,

    size_t * retlen, const u_char * buf, u_char * ecc_code);

    static int nand_write_page (struct nand_chip *nand, int page, int col, int last, u_char * ecc_code); WRITE_NAND(d , adr);

    3.2.3 U-BOOT 支持 Nand Flash 命令移植说明

    1. 设置配置选项

    在 CONFIG_COMMANDS 中, 打开 CFG_CMD_NAND 选项.

    #define CONFIG_COMMANDS

    (CONFIG_CMD_DFL | CFG_CMD_CACHE | CFG_CMD_NAND             |

    /*CFG_CMD_EEPROM |*/

    /*CFG_CMD_I2C               |*/

    /*CFG_CMD_USB             |*/ CFG_CMD_PING | CFG_CMD_REGINFO | CFG_CMD_DATE                                                | CFG_CMD_ELF)

    #if (CONFIG_COMMANDS & CFG_CMD_NAND)

    #define CFG_NAND_BASE                      0x4E000000   /* Nand Flash 控制器在 SFR 区中起始寄存器地址 */

    #define CFG_MAX_NAND_DEVICE  1                        /* 支持的最在 Nand Flash 数据 */

    #define SECTORSIZE                                512                  /* 1 页的大小 */

    #define NAND_SECTOR_SIZE                SECTORSIZE

    #define NAND_BLOCK_MASK              (NAND_SECTOR_SIZE – 1)  /* 页掩码 */

    #define ADDR_COLUMN                         1   /* 一个字节的 Column 地址 */

    #define ADDR_PAGE                                 3   /* 3 字节的页块地址, A9­A25*/

    #define ADDR_COLUMN_PAGE           4   /*  总共 4 字节的页块地址  */

    #define NAND_ChipID_UNKNOWN  0x00  /* 未知芯片的 ID 号 */

    #define NAND_MAX_FLOORS              1

    #define NAND_MAX_CHIPS                  1

    /* Nand Flash 命令层底层接口函数 */

    #define WRITE_NAND_COMMAND(d, adr) do {rNFCMD = d;} while(0)

    #define WRITE_NAND_ADDRESS(d, adr) do {rNFADDR = d;} while(0)

    #define WRITE_NAND(d, adr)           do {rNFDATA = d;} while(0)

    #define READ_NAND(adr)               (rNFDATA)

    #define NAND_WAIT_READY(nand)       {while(!(rNFSTAT&(1<<0)));}

    #define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}

    #define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}

    /* 下面一组操作对 Nand Flash 无效 */

    #define NAND_CTL_CLRALE(nandptr)

    #define NAND_CTL_SETALE(nandptr)

    #define NAND_CTL_CLRCLE(nandptr)

    #define NAND_CTL_SETCLE(nandptr)

    /* 允许 Nand Flash 写校验 */

    #define CONFIG_MTD_NAND_VERIFY_WRITE 1

    #endif    /* CONFIG_COMMANDS & CFG_CMD_NAND*/

    2. 加入自己的 Nand Flash 芯片型号

    在 include/linux/mtd/ nand_ids.h 中的对如下结构体赋值进行修改: static struct nand_flash_dev nand_flash_ids[] =   {

    ......

    {"Samsung K9F1208U0B",    NAND_MFR_SAMSUNG, 0x76, 26, 0, 4, 0x4000, 0},

    .......

    }

    这样对于该款 Nand Flash 芯片的操作才能正确执行。

    3.       编写自己的    Nand       Flash       初始化函数 在 board/crane2410/crane2410.c 中加入 nand_init()函数. void nand_init(void)

    {

    /* 初始化 Nand Flash 控制器, 以及 Nand Flash 芯片 */ nand_reset();

    /* 调用 nand_probe()来检测芯片类型 */

    printf ("%4lu MB ", nand_probe(CFG_NAND_BASE) >> 20);

    }

    该函数在启动时被 start_armboot()调用.

  • 相关阅读:
    方格取数+ 传纸条 noip2000 + noip2008 DP
    题解 P1103 【书本整理】
    CF212D 【Cutting a Fence】
    CF339D 【Xenia and Bit Operations】
    旅行 NOIP2018 luogu P5022
    CodeFores 集合
    战略游戏 SDOI2018 圆方树 + 树上倍增求点权和
    树网的核 NOIP 2007 luogu P1099
    P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G
    NOIP 2017 P3959 宝藏 (状态压缩DP板子)
  • 原文地址:https://www.cnblogs.com/fanweisheng/p/11106190.html
Copyright © 2011-2022 走看看