文章目录
- SD NAND特征
- SD卡简介
- 1.2 SD卡块图
- SD卡样片
- Zynq测试平台搭建
- 测试流程
- SOC搭建
- 软件搭建
- 测试结果
- 总结
SD NAND特征
SD卡简介
雷龙的SD NAND有很多型号,在测试中使用的是CSNP4GCR01-AMW与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最高安全标准
密码保护(密码保护)
采用机械开关的写保护功能
内置写保护功能(永久和临时)
应用程序特定命令
舒适擦除机制
该SD卡支持SDIO读写和SPI读写,最高读写速度可达25MB/s,实际读写速度要结合MCU和接口情况实测获得。通常在简单嵌入式系统并对读写速度要求不高的情况下,会使用SPI协议进行读写。但不管使用SDIO还是SPI都需要符合相关的协议规范,才能建立相应的文件系统;
1.2 SD卡块图
该SD卡封装为LGA-8;引脚分配与定义如下;在这里插入图片描述:
SD卡样片
与样片同时寄来的还有转接板,转接板将LGA-8封装的芯片转接至SD卡封装,这样只需将转接板插入SD卡卡槽即可使用。
在这里插入图片描述:
Zynq测试平台搭建
测试平台为 Xilinx 的Zynq 7020 FPGA芯片;
板卡:迪吉伦特Z7
Vivado版本:2018.3
文件系统:FATFS
SD卡接口:SD2.0
测试流程
本次测试主要针对4G和32G两个不同容量的SD卡,在Zynq FPGA上搭建 SD卡 读写回路,从而对SD卡读写速度进行测试,并检验读写一致性;
测试流程:
进入测试程序前,首先会对SD卡初始化并初始化建立FATFS文件系统,随后进入测试SD卡测试程序,在测试程序中,会写入一定大小的文件,然后对写入文件的时间进行测量,得到写入时间;然后再将写入的文件读出,测量获得读出时间,并将读出数据与写入数据相比较,检测是否读写出错。
通过写入时间、读出时间可计算得到写入速度、读出速度;将以上过程重复100次并打印报告。
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中新建一个空白工程;
点击文件—>新建—>应用项目;
在新建的过程中创建一个main.c文件,并在里面编写测试程序如下:
在每次读写开始前,通过TimerA0_start()函数开始计时,在读写结束后可以通过TimerA0_stop()结束计时,从而测得消耗时间。
相应的Timer驱动函数在user/TimerA_user.c中定义;
#include "xparameters.h" /* SDK生成的参数 */#include "xsdps.h" /* SD 设备驱动程序 */#include "xil_printf.h"#包含 "ff.h"#include "xil_cache.h"#include "xplatform_info.h"#包含 "time.h"#include "../user/headfile.h"#定义 PACK_LEN 32764静态 FIL fil; /* 文件对象 */静态FATFS FATFs;静态字符 FileName[32] = "Test.txt";静态字符 *SD_File;char目的地地址[PACK_LEN];char txt[1024];字符测试缓冲区[PACK_LEN];虚空 TimerA0_init(){TimerA_reset(TimerA0);//重新设置TimerA设备TimerA_Set_Clock_Division(TimerA0,100);//将时钟分割为 100000000/100 = 1MhzTimerA_停止计数器(TimerA0);//停止计时器A}无TimerA0_start(){TimerA_设置为连续模式(TimerA0);}无TimerA0_停止(){TimerA_停止计时器(TimerA0);}uint32 SDCard_test(){uint8 Res;uint32 NumBytesRead;uint32NumBytesWritten;uint32 BuffCnt;uint8 工作[FF_MAX_SS];uint32 占用时间=0;uint32速度=0;uint32测试时间=0;uint32 w_t=0;uint32 r_t=0;float wsum = 0;float rsum=0;TCHAR *Path = "0:/";for(int i=0;我<PACK_LEN;i++){test_buffer[i] = 'a';}Res = f_mount(&fatfs, Path, 0);如果(Res!= FR_OK) {返回XST失败;}Res = f_mkfs(路径,FM_FAT32, 0, 工作,工作大小);如果(Res!= FR_OK) {返回XST失败;}SD_File = (char *) 文件名;Res = f_open(&fil, SD_File, FA_始终生成 | FA_写入 | FA_读取);如果(Res) {返回XST失败;}Res = f_lseek(&fil, 0);如果(Res) {返回XST失败;}同时(1){TimerA_重置(TimerA0);TimerA0_开始();Res = f_write(&fil, (const void*) test_buffer, PACK_LEN,&写入字节数);TimerA0_停止();take_time = TimerA_Read_Counter_Register(TimerA0);w_t+=需要时间;xil_printf("--------------------------------\n");xil_printf("花时间:%d 我们\n",抽时间);speed = PACK_LEN*(1000000/(浮动)(占用时间)));sprintf(txt,"写入速度:%2f MB/s\n",(浮动)(速度)/1024/1024);wsum = wsum + speed;xil_printf(txt);xil_printf("--------------------------------\n");如果(Res) {返回XST失败;}Res = f_lseek(&fil, 0);如果(Res) {返回XST失败;}TimerA_重置(TimerA0);TimerA0_开始();Res = f_read(&fil, (void*)目的地地址, PACK_LEN,&NumBytesRead) 的 NumBytesRead)TimerA0_停止();take_time = TimerA_Read_Counter_Register(TimerA0);r_t+=需要时间;xil_printf("--------------------------------\n");xil_printf("花时间:%d 我们\n",抽时间);speed = PACK_LEN*(1000000/(浮动)(占用时间)));sprintf(txt,"读取速度:%2f MB/s\n",(浮动)(速度)/1024/1024);rsum = rsum + speed;xil_printf(txt);xil_printf("--------------------------------\n");如果(Res) {返回XST失败;}for(BuffCnt=0;BuffCnt PACK_LEN;BuffCNT++){如果(test_buffer[BuffCnt]!= DestinationAddress[BuffCnt]){xil_printf("%dna",BuffCnt);返回XST失败;}}xil_printf("测试编号:%d数据检查正确!\n",测试时间+1);测试时间++;如果(测试时间==100){sprintf(txt,"总写入量:%2f KB,占用时间:%2f毫秒,写入速度:%2f MB/s\n",PACK_LEN*100/1024.0,w_t/100.0/1000.0,wsum/100/1024/1024);xil_printf(txt);sprintf(txt,"总读取量:%2f KB,占用时间:%2f毫秒,读取速度:%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);如果(Res) {返回XST失败;}返回0;}}}int main(空){TimerA0_init();SDCard_test();xil_printf("完成");返回0;}
测试结果
经测试,两种型号的芯片读写速度如下图表所示。
其SD NAND的读写速度随着读写数据量的增加而增加,并且读速率大于写速率,这符合SD卡的特性;
对比两种型号SD NAND芯片,发现CSNP32GCR01-AOW型号具有更高的读写速度;
总结
本来打算拿这些样片去试试信息安全领域是否有所应用,但发现其似乎内置了复位或初始化,导致无法提取上电时的不确定值,故无法提取该SD NAND的物理不可克隆特性,所以这方面的测试无法进行;
对于芯片正常读写的测试结果,还是很让人满意的,芯片的价格也很合理。并且LGA-8封装更适合无卡槽的嵌入式开发板设计,在一定的应用领域有着简化硬件设计、减小硬件面积的功能。
最后贴上测试工程的链接,还迎复现实验: https://gitee.com/gewenjie_host/sd_-nand_-zynq700_test
官网链接:http://www.longsto.com/