第015课 NOR Flash操作原理及裸机程序分析

发布者:SparklingSoul最新更新时间:2020-03-23 来源: eefocus关键字:NOR  Flash操作  裸机程序 手机看文章 扫描二维码
随时随地手机看文章

#第001节_Nor Flash原理及硬件操作 #
Nor Flash的连接线有地址线,数据线,片选信号读写信号等,Nor Flash的接口属于内存类接口,Nor Flash可以向内存一样读,但是不能像内存一样写,需要做一些特殊的操作才能进行写操作,读只需像内存一样读很简单。

Nor Flash原理图如图:

这里写图片描述

Flash介绍

常用的Flash类型有Nor Flash和NAND Flash两种。

Nor Flash由Intel公司在1988年发明,以替代当时在市场上占据主要地位的EPROM和E2PROM。NAND Flash由Toshiba公司在1989年发明。两者的主要差别如下表:

image.png

Nor Flash支持XIP,即代码可以直接在Nor Flash上执行,无需复制到内存中。这是由于NorF lash的接口与RAM完全相同,可以随机访问任意地址的数据。Nor Flash进行读操作的效率非常高,但是擦除和写操作的效率很低,另外,Nor Flash的容量一般比较小。NAND Flash进行擦除和写操作的效率更高,并且容量更大。一般而言,Nor Flash用于存储程序,NAND Flash用于存储数据。基于NAND Flash的设备通常也要搭配Nor Flash以存储程字。

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校验。

Nor Flash的操作##

下面我们使用u-boot来体验Nor Flash的操作(开发板设置Nor启动,进入u-boot)。

1).使用OpenJTAG烧写UBOOT到Nor Flash

那么我们怎么用u-boot来操作呢?

Nor Flash手册里会有一个命令的表格,如图:
这里写图片描述

下面简单的举一些例子:

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

读ID(ReadSiliconID):很多的Nor Flash可以配置成位宽16bit(Word),位宽8bit(Byte)。对于我们使用的jz2440开发板使用是位宽16bit,怎样读ID呢?

根据前面得图可知,往Nor Flash的555地址写AA,再往2AA的地址写入55,再往555的地址写入90,然后就可以读ADI地址,就可以读到DDI数据了。

实例1

读数据:

在u-boot上执行:md.b0

结果(和我们烧进去的数据完全一样):

00000000:170000ea14f09fe514f09fe514f09fe5................
00000010:14f09fe514f09fe514f09fe514f09fe5................
00000020:6001f833c001f8332002f8337002f833`..3...3..3...3
00000030:e002f8330004f8332004f833efbeadde...3...3..3....

可以得出结论:u-boot可以像读内存一样来读nor flash

实例2

读ID(参考Nor手册)

  • 往地址555H写入AAH(解锁)

  • 往地址2AAH写入55H(解锁)

  • 往地址555H写入90H(命令)

  • 读0地址得到厂家ID(C2H)

  • 读1地址得到设备ID(22DAH或225BH)

  • 退出读ID状态:给任意地址写F0H就可以了。

下图为2440和Nor Flash的简易连接图:
这里写图片描述

2440的A1接到Nor的A0所以2440发出的地址是,Nor Flash收到的地址左移一位。比如:2440发出(555H<<1)地址,Nor Flash才能收到555H这个地址。

下面对在Nor Flash的操作,2440的操作,U-BOOT上的操作进行比较,如下表:

image.png

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 一一比较,如果发现相同的,就使用该数组的参数。
jedec 探测的优点就是简单,缺点是如果内核要支持的 flash 种类很多,这个数组就会很庞大。内核里面用 jedec 探测一个芯片时,是先通过发命令来获取 flash 的 ID,然后和数组比较,但是 flash.c 中连 ID 都是自己通过宏配置的。

一种是 CFI(common flash interface)探测,就是直接发各种命令来读取芯片的信息,比如 ID、容量等,芯片本身就包含了电压有多大,容量有有多少等信息。

下面对在Nor Flash上操作,2440上操作,U-BOOT上操作cfi 探测(读取芯片信息)进行比较参考芯片手册。

image.png

##Nor Flash写数据 ##
我们在Nor Flash的10000的地址读数据,
md.w 100000 1
结果:
00100000:ffff…
在Nor flash的10000的地址写数据下0x1234,
mw.w 100000 1234
然后在这个地址读数据,
md.w 100000 1
结果:
00100000:ffff(这个地址上的数据没有被修改,写操作无效)。

怎样把数据写进Nor Flash进去呢?

写数据之前必须保证,要写的地址是擦除的。

下面是Nor Flash的写操作,如下表:

image.png

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只有先擦出,才能烧写)。


先擦除(参考Nor Flash芯片手册)

Nor Flash操作 u-boot操作

555H AAH mw.w aaa aa

2AAH 55H mw.w 554 55

555H 80H mw.w aaa 80

555H AAH mw.w aaa aa

2AAH 55H mw.w 554 55

SA 30H //往扇区地址写入30 mw.w 100000 30


执行完上述指令后测试


执行:

md.w 100000 1

结果:

00100000:ffff…

已被擦除,这个时候再次烧写就不会有问题了。


再烧写

mw.w aaa aa

mw.w 554 55

mw.w aaa a0

mw.w 100000 5678


测试烧写结果

执行:

md.w 100000 1

结果:

00100000:5678 xV

数据被烧写进去,烧写成功。


总结:我们烧写时,如果上面的数据,不是0ffff,没有被擦除过,我们就要先擦出,擦除完后,才可以烧写,擦除烧写的命令可以从芯片手册里面获得。


= 第002节_Nor Flash编程_识别 =

本节实例的目的目的:识别nor flash

发送命令函数

nor_cmd函数代码如下,往NOR Flash某个地址发送指令,


16

17 /* offset是基于NOR的角度看到 */

18 void nor_cmd(unsigned int offset, unsigned int cmd)

19 {

20 nor_write_word(NOR_FLASH_BASE, offset, cmd);

21 }

读取函数


nor_read_word函数是从NOR Flash 读取两个字节(本开发板位宽16bit),读取数据的地址,是基于2440,所以读取NOR Flash某个地址上的数据时,需要把NOR Flash对应的地址左移一位(地址乘以2)。


23 unsigned int nor_read_word(unsigned int base, unsigned int offset)

24 {

25 volatile unsigned short *p = (volatile unsigned short *)(base + (offset << 1));

26 return *p;

27 }

读取地址中的数据


向nor_dat函数中写入NOR Flash某个地址,返回该NOR Flash地址上的数据。


29 unsigned int nor_dat(unsigned int offset)

30 {

31 return nor_read_word(NOR_FLASH_BASE, offset);

32 }

进入NOR FLASH的CFI模式,读取各类信息


do_scan_nor_flash函数代码如下,该函数的功能:进入CFI模式读取NOR Flash中的厂家ID,设备ID,容量等信息。


50/* 进入NOR FLASH的CFI模式

51 * 读取各类信息

52 */

53 void do_scan_nor_flash(void)

54 {

55 char str[4];

56 unsigned int size;

57 int regions, i;

58 int region_info_base;

59 int block_addr, blocks, block_size, j;

60 int cnt;

61

62 int vendor, device;

63

64 /* 打印厂家ID、设备ID */

65 nor_cmd(0x555, 0xaa);    /* 解锁 */

66 nor_cmd(0x2aa, 0x55); 

67 nor_cmd(0x555, 0x90);    /* read id */

68 vendor = nor_dat(0);

69 device = nor_dat(1);

70 nor_cmd(0, 0xf0);        /* reset */

71

72 nor_cmd(0x55, 0x98);  /* 进入cfi模式 */

073

74 str[0] = nor_dat(0x10);

75 str[1] = nor_dat(0x11);

76 str[2] = nor_dat(0x12);

77 str[3] = '';

78 printf("str = %s", str);

79

80 /* 打印容量 */

81 size = 1<<(nor_dat(0x27));

82 printf("v=0x%x,d=0x%x,s=0x%x,%dM",vendor,device,size,size/(1024*1024));

83

84 /* 打印各个扇区的起始地址 */

85 /* 名词解释:

86 *    erase block region : 里面含有1个或多个block, 它们的大小一样

87 * 一个nor flash含有1个或多个region

88 * 一个region含有1个或多个block(扇区)

89

90 * Erase block region information:

91 *    前2字节+1    : 表示该region有多少个block 

92 *    后2字节*256  : 表示block的大小

93 */

94

95 regions = nor_dat(0x2c);

96 region_info_base = 0x2d;

97 block_addr = 0;

98 printf("Block/Sector start Address:");

99 cnt = 0;

100 for (i = 0; i < regions; i++)

101 {

102    blocks = 1 + nor_dat(region_info_base) + (nor_dat(region_info_base+1)<<8);

103    block_size=256*(nor_dat(region_info_base+2)+(nor_dat(region_info_base+3)<<8));

104    region_info_base += 4;

105

106    //printf("…………");

107

108 for (j = 0; j < blocks; j++)

109 {

110 /* 打印每个block的起始地址 */

111 //printf("0x%08x ", block_addr);

112 printHex(block_addr);

113 putchar(' ');

114 cnt++;

115 block_addr += block_size;

116 if (cnt % 5 == 0)

117 printf("nr");

118 }

119 }

120 printf("nr");

121 /* 退出CFI模式 */

122 nor_cmd(0, 0xf0);

123 }

第65,66行 这两步是解锁,解锁之后就进入读ID状态,就可以读取厂家和设备ID了。


第68行 是把读取到的厂家ID的值,复制给vendor变量。


第69行 是把读取到的设备ID的值,复制给device变量。


第70行 退出读ID状态: 给任意地址写F0H。


第72行,往地址0x55地址写入数据0x98,是进入cfi模式。


第74,75,76行是读取NOR Flash地址0x10,0x11,x012中的字符,赋值给字符串str。


第81行,根据芯片手册可知道,读取NOR Flash地址0x27处的数据,得到的是NOR Flash容量大小2的幂数,所以把1左移读取到的数据,就可得到NOR Flash的容量。


第95行读取NOR Flash地址0x2c地址中的数据,可以得到NOR Flash中有多少region。


第102行根据Erase block region information:的信息可以知道读取[2E,2D]这两个字节的地址+1,可以得到一个region有多少block(参考芯片手册)。代码中的region_info_base变量的值是0x2d,0x2d是前两个字节中的低字节,0x2e是前两个字节中的高字节,所以需要左移8位,然后加上1就得到了一个region有多少block.。


第103行参考芯片手册,读取[30,2F]这两个字节地址,然后乘上256就可以得到一个块的大小。


第104行,地址加4,读取下一个region有多少block和每个block的大小。


第112,115行,由于NOR Flash的基地址是0,所以第一个block的首地址是0,下一个block的首地址,就是上一个block的首地址加上block的大小。


第112行往0地址写入0xf0,退出CFI模式。


Nor Flash的测试


nor_flash_test函数通过switch语句,分别处理识别NOR Flash,擦除NOR Flash某个扇区,编写某个地址,读某个地址。代码如下:


232 void nor_flash_test(void)

233 {

234 char c;

235

236 while (1)

237 {

238 /* 打印菜单, 供我们选择测试内容 */

239 printf("[s] Scan nor flashnr");

240 printf("[e] Erase nor flashnr");

241 printf("[w] Write nor flashnr");

242 printf("[r] Read nor flashnr");

243 printf("[q] quitnr");

244 printf("Enter selection: ");

245

246 c = getchar();

247 printf("%c", c);

248

249 /* 测试内容:

250 * 1. 识别nor flash

251 * 2. 擦除nor flash某个扇区

252 * 3. 编写某个地址

253 * 4. 读某个地址

254 */

255 switch (c)  

256 {

257 case 'q':

258 case 'Q':

259 return;

260 break;

261

262 case 's':

263 case 'S':

264 do_scan_nor_flash();

265 break;

266

267 case 'e':

268 case 'E':

269 do_erase_nor_flash();

270 break;

271

272 case 'w':

273 case 'W':

274 do_write_nor_flash();

275 break;

276

277 case 'r':

278 case 'R':

279 do_read_nor_flash();

280 break;

281 default:

282 break;

283 }

284 }

285 }

主函数


main函数代码如下所示。把timer中断去掉,否则: 测试NOR Flash时进入CFI等模式时, 如果发生了中断,cpu必定读NOR Flash,那么读不到正确的指令,导致程序崩溃。


12 int main(void)

13 {

14 led_init();

15 //interrupt_init();  /* 初始化中断控制器 */

16 key_eint_init();   /* 初始化按键, 设为中断源 */

17 //timer_init();

18

19 puts("nrg_A = ");

20 printHex(g_A);

21 puts("nr");

22

23 nor_flash_test();

24

25 return 0;

26 }

第003节_Nor Flash编程_擦写读

本实例的目的目的:擦除nor flash某个扇区,编写某个地址,读某个地址。


等待烧写


等待烧写完成 : 读数据, Q6无变化时表示结束 (参考芯片手册),


35 void wait_ready(unsigned int addr)

36 {

37 unsigned int val;

38 unsigned int pre;

39

40 pre = nor_dat(addr>>1);

41 val = nor_dat(addr>>1);

42 while ((val & (1<<6)) != (pre & (1<<6)))

43 {

44 pre = val;

45 val = nor_dat(addr>>1);

46 }

47}

擦除NOR Flash 某个扇区


do_erase_nor_flash函数的代码如下。参考芯片手册,就可以知道擦除某个扇区,还是相对比较简单的。


125 void do_erase_nor_flash(void)

126 {

127 unsigned int addr;

128

129 /* 获得地址 */

130 printf("Enter the address of sector to erase: ");

131 addr = get_uint();

132

133 printf("erasing ...");

134 nor_cmd(0x555, 0xaa);    /* 解锁 */

135 nor_cmd(0x2aa, 0x55); 

136 nor_cmd(0x555, 0x80); /* erase sector */

137

138 nor_cmd(0x555, 0xaa);    /* 解锁 */

139 nor_cmd(0x2aa, 0x55); 

[1] [2]
关键字:NOR  Flash操作  裸机程序 引用地址:第015课 NOR Flash操作原理及裸机程序分析

上一篇:第014课 Jz2400_ARM异常与中断体系详解
下一篇:第016课 Nand Flash操作原理及裸机程序分析

推荐阅读最新更新时间:2024-11-12 00:28

一加Nord N20 SE解密,该公司首款“SE”后缀手机
一加被曝计划很快推出一款 Nord 系列入门新机,这款手机的名字被确认为 Nord N20 SE,该机一加出现在 TDRA 认证网站上。   从列表中看,该设备的型号为 CPH2469,该机上周也已出现在 FCC 认证网站上,但现在 TDRA 的列表已经确认了新机的名字为 Nord 20 SE。值得注意的是,这款手机将是一加公司的第一款以 SE 为后缀名的手机。   截至目前,TDRA 列表没有透露有关这款即将到来的一加智能手机的任何规格。然而,Nord 20 SE 可能是 OPPO A57 的一个马甲版,可能会有一个 6.57 英寸的 HD + 水滴显示屏,搭载联发科 Helio G35 SoC,内置 5000
[手机便携]
一加<font color='red'>Nor</font>d N20 SE解密,该公司首款“SE”后缀手机
Keil 出现Debug Error! DAMAGE:after Normal block
Keil编译程序没有问题,在下载程序的时候出现: 甚至于出现,Keil死掉的情况 因为程序可以编译过,所以程序本身并没有问题,当下载时出问题就应该是 程序太大超出了单片机Flash、RAM太大等地方的问题。 最后检查是因为程序太大,所用单片机的Flash只有16K。而程序大小超过了16K。
[单片机]
Keil 出现Debug Error! DAMAGE:after <font color='red'>Nor</font>mal block
u-boot-2011.06在基于s3c2440开发板的移植之NorFlash启动
在移植之前,我们还需要安装、配置eldk,用于编译u-boot。下面我们就先介绍一下eldk的安装与配置: 1.下载eldk 在 这里 选择任一版本的eldk并下载,我选择的是eldk4.2版本的arm-2008-11-24.iso文件。把该文件下载到/home/zhaocj/download/目录下。 2.在root权限下安装eldk 创建挂载点: mkdir /mnt/dvdrom 挂载光驱: mount –o loop /home/zhaocj/download/arm-2008-11-24.iso/mnt/dvdrom 安装eldk: cd /mnt/dvdrom ./install –d /opt/eldk4.2/
[单片机]
jlink烧写Nor Flash时出错正确解决方法汇总
成都国嵌的课程:国嵌体验入门班-2-1(开发板系统安装-Jlink方式).rar毒害了不少人,那种直接烧写nor flash,不进行任何配置的方法,能够成功纯属偶然,他自己在视频中烧写时也出现了两次错误,可却没有意识到他的操作有问题,误认为是jlink不稳定,先将此文贴出,将其错误方法纠正。 如果你用国嵌的方法直接烧写nor flash,会出现下面的错误: 如果你按照国嵌的说法认为这是jlink不稳定,多试几遍就好了,你就会发现这个错误像魔鬼一样跟着你,对你不离不弃,这个方案我验证了几十次,没有一次是成功的,于是我开始寻找错误的根源。后面问题得到解决,现将方案总结如下: 方案1. 如果你有mini2440或者是你板子对应
[单片机]
jlink烧写<font color='red'>Nor</font> <font color='red'>Flash</font>时出错正确解决方法汇总
S3C2440从NAND Flash启动和NOR FLASH启动的问题
1.为什么NAND FLASH不能直接运行程序     NAND FLASH本身是连接到了控制器上而不是系统总线上。CPU运行机制为:CPU启动后是要取指令执行的,如果是SROM、NOR FLASH 等之类的,CPU 通过地址线发个地址就可以取得指令并执行,NAND FLASH不行,因为NAND FLASH 是管脚复用,它有自己的一套时序,这样CPU无法取得可以执行的代码,也就不能初始化系统了。     NAND FLASH是顺序存取设备,不能够被随机访问,程序就不能够分支或跳转,这样你如何去设计程序。     U-BOOT 支持ARM、 PowerPC等多种架构的处理器,也支持Linux、NetBSD和VxWorks等多种操作系
[单片机]
S3C2440从NAND <font color='red'>Flash</font>启动和<font color='red'>NOR</font> <font color='red'>FLASH</font>启动的问题
用J-Flash ARM烧写NorFalsh的方法
烧写Bios到Nor Flash或者Nan Flash是嵌入式系统开发硬件完成后的第一步涉及到软件的工作,很重要。烧写Nor Flash的工具和方法很多,近期网上有一篇用J-Link ARM间接烧写Nor Flash的方法: http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=3228953&bbs_page_no=1&search_mode=1&search_text=jlink&bbs_id=9999 本人按部就班,试了一把,感觉还可以,只是有些麻烦。尝试着用J-Flash ARM来烧写,该方法非常简单方便。 前段时间心血来潮,花了近800大洋,买了一个Mini
[单片机]
赛普拉斯推出业内最快的256Mb Quad SPI NOR闪存
全新FL-L系列能够以最大的灵活性将程序代码和参数数据存储在高性能嵌入式系统中 嵌入式系统解决方案领导者赛普拉斯半导体公司(纳斯达克股票交易代码:CY)今日推出一款配备四串行外设接口(Quad SPI)的256Mb NOR闪存产品。借助Quad SPI的4KB统一扇区,全新的赛普拉斯FL-L NOR闪存可提供业内最高的读取带宽和最快的编程速度,同时保证小巧的PCB布局。通过采用统一小巧的物理存储扇区,该闪存能够以最佳方式存储程序代码和参数数据。该器件是视频电子游戏机、高级驾驶辅助系统(ADAS)、汽车仪表盘及信息娱乐系统、联网设备和机顶盒等高性能应用的理想选择。 高性能系统需要最高的读取带宽来执行程序,同时
[嵌入式]
旗舰手机一加Nord N20曝光:下月海外发布
近日,外媒曝光了最新一加的旗舰手机,这款手机命名为“一加NordN20”,将在下个月正式亮相,主要投放海外市场,随后回归国内。   乍一看,这款新机的镜头模组很像可以说与华为P50系列的设计语言又异曲同工之妙,同样采用双环的设计,但没有外圈的椭圆形边框,而双主摄的配置或许也将在2022年开始流行。镜头模组之间构建了一个非常符合东方美学的对称体系,所以并没有让人感到十分突兀,反而有一种简单的美感。   一加NordN20还采用了类似iPhone13的直角中框设计,在左上角开孔,四角的边框比较窄,并且保留了3.5mm耳机插口。后置主摄为4800万像素,支持屏幕指纹识别。   一加科技首席执行官刘作虎曾在一份声明中表示:“一
[手机便携]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved