ZYNQ_Standalone_SD卡读写与性能测试

文章目录

  • 一、SD卡读写功能测试
  • 二、SD卡读写性能测试
    • 一、zynq在SDK中计算某段程序的执行时间
    • 二、把上面代码用来测SD卡读写速度

一、SD卡读写功能测试

参考文章:
1、Zynq读写SD卡:https://blog.csdn.net/jinhua1990/article/details/84100100
2、ZYNQ开发板SD卡读写:https://blog.csdn.net/love_ljq/article/details/79117738

函数返回值检查宏:

#define check_func_return(express) do { \
	int ret = 0;\
	if (XST_SUCCESS != (ret=express)) \
	{\
		xil_printf("Func:%s:Line:%d: errcode(%d)\r\n",\
				__func__,__LINE__,ret);\
		return XST_FAILURE;\
	} else {\
		;/* xil_printf("Execute %s successfully!\r\n",#express); */\
	}\
} while(0)
//用法:check_func_return(function_name1(arg));

初始化SD卡:

int SdCard_Initialize(XSdPs *InstancePtr, u16 DeviceId)
{
	u32 ret = 0;
	XSdPs_Config *ConfigPtr = XSdPs_LookupConfig(DeviceId);
	ret = XSdPs_CfgInitialize(InstancePtr, ConfigPtr, ConfigPtr->BaseAddress);
	if (ret != XST_SUCCESS) {
		xil_printf("XSdPs_CfgInitialize error\r\n");
		return XST_FAILURE;
	}
	ret = XSdPs_SdCardInitialize(InstancePtr);
	if (ret != XST_SUCCESS) {
		xil_printf("XSdPs_SdCardInitialize error\r\n");
		return XST_FAILURE;
	}

	if (isSdCard_Inserted(InstancePtr))
	{
		xil_printf("isSdCard_Inserted!!!\r\n");
	} else {
		xil_printf("Sdcard is Not Inserted ...\r\n");
	}

	return 0;
}

检测SD卡是否已插入:

//检测SD卡是否已插入
//返回值: 1(true), 0(false)
int isSdCard_Inserted(XSdPs *InstancePtr)
{
	u32 PresentStateReg = 0;
	/*
	 * Check the present state register to make sure
	 * card is inserted and detected by host controller
	 */
	PresentStateReg = XSdPs_ReadReg(InstancePtr->Config.BaseAddress,
			XSDPS_PRES_STATE_OFFSET);
	if ((PresentStateReg & XSDPS_PSR_CARD_INSRT_MASK) == 0U)	{
		return 0;//false
	}
	return 1;//true;
}

下面的代码虽然不怎么优雅,但是关于SD卡的所有标准访问都包含了,而且尽量少的依赖全局变量,就为测试SD卡读写功能测试是否正常。SD卡IO功能测试(Sdcard_IoFunctionTest)完整源代码如下:

int Sdcard_IoFunctionTest(XSdPs *InstancePtr, u16 DeviceId/* default 0 */)
{
	/*
	 * To test logical drive 0, Path should be "0:/"
	 * For logical drive 1, Path should be "1:/"
	 */
	TCHAR *Path = "0:/";

	/*
	 * To test logical drive 0, FileName should be "0:/" or
	 * "". For logical drive 1, FileName should be "1:/"
	 */
	char FileName[32] = "Test.bin";
	char *SD_File;
	FIL fil;
	FATFS fatfs;
	enum {FILE_SIZE = 8*1024 };
	u32 FileSize = FILE_SIZE;
	UINT NumBytesWritten = 0;
	UINT NumBytesRead = 0;
	u8 SourceAddress[FILE_SIZE] = {0x50};
	u8 DestinationAddress[FILE_SIZE] = {0x50};
	u32 Res = 0;

	u32 Platform = XGetPlatform_Info();
	if (Platform == XPLAT_ZYNQ_ULTRA_MP) {
		/*
		 * Since 8MB in Emulation Platform taking long time, reduced
		 * file size to 8KB.
		 */
		xil_printf("Note:%s:%d:platform is XPLAT_ZYNQ_ULTRA_MP\r\n",__FILE__,__LINE__);
		;;;
	}

	/*
	 * Register volume work area, initialize device
	 */
	Res = f_mount(&fatfs, Path, 0);
	if (Res != FR_OK) {
		xil_printf("Error:%s:%d:f_mount\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}

	/*
	 * Path - Path to logical driver, 0 - FDISK format.
	 * 0 - Cluster size is automatically determined based on Vol size.
	 */
	Res = f_mkfs(Path, 0, 0);
	if (Res != FR_OK) {
		xil_printf("Error:%s:%d:f_mkfs\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}

	/*
	 * Open file with required permissions.
	 * Here - Creating new file with read/write permissions. .
	 * To open file with write permissions, file system should not
	 * be in Read Only mode.
	 */
	SD_File = (char *)FileName;
	Res = f_open(&fil, SD_File, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
	if (Res) {
		xil_printf("Error:%s:%d:f_open\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}

	/*
	 * Pointer to beginning of file .
	 */
	Res = f_lseek(&fil, 0);
	if (Res) {
		xil_printf("Error:%s:%d:f_lseek\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}


	/*
	 * Write data to file.
	 */
	Res = f_write(&fil, (const void*)SourceAddress, FileSize,
			&NumBytesWritten);
	if (Res) {
		xil_printf("Error:%s:%d:f_write\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}

	/*
	 * Pointer to beginning of file .
	 */
	Res = f_lseek(&fil, 0);
	if (Res) {
		xil_printf("Error:%s:%d:f_lseek\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}

	/*
	 * Read data from file.
	 */
	Res = f_read(&fil, (void*)DestinationAddress, FileSize,
			&NumBytesRead);
	if (Res) {
		xil_printf("Error:%s:%d:f_read\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}

	/*
	 * Data verification
	 */
	for(int i = 0; i < FileSize; i++){
		if(SourceAddress[i] != DestinationAddress[i]){
			xil_printf("Error:%s:%d:Read and write data is inconsistent\r\n",
					__FILE__,__LINE__);
			return XST_FAILURE;
		}
	}
	xil_printf("Success:Read and write data is consistent\r\n");

	/*
	 * Close file.
	 */
	Res = f_close(&fil);
	if (Res) {
		xil_printf("Error:%s:%d:f_close\r\n",__FILE__,__LINE__);
		return XST_FAILURE;
	}
	
	return 0;
}

二、SD卡读写性能测试

一、zynq在SDK中计算某段程序的执行时间

参考文章:zynq在SDK中计算某段程序的执行时间

如何通过卡面标识区分SD卡的速度等级:https://www.cnblogs.com/pcheng/p/9156162.html
class4/class10/UHS-1/UHS-3 SD卡速度等级区别:https://www.cnblogs.com/w12n/p/6156014.html

整体速度等级如下:
ZYNQ_Standalone_SD卡读写与性能测试_第1张图片

直接可用的完整源代码片段:
void calculate_runtime(u32 Microsecond)
{
	XTime	tEnd,tCur;
	u32	tUsed;
	XTime_GetTime(&tCur);
	usleep(Microsecond);
	XTime_GetTime(&tEnd);
	tUsed = ((tEnd-tCur)*1000000)/(COUNTS_PER_SECOND);
	xil_printf("time elapsed is %d us\r\n",tUsed);
}

二、把上面代码用来测SD卡读写速度

基于前面的SD卡IO功能测试和上面的程序执行时间统计代码片段,进行有机整合就可拼接出SD卡读写性能测试,即读写速度测试。SD卡IO性能测试(Sdcard_IoPerformanceTest)完整源代码如下:

/*****************************************************************************/
/**
*
* File system example using SD driver to write to and read from an SD card
* in polled mode. This example creates a new file on an
* SD card (which is previously formatted with FATFS), write data to the file
* and reads the same data back to verify.
*
* @param	None
*
* @return	XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note		None
*
******************************************************************************/
int FfsSdPolledExample(void)
{
	FIL fil;
	FATFS fatfs;
	char FileName[32] = "Test.txt";
	char *SD_File;
	u8 DestinationAddress[10*1024];// __attribute__ ((aligned(32)));
	u8 SourceAddress[10*1024];// __attribute__ ((aligned(32)));

	FRESULT Res;
	UINT NumBytesRead;
	UINT NumBytesWritten;
	u32 BuffCnt;
	enum {FF_MAX_SS = 8*1024 };
	u32 FileSize = (8*1024);

	XTime tEnd, tCur;
	u32 tUsed;

	/*
	 * To test logical drive 0, Path should be "0:/"
	 * For logical drive 1, Path should be "1:/"
	 */
	TCHAR *Path = "0:/";

	memset(SourceAddress, 0x41, sizeof(SourceAddress));

	/*
	 * Register volume work area, initialize device
	 */
	Res = f_mount(&fatfs, Path, 0);

	if (Res != FR_OK) {
		return XST_FAILURE;
	}

	/*
	 * Path - Path to logical driver, 0 - FDISK format.
	 * 0 - Cluster size is automatically determined based on Vol size.
	 */
	Res = f_mkfs(Path, 0, 0);
	if (Res != FR_OK) {
		return XST_FAILURE;
	}

	/*
	 * Open file with required permissions.
	 * Here - Creating new file with read/write permissions. .
	 * To open file with write permissions, file system should not
	 * be in Read Only mode.
	 */
	SD_File = (char *)FileName;

	Res = f_open(&fil, SD_File, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
	if (Res) {
		return XST_FAILURE;
	}

	/*
	 * Pointer to beginning of file .
	 */
	Res = f_lseek(&fil, 0);
	if (Res) {
		return XST_FAILURE;
	}

	/*
	 * Write data to file.
	 */
	XTime_GetTime(&tCur);
	Res = f_write(&fil, (const void*)SourceAddress, FileSize,
			&NumBytesWritten);
	if (Res) {
		return XST_FAILURE;
	}
	XTime_GetTime(&tEnd);
	tUsed = ((tEnd - tCur) * 1000000) / (COUNTS_PER_SECOND);
	xil_printf("%s: Write Speed = %d Bytes/s\r\n",
			__func__, (u32) ((16 * 1000 * 1000 * 1.0) / (tUsed * 1.0)));

	/*
	 * Pointer to beginning of file .
	 */
	Res = f_lseek(&fil, 0);
	if (Res) {
		return XST_FAILURE;
	}

	/*
	 * Read data from file.
	 */
	XTime_GetTime(&tCur);
	Res = f_read(&fil, (void*)DestinationAddress, FileSize,
			&NumBytesRead);
	if (Res) {
		return XST_FAILURE;
	}
	XTime_GetTime(&tEnd);
	tUsed = ((tEnd - tCur) * 1000000) / (COUNTS_PER_SECOND);
	xil_printf("%s: Read Speed = %d Bytes/s\r\n",
			__func__, (u32) ((16 * 1000 * 1000 * 1.0) / (tUsed * 1.0)));

	/*
	 * Data verification
	 */
	for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
		if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt]){
			xil_printf("Error:%d:SourceAddress[BuffCnt] != DestinationAddress[BuffCnt]\r\n",__LINE__);
			return XST_FAILURE;
		}
	}

	xil_printf("DestinationAddress = ");
	for (int i=0; i<16; i++) {
		xil_printf("%02x ", DestinationAddress[i]);
	}
	xil_printf("\r\n");

	/*
	 * Close file.
	 */
	Res = f_close(&fil);
	if (Res) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}

运行效果截图:
ZYNQ_Standalone_SD卡读写与性能测试_第2张图片

你可能感兴趣的:(ZYNQ_Standalone_SD卡读写与性能测试)