/** * usage: t_pfs <start> <n> * * for example: t_pfs /x/ 100 * * This test case performs: * 1) create <n> files under <start>, write full file name as file content * 2) list files under <start>, check files are all listed once * 3) check file content aganist file name * 4) delete files on success */ static int cmd_TestPopulateFiles(int argc, char *argv[]) { const char *start = "/"; int count = 80; int i, fd, num; char name[128]; char buf[128]; uffs_DIR *dirp; struct uffs_dirent *ent; unsigned long bitmap[50] = {0}; // one bit per file, maximu 32*50 = 1600 files UBOOL succ = U_TRUE; #define SBIT(n) bitmap[(n)/(sizeof(bitmap[0]) * 8)] |= (1 << ((n) % (sizeof(bitmap[0]) * 8))) #define GBIT(n) (bitmap[(n)/(sizeof(bitmap[0]) * 8)] & (1 << ((n) % (sizeof(bitmap[0]) * 8)))) if (argc > 1) { start = argv[1]; if (argc > 2) { count = strtol(argv[2], NULL, 10); } } if (count > sizeof(bitmap) * 8) count = sizeof(bitmap) * 8; for (i = 0, fd = -1; i < count; i++) { sprintf(name, "%sFile%03d", start, i); fd = uffs_open(name, UO_RDWR|UO_CREATE|UO_TRUNC); if (fd < 0) { MSGLN("Create file %s failed", name); break; } if (uffs_write(fd, name, strlen(name)) != strlen(name)) { // write full path name to file MSGLN("Write to file %s failed", name); uffs_close(fd); break; } uffs_close(fd); } if (i < count) { // not success, need to clean up for (; i >= 0; i--) { sprintf(name, "%sFile%03d", start, i); if (uffs_remove(name) < 0) MSGLN("Delete file %s failed", name); } succ = U_FALSE; goto ext; } MSGLN("%d files created.", count); // list files dirp = uffs_opendir(start); if (dirp == NULL) { MSGLN("Can't open dir %s !", start); succ = U_FALSE; goto ext; } ent = uffs_readdir(dirp); while (ent && succ) { if (!(ent->d_type & FILE_ATTR_DIR) && // not a dir ent->d_namelen == strlen("File000") && // check file name length memcmp(ent->d_name, "File", strlen("File")) == 0) { // file name start with "File" MSGLN("List entry %s", ent->d_name); num = strtol(ent->d_name + 4, NULL, 10); if (GBIT(num)) { // file already listed ? MSGLN("File %d listed twice !", ent->d_name); succ = U_FALSE; break; } SBIT(num); // check file content sprintf(name, "%s%s", start, ent->d_name); fd = uffs_open(name, UO_RDONLY); if (fd < 0) { MSGLN("Open file %d for read failed !", name); } else { memset(buf, 0, sizeof(buf)); num = uffs_read(fd, buf, sizeof(buf)); if (num != strlen(name)) { MSGLN("%s Read data length expect %d but got %d !", name, strlen(name), num); succ = U_FALSE; } else { if (memcmp(name, buf, num) != 0) { MSGLN("File %s have wrong content '%s' !", name, buf); succ = U_FALSE; } } uffs_close(fd); } } ent = uffs_readdir(dirp); } uffs_closedir(dirp); // check absent files for (i = 0; i < count; i++) { if (GBIT(i) == 0) { sprintf(name, "%sFile%03d", start, i); MSGLN("File %s not listed !", name); succ = U_FALSE; } } // delete files if pass the test for (i = 0; succ && i < count; i++) { sprintf(name, "%sFile%03d", start, i); if (uffs_remove(name) < 0) { MSGLN("Delete file %s failed", name); succ = U_FALSE; } } ext: MSGLN("Populate files test %s !", succ ? "SUCC" : "FAILED"); return succ ? 0 : -1; }
static int dfs_uffs_open(struct dfs_fd* file) { int fd; int oflag, mode; char * file_path; oflag = file->flags; if (oflag & DFS_O_DIRECTORY) /* operations about dir */ { uffs_DIR * dir; if (oflag & DFS_O_CREAT) /* create a dir*/ { if (uffs_mkdir(file->path) < 0) return uffs_result_to_dfs(uffs_get_error()); } /* open dir */ file_path = rt_malloc(FILE_PATH_MAX); if(file_path == RT_NULL) return -DFS_STATUS_ENOMEM; if (file->path[0] == '/' && !(file->path[1] == 0)) rt_snprintf(file_path, FILE_PATH_MAX, "%s/", file->path); else { file_path[0] = '/'; file_path[1] = 0; } dir = uffs_opendir(file_path); if (dir == RT_NULL) { rt_free(file_path); return uffs_result_to_dfs(uffs_get_error()); } /* save this pointer,will used by dfs_uffs_getdents*/ file->data = dir; rt_free(file_path); return DFS_STATUS_OK; } /* regular file operations */ /* int uffs_open(const char *name, int oflag, ...); what is this? * uffs_open can open dir!! **/ mode = 0; if (oflag & DFS_O_RDONLY) mode |= UO_RDONLY; if (oflag & DFS_O_WRONLY) mode |= UO_WRONLY; if (oflag & DFS_O_RDWR) mode |= UO_RDWR; /* Opens the file, if it is existing. If not, a new file is created. */ if (oflag & DFS_O_CREAT) mode |= UO_CREATE; /* Creates a new file. If the file is existing, it is truncated and overwritten. */ if (oflag & DFS_O_TRUNC) mode |= UO_TRUNC; /* Creates a new file. The function fails if the file is already existing. */ if (oflag & DFS_O_EXCL) mode |= UO_EXCL; fd = uffs_open(file->path, mode); if (fd < 0) { return uffs_result_to_dfs(uffs_get_error()); } /* save this pointer, it will be used when calling read()£¬write(), * flush(), seek(), and will be free when calling close()*/ file->data = (void *)fd; file->pos = uffs_seek(fd, 0, USEEK_CUR); file->size = uffs_seek(fd, 0, USEEK_END); uffs_seek(fd, file->pos, USEEK_SET); if (oflag & DFS_O_APPEND) { file->pos = uffs_seek(fd, 0, USEEK_END); } return 0; }
/* * This verify the bug fixed by commit dede97b1. * The bug caused a clone buf failure and UFFS complain something like "no enough free pages for clone!". */ static int cmd_t_dede97b1(int argc, char *argv[]) { // assume: // total page buf: 40 // page size: 512 // pages per block: 32 // spare size: 16 #define LEN_A (508 * 30) // 30 pages #define LEN_B (508 * 10) // 10 pages int fd = -1; URET ret = -1; const int START_A = 508 * 31; // the second block const int START_B = START_A + 508 * 32; // the third block const char *name; char buf_a[LEN_A]; char buf_b[LEN_B]; uffs_Device *dev; const char *mount = "/"; if (argc < 2) { return CLI_INVALID_ARG; } name = argv[1]; fd = uffs_open(name, UO_RDWR); if (fd < 0) { MSGLN("Can't open %s", name); goto ext; } /// /// READ A /// ret = uffs_seek(fd, START_A, USEEK_SET); if (ret != START_A) { MSGLN("lseek return %d\n", ret); goto ext; } sprintf(buf_a, "start test, read %d bytes...", LEN_A); ret = uffs_read(fd, buf_a, LEN_A); if (ret != LEN_A) { MSGLN("read file failed, ret = %d", ret); ret = -1; goto ext; } else { MSGLN("read %d bytes succ.", ret); } MSGLN("now print buf status:"); dev = uffs_GetDeviceFromMountPoint(mount); if (dev == NULL) { MSGLN("Can't get device from mount point %s", mount); ret = -1; goto ext; } uffs_BufInspect(dev); uffs_PutDevice(dev); /// /// READ B /// ret = uffs_seek(fd, START_B, USEEK_SET); if (ret != START_B) { MSGLN("lseek return %d\n", ret); goto ext; } sprintf(buf_b, "start test, read %d bytes...", LEN_B); ret = uffs_read(fd, buf_b, LEN_B); if (ret != LEN_B) { MSGLN("read file failed, ret = %d", ret); ret = -1; goto ext; } else { MSGLN("read %d bytes succ.", ret); } MSGLN("now print buf status:"); dev = uffs_GetDeviceFromMountPoint(mount); if (dev == NULL) { MSGLN("Can't get device from mount point %s", mount); ret = -1; goto ext; } uffs_BufInspect(dev); uffs_PutDevice(dev); /// /// WRITE A /// ret = uffs_seek(fd, START_A, USEEK_SET); if (ret != START_A) { MSGLN("lseek return %d\n", ret); goto ext; } MSGLN("now try write %d bytes...", LEN_A); ret = uffs_write(fd, buf_a, LEN_A); if (ret != LEN_A) { MSGLN("write %d bytes failed, return %d\n", LEN_A, ret); ret = -1; goto ext; } MSGLN("now print buf status again:"); dev = uffs_GetDeviceFromMountPoint(mount); if (dev == NULL) { MSGLN("Can't get device from mount point %s", mount); ret = -1; goto ext; } uffs_BufInspect(dev); uffs_PutDevice(dev); /// /// WRITE B /// ret = uffs_seek(fd, START_B, USEEK_SET); if (ret != START_B) { MSGLN("lseek return %d\n", ret); goto ext; } MSGLN("now try write %d bytes...", LEN_B); ret = uffs_write(fd, buf_b, LEN_B); if (ret != LEN_B) { MSGLN("write %d bytes failed, return %d\n", LEN_B, ret); ret = -1; goto ext; } MSGLN("now print buf status again:"); dev = uffs_GetDeviceFromMountPoint(mount); if (dev == NULL) { MSGLN("Can't get device from mount point %s", mount); ret = -1; goto ext; } uffs_BufInspect(dev); uffs_PutDevice(dev); ret = 0; MSGLN("test completed."); ext: if (fd >= 0) uffs_close(fd); return ret; }
/** cp <src> <des> */ static int cmd_cp(int argc, char *argv[]) { const char *src; const char *des; char buf[100]; int fd1 = -1, fd2 = -1; int len; BOOL src_local = FALSE, des_local = FALSE; FILE *fp1 = NULL, *fp2 = NULL; int ret = -1; CHK_ARGC(3, 3); src = argv[1]; des = argv[2]; if (memcmp(src, "::", 2) == 0) { src += 2; src_local = TRUE; } if (memcmp(des, "::", 2) == 0) { des += 2; des_local = TRUE; } if (src_local) { if ((fp1 = fopen(src, "rb")) == NULL) { MSGLN("Can't open %s for copy.", src); goto fail_ext; } } else { if ((fd1 = uffs_open(src, UO_RDONLY)) < 0) { MSGLN("Can't open %s for copy.", src); goto fail_ext; } } if (des_local) { if ((fp2 = fopen(des, "wb")) == NULL) { MSGLN("Can't open %s for copy.", des); goto fail_ext; } } else { if ((fd2 = uffs_open(des, UO_RDWR|UO_CREATE|UO_TRUNC)) < 0) { MSGLN("Can't open %s for copy.", des); goto fail_ext; } } ret = 0; while ( (src_local ? (feof(fp1) == 0) : (uffs_eof(fd1) == 0)) ) { ret = -1; if (src_local) { len = fread(buf, 1, sizeof(buf), fp1); } else { len = uffs_read(fd1, buf, sizeof(buf)); } if (len == 0) { ret = -1; break; } if (len < 0) { MSGLN("read file %s fail ?", src); break; } if (des_local) { if ((int)fwrite(buf, 1, len, fp2) != len) { MSGLN("write file %s fail ? ", des); break; } } else { if (uffs_write(fd2, buf, len) != len) { MSGLN("write file %s fail ? ", des); break; } } ret = 0; } fail_ext: if (fd1 > 0) uffs_close(fd1); if (fd2 > 0) uffs_close(fd2); if (fp1) fclose(fp1); if (fp2) fclose(fp2); return ret; }
static byte UFFS_Benchmark(const unsigned char *cmd, const CLS1_ConstStdIOType *io) { uint16_t i, j; uint8_t read_buf[10]; TIMEREC time, startTime; int32_t start_mseconds, mseconds; int fd, fd2; /* write benchmark */ MSGLN("Benchmark: open file, write 10k times 10 bytes (100'000 bytes), close file:"); MSGLN("Deleting existing benchmark files..."); uffs_remove("/bench.txt"); uffs_remove("/copy.txt"); MSGLN("Creating benchmark file..."); (void)TmDt1_GetTime(&startTime); fd = uffs_open("/bench.txt", UO_CREATE|UO_WRONLY); if (fd < 0) { MSGLN("*** Failed opening benchmark file!"); return ERR_FAILED; } for(i=0;i<10000;i++) { if (uffs_write(fd, "benchmark ", sizeof("benchmark ")-1) <= 0) { MSGLN("*** Failed writing file!"); uffs_close(fd); return ERR_FAILED; } } uffs_close(fd); (void)TmDt1_GetTime(&time); start_mseconds = startTime.Hour*60*60*1000 + startTime.Min*60*1000 + startTime.Sec*1000 + startTime.Sec100*10; mseconds = time.Hour*60*60*1000 + time.Min*60*1000 + time.Sec*1000 + time.Sec100*10 - start_mseconds; MSGLN("%ld ms needed for creating.",mseconds); /* read benchmark */ MSGLN("Reading benchmark file..."); (void)TmDt1_GetTime(&startTime); fd = uffs_open("/bench.txt", UO_RDONLY); if (fd < 0) { MSGLN("*** Failed opening benchmark file!"); return ERR_FAILED; } for(i=0;i<10000;i++) { if (uffs_read(fd, read_buf, sizeof(read_buf)) <= 0) { MSGLN("*** Failed reading file!"); uffs_close(fd); return ERR_FAILED; } } uffs_close(fd); (void)TmDt1_GetTime(&time); start_mseconds = startTime.Hour*60*60*1000 + startTime.Min*60*1000 + startTime.Sec*1000 + startTime.Sec100*10; mseconds = time.Hour*60*60*1000 + time.Min*60*1000 + time.Sec*1000 + time.Sec100*10 - start_mseconds; MSGLN("%ld ms needed for reading.",mseconds); /* copy benchmark */ MSGLN("Copy file (100'000 bytes)..."); (void)TmDt1_GetTime(&startTime); fd2 = uffs_open("/copy.txt", UO_CREATE|UO_WRONLY); if (fd2 < 0) { MSGLN("*** Failed opening copy file!"); return ERR_FAILED; } fd = uffs_open("/bench.txt", UO_RDONLY); if (fd < 0) { MSGLN("*** Failed opening benchmark file!"); return ERR_FAILED; } i = 0; do { j = uffs_read(fd, read_buf, sizeof(read_buf)); i += j; if (uffs_write(fd2, read_buf, j) < j) { MSGLN("*** Failed writing file!"); uffs_close(fd); uffs_close(fd2); return ERR_FAILED; } } while( j > 0); uffs_close(fd); uffs_close(fd2); (void)TmDt1_GetTime(&time); start_mseconds = startTime.Hour*60*60*1000 + startTime.Min*60*1000 + startTime.Sec*1000 + startTime.Sec100*10; mseconds = time.Hour*60*60*1000 + time.Min*60*1000 + time.Sec*1000 + time.Sec100*10 - start_mseconds; MSGLN("%ld ms needed for copy.",mseconds); return ERR_OK; }
/*! * \brief Copy the source file to a destination file * \param[in] srcFileName Source file name * \param[in] dstFileName Destination file name * \param[in] io IO handler for output * \return Error code, ERR_OK for success. */ byte UFFS_FAT_CopyFile(const byte *srcFileName, const byte *dstFileName, const CLS1_StdIOType *io) { bool sourceUffs = pdTRUE; ///< source is uffs (otherwise FAT) bool destUffs = pdTRUE; ///< destination is uffs (otherwise FAT) int fd1=-1, fd2=-1; // uffs file pointers FAT1_FIL fsrc, fdst; // FAT file objects FAT1_FRESULT fres; // FAT result uint8_t buffer[32]; /* copy buffer */ UINT br, bw, bt=0; /* file read/write counters */ byte res = ERR_OK; if( srcFileName[1] == ':') sourceUffs = pdFALSE; if( dstFileName[1] == ':') { destUffs = pdFALSE; if (FAT1_isWriteProtected() || FAT1_FS_READONLY) { MSGLN("destination FAT disk is write protected!"); return ERR_FAILED; } } /* open source file */ if(sourceUffs) { fd1 = uffs_open((char*)srcFileName, UO_RDONLY); if (fd1 < 0) { MSGLN("open source file failed"); return ERR_FAILED; } } else { fres = FAT1_open(&fsrc, (char*)srcFileName, FA_OPEN_EXISTING | FA_READ); if (fres != FR_OK) { MSGLN("open source file failed. Result=%d", fres); return ERR_FAILED; } } /* create destination file */ if(destUffs) { fd2 = uffs_open((char*)dstFileName, UO_CREATE|UO_WRONLY); if (fd2 < 0) { MSGLN("open destination file failed"); return ERR_FAILED; } } else { fres = FAT1_open(&fdst, (char*)dstFileName, FA_CREATE_ALWAYS | FA_WRITE); if (fres != FR_OK) { MSGLN("open destination file failed. Result=%d", fres); return ERR_FAILED; } } /* now copy source to destination */ for (;;) { if(sourceUffs) { br = uffs_read(fd1, buffer, sizeof(buffer)); } else { fres = FAT1_read(&fsrc, buffer, sizeof(buffer), &br); if (fres != FR_OK) { MSGLN("reading source file failed. Result=%d", fres); res = ERR_FAILED; break; } } bt += br; if (br == 0) { /* EOF */ break; /* get out of loop */ } if(destUffs) { bw = uffs_write(fd2, buffer, br); } else { fres = FAT1_write(&fdst, buffer, br, &bw); if (fres != ERR_OK) { MSGLN("writing destination file failed. Result=%d", fres); res = ERR_FAILED; break; } } if (bw < br) { MSGLN("failed writing destination file, or disk full"); res = ERR_FAILED; break; } } /* for */ /* close all files */ if(sourceUffs) uffs_close(fd1); else { fres = FAT1_close(&fsrc); if (fres != FR_OK) { MSGLN("closing source file failed. Result=%d", fres); res = ERR_FAILED; } } if(destUffs) uffs_close(fd2); else { fres = FAT1_close(&fdst); if (fres != FR_OK) { MSGLN("closing destination file failed. Result=%d", fres); res = ERR_FAILED; } } MSGLN("%u bytes copied.", bt); return res; }
//uffs拷贝函数,参数之间加空格 //需要从elm拷贝到uffs时(跨文件系统),参数名称前加:: //例如uffs_copy("::/01.hdc /dir1/01.hdc") //上例从SD卡拷贝一个文件01.hdc到flash中, //也可用dfs的函数,那样就不用考虑是否跨文件系统了. int uffs_copy(const char *tail) { const char *src; const char *des; char buf[100]; int fd1=-1, fd2=-1; int len; int src_local = FALSE, des_local = FALSE; int fd3=-1, fd4=-1; if(!tail) return FALSE; src = cli_getparam(tail, &des); if(!des) return FALSE; if(memcmp(src, "::", 2) == 0) { src += 2; src_local = TRUE; } if(memcmp(des, "::", 2) == 0) { des += 2; des_local = TRUE; } if(src_local) { //if((fp1 = fopen(src, "rb")) == NULL) if((fd3 = open(src,O_RDONLY,0)) < 0) { uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", src); goto fail_ext; } } else { if((fd1 = uffs_open(src, UO_RDONLY)) < 0) { uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", src); goto fail_ext; } } if(des_local) { if((fd4 = open(des,O_WRONLY | O_CREAT,0)) < 0) { uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", des); goto fail_ext; } } else { if((fd2 = uffs_open(des, UO_RDWR|UO_CREATE|UO_TRUNC)) < 0) { uffs_Perror(UFFS_ERR_NORMAL, "Can't open %s for copy.", des); goto fail_ext; } } uffs_Perror(UFFS_ERR_NORMAL, "copy %s to %s... ",src,des); while((src_local ? (1) : (uffs_eof(fd1) == 0))) { if(src_local) { len = read(fd3, buf, sizeof(buf)); } else { len = uffs_read(fd1, buf, sizeof(buf)); } if(len == 0) break; if(len < 0) { uffs_Perror(UFFS_ERR_NORMAL, "read file %s fail!", src); break; } if(des_local) { if(write(fd4, buf, len) != len) { uffs_Perror(UFFS_ERR_NORMAL, "write file %s fail!", des); break; } } else { if(uffs_write(fd2, buf, len) != len) { uffs_Perror(UFFS_ERR_NORMAL, "write file %s fail ?", des); break; } } } uffs_Perror(UFFS_ERR_NORMAL, "succ."); fail_ext: if(fd1 > 0) uffs_close(fd1); if(fd2 > 0) uffs_close(fd2); if(fd3 > 0) close(fd3); if(fd4 > 0) close(fd4); return TRUE; }