jianghuai/SYSTEM/fileSys.c
2024-05-07 09:36:09 +08:00

379 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}