遠程加載固件_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

通過指令表中的讀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)。他們之間的區別是,擦除區域的大小不一樣。

 

扇區擦除指令將指定扇區(4K字節)內的所有存儲器設置爲全部擦除狀態置1(FFh)。需要注意的是,在執行擦除之前, 必須執行一次寫使能指令指令(狀態寄存器位WEL必須等於1)。

 

    

   另外兩種擦除方式,大同小異,就不展開說了,需要注意的是,Chip_erase在指令碼後面不需要帶目標擦除區域的起始地址。

 

  • 頁編程。Page_program。

頁編程,一次寫入256個字節的數據到flash。需注意的是,在執行頁編程之前,需執行一次寫使能指令。

 

  • 寫操作。

這裏的寫操作,主要是指設置單個寄存器的值,例如將flash設置成4字節地址模式,設置寫使能等等。

 

 

 

設置狀態寄存器的值,指令碼後面,緊跟着對應的想要設置的寄存器值即可。

 

  • 讀操作

這裏讀操作主要可以分兩種,一種是讀狀態寄存器值,另外一種是讀去flash存儲的數據。

值得注意的是,讀狀態寄存器指令在任何時候都可以執行,即使在編程,擦除或寫入時,也可以隨時使用讀狀態寄存器指令。

       常規讀數據:

讀數據指令允許從存儲器中順序讀取一個或多個數據字節。該通過將/ CS引腳驅動爲低電平然後移位指令代碼“03h”然後移位a來啓動指令24位地址(A23-A0)進入DI引腳。 代碼和地址位在上升沿鎖存CLK引腳。 收到地址後,尋址存儲單元的數據字節將被移出在CLK的下降沿處的DO引腳上,最高有效位(MSB)優先。地址會自動增加。也就是說在下發讀指令的時候,只需要配置目標區域起始地址即可。然後數據會源源不斷地被讀出來,直到片選信號cs被拉高,讀數結束

快速讀:

快速讀取指令與常規讀取數據指令類似,只是它可以在FR最高頻率下工作(參見交流電氣特性),提高讀取速度。其中dummy clock時間段裏的數據可以忽略。(該指令目前我用的比較少,沒實踐過,就不展開了)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章