OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14536|回复: 12

ST32F429,关于FATFS文件系统复制文件夹中,打开文件出现FR_TOO_MANY_OPEN_FILES的错误。

[复制链接]

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
发表于 2014-11-17 15:28:57 | 显示全部楼层 |阅读模式
5金钱
文件夹复制代码用的原子哥的,稍微改动了一下:问题及代码呈上
[mw_shl_code=c,true]/************************************************************************** // 文件复制,将源文件夹复制到目标文件夹 // 将psrc文件,copy到pdst. // psrc,pdst:源文件和目标文件 // fwmode:文件写入模式 // 0:不覆盖原有的文件 // 1:覆盖原有的文件 ***************************************************************************/ FRESULT mf_copy(uint8_t* psrc, uint8_t* pdst, uint8_t fwmode ) { FRESULT res; uint16_t br = 0; uint16_t bw = 0; FIL fsrc,fdst; uint8_t fbuf[512] = {0}; if(fbuf == NULL) { res = 100; } else { if(fwmode == 0) { fwmode = FA_CREATE_NEW; } else { fwmode = FA_CREATE_ALWAYS; } res = f_open( &fsrc, (const TCHAR *)psrc, FA_READ | FA_OPEN_EXISTING ); //打开只读文件 if(res == 0) { res = f_open( &fdst, (const TCHAR *)pdst, FA_WRITE | fwmode ); //打开第一个再打开第二个 } if(res == 0) //2个都打开了 { while(res == 0) //开始复制 { res = f_read(&fsrc, fbuf, 512, (UINT*)&br); //从源文件读出512字节 if(res || br == 0) { break; } res = f_write(&fdst, fbuf, (UINT)br, (UINT*)&bw); // 写入目的文件 if(res || bw < br) { break; } } f_close(&fsrc); f_close(&fdst); } } free(fbuf); return res; } /********************************************************** *得到路径下的文件夹 返回值:卷标号或者文件夹的首地址 ***********************************************************/ uint8_t *get_src_dname(uint8_t* dpfn) { uint16_t temp = 0; while(*dpfn != 0) { dpfn++; temp++; } if(temp < 1) { return &dpfn[0]; //卷标名,不带“/” } while((*dpfn != 0x3a)&&(*dpfn != 0x2f)) //追述到倒数第一个“/”或者“:”处 { dpfn--; } return ++dpfn; } /***************************************************************** *pdst:必须形如“1:doc/file/abc.txt” ******************************************************************/ FRESULT mf_dcopy(uint8_t* psrc, uint8_t* pdst, uint8_t fwmode) { #define MAX_PATHNAME_DEPTH 512+1 //最大文件路径+文件名深度 FRESULT res = 0; uint8_t dstarray[MAX_PATHNAME_DEPTH] = {0},srcarray[MAX_PATHNAME_DEPTH] = {0}; DIR* srcdir = NULL; //源目录 DIR* dstdir = NULL; //目标目录 FILINFO* finfo = NULL; //文件信息 uint8_t* fn = NULL; //长文件名 uint8_t* dstpathname = dstarray; //??±ê???????·??(+??????) uint8_t* srcpathname = srcarray; //?????????·??(+??????) uint16_t dstpathlen = 0; //目标文件夹路径 uint16_t srcpathlen = 0; //源文件夹路径 srcdir = (DIR*)malloc(sizeof(DIR)); dstdir = (DIR*)malloc(sizeof(DIR)); finfo = (FILINFO*)malloc(sizeof(FILINFO)); if(srcdir == NULL || dstdir==NULL || finfo == NULL) { res = 100; } if(res == 0) { finfo->lfsize = _MAX_LFN*2 + 1; //Size of LFN buffer in TCHAR finfo->lfname = malloc(finfo->lfsize); //Pointer to the LFN buffer if(finfo->lfname == NULL) { res = 101; } if (res == 0) { strcat((char*)srcpathname, (const char*)psrc); //复制原始源文件(夹)路径 strcat((char*)dstpathname, (const char*)pdst); //复制目标文件(夹)路径 res = f_opendir (srcdir, (const TCHAR *)psrc); //打开源目录 if(res == 0) //打开成功 { strcat((char*)dstpathname, (const char*)"/" ); // 加入斜杠 fn = get_src_dname(psrc); //得到文件夹名字 if(fn == 0) //卷标拷贝 { dstpathlen = strlen((const char*)dstpathname); dstpathname[dstpathlen] = psrc[0]; dstpathname[dstpathlen + 1] = 0; } else { strcat((char*)dstpathname,(const char*)fn); //加文件名 } res = f_mkdir((const TCHAR*)dstpathname); //文件存在则打开,不存在就创建 if(res == FR_EXIST) { res = 0; } while(res == 0) //开始复制文件夹里的东西 { res = f_readdir(srcdir, finfo); //遍历文件夹 if(res != FR_OK || finfo->fname[ 0 ] == 0) //到了末尾了 { break; } fn = ( uint8_t* )( *finfo->lfname ? finfo->lfname : finfo->fname ); //得到文件名 dstpathlen = strlen(( const char * )dstpathname); //得到目标路径长度 srcpathlen = strlen(( const char * )srcpathname); //得到源路径长度 strcat((char *)srcpathname, (const char *)"/" ); if ( finfo->fattrib & 0X10 ) //为子目录,0x10子目录,0x20归档文件 { strcat((char *)srcpathname, (const char *)fn ); //源路径加子目录名字 res = mf_dcopy(srcpathname, dstpathname, fwmode); //调用自己 } else //非目录 { strcat((char *)dstpathname, (const char *)"/" ); //目标路径加'/' strcat((char *)dstpathname, (const char *)fn ); //目标路径加文件名 strcat((char *)srcpathname, (const char *)fn ); //源路径加文件名 mf_copy(srcpathname, dstpathname, fwmode); //拷贝文件 } srcpathname[srcpathlen] = 0; //加结束符 dstpathname[dstpathlen] = 0; //加结束符 } } free(finfo->lfname); } } free(srcdir); free(dstdir); free(finfo ); return res; } [/mw_shl_code]

主函数:
void main(void) {
.......
.......
uint8_t *psrc = "1:src",*pdst = "0:dst";    //1:SD卡的逻辑磁盘号,0:U盘的逻辑号

uint8_t fwmode = FA_CREATE_ALWAYS;

mf_dcopy(psrc, pdst, fwmode);

while(1);
}

用的FATFS文件系统
SD卡有文件夹src,src下有文件夹file、文件1.txt、2.txt;  file文件夹里有01.txt
U盘里有空文件夹dst

问题现象:

执行到第38行代码出现FR_TOO_MANY_OPEN_FILES的错误。即res = f_open( &fdst, (const TCHAR *)pdst, FA_WRITE | fwmode );

pdst路径是全路径,0:dst/src/file/01.txt,U盘之前也没有打开其他文件,只是再SD卡中接连打开了 src ,file文件而已
搞了1天了愣是没发现错误,求指点


最佳答案

查看完整内容[请看2#楼]

最近无意中好像找出错误原因了,在此说一下解决方法: #define _FS_LOCK    2     /* 0isable or >=1:Enable */ /* To enable file lock control feature, set _FS_LOCK to 1 or greater.    The value defines how many files can b ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-11-17 15:28:58 | 显示全部楼层
最近无意中好像找出错误原因了,在此说一下解决方法:
#define _FS_LOCK    2     /* 0isable or >=1:Enable */
/* To enable file lock control feature, set _FS_LOCK to 1 or greater.
   The value defines how many files can be opened simultaneously. */
改成
#define _FS_LOCK    4     
然后OK,大家共享下
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-11-17 17:15:56 | 显示全部楼层
发现在  res = f_readdir(srcdir, finfo);读目录后,单独打开SD卡内文件可以,单独打开U盘文件也可以;但是同时打开SD卡和U盘就会FR_TOO_MANY_OPEN_FILES。SD卡和U盘貌似不相干啊,为什么会这样呢??
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2014-11-17 19:52:20 | 显示全部楼层
同时打开SD和U盘的文件是不应该有问题才对的。
我们探索者F4开发板就可以边放SD卡的歌曲,边放U盘的图片的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-11-17 20:19:38 | 显示全部楼层
我也觉得当进入一个目录,同时打开SD卡,和U盘的各一个文件不应该有问题的,但是抛开上面的文件夹复制代码,只是简单的做个测试:进入一个目录,同时打开SD卡,和U盘的各一个文件;它却报错了,感觉FATFS文件系统不应该如此脆弱啊
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-11-17 20:19:56 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
我也觉得当进入一个目录,同时打开SD卡,和U盘的各一个文件不应该有问题的,但是抛开上面的文件夹复制代码,只是简单的做个测试:进入一个目录,同时打开SD卡,和U盘的各一个文件;它却报错了,感觉FATFS文件系统不应该如此脆弱啊
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-11-17 20:23:06 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
原子哥你说的仅仅是同时打开SD卡,和U盘的各一个文件没有问题的吗,还是进入某个目录再打开?
我的是进入一个目录,再同时打开SD卡,和U盘的各一个文件出现FR_TOO_MANY_OPEN_FILES错误的。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2014-11-17 20:45:11 | 显示全部楼层
回复【6楼】黑白边缘:
---------------------------------
我的F4综合实验,测试过。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-11-17 20:52:34 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
额,我找不出来错误在哪里了,起码上层的逻辑代码找不出来。估计得改策略了mf_copy函数的while(1)(就是一个文件读出再写入另一个文件)
改成如下:
while(1) {
f_lseek(&fsrc,fsrc.fptr+4096*i);
res = f_open( &fsrc, (const TCHAR *)psrc, FA_READ | FA_OPEN_EXISTING );
res = f_read(&fsrc, fbuf, 4096, (UINT*)&br); 
f_close(&fsrc);
        if(res || br == 0)
        {
          break;
        }

f_lseek(&fdst,fdst.fptr+4096*i);
res = f_open( &fdst, (const TCHAR *)pdst, FA_WRITE | fwmode );
res = f_write(&fdst, fbuf, (UINT)br, (UINT*)&bw); 
f_close(&fdst);
        if(res || br < 4096||bw < br)
        {
          break;
        }

i++;
}    
可以这样好没效率啊,我的FATFS可能出现问题了吗
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2014-11-17 21:02:19 | 显示全部楼层
回复【8楼】黑白边缘:
---------------------------------
这个你再慢慢分析下吧,我也不知道了,呵呵。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-11-18 09:48:03 | 显示全部楼层
看下原子哥的F4代码去,借鉴下........
回复

使用道具 举报

1

主题

16

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-12
在线时间
0 小时
 楼主| 发表于 2014-12-4 14:00:47 | 显示全部楼层
真是有心栽花花不发,无心插柳柳成荫
回复

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
179
金钱
179
注册时间
2018-7-2
在线时间
34 小时
发表于 2019-8-12 15:51:39 | 显示全部楼层
我也遇到同样的问题?用阿波罗+ST32F429开发板,参考原子例程的,在文件复制过程中,出现FR_TOO_MANY_OPEN_FILES的错误,
按照上面方法将
#define _FS_LOCK    2   
改成
#define _FS_LOCK    4
问题解决了,不清楚为什么会这样
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 17:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表