/* SD_QA.c: Quality Assurence program. Compiler: BC++ 3.1, Turbo C++ 1.01 (3.01) Compile mode: large Project: SD_QA.c ..\..\lib\upac5000.lib ..\lib\sd_vnnn.lib Hardware: uPAC-5000 [May 13, 2014] by Liam */ #include #include #include #include "..\..\lib\uPAC5000.h" #include "..\lib\microSD.h" #define _Test_Length 1000 #define _Test_Loop 500 char far sFileData[_Test_Length], sStandardData[_Test_Length]; void Test_Performance(void) { int iFileHandle; int i, iRet; long lLastTimeTicks, lTimeDiff, lSize; iFileHandle=pc_open("A:\Perform.txt", (word)(PO_WRONLY|PO_CREATE|PO_TRUNC), (word)(PS_IWRITE|PS_IREAD)); if(iFileHandle<0) { Print("pc_open(): A:Perform.txt failed! Error:%d\n", iFileHandle); Print("\nTest result=failed!\n"); return; } Print("pc_open() : A:Perform.txt ok, File handle=%d.....\n", iFileHandle); lLastTimeTicks=GetTimeTicks(); for(i=0; i<10000; i++) { pc_seek(iFileHandle, 10L, PSEEK_SET); } lTimeDiff=GetTimeTicks()-lLastTimeTicks; pc_close(iFileHandle); Print("pc_lseek takes %7.3f ms\n", (float)lTimeDiff/10000.0); lLastTimeTicks=GetTimeTicks(); for(i=0; i<100; i++) { iFileHandle=pc_open("A:\Perform.txt", (word)(PO_WRONLY|PO_CREATE), (word)(PS_IWRITE|PS_IREAD)); pc_close(iFileHandle); } lTimeDiff=GetTimeTicks()-lLastTimeTicks; Print("pc_open & pc_close takes %7.3f ms\n", (float)lTimeDiff/100.0); lLastTimeTicks=GetTimeTicks(); for(i=0; i<1; i++) { if((lSize=pc_get_totalSize_KB())==-1L) { Print("pc_get_totalSize_KB error\n"); break; } } lTimeDiff=GetTimeTicks()-lLastTimeTicks; Print("pc_get_totalSize_KB=%ld takes %7.3f ms\n", lSize, (float)lTimeDiff/1.0); lLastTimeTicks=GetTimeTicks(); for(i=0; i<1; i++) { if((lSize=pc_get_freeSize_KB())==-1L) { Print("pc_get_freeSize_KB error\n"); break; } } lTimeDiff=GetTimeTicks()-lLastTimeTicks; Print("pc_get_freeSize_KB=%ld takes %7.3f ms\n", lSize, (float)lTimeDiff/1.0); lLastTimeTicks=GetTimeTicks(); for(i=0; i<1; i++) { if((lSize=pc_get_usedSize_KB())==-1L) { Print("pc_get_usedSize_KB error\n"); break; } } lTimeDiff=GetTimeTicks()-lLastTimeTicks; Print("pc_get_usedSize_KB=%ld takes %7.3f ms\n", lSize, (float)lTimeDiff/1.0); } void Test_Write_Speed(void) { /* Test item: Writing speed (calls WriteFile) Description: Create a file "Speed.txt". */ int iFileHandle,i; int iRet,iFaile=0; long lLastTimeTicks,lTimeDiff; iFileHandle=pc_open("A:\Speed.txt", (word)(PO_WRONLY|PO_CREATE), (word)(PS_IWRITE|PS_IREAD)); if(iFileHandle>0) { Print("pc_open(): A:Speed.txt failed! Error:%d\n", iFileHandle); Print("\n\rTest result=failed!\n"); return; } Print("pc_open() : A:Speed.txt ok, File handle=%d.....\n", iFileHandle); //Prepare data: 0,1,2,...,8,9,0,1,.... for(i=0; i<_Test_Length; i++) sFileData[i]='0'+i%10; lLastTimeTicks=GetTimeTicks(); for(i=0; i<_Test_Loop; i++) { iRet=pc_write(iFileHandle, sFileData, _Test_Length); if(iRet!=_Test_Length) { Print("Loop%d Write data failed! Error code=%d\n", i, iRet); iFaile=1; break; } Putch('.'); } lTimeDiff=GetTimeTicks()-lLastTimeTicks; iRet=pc_close(iFileHandle); if(iRet==NoError) { Print("\n\pc_close(): A:Speed.txt ok.\n"); if(iFaile==0) { Print("\n\rTest result=ok. WriteFile %ld Bytes takes %ld ms (%.1fKB/sec)\n", (long)_Test_Loop*(long)_Test_Length, lTimeDiff, (float)_Test_Loop*(float)_Test_Length/lTimeDiff); } else Print("\n\rTest result=failed!\n"); } else { Print("\n\pc_close(): A:Speed.txt failed! Error code=%d\n", iRet); Print("\n\rTest result=failed!\n"); } } void Test_Append(void) { /* Test item: Append speed (calls pc_write) Description: Create a file "Append.txt". */ int iFileHandle,i; int iRet,iFaile=0; iFileHandle=pc_open("A:\Append.txt",(word)(PO_WRONLY|PO_APPEND|PO_CREATE),(word)(PS_IWRITE|PS_IREAD)); if(iFileHandle>=0) { Print("pc_open() : A:Append.txt ok, File handle=%d.....\r\n", iFileHandle); //Prepare data: 0,1,2,...,8,9,0,1,.... for(i=0; i<_Test_Length; i++) sFileData[i]='0'+i%10; for(i=0; i<10; i++) { iRet=pc_write(iFileHandle,sFileData,_Test_Length); if(iRet<=0) { Print("Loop%d Write data failed! Error code=%d\r\n", i, iRet); iFaile=1; break; } else Print("Append data to append.txt ok.\n"); //Print("Append data to append.txt ok.(%ld)\n\r",pc_tell(iFileHandle)); } iRet=pc_close(iFileHandle); if(iRet==NoError) { Print("\n\pc_close(): A:Append.txt ok.\n"); if(iFaile==0) { Print("\n\rAppend to append.txt ok.\n"); } else Print("\n\rTest result=failed!\n"); } else { Print("\n\pc_close(): A:Append.txt failed! Error code=%d\n", iRet); Print("\nTest result=failed!\n"); } } else { Print("pc_open(): A:Append.txt failed! Error:%d\n", iFileHandle); Print("\n\rTest result=failed!\n"); } } void Test_Read_Speed(void) { /* Test item: Reading speed (calls ReadFile) Description: Read data from A:Speed.txt and check its correction. "Speed.txt" should be created advanced by TestWritingSpeed(). */ int iFileHandle; int i, j, iRet,iFaile=0; long lLastTimeTicks, lTimeDiff; //Prepare standard data: 0,1,2,...,8,9,0,1,.... for(i=0; i<_Test_Length; i++) sStandardData[i]='0'+i%10; iFileHandle=pc_open("A:\Speed.txt",(word)(PO_RDONLY),(word)PS_IREAD); if(iFileHandle>=0) { Print("OpenFile() : A:Speed.txt ok, File handle=%d.....\r\n", iFileHandle); lLastTimeTicks=GetTimeTicks(); for(i=0; i<_Test_Loop; i++) { memset(sFileData, 0, _Test_Length); iRet=pc_read(iFileHandle,sFileData,_Test_Length); if(iRet!=_Test_Length) { Print("Loop%d Read data failed! Error code=%u\n",i, iRet); iFaile=1; iRet=pc_close(iFileHandle); break; } else if(memcmp(sFileData,sStandardData,_Test_Length)!=NoError) { Print("Loop%d, Compare data failed! Error code=%u\n",i, iRet); Print("Standard :File\n"); for(j=0; j<_Test_Length; j++) { if(sStandardData[j]!=sFileData[j]) { Print("{Data[%d] %c:%c [%02d]:[%02d]} ", j, sStandardData[j], sFileData[j], sStandardData[j], sFileData[j]); break; } } Print("\n"); iRet=pc_close(iFileHandle); iFaile=1; break; } else Print("."); } if(i==_Test_Loop) { lTimeDiff=GetTimeTicks()-lLastTimeTicks; iRet=pc_close(iFileHandle); if(iRet==NoError) { Print("\n\rCloseFile(): A:Speed.txt ok.\n\r"); if(iFaile==0) { Print("\n\rTest result=ok. ReadFile %ld Bytes takes %ldms(%5.1fKB/Sec)\n\r", (long)_Test_Loop*(long)_Test_Length, lTimeDiff, (float)_Test_Loop*(float)_Test_Length/lTimeDiff); } else Print("\n\rTest result=failed!\n"); } else { Print("\n\pc_close(): A:Speed.txt failed! Error code=%d\n", iRet); Print("\n\rTest result=failed!\n"); } } else { Print("\n\rTest result=failed!\n"); } } else { Print("pc_open(): A:Speed.txt failed! Error:%d\n", iFileHandle); Print("\n\rTest result=failed!\n"); } } void Test_Seek_Tell(void) { /* Test item: Seek & Tell Description: Create a file "SeekTell.txt". Call Tell, Seek, then read data to check whether Tell and Seek work. */ int iFileHandle,i,j,iMode; int iRet; long lPosition, lOffset; iFileHandle=pc_open("SeekTell.txt", (word)(PO_WRONLY|PO_CREATE|PO_TRUNC), (word)(PS_IWRITE|PS_IREAD)); if(iFileHandle<0) { Print("pc_open SeekTell.txt failed! Error:%d\n", iFileHandle); Print("\nTest result=failed!\n"); return; } Print("pc_open SeekTell.txt ok, File handle=%d.....\n", iFileHandle); //Prepare data: 0,1,2,...,8,9,0,1,.... for(i=0; i<_Test_Length; i++) sFileData[i]='0'+i%10; iRet=pc_write(iFileHandle, sFileData, _Test_Length); if(iRet==_Test_Length) { Print("Write data ok.\n"); } else { Print("Write data failed! Error code=%d\n", iRet); } iRet=pc_close(iFileHandle); if(iRet==NoError) { Print("\n\rpc_close SeekTell.txt ok.\n"); } else { Print("\n\pc_close SeekTell.txt failed! Error code=%d\n", iRet); Print("\nTest result=failed!\n"); return; } for(i=0; i<_Test_Length; i++) sStandardData[i]='0'+i%10; iFileHandle=pc_open("SeekTell.txt", (word)(PO_RDONLY), (word)(PS_IREAD)); if(iFileHandle<0) { Print("pc_open SeekTell.txt failed! Error:%d\n", iFileHandle); Print("\nTest result=failed!\n"); return; } Print("pc_open SeekTell.txt ok, File handle=%d.....\n", iFileHandle); for(iMode=0; iMode<3; iMode++) { if(iMode==PSEEK_SET) Puts("\nPSEEK_SET mode:\n"); if(iMode==PSEEK_CUR) Puts("\nPSEEK_CUR mode:\n"); if(iMode==PSEEK_END) Puts("\nPSEEK_END mode:\n"); for(i=0; i<10; i++) { memset(sFileData, 0, 10); lOffset=i*(_Test_Length/10); if(iMode==PSEEK_SET) { pc_seek(iFileHandle, lOffset, PSEEK_SET); } else if(iMode==PSEEK_CUR) { pc_seek(iFileHandle, lOffset, PSEEK_SET); pc_seek(iFileHandle, 10, PSEEK_CUR); lOffset+=10; } else if(iMode==PSEEK_END) { pc_seek(iFileHandle, 0-lOffset-10L, PSEEK_END); lOffset=_Test_Length-lOffset-10L; } lPosition=pc_tell(iFileHandle); if(lPosition!=lOffset) { Print("Tell error, Tell=%ld, lOffset=%ld\n", lPosition, lOffset); Print("\nTest result=failed!\n"); break; } iRet=pc_read(iFileHandle, sFileData, 10); if(iRet<=0) { Print("Read data failed! Error code=%u\n", iRet); break; } else if(memcmp(sFileData,sStandardData+lOffset,10)!=NoError) { Print("Compare data failed! Error code=%u\n", iRet); Print("Standard :File\n"); for(j=0; j<10; j++) { if(sStandardData[lOffset+j]!=sFileData[j]) Print("{Data[%ld] %c:%c [%02d]:[%02d]} ", lOffset+j, sStandardData[lOffset+j], sFileData[j], sStandardData[lOffset+j], sFileData[j]); Delay(5); } Putch('\n'); break; } else { Print("%05ld ok. ",lOffset); //Compare data ok. if((i+1)%5==0) Putch('\n'); } } } iRet=pc_close(iFileHandle); if(iRet==NoError) { Print("\npc_close SeekTell.txt ok.\n"); Print("\nTest result=ok!\n"); } else { Print("\npc_close SeekTell.txt failed! Error code=%d\n", iRet); Print("\nTest result=failed!\n"); } } void Test_Openfile(void) { /* Test item: 10 files can be opened at the same time to allow sharing the file for read Description: 1. Create 25 files in the micro SD Steps:Create 1 file ==> give data ==> close it, repeat to create 25 files. 2. Open and read the 25 files to check whether its data is correct. Steps:Open 25 files ==> read and compare data for opend files ==> Close opend files. Each disk can open 25 files at the same time, On step2, only the first 10 files of each disk can be opend. The rest 15 files should return error code when opening. */ int iFileHandle[30], i, iLength; int iRet, iFaile=0; char sFileName[16], sData[32], sStandardData[32]; Print("Creating files...\n"); for(i=0; i<25; i++) { iFaile=0; sprintf(sFileName, "Test%02d.txt", i); iFileHandle[i]=pc_open(sFileName, (word)(PO_WRONLY|PO_CREATE|PO_TRUNC), (word)(PS_IWRITE|PS_IREAD)); if(iFileHandle[i]>=0) { sprintf(sData,"test data for %s", sFileName); iRet=pc_write(iFileHandle[i], sData, strlen(sData)); if(iRet<=0) { iFaile=1; Print("pc_write %s error, FileHandle=%d, error=%d\n", sFileName, iFileHandle[i], pc_get_errno()); } iRet=pc_close(iFileHandle[i]); if(iRet!=NoError) { iFaile=1; Print("pc_close %s error\n", sFileName); } } else { Print("pc_open %s error\n", sFileName); iFaile=1; } if(iFaile==0) Print("%s ok. ", sFileName); if((i+1)%5==0) Putch('\n'); } Putch('\n'); Print("\nReading files...\n"); for(i=0; i<25; i++) { sprintf(sFileName, "Test%02d.txt", i); iFileHandle[i]=pc_open(sFileName, (word)(PO_RDONLY), (word)PS_IREAD); if(iFileHandle[i]>=0) { sprintf(sStandardData, "test data for %s", sFileName); iLength=strlen(sStandardData); memset(sData, 0, sizeof(sData)); iRet=pc_read(iFileHandle[i], sData, iLength); if(iRet==iLength) { if(memcmp(sData, sStandardData, iLength)!=NoError) { Print("%s error!\n", sFileName); iFaile=1; } else Print("%s ok. ", sFileName); } else { Print("%s Length error\n", sFileName); iFaile=1; } } else { //The first 6 files should be opend ok. if(i<6) { Print("Open %s error(%d)\n", sFileName, iFileHandle[i]); iFaile=1; } else Putch('.'); } if((i+1)%5==0) Putch('\n'); } Putch('\n'); Print("Closing files ...\n"); for(i=0; i<25; i++) { if(iFileHandle[i]>=0) { iRet=pc_close(iFileHandle[i]); sprintf(sFileName, "Test%02d.txt", i); if(iRet==NoError) { Print("%s ok. ", sFileName); } else { Print("\nFailed to close %s file (%d)\n", sFileName, iRet); iFaile=1; } } else Print("."); if((i+1)%5==0) Putch('\n'); } Putch('\n'); if(iFaile) Print("\nTest result=failed!\n"); else Print("\nTest result=ok.\n"); } int Test_OpenMode(void) { /* Test item: Open mode, write|read|append|create|trunc|read only|write only|read and write Description: */ int iFileHandle[2]; int iRet; //Test 1. if the file is not exist, pc_open returns the FSERR_NOENT error iRet=pc_del("OpenMode.txt"); if(iRet) { Print("OpenMode.txt file has been deleted using pc_del function\n"); } iFileHandle[0]=pc_open("OpenMode.txt", (word)(PO_WRONLY), (word)(PS_IWRITE|PS_IREAD)); if(iFileHandle[0]>=0) { Print("pc_open should return error code\n"); pc_close(iFileHandle[0]); return 0; } else { iRet=pc_get_errno(); if(iRet!=FSERR_NOENT) { Print("pc_open error code =%d\n", iRet); return 0; } } Print("test 1. ok\n"); //Test 2. the same file can be opened more than once at the same time iFileHandle[0]=pc_open("OpenMode.txt", (word)(PO_RDWR|PO_CREATE), (word)(PS_IWRITE|PS_IREAD)); if(iFileHandle[0]<0) { Print("pc_open error code =%d\n", pc_get_errno()); return 0; } iFileHandle[1]=pc_open("A:OpenMode.txt", (word)(PO_RDWR|PO_CREATE), (word)(PS_IWRITE|PS_IREAD)); if(iFileHandle[1]<0) { iRet=pc_get_errno(); switch(iRet) { case FSERR_ACCESS: Print("FSERR_ACCESS\n"); break; case FSERR_NOENT: Print("FSERR_NOENT\n"); break; } Print("pc_open one file twice failed.\n"); Print("FileHandle[0]=%d, FileHandle[1]=%d\n", iFileHandle[0], iFileHandle[1]); pc_close(iFileHandle[0]); return 0; } pc_write(iFileHandle[0], "1234567890", 10); pc_write(iFileHandle[1], "abcde", 5); pc_close(iFileHandle[0]); pc_close(iFileHandle[1]); Print("test 2. ok\n"); return 1; } void Test_CheckSize(void) { unsigned long lSize; if((lSize=pc_get_freeSize_KB())==-1L) Print("pc_get_freeSize_KB error\n"); else Print(" Free Size= %7lu KB\n", lSize); if((lSize=pc_get_usedSize_KB())==-1L) Print("pc_get_usedSize_KB error\n"); else Print(" Used Size= %7ld KB\n", lSize); if((lSize=pc_get_totalSize_KB())==-1L) Print("pc_get_totalSize_KB error\n"); else Print("Total Size= %7ld KB\n", lSize); } void format_status(void) { Putch('.'); } void format_SDcard(void) { Print("Formatting "); Print(" [%s]\n", pc_format(format_status)==1?"Complete":"Fail"); } void main(void) { int iAction, iRet, iVer; char cData; char LibDate[16]; unsigned char *SD_QA_Date=__DATE__; InitLib(); Print("=============================\n"); if(pc_init()) { Print("Initialize ok.\n"); Print("[Disk Size=%ld KB]\n", pc_get_totalSize_KB()); } else { Print("Initialize failed\n"); iRet=pc_get_errno(); switch(iRet) { case PCERR_BAD_FORMAT: Print("Error 01: format is not FAT\n"); break; case PCERR_NO_CARD: Print("Error 02: no microSD card\n"); break; default: Print("Error %02d: unknow error\n", iRet); } } Print("=============================\n\n"); iVer=pc_getLibVer(); pc_getLibDate((unsigned char *) &LibDate); Print("==============================================\n"); Print(" Quality Assurence Program for microSD\n\n"); Print(" SD_V%03X.Lib built@[%s]\n", iVer, LibDate); Print(" SD_QA.exe built@[%s]\n", SD_QA_Date); Print("==============================================\n"); for(;;) { Print("\n"); Print("0) Quit\n"); Print("1) WriteFile Speed\n"); Print("2) ReadFile Speed\n"); Print("3) Performance Test\n"); Print("4) Append\n"); Print("5) Open mode\n"); Print("6) Open 10 file handles\n"); Print("7) Tell & Seek\n"); Print("8) Check Size\n"); Print("9) Format microSD Card\n"); Print("Please Select(0~9): "); Scanf("%d", &iAction); if(iAction==0) break; Print("\n"); if(iAction==1) Test_Write_Speed(); if(iAction==2) Test_Read_Speed(); if(iAction==3) Test_Performance(); if(iAction==4) Test_Append(); if(iAction==5) Test_OpenMode(); if(iAction==6) Test_Openfile(); if(iAction==7) Test_Seek_Tell(); if(iAction==8) Test_CheckSize(); if(iAction==9) format_SDcard(); Print("\n\nPress any key to continue...\n"); Getch(); } }