ZYNQ EMMC/FLASH/SD卡硬件性能测试

时间:2024-03-26 09:54:32

vivado硬件配置:勾选上SD0,SD1,FLASH和PS_UART

ZYNQ EMMC/FLASH/SD卡硬件性能测试

ZYNQ EMMC/FLASH/SD卡硬件性能测试

生成.bit,导入SDK,分别建硬件测试工程

1,EMMC裸机读写测试

方法:使用了 XILINX SDK 库函数实现读写,先往 EMMC 里面写 1024 个数据,然后读出来对比;

#include <stdio.h>
#include "xparameters.h"
#include "xil_exception.h"
#include "xsdps.h"
#include "xil_printf.h"
static XSdPs ps7_EMMC;
XSdPs_Config * EMMC_Config;
u8 WR_Buf[1024];
u8 RD_Buf[1024];
u8 Emmc_ExtCsd[1024];
int main()
{
u32 i;

s32 Status;
u32 Buffer_size=1024;
u8 SD_ERROR=0;
EMMC_Config= XSdPs_LookupConfig(XPAR_PS7_SD_1_DEVICE_ID);
Status = XSdPs_CfgInitialize(&ps7_EMMC, EMMC_Config, EMMC_Config->BaseAddress);
if (Status != XST_SUCCESS)
{
print("EMMC Config failed !\n\r");
return XST_FAILURE;
}
Status=XSdPs_MmcCardInitialize(&ps7_EMMC);
if (Status != XST_SUCCESS)
{
print("EMMC Config failed !\n\r");
return XST_FAILURE;
}
Status=XSdPs_Change_ClkFreq(&ps7_EMMC,50000000);
Status=XSdPs_Select_Card(&ps7_EMMC);
Status=XSdPs_SetBlkSize(&ps7_EMMC,XSDPS_BLK_SIZE_512_MASK);
Status=XSdPs_Get_Mmc_ExtCsd(&ps7_EMMC,Emmc_ExtCsd);
for(i=0;i<Buffer_size;i++)
{
WR_Buf[i]=i;
}
Status = XSdPs_WritePolled(&ps7_EMMC, 0x00, 2, WR_Buf);
Status = XSdPs_ReadPolled(&ps7_EMMC, 0x00, 2, RD_Buf);
//-----------------------check data-----------------------------------------------
for(i=0; i<Buffer_size;i++)
{
if(WR_Buf[i]!=RD_Buf[i])
{
SD_ERROR=1;
break;
}
}
if(SD_ERROR)
xil_printf("EMMC Data checked Error\r\n");
else
xil_printf("EMMC Data checked Successfully\r\n");
return 0;
}

ZYNQ EMMC/FLASH/SD卡硬件性能测试

2,SD卡裸机读写测试

实现了创建一个 text.txt 的文件,并且打开,只有往里面写 0~1023~共计 1024 个数据,之后再读这个文件,读出 1024 个数据,最后对比数据内容是否和写入的一致。用户可以可以直接复制以上程序到自己的工程使用。除此之外,要让自己新建的工程可以正常编译,还要设置 BSP 库:菜单栏Xilinx->Board Support Package Setting勾选 xilffs 库,以支持 SD 卡的裸机文件系统支持。

ZYNQ EMMC/FLASH/SD卡硬件性能测试

#include <stdio.h>
#include "xparameters.h"
#include "xsdps.h"
#include "xil_printf.h"
#include "ff.h"
static FATFS SD_Dev; // File System instance
char *SD_Path = "0:/"; // string pointer to the logical drive number
static char FileName[32] = "test.txt"; // name of the log
u8 WR_Buf[1024] __attribute__ ((aligned(32))); // Buffer should be word aligned (multiple of 4)
u8 RD_Buf[1024] __attribute__ ((aligned(32))); // Buffer should be word aligned (multiple of 4)
int SD_init()
{
              FRESULT result;
               result = f_mount(&SD_Dev,SD_Path, 0);
              if (result != 0)

            {
                   return XST_FAILURE;
            }
           return XST_SUCCESS;
}
int SD_read(char *FileName,u8 *DestinationAddress,u32 ByteLength)
{
            FIL file;
            FRESULT result;
            UINT BytesRd;
           result = f_open(&file,FileName,FA_READ);
          if(result)

           {
                 return XST_FAILURE;
            }
           result = f_lseek(&file, 0);
         if(result)
        {
          return XST_FAILURE;
        }
        result = f_read(&file, (void*)DestinationAddress,ByteLength,&BytesRd);
       if(result)
     {
           return XST_FAILURE;
      }
     result = f_close(&file);
   if(result)
   {
        return XST_FAILURE;
   }
       return XST_SUCCESS;
}
int SD_write(char *FileName,u8 *SourceAddress,u32 ByteLength)
{
             FIL file;
             FRESULT result;
             UINT BytesWr;
            result = f_open(&file,FileName,FA_CREATE_ALWAYS | FA_WRITE);
            if(result)
             {
                   return XST_FAILURE;
             }
            result = f_lseek(&file, 0);
            if(result)
            {
                   return XST_FAILURE;
            }
           result = f_write(&file,(void*) SourceAddress,ByteLength,&BytesWr);
           if(result)
         {
              return XST_FAILURE;
         }

          result = f_close(&file);
       if(result)

      {
          return XST_FAILURE;
       }
       return XST_SUCCESS;
}
int main()
{
           int i;
           FRESULT result;
          u8 SD_ERROR=0;
          u32 Buffer_size=1024;
          SD_init();
         for(i=0;i<Buffer_size;i++)
         {
              WR_Buf[i]=i;
          }
//-----------------------write test data to file-----------------------------------
         result=SD_write(FileName, WR_Buf, Buffer_size);
        if (result!=0)
       {
             return XST_FAILURE;
       }
        xil_printf("SD CARD written Successfully\r\n");
//-----------------------read test data ------------------------------------------
       result=SD_read(FileName, RD_Buf, Buffer_size);
        if (result!=0)
      {
          return XST_FAILURE;
       }
       xil_printf("SD CARD Data read Successfully\r\n");
//-----------------------check data-----------------------------------------------
for(i=0; i<Buffer_size;i++)
{
           if(WR_Buf[i]!=RD_Buf[i])
          {

           SD_ERROR=1;
            break;
         }
}
if(SD_ERROR)
         xil_printf("SD CARD Data checked Error\r\n");
else
          xil_printf("SD CARD Data checked Successfully\r\n");
return 0;
}

ZYNQ EMMC/FLASH/SD卡硬件性能测试

3,FLASH读写测试

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <linux/compiler.h>
#include <mtd/mtd-user.h>

struct BSL
{
 char  booslink[10];  //a fixed string idefined as booslink
 //char  serialNumber[24];
//++++add a Serial Number
 //char  PCBA_serialNumber[24];
 //char  reserved_0[24];
};

int non_region_erase(int Fd, int start, int count, int unlock)
{
    mtd_info_t meminfo;

    if (ioctl(Fd,MEMGETINFO,&meminfo) == 0)
    {
        erase_info_t erase;

        erase.start = start;

        erase.length = meminfo.erasesize;

        for (; count > 0; count--) {
            printf("\rPerforming Flash Erase of length %u at offset 0x%x",
                    erase.length, erase.start);
            fflush(stdout);

            if(unlock != 0)
            {
                //Unlock the sector first.
                printf("\rPerforming Flash unlock at offset 0x%x",erase.start);
                if(ioctl(Fd, MEMUNLOCK, &erase) != 0)
                {
                    perror("\nMTD Unlock failure");
                    close(Fd);
                    return 8;
                }
            }

            if (ioctl(Fd,MEMERASE,&erase) != 0)
            {
                perror("\nMTD Erase failure");
                close(Fd);
                return 8;
            }
            erase.start += meminfo.erasesize;
        }
        printf(" done\n");
    }
    return 0;
}

int main(int argc, char *argv[])
{
    int fd;
 
    char *cmd;
    struct mtd_info_user info;   
    int regcount;
    int ret;
    int res;

    if(3>argc)
    {
        printf("You must specify a device!\n");
        return 16;
    }
    cmd=argv[1];

    // Open the device
    if ((fd = open(argv[2],O_RDWR)) < 0)
    {
        fprintf(stderr,"File open error\n");
        return 8;
    }
    else
    {
        ioctl(fd,MEMGETINFO,&info);
        //printf("info.size=%d\n info.erasesize=%d\n info.writesize=%d\n info.oobsize=%d\n",info.size,info.erasesize,info.writesize,info.oobsize);
    }
   
    if (ioctl(fd,MEMGETREGIONCOUNT,&regcount) == 0)
    {
        //printf("regcount=%d\n",regcount);
    }


    /*erase the device*/
    if (strcmp(cmd, "erase") == 0)
    {
        if(regcount == 0)
        {    
            res = non_region_erase(fd,0,(info.size/info.erasesize),0);    
        }       
        printf("erase!\n");
    }

    /*write file to this device*/
    struct BSL *bsl_write =(struct BSL*)malloc(sizeof(struct BSL));
    if (strcmp(cmd, "write") == 0)
    {
        printf("write ok!\n");
        strcpy(bsl_write->booslink,argv[3]);
        ret = write(fd, bsl_write, sizeof(struct BSL) );

        return 0;
    }

    /*read file from this device*/
    struct BSL *bsl_read =(struct BSL*)malloc(sizeof(struct BSL));
    if (strcmp(cmd, "read") == 0)
    {
      read(fd, bsl_read, sizeof(struct BSL));
      printf("%s\n", bsl_read);
        printf("read ok!\n");
    }
    return 1;
}