转自:https://blog.csdn.net/pengrui18/article/details/32337297

今天在看别人如何根据物理地址计算NANDFLASH的列地址(column addres)和页地址(page address),结果看到这篇文章时,感觉有点不对劲。http://blog.csdn.net/feihuxiaozi/article/details/6943124。我在u-boot下根据代码计算,不管怎么计算都和他的例子对不上:

0xBB8CCB8 = 00001011  1011 1000  1100 1100  1011 1000,分别分配到5个地址周期就是:

B      B     8    C   C    B     8

第一个周期:A[0:7]  也就是B8

第二个周期:A[8:11]  取四位 1100, 再添4位0,也就是0000 1100   即0C

第三个周期:A[12:19]  取八位 1000 1100  即8C

第四个周期:A[20:27]  取八位 1011 1011  即BB

第五个周期:A[28]     取一位 0,补齐八位 即 0000 0000 也就是00

看一下K9F2G08X0A的寻址图:

Column address=addr%2048

ROW Address     =addr/2048

在此处,A0-A11代表Column address,A12-A28代表ROW Address,此处的A11还是column address,不需要我们确定,因此对于输入的addr=0xBB8CCB8,其中每周期的数据输入如下:

第一个周期:A[0:7]  也就是B8

第二个周期:A[8:11]  取addr[8:10]=100, 再添5位0,也就是0000 0100   即04

第三个周期:A[12:19]  取addr[11:18]=000 11001  即19

第四个周期:A[20:27]  取addr[11:18]=0111 0111  即77

第五个周期:A[28]     取一位addr[19] =1,补齐八位 即 0000 0001 也就是01

同时我研究了下page =(512+16)byte的NANDFLASH,发现它与(2K+64)字节的NANDFLASH的又不同,这里借用这位博主的博客说明下:http://www.cnblogs.com/hnrainll/archive/2011/06/01/2065508.html

关于NANDFLASH地址 A8寻址

在NAND Flash中有8个I/O引脚(IO0—IO7)、5个全能信号(nWE ALE CLE nCE
nRE)、一个引脚,1个写保护引脚。操作NAND Flash时,先传输命令,然后传输地址,最后读写数据。对于64MB的NAND
Flash,需要一个26位的地址。只能8个I/O引脚充当地址、数据、命令的复用端口,所以每次传地址只能传8位。这样就需要4个地址序列。因此读写一次nand
flash需要传送4次(A[7:0] A[16:9] A[24:17] A[25])。64M的NAND
Flash的地址范围为0x00000000—0x03FFFFFF。128M的NAND
Flash的地址范围为0x00000000---0x07FFFFFF。1KB = 0x000-0x3FF.128字节=0x00H--7FH。

一页有528个字节,而在前512B中存放着用户的数据。在后面的16字节中(OOB)中存放着执行命令后的状态信息。主要是ECC校验的标识。列地址A0-A7可以寻址的范围是256个字节,要寻址528字节的话,将一页分为了A.(1half array)B(2 half array) C(spare array)。A区0—255字节,B区 256-511 字节C区512—527字节。访问某页时必须选定特定的区。这可以使地址指针指向特定的区实现。

在NAND Flash 中存在三类地址,分别为Block Address 、Column Address Page Address.。(实际就是块地址和页地址)

Column Address
用来选择是在上半页寻址还是在下半页寻址A[0]—A[7].也就相当于页内的偏移地址。在进行擦除时不需要列地址,因为擦除是以块为单位擦除。32个Page需要5bit来表示。也就是A[13:9];也就是页在块内的相对地址。A8这一位用来设置512字节的上半页,还是下半页,1表示是在上半页,而2表示是在下半页。Block的地址有A[25:14]组成.

一个容量为64M(512Mbit)的NAND Flash,分为131072页,528列。(实际中由于存在spare
area,故都大于这个值),有4096块,需要12bit来表示即A[25:14].如果是128M(1Gbit)的话,blodk
Address为A[26:14].由于地址只能在IO0—IO7上传送。编程时通常通过移位来实现地址的传送。传送过程如下:

第1个地址序列:传递column address,也就是NAND
Flash[7:0],这一周期不需要移位即可传递到I/O[7:0]上,而half page pointer
即A8是由操作指令决定,00h,在A区,01h在B区,指令决定在哪个half page上进行读写,而真正A8的值是不需要程序员关心的;

第2个地址序列:就是将NAND_ADDR 右移9位,而不是8位,将NAND_ADDR[16:9]传递到I/O[7:0]上;

第3个地址序列:将NAND_ADDR[24:17] 传递到I/O[7:0]上;

第4个地址序列:将NAND_ADDR[25]传送到I/O上。

整个地址的传送过程需要4步才能完成。如果NAND Flash 的大小是32MB的以下的话,那么block address 最高位只到bit24,因此寻址只需要3步,就可以完成。

在进行擦除操作时由于是以块进行擦除,所以只需要3个地址序列,也就是只传递块的地址,即A[14:25]。

NAND Flash地址的计算:

Column Address 翻译过来是列地址,也就是在一页里的偏移地址。其实是指定Page上的某个Byte,指定这个Byte,其实也就是指定此页的读写起始地址。

Page Address:页地址。页的地址总是以512Bytes对齐的,所以它的低9位问题0,确定读写操作在NAND Flash中的哪个页进行。

当我们得到一个Nand Flash地址addr时,我们可以这样分解出Column Address和Page Address。

Columnaddr = addr % 512   // column address

Pageaddr = addr>>9           // page address

实际上A0~A7是页内地址,比如从第2个开始读起。不过一般都从0开始读起,呵呵。

也就是一个Nand Flash地址的A0-A7是它的column address ,A9—A25是它的Page Address,地址A8被忽略。

现在假设我要从Nand Flash中的第5000字节处开始读取1024个字节到内存的0x30000000处,我们这样调用read函数

NF_Read(5000, 0x30000000,1024);

我们来分析5000这个src_addr.

根据:

column_addr=src_addr%512;

page_address=(src_addr>>9);

我们可得出column_addr=5000%512=392

page_address=(5000>>9)=9

于是我们可以知道5000这个地址是在第9页的第392个字节处,于是我们的NF_read函数将这样发送命令和参数

column_addr=5000%512;

page_address=(5000>>9);

NF_CMD=0x01; //要从2nd half开始读取 所以要发送命令0x01

NF_ADDR= column_addr &0xff; //1st Cycle A[7:0]

NF_ADDR=page_address& 0xff

NF_ADDR=(page_address>>8)&0xff; //3rd.Cycle A[24:17]

NF_ADDR=(page_address>>16)&0xff; //4th.Cycle A[25]

向NandFlash的命令寄存器和地址寄存器发送完以上命令和参数之后,我们就可以从rNFDATA寄存器(NandFlash数据寄存器)读取数据了.

我用下面的代码进行数据的读取.

for(i=column_addr;i<512;i++)

*buf++=NF_RDDATA();

每当读取完一个Page之后,数据指针会落在下一个Page的0号Column(0号Byte).

//========================下面是另外一篇,差不多=====================

http://blog.csdn.net/intint/archive/2009/10/13/4664659.aspx

一、NAND flash的物理组成
NAND Flash 的数据是以bit的方式保存在memory cell,一般来说,一个cell 中只能存储一个bit。这些cell
以8个或者16个为单位,连成bit line,形成所谓的byte(x8)/word(x16),这就是NAND
Device的位宽。这些Line会再组成Page,(NAND Flash 有多种结构,我使用的NAND Flash
是K9F1208,下面内容针对三星的K9F1208U0M),每页528Bytes(512byte(Main Area)+16byte(Spare

Area)),每32个page形成一个Block(32*528B)。具体一片flash上有多少个Block视需要所定。我所使用的三星k9f1208U0M具有4096个block,故总容量为4096*(32*528B)=66MB,但是其中的2MB是用来保存ECC校验码等额外数据的,故实际中可使用的为64MB。

NAND flash以页为单位读写数据,而以块为单位擦除数据。按照这样的组织方式可以形成所谓的三类地址:
Column Address:Starting Address of the Register. 翻成中文为列地址,地址的低8位
Page Address :页地址
Block Address :块地址
对于NAND Flash来讲,地址和命令只能在I/O[7:0]上传递,数据宽度是8位。

二、NAND Flash地址的表示
512byte需要9bit来表示,对于528byte系列的NAND,这512byte被分成1st half Page Register和2nd half Page Register,各自的访问由地址指针命令来选择,A[7:0]就是所谓的column address(列地址),在进行擦除操作时不需要它,why?因为以块为单位擦除。32个page需要5bit来表示,占用A[13:9],即该page在块内的相对地址。A8这一位地址被用来设置512byte的1st
half page还是2nd half page,0表示1st,1表示2nd。Block的地址是由A14以上的bit来表示。
例如64MB(512Mb)的NAND flash(实际中由于存在spare
area,故都大于这个值),共4096block,因此,需要12个bit来表示,即A[25:14],如果是128MB(1Gbit)
的528byte/page的NAND Flash,则block address用A[26:14]表示。而page address就是blcok
address|page address in block NAND Flash 的地址表示为: Block Address|Page
Address in block|halfpage
pointer|Column Address 地址传送顺序是Column Address,Page Address,Block Address。

由于地址只能在I/O[7:0]上传递,因此,必须采用移位的方式进行。 例如,对于512Mbit x8的NAND flash,地址范围是0~0x3FF_FFFF,只要是这个范围内的数值表示的地址都是有效的。 以NAND_ADDR 为例:

第1 步是传递column address,就是NAND_ADDR[7:0],不需移位即可传递到I/O[7:0]上,而halfpage pointer即A8 是由操作指令决定的,即指令决定在哪个halfpage 上进行读

写,而真正的A8 的值是不需程序员关心的
第2 步就是将NAND_ADDR 右移9位,将NAND_ADDR[16:9]传到I/O[7:0]上;
第3 步将NAND_ADDR[24:17]放到I/O上;
第4步需要将NAND_ADDR[25]放到I/O上;
因此,整个地址传递过程需要4 步才能完成,即4-step addressing。 如果NAND Flash 的容量是32MB(256Mbit)以下,那么,block adress最高位只到bit24,因此寻址只需要3步。

下面,就x16 的NAND flash 器件稍微进行一下说明。 由于一个page 的main area 的容量为256word,仍相当于512byte。但是,这个时候没有所谓的1st halfpage 和2nd halfpage 之分了,所以,bit8就变得没有意义了,也就是这个时候 A8 完全不用管,地址传递仍然和x8 器件相同。除了,这一点之外,x16 的NAND使用方法和 x8 的使用方法完全相同

纠正几个NANDFLASH很容易犯的错误【转】的更多相关文章

  1. css : 使用浮动实现左右各放一个元素时很容易犯的错误

    比如说,有一个div,我想在左侧和右侧各方一个元素. 如果不想用flex,那就只能用浮动了. ... <div class="up clearfix"> <h6& ...

  2. PHP二维数组的引用赋值容易犯的错误

    大家一起来分析一下下面这段代码: <?php $arr = array(); $arr["abc"] = array("sex" => 100, & ...

  3. 在CMMI推广过程中EPG常犯的错误(转)

    本文转自: http://developer.51cto.com/art/200807/86953.htm 仅用于个人收藏,学习.如有转载,请联系原作者. ---------------------- ...

  4. 总结下java经常犯的错误

    编写代码是一种艺术,认识错误是我们代码改进的重要途径之一.以下情况并非大家都能碰到过,但希望提高代码质量的人都引以为戒.以下各种情况,都是初学者经常犯的错误. 1.1       字符串没有判断是否为 ...

  5. 十个JAVA程序员容易犯的错误

    十个JAVA程序员容易犯的错误 1. Array 转 ArrayList 一般开发者喜欢用: List<String> list = Arrays.asList(arr); Arrays. ...

  6. C#中几个经常犯的错误总汇

    在我们平常编程中,时间久了有时候会形成一种习惯性的思维方式,形成固有的编程风格,但是有些地方是需要斟酌的,即使是一个很小的错误也可能会导致昂贵的代价,要学会善于总结,从错误中汲取教训,尽量不再犯同样错 ...

  7. 十个 PHP 开发者最容易犯的错误

    PHP 语言让 WEB 端程序设计变得简单,这也是它能流行起来的原因.但也是因为它的简单,PHP 也慢慢发展成一个相对复杂的语言,层出不穷的框架,各种语言特性和版本差异都时常让搞的我们头大,不得不浪费 ...

  8. 64位平台C/C++容易犯的错误

     64位平台的介绍 IA-64 is a 64-bit microprocessor architecture developed by Intel and Hewlett Packard compa ...

  9. javascript中易犯的错误有哪些

    javascript中易犯的错误有哪些 一.总结 一句话总结: 比如循环中函数的使用 函数中this的指向谁(函数中this的使用) 变量的作用域 1.this.timer = setTimeout( ...

随机推荐

  1. Do in SDN

    Do in SDN 书籍 <深度解析SDN 利益.战略.战术.实践> 张卫锋 <重构网络-SDN构架与实现>杨泽卫.李呈 <软件定义网络核心原理与应用实践> 黄韬. ...

  2. 『编程题全队』Alpha 阶段冲刺博客Day7

    1.每日站立式会议 1.会议照片 2.昨天已完成的工作统计 孙志威: 1.添加了网络通信管理类 2.稍微修改了燃尽图模块ChartWidget 3.在主窗口中添加了用户信息框 4.重构了项目中的文件结 ...

  3. [转帖] Linux 下面栈空间大小的实验

    比如局部变量是保存在栈空间中的,今天突然在想栈的上限是多大呢,什么时候才会栈溢出? ulimit 命令 linux下使用ulimit 命令可以查看系统的很多上限值. ulimit -a 查看所有 ul ...

  4. PSP(3.13——3.15)以及周记录

    3.13 0:00 4:00 10 230 Cordova插件1,的尝试 N min 10:50 11:30 10 30 英语百词斩 N min 18:00 22:55 20 275 写博客 Y mi ...

  5. BZOJ1018 SHOI2008堵塞的交通(线段树)

    动态图的连通性当然是可以用LCT维护的.但这相当的不优美,毕竟这样做没有用到任何该图的性质,LCT自带的大常数也会使其跑得非常慢. 考虑用线段树维护区间左右端四个点之间各自的连通性(仅经过该区间内路径 ...

  6. Merkle Tree 概念

    Merkle Tree 概念 来源 https://www.cnblogs.com/fengzhiwu/p/5524324.html /*最近在看Ethereum,其中一个重要的概念是Merkle T ...

  7. MT【103】二阶递推找规律

    评:如果直接找$a_n$的二阶递推式:$a_{n+2}-2\sqrt{2}a_{n+1}-a_n=0$有根号,不利于估计尾数.

  8. JS发送跨域Post请求出现两次请求的解决办法

    原文地址: http://www.cnblogs.com/JimmyBright/p/7681097.html 所有跨域的js在提交post请求的时候,如果服务端设置了可跨域访问 public sta ...

  9. bzoj1345 序列问题 (贪心)

    考虑某个点产生的贡献: 如果i左边是一个比它小的数x,那有两种情况: 1.x的左边的数y大于i,肯定要把x合并到i,i的贡献++ 2.x的左边的数y小于i,那肯定要把x合并到y,而这时候递归地来考虑, ...

  10. 【bzoj3992】 SDOI2015—序列统计

    http://www.lydsy.com/JudgeOnline/problem.php?id=3992 (题目链接) 题意 集合${S}$中有若干个不超过${m}$的非负整数,问由这些数组成一个长度 ...