基于linux2.6.16的nand驱动开发(二)

来源:互联网 发布:人工智能股票有哪些股 编辑:程序博客网 时间:2024/06/06 06:42

第二部分:具体的Nand Flash驱动

搞清楚了MTD,内核,nandflash设备驱动的关系后,现在就是如何编写针对我们这款处理器的驱动,首先介绍一下nandflash结构struct nand_chip

. struct nand_chip {

       void  __iomem      *IO_ADDR_R;  //这是nandflash的读写寄存器,对于我们的芯片是

       void  __iomem     *IO_ADDR_W;  //EMI_NAND_DATA

 

//以下都是nandflash的操作函数,这些函数将根据相应的配置进行重载,也是在nand_scan这个函数中,nand_scan这个函数非常重要,在下文讲详细阐述

       u_char    (*read_byte)(struct mtd_info *mtd);

       void        (*write_byte)(struct mtd_info *mtd, u_char byte);

       u16         (*read_word)(struct mtd_info *mtd);

       void        (*write_word)(struct mtd_info *mtd, u16 word);

       void        (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);

       void        (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);

       int           (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);

       void        (*select_chip)(struct mtd_info *mtd, int chip);

       int           (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);

       int           (*block_markbad)(struct mtd_info *mtd, loff_t ofs);

       void              (*hwcontrol)(struct mtd_info *mtd, int cmd);

       int                (*dev_ready)(struct mtd_info *mtd);

       void              (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);

       int          (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);

       int           (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);

       int          (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);

       void        (*enable_hwecc)(struct mtd_info *mtd, int mode);

       void        (*erase_cmd)(struct mtd_info *mtd, int page);

       int           (*scan_bbt)(struct mtd_info *mtd);

       int           eccmode;   //ecc是软件校验?硬件校验?无?

       int          chip_delay;  //芯片时序延迟参数

       int          page_shift;  //页偏移,对于512/页的,一般是9

       u_char           *data_buf; //数据缓存区

(其它参数解释详解linux内核源码)

 

●其实我们需要做的事情,就是将上述这些函数,根据我们sep4020的特性,将其重载。

主要重载的函数有:

 

this->hwcontrol = sep4020_hwcontrol;

这是一个硬件操作函数,由于在nandflash中对寄存器的操作都是通过IO_ADDR_RIO_ADDR_W来实现的,而我们需要根据需要在地址寄存器,数据寄存器,命令寄存器,ID寄存器,状态寄存器之间切换,通过这个函数来实现对IO_ADDR_RIO_ADDR_W的变动。

 

this->dev_ready = sep4020_nand_dev_ready;

nandflash是否完成的函数,通过读取EMI_NAND_IDLE寄存器位来判断。

 

this->write_buf      = sep4020_nand_write_buf;

Nandflash的写函数,nandflash的最基本也是最重要的命令之一。

 

this->read_buf  = sep4020_nand_read_buf;

Nanflash的读函数,功能同上。

 

this->write_byte = sep4020_nand_write_byte;

this->read_byte =  sep4020_nand_read_byte;

实际这两个函数实现了读取和写入寄存器一个byte的功能,

 

this->eccmode = NAND_ECC_SOFT;//软件ecc校验

 

this->select_chip = sep4020_nand_select_chip;//无此功能,空留

 

this->cmdfunc = sep4020_nand_command;

linux中对nand的操作都是通过两个函数来实现的,一个是发命令也就是此处的cmdfuc,还有一个就是读写函数,由于sep4020nandflash控制器的特殊,需要将这个函数重载(下文会介绍我们nandflash的特性)

 

this->erase_cmd = sep4020_nand_cmd_erase;

擦除命令,理由同上。

 

关于nand_scan函数

Nand_scan是在初始化nand的时候对nand进行的一步非常好重要的操作,在nand_scan中会对我们所写的关于特定芯片的读写函数重载到nand_chip结构中去,并会将mtd_info结构体中的函数用nand的函数来重载,实现了mtd到底层驱动的联系。

并且在nand_scan函数中会通过读取nand芯片的设备号和厂家号自动在芯片列表中寻找相应的型号和参数,并将其注册进去。

原创粉丝点击