📄 rtfsdem.c
字号:
/*
*****************************************************************************
REGRESS.C - RTFS Excerciser
This program performs two functions. It calls virtually all of the API
routines plus it stress tests the system for driver bugs and memory leaks.
It works by repeatedly opening a disk and then entering an inner loop
which creates a directory and then creates N subdirectories below that.
Finally the inner loop creates NUSERFILES files, writes to them, reads from
them, seeks, truncates, closes, renames and deletes them. Along the way
it check set current working directory and get working directory. Finally
the inner loop deletes all of the subdirectories it created and compares
the current disk free space to the free space before it started. These
should be the same. After the inner loop completes the outer loop closes
the drive and then reopens it to continue the test.
There are a few functions that do not get tested, they are:
pc_gfirst
pc_gnext
pc_gdone
pc_abort
Not all modes of po_open and po_lseek are tested either. Nor does it
test your port in multitasking mode. You may modify this program and
run it in multiple threads if you wish.
The following parameters may be changed:
USEPRINTF - Set this to zero to run completely quietly. If this
is done you should set a break point in regress_error()
to catch errors.
test_drive[] - The drive where the test will occur.
test_dir[] - The directory where the test will occur
INNERLOOP - The Number of times we run the inner loop
OUTERLOOP - The Number of times we run the inner loop
SUBDIRDEPTH - The depth of the tested subdirectories.
NSUBDIRS - The number of subdirectories below test_dir. Must
be less then 26. Each of these directories will
have SUBDIRDEPTH subdirectories below it.
To run the program type REGRESS.
*****************************************************************************/
#include <pcdisk.h>
#define INCLUDE_REGRESS 1
#define RGE_FLTDRIVE 3
#define RGE_FREEERROR 4
#define RGE_LEAKERROR 5
#define RGE_MKDIR 6
#define RGE_SCWD 7
#define RGE_MKDIRERR 9
#define RGE_PWD 10
#define RGE_RMDIR 11
#define RGE_DSKCLOSE 12
#define RGE_OPEN 13
#define RGE_SEEK 14
#define RGE_WRITE 15
#define RGE_READ 16
#define RGE_TRUNC 17
#define RGE_FLUSH 18
#define RGE_CLOSE 19
#define RGE_UNLINK 20
#define RGE_MV 21
/* Porting issues */
/* Set this to zero if you don't have tm_printf */
#define USEPRINTF 1
/* Set this to 1 if you have tm_printf and want to see more */
#define VERBOSE 1
char test_drive[] = "C:"; /* The drive where the test will occur */
#define NLONGS 512 /* Longs to write in file write test */
#define SUBDIRDEPTH 10 /* Depth of subdirectories */
#define NSUBDIRS 26 /* <= 26 Number of subdirs at below RTFSTEST */
#define NTESTFILES NUSERFILES
dword test_rtfs_buf[NLONGS]; /* Used in the file write test */
#if (VFAT)
char test_dir[] = "RTFS_Test_Directory"; /* Test will occur in this Directory */
#else
char test_dir[] = "RTFSTEST"; /* Test will occur in this Directory */
#endif
#define INNERLOOP 1 /* Number of times we run the tes suite
between open and close. */
#define OUTERLOOP 1 /* Number of times we open the drive
run the inner loop and close the drive */
int which_demo_running;
#if (VERBOSE)
#define DIAG_OUT(X,Y) tm_printf_3("%s %s\n", X, Y);
#else
#define DIAG_OUT(X,Y)
#endif
void do_test(void);
char get_test(void);
void do_file_test(void);
void do_rm(char *buffer, int level);
void regress_error(int error);
void regress_test(void);
void tst_shell(void);
// ********************************************************************
// THIS TASK IS THE MAIN PROGRAM
// ********************************************************************
void app_entry(void);
void main()
{
__rt_lib_init();
#define rSYSCFG (*(volatile unsigned *)0x1c00000)
rSYSCFG=0; // disable cache
Port_Init();
Uart_Init(0,115200);
Led_Display(0xf);
Delay(0);
app_entry();
}
void app_entry(void) /* __fn__ */
{
char option;
/* Initialize ertfs */
if (!pc_ertfs_init())
tm_printf("pc_ertfs_init failed");
#if (INCLUDE_REGRESS)
do
{
option = get_test();
switch (option)
{
case 'R':
regress_test();
break;
case 'S':
tst_shell();
break;
case 'Q':
case 'q':
aos_exit();
break;
default:
DIAG_OUT("\n","Invalid Choice");
} // end of switch
} while ( (option != 'Q') && (option != 'q') );
#else
tst_shell();
#endif
}
#if (INCLUDE_REGRESS)
void regress_test(void)
{
int inner_loop;
int outer_loop;
long nfree, nfree_too;
dword blocks_total, blocks_free;
char home[512];
for (outer_loop = 0; outer_loop < OUTERLOOP; outer_loop++)
{
#if USEPRINTF
#if (!VERBOSE)
tm_printf_2("\n %d:", outer_loop);
#endif
#endif
if (!pc_set_default_drive(test_drive))
regress_error(RGE_FLTDRIVE);
/* Make the top level subdirs and subdirs down to layer SUBDIRDEPTH */
home[0] = '\0';
tc_strcat(home, test_drive);
tc_strcat(home, "\\");
if (!pc_set_cwd(home))
regress_error(RGE_SCWD);
/* If test_dir is not there, deltree will just fail */
pc_deltree(test_dir);
for (inner_loop = 0; inner_loop < INNERLOOP; inner_loop++)
{
#if USEPRINTF
#if (!VERBOSE)
tm_printf("+");
#endif
#endif
/* Check freespace */
nfree = pc_free(test_drive, &blocks_total, &blocks_free);
if (!nfree)
regress_error(RGE_FREEERROR);
do_test(); /* Call the main test routine */
/* Check freespace again. They should match */
nfree_too = pc_free(test_drive, &blocks_total, &blocks_free);
if (!nfree_too)
regress_error(RGE_FREEERROR);
//if (nfree_too != nfree)
// regress_error(RGE_LEAKERROR);
}
}
}
/*
Make the test directory
loop
Step into the test directory
Make another subdiretory
loop
Make N deep subdirectories
Change into each
compare what we know is the directory with
what pc_pwd returns.
End loop
In the lowest level directory
loop
create a file
open it with multiple file descriptors
loop
write to it on multiple FDs
loop
seek and read on multiple FDs. Testing values
flush
truncate
close
end loop
loop
rename
delete
end loop
now delete all of the subdirectories
*/
char get_test(void)
{
char option;
char io_buf[10];
char drive;
int driveno;
while(1)
{
tm_printf("Select test to run where:\n");
tm_printf("S) RTFS Test Shell\n");
tm_printf("R) Regression Test only\n");
tm_printf("Q) Quit\n");
tm_printf("Enter choice: ");
tm_gets(io_buf);
option = io_buf[0];
if (option == 'R')
{
tm_printf("Select Drive (A, B, C, ..):\n");
tm_printf("Enter choice: ");
tm_gets(io_buf);
drive = io_buf[0];
driveno = (int) (drive - 'A');
if (driveno < 0 || driveno >= NDRIVES)
{
tm_printf("Invalid Drive number\n");
}
else
{
test_drive[0] = drive;
break;
}
}
else
break;
}
return(option);
}
void do_test() /* __fn__ */
{
int i;
int j;
#if (VFAT)
char buffer[2560];
char home[640];
char buffer3[2560];
#else
char buffer[1320];
char home[320];
char buffer3[1320];
#endif
char c;
char *p;
char *p2;
DIAG_OUT("Creating Subdirectory", test_dir)
if (!pc_mkdir(test_dir))
regress_error(RGE_MKDIR);
if (!pc_set_cwd(test_dir))
regress_error(RGE_SCWD);
/* Make the top level subdirs and subdirs down to layer SUBDIRDEPTH */
home[0] = '\0';
tc_strcat(home, test_drive);
tc_strcat(home, "\\");
tc_strcat(home, test_dir);
for (i = 0; i < NSUBDIRS; i++)
{
if (!pc_set_cwd(home))
regress_error(RGE_SCWD);
/* Make the top level subdirs */
buffer[0] = '\0'; /* These two lines are strcpy() */
#if (VFAT)
tc_strcat(buffer, "Subdirectory_?");
#else
tc_strcat(buffer, "SUB_?");
#endif
c = 'A';
c = (char) (c + i);
#if (VFAT)
buffer[13] = c;
#else
buffer[4] = c;
#endif
DIAG_OUT(" Creating Subdirectory", buffer)
if (!pc_mkdir(buffer))
regress_error(RGE_MKDIR);
for (j = 0; j < SUBDIRDEPTH; j++)
{
if (!pc_set_cwd(home))
regress_error(RGE_SCWD);
#if (VFAT)
tc_strcat(buffer,"\\Subdirectory");
#else
tc_strcat(buffer,"\\SUBDIR");
#endif
DIAG_OUT(" Creating Subdirectory", buffer)
if (!pc_mkdir(buffer))
regress_error(RGE_MKDIR);
/* Create a dir. We know this will fail. Force error recovery */
if (pc_mkdir(buffer))
regress_error(RGE_MKDIRERR);
/* Go into the new directory */
if (!pc_set_cwd(buffer))
regress_error(RGE_SCWD);
/* Get the dir string */
if (!pc_pwd(test_drive, buffer3))
regress_error(RGE_PWD);
DIAG_OUT("PWD Returns", buffer3)
/* Funky. skip D:\RTFSTEST\ and then compare pwd with what we
set. Should match */
p = buffer3;
p2 = home;
p2 += 2;
while (*p2) { p++; p2++; };
p++;
if (tc_strcmp(p, buffer) != 0)
regress_error(RGE_PWD);
}
}
/* Do the file test */
do_file_test();
}
/* Delete a subdir at level */
void do_rm(char *buffer, int level) /*__fn__*/
{
int i;
for (i = 0; i < level; i++)
#if (VFAT)
tc_strcat(buffer,"\\Subdirectory");
#else
tc_strcat(buffer,"\\SUBDIR");
#endif
DIAG_OUT(" Removing Directory", buffer)
if (!pc_rmdir(buffer))
regress_error(RGE_RMDIR);
}
/* Test file manipulation routines */
void do_file_test() /*__fn__*/
{
PCFD fdarray[NTESTFILES];
int i;
int j;
dword index;
char buffer[512];
char c;
#if USEPRINTF
#if (!VERBOSE)
tm_printf("-");
#endif
#endif
DIAG_OUT(" Performing File io test", " ")
for (i = 0; i < NTESTFILES;i++)
{
/* Make the filenames */
buffer[0] = '\0'; /* These two lines are strcpy() */
#if (VFAT)
tc_strcat(buffer, "Long File Name_?");
#else
tc_strcat(buffer, "FILE_?");
#endif
c = 'A';
c = (char) (c + i);
#if (VFAT)
buffer[15] = c;
#else
buffer[5] = c;
#endif
fdarray[i] = po_open(buffer, PO_RDWR|PO_CREAT|PO_EXCL, PS_IWRITE|PS_IREAD);
if (fdarray[i] < 0)
regress_error(RGE_OPEN);
}
/* Write into the file using all file descriptors */
for (i = 0; i < NTESTFILES;i++)
{
index = 0;
if (po_lseek(fdarray[i], 0L, PSEEK_SET) == ~0L)
regress_error(RGE_SEEK);
for (j = 0; j < NLONGS; j++)
test_rtfs_buf[j] = index++;
if (po_write(fdarray[i], (byte *) test_rtfs_buf, (NLONGS*4)) != (NLONGS*4))
regress_error(RGE_WRITE);
}
/* Read file using all fds */
for (i = 0; i < NTESTFILES;i++)
{
index = 0;
if (po_lseek(fdarray[i], 0, PSEEK_SET) != 0)
regress_error(RGE_SEEK);
if (po_read(fdarray[i], (byte *) test_rtfs_buf, (NLONGS*4)) != (NLONGS*4))
regress_error(RGE_READ);
for (j = 0; j < NLONGS; j++)
{
if (test_rtfs_buf[j] != index++)
regress_error(RGE_READ);
}
}
/* Close all secondary files */
for (i = 0; i < NTESTFILES;i++)
{
if (!po_flush(fdarray[i]))
regress_error(RGE_FLUSH);
if (po_close(fdarray[i]) != 0)
regress_error(RGE_CLOSE);
}
}
void regress_error(int error) /*__fn__*/
{
#if USEPRINTF
tm_printf_2("Error number : %d\n", error);
#endif
aos_exit();
}
#endif /* #if (INCLUDE_REGRESS) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -