NAND
文章目錄
NAND
一、FLASH閃存是什么?
二、SD NAND Flash
三、STM32例程
一、FLASH閃存是什么?
簡介
FLASH閃存是屬于內存器件的一種,“Flash”。閃存則是一種非易失性( Non-Volatile )內存,在沒有電流供應的條件下也能夠長久地保持數據,其存儲特性相當于硬盤,這項特性正是閃存得以成為各類便攜型數字設備的存儲介質的基礎。
各類 DDR 、 SDRAM 或者 RDRAM 都屬于揮發性內存,只要停止電流供應內存中的數據便無法保持,因此每次電腦開機都需要把數據重新載入內存。
閃存則是一種非易失性( Non-Volatile )內存,在沒有電流供應的條件下也能夠長久地保持數據,其存儲特性相當于硬盤,這項特性正是閃存得以成為各類便攜型數字設備的存儲介質的基礎。
分類
NOR和NAND是市場上兩種主要的非易失閃存技術。
在1984年,東芝公司的發明人舛岡富士雄首先提出了快速閃存存儲器(此處簡稱閃存)的概念。與傳統電腦內存不同,閃存的特點是NVM,其記錄速度也非常快。
Intel是世界上第一個生產閃存并將其投放市場的公司。1988年,公司推出了一款256K bit閃存芯片。它如同鞋盒一樣大小,并被內嵌于一個錄音機里。後來,Intel發明的這類閃存被統稱為NOR閃存。它結合EPROM和EEPROM兩項技術,并擁有一個SRAM接口。
第二種閃存稱為NAND閃存。它由日立公司于1989年研制,并被認為是NOR閃存的理想替代者。NAND閃存的寫周期比NOR閃存短90%,它的保存與刪除處理的速度也相對較快。NAND的存儲單元只有NOR的一半,在更小的存儲空間中NAND獲得了更好的性能。鑒于NAND出色的表現,它常常被應用于諸如CompactFlash、SmartMedia、 SD、 MMC、 xD、 and PC cards、USB sticks等存儲卡上。
NAND 閃存的存儲單元采用串行結構,存儲單元的讀寫是以頁和塊為單位來進行(一頁包含若干字節,若干頁則組成儲存塊, NAND 的存儲塊大小為 8 到 32KB ),這種結構最大的優點在于容量可以做得很大,超過 512MB 容量的 NAND 產品相當普遍, NAND 閃存的成本較低,有利于大規模普及。
特點
性能
flash閃存是非易失存儲器,可以對稱為塊的存儲器單元塊進行擦寫和再編程。任何flash器件的寫入操作只能在空或已擦除的單元內進行,所以大多數情況下,在進行寫入操作之前必須先執行擦除。NAND器件執行擦除操作是十分簡單的,而NOR則要求在進行擦除前先要將目標塊內所有的位都寫為1。
由于擦除NOR器件時是以64~128KB的塊進行的,執行一個寫入/擦除操作的時間為5s,與此相反,擦除NAND器件是以8~32KB的塊進行的,執行相同的操作最多只需要4ms。
執行擦除時塊尺寸的不同進一步拉大了NOR和NADN之間的性能差距,統計表明,對于給定的一套寫入操作(尤其是更新小文件時),更多的擦除操作必須在基于NOR的單元中進行。這樣,當選擇存儲解決方案時,設計師必須權衡以下的各項因素。
● NOR的讀速度比NAND稍快一些。
● NAND的寫入速度比NOR快很多。
● NAND的4ms擦除速度遠比NOR的5s快。
● 大多數寫入操作需要先進行擦除操作。
● NAND的擦除單元更小,相應的擦除電路更少。
可靠性
采用flash介質時一個需要重點考慮的問題是可靠性。對于需要擴展MTBF的系統來說,Flash是非常合適的存儲方案。可以從壽命(耐用性)、位交換和壞塊處理三個方面來比較NOR和NAND的可靠性。
耐用性
在NAND閃存中每個塊的最大擦寫次數是一百萬次,而NOR的擦寫次數是十萬次。NAND存儲器除了具有10比1的塊擦除周期優勢,典型的NAND塊尺寸要比NOR器件小8倍,每個NAND存儲器塊在給定的時間內的刪除次數要少一些。
易于使用
可以非常直接地使用基于NOR的閃存,可以像其他存儲器那樣連接,并可以在上面直接運行代碼。
由于需要I/O接口,NAND要復雜得多。各種NAND器件的存取方法因廠家而異。
在使用NAND器件時,必須先寫入驅動程序,才能繼續執行其他操作。向NAND器件寫入信息需要相當的技巧,因為設計師絕不能向壞塊寫入,這就意味著在NAND器件上自始至終都必須進行虛擬映射。
其他作用
驅動還用于對DiskOnChip產品進行仿真和NAND閃存的管理,包括糾錯、壞塊處理和損耗平衡。
虛擬化
FLASH閃存是一種內存技術,與RAM不同,在斷電時它仍舊可以保留所存儲的信息。盡管FLASH閃存在執行讀寫操作時并不像RAM那樣快,但性能遠遠高于典型的硬盤。更為重要的是,FLASH閃存訪問數據時幾乎不存在任何時間延遲。FLASH閃存技術非常適合隨機I/O,而虛擬服務器環境中恰恰存在大量的隨機I/O。
對FLASH閃存主要的關注點之一是其執行寫操作的方式。FLASH閃存可以執行的寫操作次數有限,這意味著FLASH閃存廠商需要開發復雜的控制器技術,對寫入FLASH閃存模塊的方式進行管理,確保每個FLASH閃存單元接收相同的寫請求。
目前有三種類型的FLASH閃存,耐久性各不相同。單階存儲單元(SLC)FLASH閃存在每個單元寫一位數據,耐久性最好。多階存儲單元(MLC)FLASH閃存在每個單元寫多位數據,耐久性排名第二。三階存儲單元(TLC)在每個單元寫三位數據,耐久性最差。每個單元寫入的數據位越多意味著每個單元的容量越高,每GB的成本越低,同樣意味著平均壽命更短。
SLC是數據中心標準,但控制器技術的不斷優化使得MLC被大多數用例所接受。尤其是在采用了某種方式的數據保護,比如鏡像或者RAID或者使用了FLASH閃存層時。
二、SD NAND Flash
我以貼片式TF卡“CSNP32GCR01-AOW”型號為例介紹
芯片樣子都一樣,這里隨便放一張
概述
CSNP32GCR01-AOW是基于NAND閃存和SD控制器的32Gb密度嵌入式存儲。該產品與原始NAND相比,它有許多優點,包括嵌入式壞塊管理和更強的嵌入式ECC。即使在異常斷電的情況下,它仍然可以安全地保存數據。
特點
接口:標準SD規范2.0版,帶有1-I/O和4-I/O。
電源:Vcc=2.7V-3.6V
默認模式:可變時鐘頻率0-25 MHz,最高12.5 MB/秒接口速度(使用4條并行數據線)
高速模式:可變時鐘頻率0-50 MHz,最高25 MB/秒接口速度(使用4條并行數據線)
工作溫度:-25°C至+85°C
儲存溫度:-40°C至+85°C
備用電流:<250uA
開關功能命令支持高速、電子商務和未來功能
內存字段錯誤的糾正
內容保護機制-符合SDMI標準的最高安全性。
SD NAND的密碼保護(CMD42-鎖定和解鎖)
使用機械開關的寫保護功能
內置寫保護功能(永久和臨時)
特定于應用程序的命令
3. 引腳分配
4.數據傳輸模式
5. SD NAND寄存器
SDNAND接口中定義了六個寄存器:OCR、CID、CSD、RCA、DSR和SCR。這些信息只能通過
相應的命令。OCR、CID、CSD和SCR寄存器攜帶SDNAND/內容特定信息,而RCA、DSR寄存器是存儲實際配置參數的配置寄存器(這里選取倆個寄存器進行展示)。
CID register
SCR register
通電圖
通電時間
Tips: RDAT和RCMD(10K~100 kΩ)是上拉電阻器,當SDNAND處于a狀態時,保護CMD和DAT線路不受總線浮動的影響;在高阻抗模式,即使主機僅在SD模式下使用SDNAND作為1位模式,主機也應通過RDAT上拉所有DAT0-3線。它是建議VCC上有2.2uF電容。RCLK參考0~120Ω。
三、STM32例程
1. 初始化
SD_Error SD_Init(void)
{
uint32_t i = 0;
/*!< Initialize SD_SPI */
GPIO_Configuration();
/*!< SD chip select high */
SD_CS_HIGH();
/*!< Send dummy byte 0xFF, 10 times with CS high */
/*!< Rise CS and MOSI for 80 clocks cycles */
for (i = 0; i <= 9; i++)
{
/*!< Send dummy byte 0xFF */
SD_WriteByte(SD_DUMMY_BYTE);
}
//獲取卡的類型,最多嘗試10次
i=0;
do
{
/*------------Put SD in SPI mode--------------*/
/*!< SD initialized and set to SPI mode properly */
SD_GoIdleState();
/*Get card type*/
SD_GetCardType();
}while(SD_Type == SD_TYPE_NOT_SD && i++ >10);
//不支持的卡
if(SD_Type == SD_TYPE_NOT_SD)
return SD_RESPONSE_FAILURE;
return SD_GetCardInfo(&SDCardInfo);
}
2. 單數據塊測試
void SD_SingleBlockTest(void)
{
/*------------------- Block Read/Write --------------------------*/
/* Fill the buffer to send */
Fill_Buffer(Buffer_Block_Tx, BLOCK_SIZE, 0x320F);
if (Status == SD_RESPONSE_NO_ERROR)
{
/* Write block of 512 bytes on address 0 */
Status = SD_WriteBlock(Buffer_Block_Tx, 0x00, BLOCK_SIZE);
/* Check if the Transfer is finished */
}
if (Status == SD_RESPONSE_NO_ERROR)
{
/* Read block of 512 bytes from address 0 */
Status = SD_ReadBlock(Buffer_Block_Rx, 0x00, BLOCK_SIZE);
}
/* Check the correctness of written data */
if (Status == SD_RESPONSE_NO_ERROR)
{
TransferStatus1 = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE);
}
if(TransferStatus1 == PASSED)
{
LED2_ON;
printf("Single block 測試成功!\n");
}
else
{
LED1_ON;
printf("Single block 測試失敗,請確保SD卡正確接入開發板,或換一張SD卡測試!\n");
}
}
3. 多數據塊測試
void SD_MultiBlockTest(void)
{
/*--------------- Multiple Block Read/Write ---------------------*/
/* Fill the buffer to send */
Fill_Buffer(Buffer_MultiBlock_Tx, MULTI_BUFFER_SIZE, 0x0);
if (Status == SD_RESPONSE_NO_ERROR)
{
/* Write multiple block of many bytes on address 0 */
Status = SD_WriteMultiBlocks(Buffer_MultiBlock_Tx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);
/* Check if the Transfer is finished */
}
if (Status == SD_RESPONSE_NO_ERROR)
{
/* Read block of many bytes from address 0 */
Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);
/* Check if the Transfer is finished */
}
/* Check the correctness of written data */
if (Status == SD_RESPONSE_NO_ERROR)
{
TransferStatus2 = Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);
}
if(TransferStatus2 == PASSED)
{
LED2_ON;
printf("Multi block 測試成功!");
}
else
{
LED1_ON;
printf("Multi block 測試失敗,請確保SD卡正確接入開發板,或換一張SD卡測試!");
}
}
4. 狀態緩沖
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength)
{
while (BufferLength--)
{
if (*pBuffer1 != *pBuffer2)
{
return FAILED;
}
pBuffer1++;
pBuffer2++;
}
return PASSED;
}
void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset)
{
uint16_t index = 0;
/* Put in global buffer same values */
for (index = 0; index < BufferLength; index++)
{
pBuffer[index] = index + Offset;
}
}
了解產品更多詳情:官網 http://www.longsto.com/