韦一之Nor flash和Nand flash读写(015-016课)

插:网络上有2440中文手册,看起来挺方便。

Nor和Nand flash概述

nor flash不可以直接写,否则就跟内存一样了,上面的程序很容易被破坏。
但是读nor就和读内存一样,发出地址直接读就行了。
在这里插入图片描述
nand的接线少,数据线上既传输命令又传输数据还传输地址!
nor和nand都是不能直接写的,要发出一定的命令。
nor贵且容量小,为什么还用呢?
优点就是无位反转和坏块,如果要高可靠性地存储程序,尤其是重要的需要稳定的程序,错一点都不行的,一般就用nor。
海量数据用nand存储,比如视频监控的信息。
手机里面都是用的nand,现在技术好了,位反转和坏块出现的几率也小了。万一真的出现了,重新刷个固件也就好了。

Nor Flash支持XIP,即代码可以直接在Nor Flash上执行,无需复制到内存中。这是由于NorF lash的接口与RAM完全相同,可以随机访问任意地址的数据。Nor Flash进行读操作的效率非常高,但是擦除和写操作的效率很低,另外,Nor Flash的容量一般比较小。NAND Flash进行擦除和写操作的效率更高,并且容量更大。一般而言,Nor Flash用于存储程序,NAND Flash用于存储数据。基于NAND Flash的设备通常也要搭配Nor Flash以存储程字。
cpu可以直接从nor上面读取指令执行,但是nand就得把程序弄到sram中了,不过这个是2440帮我们做好的,不用管,自动拷贝4K到片内内存SRAM。

Flash存储器件由擦除单元(也称为块)组成,当要写某个块时,需要确保这个块己经
被擦除。Nor Flash的块大小范围为64kB、128kB:NAND Flash的块大小范围为8kB,64kB,擦/写一个Nor Flash块需4s,而擦/写一个NAND Flash块仅需2ms。Nor Flash的块太大,不仅增加了擦写时间,对于给定的写操作,Nor Flash也需要更多的擦除操作——特别是小文件,比如一个文件只有IkB,但是为了保存它却需要擦除人小为64kB—128kB的Nor Flash块。

Nor Flash的接口与RAM完全相同,可以随意访问任意地址的数据。而NAND Flash的
接口仅仅包含几个I/O引脚,需要串行地访问。NAND Flash一般以512字节为单位进行读写。这使得Nor Flash适合于运行程序,而NAND Flash更适合于存储数据。

容量相同的情况下,NAND Flash的体积更小,对于空间有严格要求的系统,NAND Flash可以节省更多空间。市场上Nor Flash的容量通常为IMB~4MB(也有32MB的Nor Flash),NAND Flash的容量为8MB~512MB。容量的差别也使得Nor Flash多用于存储程序,NAND Flash多用于存储数据。

对于Flash存储器件的可靠性需要考虑3点:位反转、坏块和可擦除次数。所有Flash器件都遭遇位反转的问题:由于Flash固有的电器特性,在读写数据过程中,偶然会产生一位或几位数据错误(这种概率很低),而NAND Flash出现的概率远大于Nor Flash,当位反转发生在关键的代码、数据上时,有可能导致系统崩溃。当仅仅是报告位反转,重新读取即可:如果确实发生了位反转,则必须有相应的错误检测/恢复措施。在NAND Flash上发生位反转的概率史高,推荐使用EDC/ECC进行错误检测和恢复。NAND Flash上面会有坏块随机分布在使用前需要将坏块扫描出来,确保不再使用它们,否则会使产品含有严重的故障。NAND Flash每块的可擦除次数通常在100000次左右,是Nor Flash的10倍。另外,因为NAND Flash的块大小通常是NorF lash的1/8,所以NAND Flash的寿命远远超过Nor Flash。

嵌入式Linux对Nor、NAND Flash的软件支持都很成熟。在Nor Flash上常用jffs2文
件系统,而在NAND Flash常用yaffs文件系统。在更底层,有MTD驱动程序实现对它们的读、写、擦除操仵,它也实现了EDC/ECC校验。

Nand Flash只有8个I/O引脚的好处:

  1. 减少外围引脚
  2. 提高系统的可扩展性,因为没有像其他设备一样用物理大小对应的完全数目的addr引脚,在芯片内部换了芯片的大小等的改动,对于用全部的地址addr的引脚,那么就会引起这些引脚数目的增加,比如容量扩大一倍,地址空间/寻址空间扩大一倍,所以,地址线数目/addr引脚数目,就要多加一个,而对于统一用8个I/O的引脚的Nand Flash,由于对外提供的都是统一的8个引脚,内部的芯片大小的变化或者其他的变化,对于外部使用者(比如编写nand flash驱动的人)来说,不需要关心,只是保证新的芯片,还是遵循同样的接口,同样的时序,同样的命令,就可以了。这样就提高了系统的扩展性。

nor flash不需要初始化,但是nand flash需要!详情见nand初始化章节!

补:
sdram需要初始化才能读写,实际是配置些寄存器满足时序。
nor flash呢?
要读些nor flash也是要配置寄存器满足时序的,我们前面的代码中都没有配置,因为nor只需要配置bank0的寄存器,只有两个需要设置,默认值却都可以工作,所以没有配置。
而是直接可读: volatile unsigned short *p = (volatile unsigned short *)(base + offset); return *p;
(寄存器配置见内存控制器章节,nor和sdram同属于内存控制器管理,用一套寄存器。只不过sdram寄存器设置更复杂,需要专门初始化用来配置时序)
但是我们的代码放在nor可以直接启动,貌似xip片内执行代码就不需要配置时序了??????
(可能也是因为不需要配置就可以读吧,毕竟CPU也是要从nor中读取指令运行的。)

eXecute In Place,即芯片内执行,指应用程序可以直接在flash闪存内运行,不必再把代码读到系统RAM中。flash内执行是指nor flash 不需要初始化,可以直接在flash内执行代码。但往往只执行部分代码,比如初始化RAM.
(注:片内执行不是说程序在存储器内执行哦,CPU的基本功能就是取指、译码和执行。norflash能在芯片内执行,就是指CPU的取指模块能够直接从norflash中把指令取出来,供后面的译码和执行模块使用。

那么为什么norflash可以实现XIP,而nandflash就不可以呢?
芯片内执行主要是是看芯片可不可以线性存储代码(假如硬件支持芯片接口),只要能保证芯片的存储空间是线性的(也就是无坏块),都可以片上执行
在读取Flash时候,容易出现“位翻转(bitconvert)
在Flash的位翻转(一个bit位发生翻转)现象上,NAND的出现几率要比NorFlash大得多。这个问题在Flash存储关键文件时是致命的,所以在使用NandFlash时建议同时使用EDC/ECC等校验算法。 ”
但是,如果能保证不出错,也还是可以进行XIP,可以在其上执行代码的:
“所谓XIP,就是CODE是在FLASH上直接运行. NANDFLASH只是不适合做XIP,但并不是不能做XIP“

用Uboot操作Nor Flash查看其特性

(下文中有uboot操作nand,跟nor不同,值得关注。nor是直接操作内存,nand是操作寄存器,因为nand时序复杂,有自己的控制器方便操作。对uboot而言,还是差不多的)

uboot有命令可以访问内存,nor又可以像内存一样访问,所有把uboot下载到nor中启动,然后就可以用UBOOT的命令读写nor了,不用编程就可以读写nor了,方便我们学习和验证nor的特征和命令格式等。比如下表:
在这里插入图片描述

下面我们使用u-boot来体验Nor Flash的操作(开发板设置Nor启动,进入u-boot)。
开发板一定要设为nor启动,因为nor启动时,cpu访问0开始的地址就是nor地址了。
而在nand启动的,CPU可以看到的零地址是片内内存SRAM,看不到NOR,更无法读写nor了。

首先要使用OpenJTAG烧写UBOOT到Nor Flash
OpenJTAG开发了一个工具:oflash,用它来烧写。

那么我们怎么用u-boot来操作呢?
Nor Flash手册里都会有一个命令的表格,如图:
在这里插入图片描述

上面的word和byte指的是,这个nor芯片(很多的Nor Flash)可以配置成位宽是16或者是8。
(word是16?!!!!!)
对于我们使用的jz2440开发板,我们的nor接了16根数据线,位宽是16,看word行就好了。

复位(reset):往任何一个地址写入F0。

怎样读ID呢?
读ID(ReadSiliconID):往Nor Flash的555地址写AA,再往2AA的地址写入55,再往555的地址写入90,然后就可以读数据了。通过读ADI这个地址,就可以读到DDI数据了。
在这里插入图片描述
ADI是什么呢?A1=0,A0=0的时候读到的是厂家ID。0/1时读出的是设备ID。
这A1,A0是什么意思呢???????????????????
根据后面的实验,貌似是00表示0地址,01就表示地址1。不是很明白。

后面实验可以看一下读出的内容和这里是否对应。

实验1:
读数据:在u-boot上执行:md.b0(这应该就是一个读内存的指令)
结果(和我们烧进去的数据完全一样):
在这里插入图片描述

这些数据就是我们烧写的uboot,在电脑上用二进制工具打开uboot.bin:
在这里插入图片描述

可见,内容和上面是一样的。
可以得出结论:u-boot可以像读内存一样来读nor flash。

实例2
读ID(参考Nor手册):
往地址555H写入AAH(解锁)
往地址2AAH写入55H(解锁)
往地址555H写入90H(命令)
读0地址得到厂家ID(C2H)
读1地址得到设备ID(22DAH或225BH)
退出读ID状态:给任意地址写F0H就可以了。
在这里插入图片描述
容易忘记:
2440发出(555H<<1)地址,Nor Flash才能收到555H这个地址。
在这里插入图片描述
其中涉及的地址的变换容易忘记做!!2440发出的地址其实就是nor需要的地址×2。

1).当执行过
md.w 0 1
结果(输出厂家ID):
00000000:00c2…(00c2就是厂家ID)
2).当执行过
md.w 2 1
结果(输出设备ID):
00000002:2249I"(2249就是设备ID)
3).当执行
mw.w 0 f0
就退出读ID的状态,
执行:
md.b0
结果:
00000000:17.(读到的就是Nor Flash地址·0的数据)

Nor Flash的两种规范:
两种规范,貌似就是对应两种接口。

通常内核里面要识别一个 Nor Flash 有两种方法:
一种是 jedec 探测,读取Flash的制造商ID和设备ID(在内核里有这个nor flash 的所有信息,换另外一款芯片时,若内核里没有这款芯片的描述,需手动添加该器件的各种参数),以确定Flash的大小和算法。
就是在内核里面事先定义一个数组,该数组里面放有不同厂家各个芯片的一些参数,探测的时候将 flash 的 ID 和数组里面的 ID 一一比较,如果发现相同的,就使用该数组的参数。
(jedec就是读ID的命令,发出命令实现识别nor,和代码中的数组信息进行匹配。老式的norflash规范都是要先读id然后跟数组比较,如果数组中没有对应的信息还得修改数组的内容使有匹配的,比较麻烦。)(貌似芯片中不带有更多信息,都靠软件数组的内容获取信息。)
(可是这里nor flash的信息又可以通过发上面表格的命令获取,貌似 jedec 探测也能获取信息呀????????上面表格table5中的命令是什么模式的呢????好像只有最后一个是进入cfi模式呀???????)
总结:上面表格中nor的大部分命令都是和这两个规范无关的。两种规范仅是针对如何获取某些特定描述信息而言的,(具体可以查看cfi的命令都是查询些什么)。和规范相关的只有两个命令:
在这里插入图片描述
查询ID,后续通过jedec规范得到那些信息。
在这里插入图片描述
进入cfi模式,通过后续cfi的命令查询哪些信息。

jedec规范对应的内核中的数组:
在这里插入图片描述
jedec 探测的优点就是简单,缺点是如果内核要支持的 flash 种类很多,这个数组就会很庞大。内核里面用 jedec 探测一个芯片时,是先通过发命令来获取 flash 的 ID,然后和数组比较,但是 flash.c 中连 ID 都是自己通过宏配置的。

② 一种是 CFI(common flash interface)探测,公共Flash接口。
用来帮助程序从Flash芯片中获取操作方式信息,就是直接发各种命令来读取芯片的信息,比如 ID、容量等,芯片本身就包含了电压有多大,容量有有多少等信息。
新的nor flash规范让nor flash去支持 CFI接口,芯片内部本身就带有各种属性,可以直接读出来。换芯片时,不需修改内核代码。
而上面的EDEC用来帮助程序读取Flash的制造商ID和设备ID(在内核里有这个nor flash 的所有信息,换另外一款芯片时,若内核里没有这款芯片的描述,需手动添加该器件的各种参数),以确定Flash的大小和算法,如果芯片不支持CFI,就需使用JEDEC了。

下面对在Nor Flash上操作,2440上操作,U-BOOT上操作cfi 探测(读取芯片信息)进行比较参考芯片手册。
在这里插入图片描述
往nor flash的55H地址写入98H,就会进入cfi 接口查询的模式。
在这里插入图片描述
…中间省略很多对应于cfi接口查询信息的命令。

在这里插入图片描述
往nor flash的55H地址写入98H,就会进入cfi 接口查询的模式之后,读取读地址10H就可以得到0051,读地址11H得到0052,读地址12H得到0059 (连起来其实就是cfi)
读地址27H得到容量。
在这里插入图片描述
实验现象:
在这里插入图片描述

15的十进制就是21,2的21次方=2M,所以这个nor flash就是两兆的。

读完信息,怎么退出CFI模式呢?
往任意一个地址写F0就可以了。如mw.w 0 f0

(上文中jedec模式下可以发命令读取ID和软件中数组比较。读取ID后怎么退出读ID的状态,也是任意地址写F0,如mw.w 0 f0!)

只有退出了上面这些查询的模式,才能读取nor上实际的数据的(像读内存那样)。
在这里插入图片描述

补充:手册表格里下面两个区域是什么意思呢?
在这里插入图片描述
有的norflash可以支持:前面一部分32K擦除,后面一个区域是64K为单位擦除。

用Uboot写nor flash

上面说的都是读nor,写是怎样的?
nor是不可以直接像内存一样写的!
在这里插入图片描述
注意,地址要选大一点,我们uboot是放在nor中的,做这个实验如果写在前面的地址会破坏uboot的。

怎样把数据写进Nor Flash进去呢?
写数据之前必须保证,要写的地址是擦除的。
因为nor的写操作只能把1写成0,0是不能写成1的。而擦除是写成全1的。
我们烧写时,如果上面的数据,不是0ffff,就是没有被擦除过,我们就要先擦出,擦除完后,才可以烧写,擦除烧写的命令可以从芯片手册里面获得。

芯片手册中命令表格查到:
在这里插入图片描述
下面是Nor Flash的写操作,如下表:
在这里插入图片描述
1).U-BOOT执行完上述指令后,0x1234,就被写到0x100000地址处,
执行:
md.w1000001
结果(1234被写进去):
00100000:1234 4
从这里可以看出来U-BOOT的操作不是很复杂。

2).我们再次往0x100000地址处,写入0x5678,执行如下命令,出错!!!!易错点!
mw.w aaa aa
mw.w 554 55
mw.w aaa a0
mw.w 100000 5678
查看0x100000地址处的数据
md.w 100000 1
结果:
00100000:12300.
0x100000地址处的数据不是0x5678,写操作失败,失败的原因是,原来的数据已经是0x1234不是全0xffff,再次写操作失败,(Nor Flash只有先擦出,才能烧写)。

在这里插入图片描述
注意擦除:
在这里插入图片描述
SA表示的是这个扇区地址。

Nor Flash编程,代码读写nor

上面的内容回了,这里挺简单的,视频不看了,笔记不记了。
详情参考https://blog.csdn.net/thisway_diy/article/details/79397638

这里部分代码挺有意思,复制过来。

最关键的基础函数,值得学习:

#define NOR_FLASH_BASE  0  /* jz2440, nor-->cs0, base addr = 0 */


/* 比如:   55H 98 
 * 本意是: 往(0 + (0x55)<<1)写入0x98
 */
void nor_write_word(unsigned int base, unsigned<
  • 6
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值