远程加载固件_flash基础知识_3-1

                                       Flash基础知识以及常用指令

  1. 背景知识

最近在做的项目中,有个需要支持远程升级固件的需求。大体架构就是通过上位机把需更新的固件下发到FPGA中,然后通过FPGA写入用来存放固件的Flash里。调试了一段时间,总算实现了这一功能,在实现的过程中,网上前辈们的分享帮了我很大的忙,所以作为回馈,我也把实现过程中相关的知识点记录下来与大家分享,可能有说得不对的地方,欢迎指正。打算分三篇文章来讲述。

 

  1. Flash的简单分类

flash闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。flash按照内部存储结构不同,大体上可以分为两种:nor flashnand flashnor flash数据线和地址线分开,可以实现ram一样的随机寻址功能,可以读取任何一个字节。但是擦除仍要按块来擦。nand flash同样是按块擦除,但是数据线和地址线复用,不能利用地址线随机寻址。读取只能按页来读取。NOR Flash的读取,用户可以直接运行装载在NOR FLASH里面的代码。NAND Flash没有采取内存RAM的随机读取技术,它的读取是以一次读取一块的形式来进行的,通常是一次读取512个字节,采用这种技术的Flash比较廉价。用户不能直接运行NAND Flash上的代码,因此好多使用NAND Flash的开发板除了使用NAND Flah以外,还作上了一块小的NOR Flash来运行启动代码。

现在有些芯片为了减少启动引脚,可以采用QSPI serial flash作为启动存储器。其采用spi/qspi 的方式进行串行的读取数据,减小引脚消耗。这个只是通信方式的改变,其内部结构一般还是nor flash或者nand flash。这个我们就不去深究了。

 

  1. Flash常用指令以及时序关系

Flash常用的指令操作有:读ID、擦除(有三种方式)、页编程、读操作(读寄存器、读数据)、写操作(设置寄存器)等。一般来说,Flash的地址是24bit,最大只能支持16MB,面对更大容量的Flash,需要将地址配置为32bit,也就是需要将flash设置成4-byte模式。

下面以微邦的一款flash芯片W25Q128手册为例,描述一下上述的主要操作指令。不同厂家的芯片可能指令码可能会不大一样,注意区别。涉及到的时序,以标准的四线SPI总线为例,因为这种模式用的最普遍。

 FLASH常用芯片指令表(部分)

指令

第一字节(指令编码)

第二字节

第三字节

第四字节

第五字节

第六字节

第七-N字节

Write Enable

06h

 

 

 

 

 

 

Write Disable

04h

 

 

 

 

 

 

Read Status Register

05h

(S7–S0)

 

 

 

 

 

Write Status Register

01h

(S7–S0)

 

 

 

 

 

Read Data

03h

A23–A16

A15–A8

A7–A0

(D7–D0)

(Next byte)

continuous

Fast Read

0Bh

A23–A16

A15–A8

A7–A0

dummy

(D7–D0)

(Next Byte) continuous

Fast Read Dual Output

3Bh

A23–A16

A15–A8

A7–A0

dummy

I/O = (D6,D4,D2,D0) O = (D7,D5,D3,D1)

(one byte per 4 clocks, continuous)

Page Program

02h

A23–A16

A15–A8

A7–A0

D7–D0

Next byte

Up to 256 bytes

Block Erase(64KB)

D8h

A23–A16

A15–A8

A7–A0

 

 

 

Sector Erase(4KB)

20h

A23–A16

A15–A8

A7–A0

 

 

 

Chip Erase

C7h

 

 

 

 

 

 

Power-down

B9h

 

 

 

 

 

 

Release Power- down / Device ID

ABh

dummy

dummy

dummy

(ID7-ID0)

 

 

Manufacturer/ Device ID

90h

dummy

dummy

00h

(M7-M0)

(ID7-ID0)

 

JEDEC ID

9Fh

(M7-M0)

生产厂商

(ID15-ID8)

 存储器类型

(ID7-ID0) 容量

 

 

 

该表中的第一列为指令名,第二列为指令编码,第三至第N列的具体内容根据指令的不同而有不同的含义。表中“A0~A23”指FLASH芯片内部存储器组织的地址;“M0~M7为厂商号(MANUFACTURER ID);ID0-ID15”为FLASH芯片的ID;“dummy”指该处可为任意数据;“D0~D7”为FLASH内部存储矩阵的内容。

 

  • Read ID

远程加载固件_flash基础知识_3-1_第1张图片

通过指令表中的读ID指令“JEDEC ID”可以获取这两个编号,该指令编码为9F h”,其中“9F h”是指16进制数“9F” (相当于C语言中的0x9F)。紧跟指令编码的三个字节分别为FLASH芯片输出的“(M7-M0)”、“(ID15-ID8)”及“(ID7-ID0) 。通过read ID的指令,我们可以获取芯片的相关ID信息。

  • 擦除。也可以叫预编程吧,根据flash的特性,在进行写入之前,需要对目标区域进行擦除,将对应的位置置1。在所列举的芯片中,擦除分了三种类型(扇区擦除Sector_erase、块擦除Block_erase,以及整个芯片擦除Chip_erase)。他们之间的区别是,擦除区域的大小不一样。

 

远程加载固件_flash基础知识_3-1_第2张图片

扇区擦除指令将指定扇区(4K字节)内的所有存储器设置为全部擦除状态置1(FFh)。需要注意的是,在执行擦除之前, 必须执行一次写使能指令指令(状态寄存器位WEL必须等于1)。

远程加载固件_flash基础知识_3-1_第3张图片

 

远程加载固件_flash基础知识_3-1_第4张图片    

   另外两种擦除方式,大同小异,就不展开说了,需要注意的是,Chip_erase在指令码后面不需要带目标擦除区域的起始地址。

 

  • 页编程。Page_program。

页编程,一次写入256个字节的数据到flash。需注意的是,在执行页编程之前,需执行一次写使能指令。

远程加载固件_flash基础知识_3-1_第5张图片

 

  • 写操作。

这里的写操作,主要是指设置单个寄存器的值,例如将flash设置成4字节地址模式,设置写使能等等。

远程加载固件_flash基础知识_3-1_第6张图片

 

 

 

远程加载固件_flash基础知识_3-1_第7张图片

设置状态寄存器的值,指令码后面,紧跟着对应的想要设置的寄存器值即可。

 

  • 读操作

这里读操作主要可以分两种,一种是读状态寄存器值,另外一种是读去flash存储的数据。

远程加载固件_flash基础知识_3-1_第8张图片

值得注意的是,读状态寄存器指令在任何时候都可以执行,即使在编程,擦除或写入时,也可以随时使用读状态寄存器指令。

       常规读数据:

远程加载固件_flash基础知识_3-1_第9张图片

读数据指令允许从存储器中顺序读取一个或多个数据字节。该通过将/ CS引脚驱动为低电平然后移位指令代码“03h”然后移位a来启动指令24位地址(A23-A0)进入DI引脚。 代码和地址位在上升沿锁存CLK引脚。 收到地址后,寻址存储单元的数据字节将被移出在CLK的下降沿处的DO引脚上,最高有效位(MSB)优先。地址会自动增加。也就是说在下发读指令的时候,只需要配置目标区域起始地址即可。然后数据会源源不断地被读出来,直到片选信号cs被拉高,读数结束

快速读:

快速读取指令与常规读取数据指令类似,只是它可以在FR最高频率下工作(参见交流电气特性),提高读取速度。其中dummy clock时间段里的数据可以忽略。(该指令目前我用的比较少,没实践过,就不展开了)

远程加载固件_flash基础知识_3-1_第10张图片

 

你可能感兴趣的:(FPGA,flash,远程升级固件)