nandflash驱动程序之完善识别过程

原创 2017年04月02日 00:20:04

我们发出了那些信号,

如上图,发出一些信号我们应该会维持一段时间啊,太短了 nandflash可能反应不过来,所以我们还要设置一些事件参数


根据nandflash的手册 设置时间参数


我们看一看那开发板的芯片手册


它的时间参数就在TACLS TWRPH0 TWRPH1 ,我们来看看这个时间参数是什么意思




在这张图可以看出TACLS是说你发出CLE与ALE之后过多长时间才能发出写信号,TWRPH0表示这个写信号的脉冲宽度,TWRPH1表示你写信号变为高电平之后还要过多长事件你这个ALE和CLE才能变为低电平



在这张图上我们一眼就可以看出twp这个脉冲宽度,可以看出tclh是写信号结束之后CLE维持的时间  然后TACLS就是tcls-twp

由这里可以看出,twp最小是12ns。tclh最小值5ns, 我们可以看到tcls最小值是12ns,twp最小值也是12ns,显然我们的tacls可以是0


现在还不需要把原理的nandflash驱动去掉,现在还只做了识别


我们把芯片手册打开,会发现我们的nandflash挺有意思的,


这里面是一页一页的东西,一页是2k,除了2k之外还有64字节的空间  这64字节称为oob区 oob是out of bank 在bank之外的东西

为什么引入oob呢,因为nandflash有个缺点,就是位反转,就是说我读一页数据,读出来有很大的几率某一位发生发转,我本来想读的是1,但是读出来是0

写进去的时候一样的。怎么办呢,就引入了ECC校验,我除了写这一页之外,还会用这一页数据生成ECC码 校验码,这个校验码把ECC写入OOB

读的操作就是把这整页数据,读OOB,然后根据数据重新算校验码,然后比较,可以判断是否发生位反转,而且可以知道哪一位发生了错误。这个校验码可以硬件生成也可以软件生成,我们用软件生成

在atmel_nand.c下有这么一行话来设置




驱动程序如图

#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>


#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>


#include <asm/io.h>


#include <plat/regs-nand.h>
#include <plat/nand.h>


static struct nand_chip *nand;
static struct mtd_info *nand_mtd;
struct s5p_nand_regs{
unsigned long nfconf;
unsigned long nfcont;
unsigned long nfcmmd;
unsigned long nfaddr;
unsigned long nfdata;
unsigned long nfmeccd0;
unsigned long nfmeccd1;
unsigned long nfseccd;
unsigned long nfsblk;
unsigned long nfeblk;
unsigned long nfstat;
unsigned long nfeccerr0;
unsigned long nfeccerr1;
};
static struct s5p_nand_regs *s5p_nand_regs;




static void gh_select_chip(struct mtd_info *mtd, int chipnr)
{
if(chipnr == -1)
{
//取消选中 将NFCONT[1] 设置为1
s5p_nand_regs->nfcont |=(1<<1);
}
else
{
//选中 NFCONT【1】设置为0
s5p_nand_regs->nfcont &= ~(1<<1);

}


}


static void gh_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{


if (ctrl & NAND_CLE)
{
//发命令 NFCMD寄存器 = cmd的值
s5p_nand_regs->nfcmmd = cmd;
}
else
{
//发地址 NFADDR寄存器=cmd的值
s5p_nand_regs->nfaddr = cmd;

}

}


static  int gh_dev_ready(struct mtd_info *mtd)
{
return (s5p_nand_regs->nfstat & (1<<0));
}


static int nand_init(void)
{
struct clk *nand_clk;
/*1.分配一个nand_chip结构体*/
nand = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
/*2.设置*/
s5p_nand_regs = ioremap(0xb0e00000,sizeof(struct s5p_nand_regs));
//设置nand_chip是给nand_scan_ident函数用的,如果不知道怎么设置,先看nand_scan_ident怎么使用*/
//它应该提供发命令,发地址,发数据,读数据,判断状态的功能
nand->select_chip = gh_select_chip; 
nand->cmd_ctrl = gh_cmd_ctrl;
nand->dev_ready = gh_dev_ready;
nand->IO_ADDR_R = &s5p_nand_regs->nfdata;
nand->IO_ADDR_W = &s5p_nand_regs->nfdata;
nand->ecc.mode      = NAND_ECC_SOFT;
/*硬件相关的操作*/

/*3.硬件相关*/
/*使能时钟*/
nand_clk = clk_get(NULL, "nand");
clk_enable(nand_clk);






/*设置时钟*/
//hclk是166.75Mhz,就是16.675ns
#define TWRPH1    1
#define TWRPH0    1
#define TACLS     1
s5p_nand_regs->nfconf |= (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);

/*
* AddrCycle[1]:1 = 发送地址需要5个周期
*/
s5p_nand_regs->nfconf |= 1<<1;
/*
* MODE[0]:1     = 使能Nand Flash控制器
* Reg_nCE0[1]:1 = 取消片选
*/
s5p_nand_regs->nfcont |= (1<<1)|(1<<0);

/*3.使用*/
nand_mtd=kzalloc(sizeof(struct mtd_info),GFP_KERNEL);

//将mtd_info与nandchip相联系起来


nand_mtd->owner = THIS_MODULE;
nand_mtd->priv = nand;




//nand_scan_ident(nand_mtd,1,NULL);//第二个参数是最大芯片个数
//nand_scan_tail(nand_mtd);
nand_scan(nand_mtd, 1);
return 0;
}


static void nand_exit(void)
{
kfree(nand);
iounmap(s5p_nand_regs);
kfree(nand_mtd);
}


module_init(nand_init);
module_exit(nand_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EIGHT");
 

测试效果如图





版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

基于MTD的NANDFLASH设备驱动底层实现原理分析(七)

上接: 基于MTD的NANDFLASH设备驱动底层实现原理分析(六) 初始化基本的硬件配置后probe函数就会开始与NAND芯片进行交互了,它要做的事情主要包括这几个方面:读取NAND芯片的ID,...

NandFlash驱动超详细分析

今天学习了NandFlash的驱动,硬件操作非常简单,就是这个linux下的驱动比较复杂,主要还是MTD层的问题,用了一下午时间整理出来一份详细的分析,只是分析函数结构和调用关系,具体代码实现就不看了...

基于MTD的NANDFLASH设备驱动底层实现原理分析(三)

非常的说:我突然发现在写这些关于NAND驱动的文章的时候,原来我一直是在改写别人的博客。。。。。其实这并不要紧的,我也觉得这不仅仅是一种比较好的学习方法了,为什么呢,因为当我在看他的博客的时候,我明白...

基于MTD的NANDFLASH设备驱动底层实现原理分析(六)

实在写不下去了,仔细的想了一想还是把mtd/nand/s3c2410.c好好的分析分析 在Linux中NANDFLASH设备驱动是被注册成平台驱动的。我还是从函数的入口出发一步一个脚印的分析。突然间...

基于MTD的NANDFLASH设备驱动底层实现原理分析(二)

四、常见的NANDFLASH的操作       1、要实现对 Nand Flash 的操作,比如读取一页的数据,写入一页的数据等,都要发送对应的命令,而且要符合硬件的规定,如图:     ...

基于MTD的NANDFLASH设备驱动底层实现原理分析(一)

经过UBOOT初步的移植,Linux内核初步的移植,Linux内核总线设备模型的分析,等一系列 痛苦的折腾,目的就是想更好的来分析下NANDFLASH的驱动。。大概一共历经了半个月 的时间,慢慢的...

基于MTD的NANDFLASH设备驱动底层实现原理分析(五)

Linux内核在MTD的下层实现了通用的NAND驱动(/driver/mtd/nand/nand_base.c)因此芯片级的驱动实现不再需要我们关心mtd中的那些成员函数了主题转移到nand_chip...

基于MTD的NANDFLASH设备驱动底层实现原理分析(四)

进过前面3篇文章对NANDFLASH的一些硬件特性以及MTD的上层操作已经有了一个大体概念,这些东西的重要性就像你要吃饭那么你首先得学会拿筷子道理一样吧,应该一样的。 五、MTD原始设备层和硬件驱动...

NAND FLASH学习笔记之MTD下nand flash驱动(二)

在这里补充这一片是为了更好的理解上一篇,补充的内容包括:MTD下NAND的布局中几个重要文件的诠释和MTD涉及的几个重要的结构体(更好的理解接口) 一、内核中的NAND代码布局 内核中的NAN...

块设备驱动程序之nandflash——基础知识

我们先来看一下原理图:   我们先来分析一下这个原理图: LDATA0——LDATA7:既传输数据,也传输地址,还传输命令。那么如何区分传输的是什么呢?不要担心,下面会说到控制引脚 R...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)