379 lines
10 KiB
C
379 lines
10 KiB
C
|
||
#include <string.h>
|
||
#include <stdio.h>
|
||
|
||
|
||
#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;
|
||
}
|
||
|
||
|
||
|