nandflash裸机驱动程序的分析
nandflash在嵌入式设备中广泛的应用,学些nandflash的重要性不言而喻,这里分析一段实例代码,不管是编码规范还是程序的结构都是很有价值的。下边是K9F1208U0M的实例代码。 extern void ReadPage(unsigned int addr,unsigned char *buf);??? //K9F1208U0M nand flash 的页数据读 extern void WritePage(unsigned int addr,unsigned char *buf);??? //K9F1208U0M nand flash 的页数据写 extern void MarkBadBlk(unsigned int addr);??????????? //屏蔽 K9F1208U0M nand flash 的坏块 extern int CheckBadBlk(unsigned int addr);??????????? //检查 K9F1208U0M nand flash 的坏块 extern void InitNandFlash(void);??????????? //K9F1208U0M nand flash 的初始化 #endif 需要详细看的是nandflash.c文件: // 常量定义区 //==================================================== #define??? DsNandFlash()??? (rNFCONF &= ~0x8000) //bit15=1 disable NAND flash controller #define??? InitEcc()??????? (rNFCONF |= 0x1000) //bit12=1 initialize ECC #define??? NoEcc()??????????? (rNFCONF &= ~0x1000) //bit12=0 initialize ECC #define??? NFChipEn()??????? (rNFCONF &= ~0x800) //bit11=0 NAND flash nFCE = L (active) #define??? NFChipDs()??????? (rNFCONF |= 0x800) //bit11=1 NAND flash nFCE = H (inactive) #define??? WrNFAddr(addr)??? (rNFADDR = (addr)) //write address to nand flash #define??? WrNFDat(dat)??? (rNFDATA = (dat)) //write data to nand flash #define??? RdNFDat()??????? (rNFDATA) //read data from nand flash #define??? RdNFStat()??????? (rNFSTAT) //read status from nand flash #define??? NFIsBusy()??????? (!(rNFSTAT&1)) //whether nand flash is busy? #define??? NFIsReady()??????? (rNFSTAT&1) //whether nand flash is ready? #define??? READCMD0??? 0 //Read0 model command == Page addr 0~127 #define??? READCMD1??? 1 //Read1 model command == Page addr 128~511 #define??? READCMD2??? 0x50 //Read2 model command == Page addr 512~527 #define??? ERASECMD0??? 0x60 //Block erase command 0 #define??? ERASECMD1??? 0xd0 //Block erase command 1 #define??? PROGCMD0??? 0x80 //page write command 0 #define??? PROGCMD1??? 0x10 //page write command 1 #define??? QUERYCMD??? 0x70 //query command #define??? RdIDCMD??????? 0x90 //read id command // 函数定义区 //==================================================== #include "NAND_Flash.h" /* 在第一次实用NAND Flash前,复位一下NAND Flash */ ??? wait_idle(); //==================================================== // 语法格式: void InitNandCfg(void) // 功能描述: 初始化 K9F1208U0M nand flash 配置 // 入口参数: 无 // 出口参数: 无 //==================================================== ??? //基本所有的falsh都可以公用的。 rNFCONF = (1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7);?? //使用控制器,使用ECC,不激活NandFlash,持续时间都设定为HCLK*8. } // 语法格式: unsigned int ReadChipId(void) // 功能描述: 读Nand Flash的ID号 // 入口参数: 无 // 出口参数: Nand Flash ID //==================================================== //==================================================== // 语法格式: unsigned short ReadStatus(void) // 功能描述: 读Nand Flash的状态 // 入口参数: 无 // 出口参数: Nand Flash 状态 //==================================================== //==================================================== // 语法格式: unsigned int EraseBlock(unsigned int addr) // 功能描述: Nand Flash块擦除 // 入口参数: 块地址 // 出口参数: 擦除状态 0 为成功 非0 失败 //==================================================== unsigned int EraseBlock(unsigned int addr) ??? addr &= ~0x1f; ? ?????? ?//保留9-25位 ?? ??? WrNFAddr(addr>>8); ??????? WrNFAddr(addr>>16); ?? ?????? ?? // 语法格式: void ReadPage(unsigned int addr,unsigned char *buf) // 功能描述: 读取页的内容 // 入口参数: 1,页地址 2,读出的页内数据 // 出口参数: 无 //==================================================== /**** K9F1208U0M nand flash 的页数据读 ****/ {???? ?????? ?????? ?????? ?????? ?????? ?????? //该程序是读取一页(512字节)内容. //==================================================== // 语法格式:extern unsigned int WritePage(unsigned int addr,unsigned char *buf) // 功能描述: 写页数据 // 入口参数: 1,页地址 2,写页内数据 // 出口参数: 无 //==================================================== ??? WrNFAddr(addr); //页地址 ??? WrNFAddr(addr>>8); // ?? ??? tmp[1] = rNFECC1; ??? WrNFDat(tmp[1]); ??? wait_idle(); // 语法格式:extern void MarkBadBlk(unsigned int addr) // 功能描述: 屏蔽 K9F1208U0M nand flash 的坏块 // 入口参数: 块地址 // 出口参数: 无 //==================================================== ?? ??? WrNFAddr(addr); ??? WrNFDat(0); ??? WrNFDat(0); ??? WrNFCmd(READCMD0);??? //point to area a?????? ??? NFChipDs(); // 语法格式:int CheckBadBlk(unsigned int addr) // 功能描述: 检查 K9F1208U0M nand flash 的坏块 // 入口参数: 块地址 // 出口参数: 是否为坏块 0 坏块 1非坏块 //==================================================== int CheckBadBlk(unsigned int addr) WrNFAddr(5);??????????? //第517个字节(5=517&0xf) ??? WrNFAddr(addr); ?? ??? return (dat!=0xff); //==================================================== // 语法格式:void InitNandFlash(void) // 功能描述: K9F1208U0M nand flash 的初始化 // 入口参数: 无 // 出口参数: 无 //==================================================== ??????? NandAddr = 1; } 从上边的代码可以看出,尽管nandflash自身的操作时序非常的复杂,但在nandflash控制器的帮助下,nandflash的操作就变得非常的简单,这里只需要操作少量的寄存器就可以完成操作。首先分析代码,在驱动程序编程中,用的非常广泛的就是宏的定义, #define??? EnNandFlash()??? (rNFCONF |= 0x8000) //bit15=1 enable NAND flash controller #define??? DsNandFlash()??? (rNFCONF &= ~0x8000) //bit15=1 disable NAND flash controller可以在上边看到,同样是一个操作,定义成宏之后,就可以很直观的通过宏名来识别具体要完成的操作,所以以后在写一些和硬件相关的操作与函数时,要多加使用宏定义。 通常norflash与nandflash的区别在网上是很容易查到的,这里不重复了,这里看一些nandflash 的ecc校验,nandflash存在两种导致数据出错的问题就是反转与坏块,坏块需要标记出来,以后不能在存入数据,而数据的反转是一种正常的现象,通常需要检测多次如果成功就认为是反转,不用标记为坏块了,通常情况下,在写数据之前需要进行坏块检测,首先关于ecc,ecc的实现在ARM中是通过硬件来完成,操作的时候只需要把经过ECC校验的结构重新写入到nandflash的相应区域就可以了。nandflash是串行的数据传输,而norflash是三总线结构的存储器件,所以nandflash是不能随即读写的,通常的nandflash占用的I/O口有限,数据需要通过多次发送才能完成,我们需要了解nandflash的组织模式,nandflash通过层层细化,划分为不同的小单元进行操作。在进行擦除操作时,是以block为单位进行操作的,而编程与读取操作是以page为单位进行操作的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 4.12 Swift那些非常实用的内部函数 [Swift原创教
- c# – 未知解决方案项目类型:{42C0BBD9-55CE-4F
- FMDB -- SQLite( 自封装的DataBaseManager )
- flex datagrid 中实现combobox联动
- 在vue中添加Echarts图表的基本使用教程
- 收集一些常用的正则表达式(匹配中文字符、匹配双
- ruby-on-rails – Rails 4 Rolify Gem:用户角色
- 树莓派 2 和 3 上的 Swift 3.0
- ruby-on-rails – Rails – PostGIS postgis_ada
- ruby-on-rails – 如何在rails text_area字段中允