FATFS 版本:Nov 09 14 R0.10c
在 FATFS 已经移植好的基础上,首先打开 ffconf.h 配置文件,找到如下图配置项:
可以将此值从 0 改为 1 使用 static working buffer on the BSS,但官方不建议这么做,会产生线程安全问题(Always NOT thread-safe.);
我采用的配置 2,使用栈来分配 LFN working buffer,官方提示的(take care on stack overflow)很良心,当时我是用 STM32RCT6 来做的此实验,发现无法输出 SD 卡内的文件名,百思不得其解,后来突然想到了这个提示,故将栈区放大试一试,果然成功了。修改方法如下(在 STM32 的启动文件中修改):
初始值为 0x00000400 为 1kbytes,改为 0x00001000 4kbytes。
当然我们可以在单片机上模拟出个内存管理,实现 mallock free 等函数,这时我们就可以将此项配置为 3 ,以堆的方式来实现(Enable LFN with dynamic working buffer on the HEAP.),这里我们不做此介绍。
为了能够支持中文,还需要把 _CODE_PAGE 的值改为 936,并把 option/cc936.c 文件添加到工程中, 如下图所示:
实例演示:
调用如下代码:
u8 scan_files(u8 * path)
{
FRESULT res;
char buf[512] = {0};
char *fn;
#if _USE_LFN
fileinfo.lfsize = _MAX_LFN * 2 + 1;
fileinfo.lfname = buf;
#endif
res = f_opendir(&dir,(const TCHAR*)path);
if (res == FR_OK)
{
printf("\r\n");
while(1){
res = f_readdir(&dir, &fileinfo);
if (res != FR_OK || fileinfo.fname[0] == 0) break;
#if _USE_LFN
fn = *fileinfo.lfname ? fileinfo.lfname : fileinfo.fname;
#else
fn = fileinfo.fname;
#endif
/* 输出目录及文件名 */
printf("%s/", path);
printf("%s\r\n", fn);
}
}
return res;
}
串口输出如下:
感谢花费宝贵的时间浏览, 转载请注明出处。 本人将在[资源共享]分类下陆续加入学习过程中一些比较重要且有用处的资料、源码,大家可前往下载,一起进步。 感谢支持!
配置 FATFS 支持长文件名 - Lance丶丶 - 博客园
https://www.cnblogs.com/GyForever1004/p/8868922.html
fatfs f_readdir 在使用长文件名时的问题_jerry是个程序员-CSDN博客_f_readdir用法
https://blog.csdn.net/zuowanbishe/article/details/86751627
FATFS支持英文长文件名_冷饮-CSDN博客_单片机sd 卡 ntfs 文件系统长命名
https://blog.csdn.net/lan120576664/article/details/48344311?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param
FATFS支持英文长文件名;出现BUG
你会发现“fno->lfsize”这个值很大。如果你一路从f_stat函数跟踪进来,你会知道这整个过程“fno->lfsize”都没有被赋值过.因此,解决这个问题的方法是,开始的时候对"FILINFO fno"进行赋值.可以写成"FILINFO fno = {0};"
至此,读文件内容也正常了.补充一点,当不支持长命名文件时,都是很正常(但或许存在风险,因此无论如何对该结构体变量都需要进行赋初值).
版权声明:本文为CSDN博主「lan120576664」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lan120576664/article/details/48344311
//202007270950.jpg
typedef struct
{
uint8_t type[6]; //6 后缀 6 个字节
uint8_t name[34];//34 路径和文件名字 50 个字节(支持 12 个汉字大小名字)
} FileNameTypeDef;
typedef struct
{
FileNameTypeDef PICFile[20];//401
uint16_t number; //照片数量
}PicNameTypeDef;
extern PicNameTypeDef Pic_SD;
PicNameTypeDef Pic_SD={0};
uint16_t MAX_Pic_Num = 10000;
//获取图片总数
void Get_Pic_Nums(void)
{
FRESULT res;
FILINFO finfo = {0};
DIR dir;
TCHAR *fn;
char SD_ERROR_Pic_Name[30];
uint16_t fileCnt=0;
App_Printf("\r\n 查看图片数量 \r\n");
res = f_opendir(&dir,"0:/PHOTO");
if(res == FR_OK)
{
while (f_readdir(&dir, &finfo) == FR_OK)
{
#if _USE_LFN
fn = finfo.fname;
// fn = *finfo.lfname ? finfo.lfname : finfo.fname;
#else
fn = finfo.fname;
#endif
if((strstr(finfo.fname,".jpg")||strstr(finfo.fname,".jpg"))&&(strlen(finfo.fname) == 12))
{
if((MAX_Pic_Num != 10000)&&((MAX_Pic_Num - fileCnt) < 10))
{
memset(Pic_SD.PICFile[fileCnt].name,0,20);
memcpy(Pic_SD.PICFile[fileCnt].name,fn,strlen(fn));
App_Printf("\r\n 查看存储图片:%s ;%d;%d\r\n",fn,MAX_Pic_Num,fileCnt);
}
}
else
{
App_Printf("\r\n 删除图片:%s :%d : %d\r\n", finfo.fname, strlen(finfo.fname), finfo.fsize);
memset(SD_ERROR_Pic_Name,0,sizeof(SD_ERROR_Pic_Name));
sprintf(SD_ERROR_Pic_Name,"0:/PHOTO/%s",finfo.fname);
f_unlink(SD_ERROR_Pic_Name);
}
if(!fn[0])
{
break;
}
fileCnt++; //图片总数(全局变量)
if(fileCnt%500 == 499)
{
vTaskDelay(10);
}
}
}
Pic_SD.number = fileCnt;
MAX_Pic_Num = Pic_SD.number;
f_closedir(&dir);
App_Printf("图片总数:%d\r\n",Pic_SD.number);
}