📄 tffs.c
字号:
/******************************************************************************
* Flash File System (ffs)
* Idea, design and coding by Mads Meisner-Jensen, mmj@ti.com
*
* ffs test scaffold/framework
*
* $Id: tffs.c 1.12.1.1.1.20 Fri, 19 Dec 2003 12:00:13 +0100 tsj $
*
******************************************************************************/
#ifndef TARGET
#include "ffs.cfg"
#endif
#include "ffs/ffs_api.h"
#include "ffs/board/core.h"
#include "ffs/board/drv.h"
#include "ffs/board/tffs.h"
#include "ffs/board/tdata.h"
#include "ffs/board/tmffs.h"
#include "ffs/board/ffstrace.h"
#if (TARGET == 1)
#include "ffs/board/task.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
/******************************************************************************
* Prototypes and Globals
******************************************************************************/
struct dir_s dir;
struct stat_s tstat;
struct xstat_s txstat;
int error;
#if (TARGET == 1)
int smallbuf_size = 512;
int bigbuf_size = 65536;
#else
int smallbuf_size = 1024;
int bigbuf_size = 1024*1024*8;
#endif
char *smallbuf = 0;
char *bigbuf = 0;
/******************************************************************************
* Globals and Main
******************************************************************************/
extern struct testcase_s testcase[];
struct test_s {
char *name; // name of currently executing test case
int numcases; // number of test cases run so far
int numcalls; // total number of ffs function calls so far
int numfails; // total number of failed test cases
int keepgoing; // keep going when a test case fails
} test;
struct ffs_params_s param;
/******************************************************************************
* Main Functions
******************************************************************************/
effs_t ffs_initialize(void);
effs_t ffs_exit(void);
// Each test case returns zero on success, non-zero on failure.
// test_execute() decides whether to continue with remaining test cases or
// not.
#if (TARGET == 0)
void test_listall(void)
{
struct testcase_s *p;
printf("Test Cases:\n");
for (p = testcase; p->name != 0; p++) {
printf("%8s: %s\n", p->name, p->comment);
}
}
#endif
// <tests> is a comma-separated string of names of the test cases to
// run. Return number of test cases that failed. This is typically only 1,
// unless arg_keepgoing is set in which case it can be several.
int test_run(char *tests)
{
struct testcase_s *ptc;
int i, failed, tparams[FFS_TESTCASE_PARAMS_MAX];
struct this_test_s this;
char *pname, *testsnew;
failed = 0;
while (*tests != 0 && (failed == 0 || test.keepgoing))
{
// Make local copy of test case name. We have to make local copies
// because we can be recursively called
pname = this.name;
while (isalpha(*tests) && *tests != 0 && *tests != ';')
*pname++ = *tests++;
*pname = 0;
// Reset test case parameter(s)
for (i = 0; i < FFS_TESTCASE_PARAMS_MAX; i++)
tparams[i] = 0;
// Collect parameter(s) for test case
i = 0;
while (isdigit(*tests)) {
tparams[i] = strtol(tests, &testsnew, 0);
if (tests == testsnew)
break;
tests = testsnew;
if (*tests == ',')
tests++;
i++;
if (i > FFS_TESTCASE_PARAMS_MAX) {
ttw(ttr(TTrTest, "TEST %s has TOO MANY PARAMS" NL, this.name));
tw(tr(TR_FUNC, TrTest, "TEST %s TOO MANY PARAMS\n", this.name));
return 1;
}
}
if (*tests == ';')
tests++;
// Lookup the test name in the array of test cases
for (ptc = testcase; ptc->name != 0; ptc++) {
if (strcmp(this.name, ptc->name) == 0)
break;
}
if (ptc->name == 0) {
ttw(ttr(TTrTest, "TEST %s UNKNOWN" NL, this.name));
tw(tr(TR_FUNC, TrTest, "TEST %s UNKNOWN\n", this.name));
return 1;
}
this.numcalls = test.numcalls;
test_begin(this.name, tparams);
i = ptc->function(tparams[0], tparams[1]);
if (i != 0) {
failed++;
test_error(&this, test.numcalls);
}
test_end(&this, test.numcalls);
}
return failed;
}
// Overall test initialization. Read static ffs params with ffs_query()
void test_init(int keepgoing)
{
test.numcases = 0;
test.numcalls = 0;
test.numfails = 0;
test.keepgoing = keepgoing;
memset(¶m, 0, sizeof(struct ffs_params_s));
if (smallbuf == 0) {
#if (TARGET == 1)
smallbuf = (char*)tffs_malloc(smallbuf_size);
#else
smallbuf = malloc(smallbuf_size);
#endif
tw(tr(TR_FUNC, TrTest, "smallbuf = 0x%X, %d\n",
smallbuf, smallbuf_size));
}
if (bigbuf == 0) {
#if (TARGET == 1)
// We continuously halve the buffer size until we succeed to allocate
// it.
while(1) {
if ((bigbuf = (char*)tffs_malloc(bigbuf_size)) != 0)
break;
bigbuf_size /= 2;
}
#else
bigbuf = malloc(bigbuf_size);
#endif
tw(tr(TR_FUNC, TrTest, "bigbuf = 0x%X, %d\n", bigbuf, bigbuf_size));
}
test_tdata_init();
tffs_initialize();
}
void test_exit(void)
{
test_state_print(0);
}
// Begin new test case
void test_begin(char *name, int *params)
{
test.numcases++;
tw(tr(TR_BEGIN, TrTest, "TEST %s(%d,%d)\n", name, params[0], params[1]));
ttw(ttr(TTrTest, "TEST %s(%d,%d)" NL, name, params[0], params[1]));
}
void test_end(struct this_test_s *test, int n)
{
int objects = 0;
ffs_query(Q_TOTAL_OBJECTS, (uint16 *) &objects);
tw(tr(TR_FUNC, TrTestHigh, "(total objects = %d)\n", objects));
tw(tr(TR_END, TrTest, ""));
//tw(tr(TR_END, TrTest, "TEST END %s (calls = %d)\n",
// test->name, n - test->numcalls));
}
void test_error(struct this_test_s *test, int n)
{
ttw(ttr(TTrTest, "TEST FAIL %s, call %d" NL,
test->name, n - test->numcalls));
tw(tr(TR_FUNC, TrTest, "TEST FAIL %s, call %d\n",
test->name, n - test->numcalls));
}
/******************************************************************************
* Miscellaneous
******************************************************************************/
int test_ffs_state_get(struct ffs_state_s *s)
{
memset(s, 0, sizeof(struct ffs_state_s));
error = ffs_query(Q_INODES_USED, (uint16 *) &s->inodes_used);
error += ffs_query(Q_INODES_LOST, (uint16 *) &s->inodes_lost);
error += ffs_query(Q_OBJECTS_FREE, (uint16 *) &s->objects_free);
error += ffs_query(Q_TOTAL_OBJECTS, (uint16 *) &s->objects_total);
error += ffs_query(Q_BYTES_USED, (uint16 *) &s->bytes_used);
error += ffs_query(Q_BYTES_LOST, (uint16 *) &s->bytes_lost);
error += ffs_query(Q_BYTES_FREE, (uint16 *) &s->bytes_free);
error += ffs_query(Q_BLOCKS_FREE, (uint16 *) &s->blocks_free);
return error;
}
void test_ffs_state_copy(struct ffs_state_s *dst, struct ffs_state_s *src)
{
memcpy(dst, src, sizeof(struct ffs_state_s));
}
void test_state_print(struct ffs_state_s *state)
{
struct ffs_state_s mystate;
if (state == 0) {
state = &mystate;
test_ffs_state_get(state);
}
tw(tr(TR_FUNC, TrTest, "\nFFS State Summary:\n\n"));
ttw(str(TTrTest, NL "FFS State Summary:" NL NL));
tw(tr(TR_FUNC, TrTest, " block_size = %d\n", param.block_size));
tw(tr(TR_FUNC, TrTest, " bytes_avail = %d\n\n", param.bytes_avail));
ttw(ttr(TTrTest, " block_size = %d" NL, param.block_size));
ttw(ttr(TTrTest, " bytes_avail = %d" NL NL, param.bytes_avail));
test_state_bytes_print(state, 0);
test_state_objects_print(state, 0);
}
void test_state_objects_print(struct ffs_state_s *old, struct ffs_state_s *new)
{
ttw(str(TTrTest, " inodes objects" NL));
ttw(str(TTrTest, " -------------------------------------------" NL));
ttw(str(TTrTest, " objects: used lost free total" NL));
ttw(ttr(TTrTest, " old: %6d %6d %6d %6d" NL,
old->inodes_used, old->inodes_lost,
old->objects_free, old->objects_total));
tw(tr(TR_FUNC, TrTest, " inodes objects\n"));
tw(tr(TR_FUNC, TrTest, " -------------------------------------------\n"));
tw(tr(TR_FUNC, TrTest, " objects: used lost free total\n"));
tw(tr(TR_FUNC, TrTest, " old: %6d %6d %6d %6d\n",
old->inodes_used, old->inodes_lost,
old->objects_free, old->objects_total));
if (new != NULL)
{
ttw(ttr(TTrTest,
" new: %6d %6d %6d %6d" NL,
new->inodes_used, new->inodes_lost,
new->objects_free, new->objects_total));
ttw(ttr(TTrTest,
" diff: %6d %6d %6d %6d" NL,
new->inodes_used - old->inodes_used,
new->inodes_lost - old->inodes_lost,
new->objects_free - old->objects_free,
new->objects_total - old->objects_total));
tw(tr(TR_FUNC, TrTest,
" new: %6d %6d %6d %6d\n",
new->inodes_used, new->inodes_lost,
new->objects_free, new->objects_total));
tw(tr(TR_FUNC, TrTest,
" diff: %6d %6d %6d %6d\n",
new->inodes_used - old->inodes_used,
new->inodes_lost - old->inodes_lost,
new->objects_free - old->objects_free,
new->objects_total - old->objects_total));
}
ttw(str(TTrTest, "" NL));
tw(tr(TR_FUNC, TrTest, "\n"));
}
void test_state_bytes_print(struct ffs_state_s *old, struct ffs_state_s *new)
{
tw(tr(TR_FUNC, TrTest, " bytes: used lost free total\n"));
tw(tr(TR_FUNC, TrTest, " old: %8d %8d %8d %8d\n",
old->bytes_used, old->bytes_lost,
old->bytes_free, param.bytes_max));
tw(tr(TR_FUNC, TrTest, " +/-: %8d %8d\n",
old->bytes_used - old->bytes_lost,
old->bytes_free + old->bytes_lost));
ttw(str(TTrTest, " bytes: used lost free total" NL));
ttw(ttr(TTrTest, " old: %8d %8d %8d %8d" NL,
old->bytes_used, old->bytes_lost,
old->bytes_free, param.bytes_max));
ttw(ttr(TTrTest, " +/-: %8d %8d" NL,
old->bytes_used - old->bytes_lost,
old->bytes_free + old->bytes_lost));
if (new != NULL) {
tw(tr(TR_FUNC, TrTest, " new: %8d %8d %8d\n",
new->bytes_used, new->bytes_lost,
new->bytes_free));
tw(tr(TR_FUNC, TrTest, " diff: %8d %8d %8d\n",
new->bytes_used - old->bytes_used,
new->bytes_lost - old->bytes_lost,
new->bytes_free - old->bytes_free));
ttw(ttr(TTrTest, " new: %8d %8d %8d" NL,
new->bytes_used, new->bytes_lost,
new->bytes_free));
ttw(ttr(TTrTest, " diff: %8d %8d %8d" NL,
new->bytes_used - old->bytes_used,
new->bytes_lost - old->bytes_lost,
new->bytes_free - old->bytes_free));
}
tw(tr(TR_FUNC, TrTest, "\n"));
ttw(str(TTrTest, "" NL));
}
// Retrieve all static ffs parameters with ffs_query()
int test_ffs_params_get(void)
{
error = ffs_query(Q_FILENAME_MAX, ¶m.filename_max);
error += ffs_query(Q_PATH_DEPTH_MAX, ¶m.pathdepth_max);
error += ffs_query(Q_INODES_MAX, ¶m.inodes_max);
error += ffs_query(Q_BYTES_MAX, ¶m.bytes_max);
error += ffs_query(Q_DEV_BLOCKS, ¶m.numblocks);
error += ffs_query(Q_DEV_ATOMSIZE, ¶m.atomsize);
error += ffs_query(Q_BLOCKS_FREE_MIN, ¶m.blocks_free_min);
// Compute block size
param.block_size = param.bytes_max / param.numblocks;
// Compute total number of available storage space, subtracting
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -