基于Zynq FPGA对雷龙SD NAND的测试

一、SD NAND特征

1.1 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最高安全标准

SDNAND密码保护(CMD42 - LOCK_UNLOCK)

采用机械开关的写保护功能

内置写保护功能(永久和临时)

应用程序特定命令

舒适擦除机制

  该SD卡支持SDIO读写和SPI读写,最高读写速度可达25MB/s,实际读写速度要结合MCU和接口情况实测获得。通常在简单嵌入式系统并对读写速度要求不高的情况下,会使用SPI协议进行读写。但不管使用SDIO还是SPI都需要符合相关的协议规范,才能建立相应的文件系统;

1.2 SD卡Block图

SD卡Block图

 该SD卡封装为LGA-8;引脚分配与定义如下;在这里插入图片描述:

SD卡封装为LGA-8引脚分配与定义

二、SD卡样片

  与样片同时寄来的还有转接板,转接板将LGA-8封装的芯片转接至SD卡封装,这样只需将转接板插入SD卡卡槽即可使用。

在这里插入图片描述:

CS创世SD NAND转接板

三、Zynq测试平台搭建

  •   测试平台为 Xilinx 的Zynq 7020 FPGA芯片;

  •   板卡:Digilent Zybo Z7

  •   Vivado版本:2018.3

  •   文件系统:FATFS

  •   SD卡接口:SD2.0

3.1 测试流程

  本次测试主要针对4G和32G两个不同容量的SD卡,在Zynq FPGA上搭建SD卡读写回路,从而对SD卡读写速度进行测试,并检验读写一致性;

测试流程:

  进入测试程序前,首先会对SD卡初始化并初始化建立FATFS文件系统,随后进入测试SD卡测试程序,在测试程序中,会写入一定大小的文件,然后对写入文件的时间进行测量,得到写入时间;然后再将写入的文件读出,测量获得读出时间,并将读出数据与写入数据相比较,检测是否读写出错。

  通过写入时间、读出时间可计算得到写入速度、读出速度;将以上过程重复100次并打印报告。

在Zynq FPGA上搭建SD卡读写回路

3.2 SOC搭建

  硬件搭建框图如下,我们在本次系统中使用PS端的SDIO接口来驱动SD NAND芯片,并通过UART向PC打印报告;

  PL端的硬件搭建也很简单,只需一个Timer定时器来做时间测量;

SD NAND(SD卡)PL端的硬件搭建

我们直接使用Zybo板卡文件创建一个工程,工程会将Zybo具有的硬件资源配置好;

Zybo板卡文件创建

首先点击setting->IP->Repository->+;添加Timer IP核的路径,Timer IP核会在工程中给出;

SOC搭建

 点击Create Block Design创建BD工程

Create Block Design创建BD工程

 在创建的过程中添加Zynq 内核;

SD NAND添加Zynq 内核

       由于我们使用了板卡文件,所以内核IP是配置好的,我们只需稍作修改即可,如果是其他板卡,则需要自行配置DDR等配置;

  双击内核IP,点击Clock Configuration->PL Fabric Clocks,将FCLK_CLK0的时钟频率修改为100Mhz

  双击内核IP,点击Clock Configuration->PL Fabric Clocks,将FCLK_CLK0的时钟频率修改为100Mhz

 添加TimerA IP;

 添加TimerA IP

依次点击上方的自动设计,完成SOC搭建;

SOC搭建

 点击BD设计,并创建顶层文件

SD NAND的SOC搭建

生成比特流文件;

SD NAND的SOC搭建 比特流文件

       在生成比特流文件后,将其导入SDK;

  点击Export->Export Hardware,导出硬件;然后点击Launch SDK打开SDK进行软件设计;

Export->Export Hardware,导出硬件

Launch SDK打开SDK进行软件设计

四、软件搭建

  在SDK中新建一个空白工程;

  点击file -> new -> Application project;

SD NAND软件搭建

在新建的过程中创建一个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<PACK_LEN;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的读写速度数据

SD NAND的写入速度数据

SD NAND的读出速度数据

六、总结

  本来打算拿这些样片去试试信息安全领域是否有所应用,但发现其似乎内置了复位或初始化,导致无法提取上电时的不确定值,故无法提取该SD NAND的物理不可克隆特性,所以这方面的测试无法进行;

  对于芯片正常读写的测试结果,还是很让人满意的,芯片的价格也很合理。并且LGA-8封装更适合无卡槽的嵌入式开发板设计,在一定的应用领域有着简化硬件设计、减小硬件面积的功能。

 最后贴上测试工程的链接,还迎复现实验: SD_Nand_Zynq700_test: SD Nand SOC test

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/915985.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

<Project-23 Navigator Portal> Python flask web 网站导航应用 可编辑界面:添加图片、URL、描述、位置移动

目的&#xff1a; 浏览器的地址簿太厚&#xff0c;如下图&#xff1a; 开始&#xff0c;想给每个 Web 应用加 icon 来提高辨识度&#xff0c;发现很麻烦&#xff1a;create image, resize, 还要挑来挑去&#xff0c;重复性地添加代码。再看着这些密密麻麻的含有重复与有规则的…

【Kafka】集成案例:与Spark大数据组件的协同应用

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《大数据前沿&#xff1a;技术与应用并进》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是kafka 2、Kafka 的主要特性 3、Kafka 的…

Windows上安装专业版IDEA2024并激活

1、IDEA官方下载 搜索IDEA官网点击进入&#xff0c;点击Download&#xff08;目前这个激活脚本只能激活2024.1.7&#xff0c;2024.2.x的版本都不能激活&#xff0c;2024.1.7版本已上传资源&#xff09;&#xff0c;如图&#xff1a; 2、开始安装 1&#xff09;、双击下载的.…

CSS教程(二)- CSS选择器

1. 作用 匹配文档中的某些元素为其应用样式。根据不同需求把不同的标签选出来。 2. 分类 分类 基础选择器 包含 标签选择器、ID选择器、类选择器、通用选择器等 复合选择器 包含 后代选择器、子代选择器、伪类选择器等 1 标签选择器 介绍 又称为元素选择器&#xff0c;根…

Unix进程

文章目录 命令行参数进程终止正常结束异常终止exit和_exitatexit 环境变量环境变量性质环境表shell中操作环境变量查看环境变量设置环境变量 环境变量接口获取环境变量设置环境变量 环境变量的继承性 进程资源shell命令查看进程的资源限制 进程关系进程标识进程组会话控制终端控…

c# onnx 调用yolo v11进行目标检测

先上图&#xff0c;支持图片&#xff0c;视频检测 FormYoloV11.cs using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Diagnostics; usin…

【多语言】每种语言打印helloworld,编译为exe会占多大空间

文章目录 背景c语言 53KBc 53KBgo 1.8Mdart 4.6Mpython未测试nodejs未测试rust未测试java未测试cmd || bash || powershell 未测试other 背景 各个版本的helloworld&#xff0c;纯属闲的, 环境如下: - win10 - mingw: gcc8.1.0 - go1.21 - dart3.5.4c语言 53KB gcc main.c -…

前端搭建低代码平台,微前端如何选型?

目录 背景 一、微前端是什么&#xff1f; 二、三大特性 三、现有微前端解决方案 1、iframe 2、Web Components 3、ESM 4、EMP 5、Fronts 6、无界&#xff08;文档&#xff09; 7、qiankun 四、我们选择的方案 引入qiankun并使用&#xff08;src外层作为主应用&#xff09; 主应…

CVE-2024-2961漏洞的简单学习

简单介绍 PHP利用glibc iconv()中的一个缓冲区溢出漏洞&#xff0c;实现将文件读取提升为任意命令执行漏洞 在php读取文件的时候可以使用 php://filter伪协议利用 iconv 函数, 从而可以利用该漏洞进行 RCE 漏洞的利用场景 PHP的所有标准文件读取操作都受到了影响&#xff1…

InternVL 多模态模型部署微调实践

目录 0 什么是MLLM 1 开发机创建与使用 2 LMDeploy部署 2.1 环境配置 2.2 LMDeploy基本用法介绍 2.3 网页应用部署体验 3 XTuner微调实践 3.1 环境配置 3.2.配置文件参数解读 3.3 开始微调 4.体验模型美食鉴赏能力 0 什么是MLLM 多模态大语言模型 ( Multimodal Larg…

干货分享之Python爬虫与代理

嗨伙伴们&#xff0c;今天是干货分享哦&#xff0c;可千万不要错过。今天小蝌蚪教大家使用phthon时学会巧妙借用代理ip来更好地完成任务。 让我们先了解一下为什么说咱们要用爬虫代理ip呢&#xff0c;那是因为很多网站为了防止有人过度爬取数据&#xff0c;对自身资源造成损害…

鸿蒙学习生态应用开发能力全景图-赋能套件(1)

文章目录 赋能套件鸿蒙生态应用开发能力全景图 赋能套件 鸿蒙生态白皮书: 全面阐释了鸿蒙生态下应用开发核心理念、关键能力以及创新体验,旨在帮助开发者快速、准确、全面的了解鸿蒙开发套件给开发者提供的能力全景和未来的愿景。 视频课程: 基于真实的开发场景,提供向导式…

netcat工具安装和使用

netcat是一个功能强大的网络实用工具&#xff0c;可以从命令⾏跨⽹络读取和写⼊数据。 netcat是为Nmap项⽬编写的&#xff0c;是⽬前分散的Netcat版本系列的经典。 它旨在成为可靠的后端⼯具&#xff0c;可⽴即为其他应⽤程序和⽤户提供⽹络连接。 一&#xff0c;下载安装 1&a…

【PHP】ThinkPHP基础

下载composer ComposerA Dependency Manager for PHPhttps://getcomposer.org/ 安装composer 查看composer是否安装 composer composer --version 安装 ThinkPHP6 如果你是第一次安装的话&#xff0c;首次安装咱们需要打开控制台&#xff1a; 进入后再通过命令,在命令行下面&a…

【HarmonyOS】应用实现读取剪切板内容(安全控件和自读取)

【HarmonyOS】应用实现读取粘贴板内容(安全控件和自读取) 前言 三方应用 读取系统剪切板是比较常见的功能。可以实现功能入口的快捷激活跳转&#xff0c;以及用户粘贴操作的简化&#xff0c;增强用户的体验感。 但是在用户日渐注重隐私的今天&#xff0c;系统对于剪切板权限的…

飞牛云fnOS本地部署WordPress个人网站并一键发布公网远程访问

文章目录 前言1. Docker下载源设置2. Docker下载WordPress3. Docker部署Mysql数据库4. WordPress 参数设置5. 飞牛云安装Cpolar工具6. 固定Cpolar公网地址7. 修改WordPress配置文件8. 公网域名访问WordPress 前言 本文旨在详细介绍如何在飞牛云NAS上利用Docker部署WordPress&a…

解析安卓镜像包和提取DTB文件的操作日志

概述 想查看一下安卓的镜像包里都存了什么内容 步骤 使用RKDevTool_v3.15对RK3528_DC_HK1_RBOX_K8_Multi_WIFI_13_20230915.2153.img解包 路径: 高级(Advancing) > 固件(firmware) > 解包(unpacking)得到\Output\Android\Image boot.imguboot.imgsuper.img 处理boot.…

LeetCode 热题100(八)【二叉树】(3)

目录 8.11二叉树展开为链表&#xff08;中等&#xff09; 8.12从前序与中序遍历序列构造二叉树&#xff08;中等&#xff09; 8.13路径总和III&#xff08;中等&#xff09; 8.14二叉树的最近公共祖先&#xff08;中等&#xff09; 8.15二叉树中的最大路径和&#xff08;困…

FPGA实现PCIE3.0视频采集转SDI输出,基于XDMA+GS2971架构,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案本博已有的 SDI 编解码方案本博客方案的PCIE2.0版本 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图电脑端视频QT上位机XDMA配置及使用XDMA中断模块FDMA图像缓存Native视频时序生成RGB转BT1120SDI转HDM…

纽约大学:指导LLM提出澄清性问题

&#x1f4d6;标题&#xff1a;Modeling Future Conversation Turns to Teach LLMs to Ask Clarifying Questions &#x1f310;来源&#xff1a;arXiv, 2410.13788 &#x1f31f;摘要 &#x1f538;大型语言模型&#xff08;LLM&#xff09;必须经常对高度模糊的用户请求做出…