#include #include #include "fileSys.h" #include "sd.h" //#define DEPRINT printf #define DEPRINT printf /* FA_OPEN_EXISTING 打开文件。如果文件不存在,则打开失败。(默认) FA_OPEN_ALWAYS 如果文件存在,则打开;否则,创建一个新文件。 FA_CREATE_NEW 创建一个新文件。如果文件已存在,则创建失败。 FA_CREATE_ALWAYS 创建一个新文件。如果文件已存在,则它将被截断并覆盖。 */ /********************************************************************************************************** * 函数 : * 功能 : 文件系统初始化 ***********************************************************************************************************/ FRESULT res33; // FatFs function common result code int filesys_init(void) { FATFS fs; // Work area (file system object) for logical drive FIL fsrc; // file objects FRESULT res; // FatFs function common result code UINT br = 10; // File R/W count BYTE work[10]; res = f_mount(&fs,"0:",1); //挂载SD卡 Delay(100); res = f_open(&fsrc,"0:/Demo.TXT",FA_CREATE_NEW | FA_READ | FA_WRITE ); //创建或打开一个文本文档保存数据 Delay(100); if (FR_NO_FILESYSTEM == res) { res = f_mkfs("0:/", 1, 0); //创建文件系统 DEPRINT("fileSys: create Demo.TXT %u\n", res); } else if ( res == FR_OK ) { /* 将缓冲区的数据写到文件中 */ memset(work, 0, sizeof(work)); memmove(work, "init", 4); res = f_write(&fsrc, work, 4, &br); f_sync(&fsrc); //同f_close保存文件 DEPRINT("fileSys: open and write Demo.TXT %u\n", res); res = f_close(&fsrc); /*关闭文件 */ } else if ( res == FR_EXIST ) { DEPRINT("fileSys: Demo.TXT exist!\n"); } res = f_mount(0, "0:", 1); return 0; } /********************************************************************************************************** * 函数 : * 功能 : 移除指定文件 ***********************************************************************************************************/ uint8_t fileSys__remove (char* path) { FATFS fs; // Work area (file system object) for logical drive FRESULT res; res = res; DEPRINT("removed file: %s\n", path); res = f_mount(&fs, "0:/", 1); //载入工作区间 DEPRINT("f_mount: res %u\n", res); res = f_unlink((char*)path); DEPRINT("f_unlink: res %u\n", res); res = f_mount(0, "0:/", 1); //注销工作区间 DEPRINT("f_unmount: res %u\n", res); return 0; } /********************************************************************************************************** * 函数 : * 功能 : 清除所有数据 ***********************************************************************************************************/ uint8_t fileSys__mkfs(void) { FATFS fs; // Work area (file system object) for logical drive FRESULT res; // FatFs function common result code res = f_mount(&fs, "0:/", 1); //在驱动器上创建一个文件系统,最小单元512K res = f_mkfs("0:/", 0, 512); /* Create an FAT volume on the logical drive 0. 2nd argument is ignored. */ res = f_mount(0, "0:/", 1); return res; } /********************************************************************************************************** * 函数 : fileSys__freeSpace * 功能 : 获得空闲空间 ***********************************************************************************************************/ uint8_t fileSys__freeSpace(char* fileName, uint32_t* totalkB, uint32_t* freekB) { uint8_t retValue = 0; FRESULT res; FATFS fs; FATFS* p__fs = &fs; DWORD fre_clust, fre_sect, tot_sect; res = f_mount(&fs, "0:/", 1); Delay(100); /* Get volume information and free clusters of drive 1 */ res = f_getfree(fileName, &fre_clust, &p__fs); if (res) { retValue = OPS__FAIL; goto getfree__result; } /* Get total sectors and free sectors */ tot_sect = (p__fs->n_fatent - 2) * p__fs->csize; fre_sect = fre_clust * p__fs->csize; //x. *totalkB = tot_sect * SF__DF__SECTOR__SIZE / 1024; //转换成KB *freekB = fre_sect * SF__DF__SECTOR__SIZE / 1024; //转换成KB /* Print free space in unit of KB (assuming 512 bytes/sector) */ getfree__result: res = f_mount(0, "0:/", 1); return retValue; } /********************************************************************************************************** * 函数 : * 功能 : 添加或追加文件 ***********************************************************************************************************/ uint8_t fileSys__append(char* fileName, uint8_t apdType, uint8_t* data, uint16_t dataLength) { FATFS fs; // Work area (file system object) for logical drive FIL fsrc; // file objects FRESULT res; // FatFs function common result code UINT br; // File R/W count uint8_t retValue = FERROR__SUCC; res = f_mount(&fs, "0:/", 1); /*在刚刚注册的工作区中打开一个文件,如果文件不存在则创建该文件,属性为可写 */ if (FILE__APD == apdType) //增加 { //res = f_open(&fsrc, fileName, FA_OPEN_ALWAYS | FA_WRITE); res = f_open(&fsrc, fileName, FA_OPEN_EXISTING | FA_WRITE); res = f_lseek(&fsrc, f_size(&fsrc)); //定位到文件末尾 } else { res = f_open(&fsrc , fileName , FA_CREATE_ALWAYS | FA_WRITE); res = f_lseek(&fsrc, 0); //定位到起始 res = f_truncate(&fsrc); //函数截断文件到当前的文件读/写指针 } if (res != FR_OK) // { retValue |= FERROR__OPEN; DEPRINT("file: open error.\n"); } /* 将缓冲区的数据写到文件中 */ res = f_write(&fsrc, data, dataLength, &br); // 写数据 if (res != FR_OK) { retValue |= FERROR__WRITE; DEPRINT("file: write error.\n"); } f_sync(&fsrc); //同f_close保存文件 DEPRINT("should write %u, actually %u\n", dataLength, br); res = f_close(&fsrc); // 关闭文件 if (res != FR_OK) { retValue |= FERROR__CLOSE; DEPRINT("file: close error.\n"); } res = f_mount(0, "0:/", 1); return retValue; } /********************************************************************************************************** * 函数 : * 功能 : 读出指定目录文件 ***********************************************************************************************************/ uint8_t fileSys__read(char* fileName, uint8_t* data, uint16_t* dataLength, uint32_t cacheSize) { FATFS fs; FIL fsrc; // file objects FRESULT res; // FatFs function common result code UINT br; // File R/W count BYTE work[10]; uint8_t retValue = OPS__RW__SUCC; uint16_t tmpReadDataLength = 0; res = f_mount(&fs, "0:/", 1); res = f_open(&fsrc, fileName, FA_OPEN_EXISTING | FA_READ); /* 以只读的方式打开刚刚创建的文件 */ if(res == FR_OK) { uint32_t fileSize = f_size(&fsrc); //文件大小 DEPRINT("fileread: file size: %u\n", fileSize); // 判断缓冲区够不够大 if(cacheSize < fileSize) return OPS__RW__OVERSIZE; while(1) { memset(work, 0, sizeof(work)); res = f_read( &fsrc, work, sizeof(work), &br ); /* 将文件里面的内容读到缓冲区 */ //memmove(data + tmpReadDataLength, work, br); memcpy(data + tmpReadDataLength, work, br); tmpReadDataLength += br; if (res || br == 0) break; /* 错误或者到了文件尾 */ } } else { retValue = OPS__RW__NOEXIST; } res = f_close(&fsrc); /* 关闭打开的文件 */ res = f_mount(0, "0:/", 1); *dataLength = tmpReadDataLength; return retValue; } /********************************************************************************************************** * 函数 : * 功能 : 搜索类型遍历操作 char* path 路径 uint8_t type 搜索类型 ***********************************************************************************************************/ uint8_t fileSys__traversalOps (char* path, uint8_t type, uint32_t tarIdx, uint8_t* paraData, uint16_t* paraDataLength) { uint32_t tmpIdx = 0; uint8_t retValue = OPS__FAIL; uint16_t tmpFileNameLength = 0; uint8_t fileName[50]; FIL fsrc; FATFS fs; FRESULT res; FILINFO fno; DIR dir; char *fn; /* This function is assuming non-Unicode cfg. */ #if _USE_LFN static char lfn[_MAX_LFN + 1]; fno.lfname = lfn; fno.lfsize = sizeof lfn; #endif if (type == FILESYS__DELETEALL) retValue = OPS__RM__SUCC; else if (type == FILESYS__SEARCHANY) retValue = OPS__DIR__ERROR; res = f_mount(&fs, "0:/", 1); // 载入工作区间 res = f_opendir(&dir, (const TCHAR*)path); // Open the directory 打开一个已存在的目录,并为后续的调用创建一个目录对象 if (res == FR_OK) //加载、打开成功 { while(1) { res = f_readdir(&dir, &fno); /* Read a directory item */ if(res != FR_OK || fno.fname[0] == 0) //错误了或到末尾了 { break; /* Break on error or end of dir */ } if(fno.fname[0] == '.') continue; /* Ignore dot entry */ #if _USE_LFN fn = *fno.lfname ? fno.lfname : fno.fname; #else fn = fno.fname; #endif if(fno.fattrib & AM_DIR) { // /* It is a directory */ // sprintf(&path[i], "Dir: /%s", fn); // res = scan_files(path); // if (res != FR_OK) // break; // path[i] = 0; } else { if(FILESYS__SEARCHANY == type) // 搜索任意一个文件 { if(tmpIdx == tarIdx) { uint16_t tmpFileNameLength = 0; memcpy(paraData + tmpFileNameLength, path, strlen(path)); tmpFileNameLength += strlen(path); memcpy(paraData + tmpFileNameLength, "/", strlen("/")); //二级目录 tmpFileNameLength += strlen("/"); memcpy(paraData + tmpFileNameLength, fn, strlen(fn)); tmpFileNameLength += strlen(fn); *paraDataLength = tmpFileNameLength; paraData[tmpFileNameLength] = 0; retValue = OPS__DIR__SUCC; } tmpIdx += 1; } else if (FILESYS__DELETEALL == type) //删除目录下所有数据 { memset(fileName, 0, sizeof(fileName)); tmpFileNameLength = 0; memcpy(fileName + tmpFileNameLength, path, strlen(path)); tmpFileNameLength += strlen(path); memcpy(fileName + tmpFileNameLength, "/", strlen("/")); tmpFileNameLength += strlen("/"); memcpy(fileName + tmpFileNameLength, fn, strlen(fn)); tmpFileNameLength += strlen(fn); fileName[tmpFileNameLength] = 0; res = f_open(&fsrc, (char*)fileName, FA_OPEN_EXISTING | FA_WRITE); res = f_close(&fsrc); res = f_unlink((char*)fileName); //移除一个对象 if (res != FR_OK) { retValue = OPS__RM__ERROR; } DEPRINT("f_unlink file: %s res %u\n", fileName, res); } } } //while(1) } res = f_mount(0, "0:/", 1); //注销工作区间 return retValue; }