基于linux2.6.16的nand驱动开发(二)
2008-10-11 16:57
357 查看
第二部分:具体的[/b]Nand Flash[/b]驱动[/b][/b]
搞清楚了MTD,内核,nandflash设备驱动的关系后,现在就是如何编写针对我们这款处理器的驱动,首先介绍一下nandflash结构struct nand_chip
●. struct nand_chip[/b] {
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_R和IO_ADDR_W来实现的,而我们需要根据需要在地址寄存器,数据寄存器,命令寄存器,ID寄存器,状态寄存器之间切换,通过这个函数来实现对IO_ADDR_R和IO_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;
擦除命令,理由同上。
●关于[/b]nand_scan[/b]函数[/b]
Nand_scan是在初始化nand的时候对nand进行的一步非常好重要的操作,在nand_scan中会对我们所写的关于特定芯片的读写函数重载到nand_chip结构中去,并会将mtd_info结构体中的函数用nand的函数来重载,实现了mtd到底层驱动的联系。
并且在nand_scan函数中会通过读取nand芯片的设备号和厂家号自动在芯片列表中寻找相应的型号和参数,并将其注册进去。
搞清楚了MTD,内核,nandflash设备驱动的关系后,现在就是如何编写针对我们这款处理器的驱动,首先介绍一下nandflash结构struct nand_chip
●. struct nand_chip[/b] {
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_R和IO_ADDR_W来实现的,而我们需要根据需要在地址寄存器,数据寄存器,命令寄存器,ID寄存器,状态寄存器之间切换,通过这个函数来实现对IO_ADDR_R和IO_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;
擦除命令,理由同上。
●关于[/b]nand_scan[/b]函数[/b]
Nand_scan是在初始化nand的时候对nand进行的一步非常好重要的操作,在nand_scan中会对我们所写的关于特定芯片的读写函数重载到nand_chip结构中去,并会将mtd_info结构体中的函数用nand的函数来重载,实现了mtd到底层驱动的联系。
并且在nand_scan函数中会通过读取nand芯片的设备号和厂家号自动在芯片列表中寻找相应的型号和参数,并将其注册进去。
相关文章推荐
- 基于linux2.6.16的nand驱动开发(一)
- 基于linux2.6.16的nand驱动开发(一)
- 基于linux2.6.16的nand驱动开发(三)
- 基于linux2.6.16的nand驱动开发(二)
- 基于linux2.6.16的nand驱动开发(三)
- 基于MTD的NAND驱动开发(一)
- linux驱动开发—基于Device tree机制的驱动编写
- 基于MTD的NAND驱动开发(1、2、3)
- 3、基于MTD的NAND驱动开发(三) .
- 基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号
- 基于MTD的NAND驱动开发(完)
- 基于MTD的NAND驱动开发(完)
- 基于MTD的NAND驱动开发
- 基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号
- 基于MTD的NAND驱动开发
- 基于MTD的NAND驱动开发(完)
- 《嵌入式设计及Linux驱动开发指南——基于ARM9处理器》读书笔记
- 基于MTD的NAND驱动开发
- 基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号
- 基于MTD的NAND驱动开发