前言
本文重點介紹flash的數據存取特性、flash的內存划分、一個簡單的存取圖片的內存管理方式,以及對flash寫前刪的時間、刪后讀的時間、寫后讀的時間進行測量的一個小實驗。目的在於更全面了解flash本身特點(尤其是限制),從而方便設計出高效的內存管理驅動。
本文參考論文:閃存的存儲管理及索引方法研究_趙培_華中科技大博士論文_2011年
e-mail:beautifulzzzz@qq.com
一、Flash的特點
flash有幾大奇葩的特點:
閃存具有多種不用於磁盤的特性,例如:(1)閃存具有不對稱的讀寫操作時間,即閃存的寫時間遠大於讀時間,擦除時間遠大於寫時間。(2)閃存在重寫同一閃存存儲位置的數據之前需要執行擦除操作,即具有Erase-Before-Write特性。很顯然,采用傳統的“In-place-update"方法(即每次更新閃存頁前均擦除整個閃存塊)更新閃存的策略是不可行的。因此一般情況下,閃存存儲系統采用”out-place-updata"方式更新閃存中的數據,即:將新版本的數據寫入其他空閑的頁面內,然后再將原始數據所在頁面記為失效頁面(Dead page 或Dirty Page),包含最新版本的閃存頁面成為Live頁面。當閃存中的空頁面不足時,才執行擦除操作回收空間。若待回收的閃存塊包含有效數據,則需要在執行擦除操作前將有效數據復制到閃存其他空閑頁面,這一過程成為Garbage Collection。(3)每個閃存塊具有有限的擦除次數(一般為10K或100K次),若某個塊超過最大擦除次數,則此塊為“壞塊”(Worn-out Block或Bad Block)。壞塊的可靠性差,將會頻繁出現讀寫錯誤,不能用於存儲數據。(4)為了延長閃存使用壽命,閃存存儲系統需要通過Wear-leveling機制盡量使所有閃存塊具有相同或相似的擦除次數。
這些特性使得傳統的基於磁盤設計的數據管理拌飯直接應用到閃存系統時的性能很差,不能充分發揮閃存本省的優良特性(SSD和機械式硬盤)。
二、GD25Q128B(16M)介紹
http://www.xinyahong.com/upLoad/product/month_1411/20141118164301603.pdf
2.1、GD25Q128B存儲划分
該款芯片在nRF51822EK_TM開發板上用~
2.2、GD25Q128B操作速度
2.3、GD25Q128B的頁寫操作及函數
- 像驅動代碼里面的:void SpiFlash_Write_Data(char *pBuffer, uint8_t Block_Num, uint8_t Page_Num, uint32_t WriteBytesNum)
- void SpiFlash_Write_Sector_Data(char *pBuffer, uint8_t Block_Num, uint8_t Sector_Num, uint32_t WriteBytesNum)
- uint8_t SpiFlash_Write_MorePage(uint8_t *pBuffer, uint32_t WriteAddr, uint32_t WriteBytesNum)
按頁寫,寫多頁,傳入是地址和要寫數據的量,內部寫寫的是零頭,然后按頁整頁整頁的寫
三、Flash存取圖片的具體案例(比較簡單的一種內存管理)
一張圖128X160的40960bytes=160X256(頁),而1block為64KB=2^16=2^8X256≈256頁(而2^7又小於160,因此把1block的64K用來存儲一個圖片)。因此:
1 SPIFlash_Erase_Block(0); 2 SPIFlash_Erase_Block(1); 3 SPIFlash_Erase_Block(2); 4 nrf_delay_ms(400); 5 SpiFlash_Write_MorePage(gImage_A, 0, 40960); 6 SpiFlash_Write_MorePage(gImage_B, 1<<16, 40960); 7 SpiFlash_Write_MorePage(gImage_C, 2*(1<<16), 40960); 8 //DispPic(pic_eval); 9 DispPicFromSD(0); 10 DispPicFromSD(1); 11 DispPicFromSD(2);
四、實測Flash讀寫及清除的速度(為做更復雜、高效的存儲管理做准備)
由於第三節中介紹的一張圖片約為1block大小,此外整個存儲全部用來存放相同規格的圖片,加之這些圖片只需要存一遍,之后僅僅是讀取這些圖片(不涉及多次刪除、隨機索引等情況),因此,在第三節中的存儲利用方法還算可以滿足需求。
但是對於一種帶有陀螺儀采集數據、存儲和同步的一種手環:每幀17byte的傳感器采集數據,(1)首先要滿足采集數據的時候高速存儲,(2)其次要滿足同步數據時完整同步,(3)同時也要滿足Flash滿了之后能用新的數據覆蓋老的數據。
針對這3點要求可以按照下面的方法進行實施:
針對上面實施辦法,需要具體測試下存取的效果:
4.1、Write_Before_EraseSector與Read_Before_EraseSector延時時差計算:
實驗核心代碼:48行以上測試sector erase后最短多久進行write操作沒有問題;48行以下是測試sector erase后最短多久read操作沒有問題:
測試結果:erase sector后write至少需要100ms的延時(建議選120ms),write后read和erase sector后read均不需要延時。
4.2、Write_Before_EraseBlock與Read_Before_EraseBlock延時時差計算:
同4.1理解.
測試結果:erase block后至少需要350ms的延時,才能進行有效寫!(其中后半段是注釋掉第50行代碼導致的)
PS:erase full至少40s,測試6次未出現錯誤,實驗同4.1,4.2。
PS:如果您覺得還不錯,點個贊,讓更多人受益~
@link:http://pan.baidu.com/s/1pK13HUV(私用)
@beautifulzzzz 2016-03-19 continue~
e-mail:beautifulzzzz@qq.com