文章目錄
一、SD NAND特征
1.1 SD卡簡介
1.2 SD卡Block圖
二、SD卡樣片
三、Zynq測試平臺搭建
3.1 測試流程
3.2 SOC搭建
四、軟件搭建
五、測試結果
六、總結
一、SD NAND特征
1.1 SD卡簡介
??雷龍的SD NAND有很多型號,在測試中使用的是CSNP4GCR01-AWM與CSNP32GCR01-AOW。芯片是基于NAND FLASH和 SD控制器實現的SD卡。具有強大的壞塊管理和糾錯功能,并且在意外掉電的情況下同樣能保證數據的安全。
??其特點如下:
接口支持SD2.0 2線或4線;
電壓支持:2.7V-3.6V;
默認模式:可變時鐘速率0 - 25MHz,高達12.5 MB/s的接口速度(使用4條并行數據線)
高速模式:可變時鐘速率0 - 50MHz,高達25 MB/s的接口速度(使用4條并行數據線)
工作溫度:-40°C ~ +85°C
存儲溫度:-55°C ~ +125°C
待機電流小于250uA
修正內存字段錯誤;
內容保護機制——符合SDMI最高安全標準
SDNAND密碼保護(CMD42 - LOCK_UNLOCK)
采用機械開關的寫保護功能
內置寫保護功能(永久和臨時)
應用程序特定命令
舒適擦除機制
??該SD卡支持SDIO讀寫和SPI讀寫,最高讀寫速度可達25MB/s,實際讀寫速度要結合MCU和接口情況實測獲得。通常在簡單嵌入式系統并對讀寫速度要求不高的情況下,會使用SPI協議進行讀寫。但不管使用SDIO還是SPI都需要符合相關的協議規范,才能建立相應的文件系統;
1.2 SD卡Block圖
?該SD卡封裝為LGA-8;引腳分配與定義如下;在這里插入圖片描述:
二、SD卡樣片
??與樣片同時寄來的還有轉接板,轉接板將LGA-8封裝的芯片轉接至SD卡封裝,這樣只需將轉接板插入SD卡卡槽即可使用。
在這里插入圖片描述:
三、Zynq測試平臺搭建
3.1 測試流程
??本次測試主要針對4G和32G兩個不同容量的SD卡,在Zynq FPGA上搭建SD卡讀寫回路,從而對SD卡讀寫速度進行測試,并檢驗讀寫一致性;
測試流程:
??進入測試程序前,首先會對SD卡初始化并初始化建立FATFS文件系統,隨后進入測試SD卡測試程序,在測試程序中,會寫入一定大小的文件,然后對寫入文件的時間進行測量,得到寫入時間;然后再將寫入的文件讀出,測量獲得讀出時間,并將讀出數據與寫入數據相比較,檢測是否讀寫出錯。
??通過寫入時間、讀出時間可計算得到寫入速度、讀出速度;將以上過程重復100次并打印報告。
3.2 SOC搭建
??硬件搭建框圖如下,我們在本次系統中使用PS端的SDIO接口來驅動SD NAND芯片,并通過UART向PC打印報告;
??PL端的硬件搭建也很簡單,只需一個Timer定時器來做時間測量;
我們直接使用Zybo板卡文件創建一個工程,工程會將Zybo具有的硬件資源配置好;
首先點擊setting->IP->Repository->+;添加Timer IP核的路徑,Timer IP核會在工程中給出;
?點擊Create Block Design創建BD工程
?在創建的過程中添加Zynq 內核;
由于我們使用了板卡文件,所以內核IP是配置好的,我們只需稍作修改即可,如果是其他板卡,則需要自行配置DDR等配置;
??雙擊內核IP,點擊Clock Configuration->PL Fabric Clocks,將FCLK_CLK0的時鐘頻率修改為100Mhz
?添加TimerA IP;
依次點擊上方的自動設計,完成SOC搭建;
?點擊BD設計,并創建頂層文件
生成比特流文件;
在生成比特流文件后,將其導入SDK;
??點擊Export->Export Hardware,導出硬件;然后點擊Launch SDK打開SDK進行軟件設計;
四、軟件搭建
??在SDK中新建一個空白工程;
??點擊file -> new -> Application project;
在新建的過程中創建一個main.c文件,并在里面編寫測試程序如下:
??在每次讀寫開始前,通過TimerA0_start()函數開始計時,在讀寫結束后可以通過TimerA0_stop()結束計時,從而測得消耗時間。
??相應的Timer驅動函數在user/TimerA_user.c中定義;
- #include "xparameters.h" /* SDK generated parameters */
- #include "xsdps.h" /* SD device driver */
- #include "xil_printf.h"
- #include "ff.h"
- #include "xil_cache.h"
- #include "xplatform_info.h"
- #include "time.h"
- #include "../user/headfile.h"
- #define PACK_LEN 32764
- static FIL fil; /* File object */
- static FATFS fatfs;
- static char FileName[32] = "Test.txt";
- static char *SD_File;
- char DestinationAddress[PACK_LEN] ;
- char txt[1024];
- char test_buffer[PACK_LEN];
- void TimerA0_init()
- {
- TimerA_reset(TimerA0);//reset timerA device
- TimerA_Set_Clock_Division(TimerA0,100);//divide clock as 100000000/100 = 1Mhz
- TimerA_Stop_Counter(TimerA0);//stop timerA
- }
- void TimerA0_start()
- {
- TimerA_SetAs_CONTINUS_Mode(TimerA0);
- }
- void TimerA0_stop()
- {
- TimerA_Stop_Counter(TimerA0);
- }
- uint32 SDCard_test()
- {
- uint8 Res;
- uint32 NumBytesRead;
- uint32 NumBytesWritten;
- uint32 BuffCnt;
- uint8 work[FF_MAX_SS];
- uint32 take_time=0;
- uint32 speed = 0;
- uint32 test_time = 0;
- uint32 w_t=0;
- uint32 r_t=0;
- float wsum = 0;
- float rsum = 0;
- TCHAR *Path = "0:/";
- for(int i=0;i
- {
- test_buffer[i] = 'a';
- }
- Res = f_mount(&fatfs, Path, 0);
- if (Res != FR_OK) {
- return XST_FAILURE;
- }
- Res = f_mkfs(Path, FM_FAT32, 0, work, sizeof work);
- if (Res != FR_OK) {
- return XST_FAILURE;
- }
- SD_File = (char *)FileName;
- Res = f_open(&fil, SD_File, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
- if (Res) {
- return XST_FAILURE;
- }
- Res = f_lseek(&fil, 0);
- if (Res) {
- return XST_FAILURE;
- }
- while(1)
- {
- TimerA_reset(TimerA0);
- TimerA0_start();
- Res = f_write(&fil, (const void*)test_buffer, PACK_LEN,
- &NumBytesWritten);
- TimerA0_stop();
- take_time = TimerA_Read_Counter_Register(TimerA0);
- w_t+=take_time;
- xil_printf("--------------------------------\n");
- xil_printf("take time:%d us\n",take_time);
- speed = PACK_LEN*(1000000/((float)(take_time)));
- sprintf(txt,"write speed:%.2f MB/s\n",(float)(speed)/1024/1024);
- wsum = wsum+speed;
- xil_printf(txt);
- xil_printf("--------------------------------\n");
- if (Res) {
- return XST_FAILURE;
- }
- Res = f_lseek(&fil, 0);
- if (Res) {
- return XST_FAILURE;
- }
- TimerA_reset(TimerA0);
- TimerA0_start();
- Res = f_read(&fil, (void*)DestinationAddress, PACK_LEN,
- &NumBytesRead);
- TimerA0_stop();
- take_time = TimerA_Read_Counter_Register(TimerA0);
- r_t+=take_time;
- xil_printf("--------------------------------\n");
- xil_printf("take time:%d us\n",take_time);
- speed = PACK_LEN*(1000000/((float)(take_time)));
- sprintf(txt,"read speed:%.2f MB/s\n",(float)(speed)/1024/1024);
- rsum = rsum+speed;
- xil_printf(txt);
- xil_printf("--------------------------------\n");
- if (Res) {
- return XST_FAILURE;
- }
- for(BuffCnt = 0; BuffCnt < PACK_LEN; BuffCnt++){
- if(test_buffer[BuffCnt] != DestinationAddress[BuffCnt]){
- xil_printf("%dno",BuffCnt);
- return XST_FAILURE;
- }
- }
- xil_printf("test num:%d data check right!\n",test_time+1);
- test_time++;
- if(test_time==100)
- {
- sprintf(txt,"Total write: %.2f KB,Take time:%.2f ms, Write speed:%.2f MB/s\n",PACK_LEN*100/1024.0,w_t/100.0/1000.0,wsum/100/1024/1024);
- xil_printf(txt);
- sprintf(txt,"Total read: %.2f KB,Take time:%.2f ms, Read speed:%.2f MB/s\n",PACK_LEN*100/1024.0,r_t/100.0/1000.0,rsum/100/1024/1024);
- xil_printf(txt);
- Res = f_close(&fil);
- if (Res) {
- return XST_FAILURE;
- }
- return 0;
- }
- }
- }
- int main(void)
- {
- TimerA0_init();
- SDCard_test();
- xil_printf("finish");
- return 0;
- }
五、測試結果
??經測試,兩種型號的芯片讀寫速度如下圖表所示。
??其SD NAND的讀寫速度隨著讀寫數據量的增加而增加,并且讀速率大于寫速率,這符合SD卡的特性;
??對比兩種型號SD NAND芯片,發現CSNP32GCR01-AOW型號具有更高的讀寫速度;
六、總結
??本來打算拿這些樣片去試試信息安全領域是否有所應用,但發現其似乎內置了復位或初始化,導致無法提取上電時的不確定值,故無法提取該SD NAND的物理不可克隆特性,所以這方面的測試無法進行;
??對于芯片正常讀寫的測試結果,還是很讓人滿意的,芯片的價格也很合理。并且LGA-8封裝更適合無卡槽的嵌入式開發板設計,在一定的應用領域有著簡化硬件設計、減小硬件面積的功能。
————————————————
【本文轉載自CSDN,作者:PPRAM】
-
FPGA
+關注
關注
1626文章
21678瀏覽量
602031 -
測試
+關注
關注
8文章
5174瀏覽量
126488 -
NAND
+關注
關注
16文章
1678瀏覽量
136029
發布評論請先 登錄
相關推薦
評論