搜索
bottom↓
回复: 16

为什么FatFs的f_lseek函数执行时间从会几us到几秒钟增加,见图

[复制链接]

出0入0汤圆

发表于 2015-9-2 13:46:24 | 显示全部楼层 |阅读模式
我在测试播放一个2GB的无压缩BMP编码的avi视频文件,分辨率320*240 (主芯片STM32F407)

测试发现刚开始播放的速度能到7fps(主要播放速度受读SD速度限制,一张320*240,24位的图片就225KB了),

可是速度会慢慢的下降,慢慢的降到零点几fps

调试跟踪发现是卡在了f_lseek 文件偏移函数中

复位后,刚开始f_lseek用时才几us,随着播放,几秒钟后就升到了几百个ms,在过多一会甚至是用时1秒多..

刚刚移植了2015年9月份的 R0.11版本,也是如此,不知道大家有没有遇见过这样的问题


见图:(这个是f_lseek函数用时537ms的图片,大概播放了20多秒就降到了500多毫秒了)


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2015-9-2 13:52:15 | 显示全部楼层
测试过,SD卡的读速度一直都拨动不大,问题在于f_lseek

出0入0汤圆

发表于 2015-9-2 14:14:11 | 显示全部楼层
那你跟一下这个f_lseek吧,看看瓶颈到底在哪里

出0入0汤圆

 楼主| 发表于 2015-9-2 14:39:02 | 显示全部楼层
myxiaonia 发表于 2015-9-2 14:14
那你跟一下这个f_lseek吧,看看瓶颈到底在哪里

是的,就是卡在这里,一直循环很久,但刚开始又不会

while (ofs > bcs) {                                                /* Cluster following loop */
                                        clst = get_fat(fp->fs, clst);        /* Follow cluster chain if not in write mode */
                                        if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
                                        if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR);
                                        fp->clust = clst;
                                        fp->fptr += bcs;
                                        ofs -= bcs;
                        }

出0入0汤圆

发表于 2015-9-2 14:54:44 | 显示全部楼层
在同个已cache的sector中,当然很快。
如果新的位置还要读磁盘,那可想而知了。

所以最好应用这块好好优化,即使用seek也不要乱跳。

出0入0汤圆

发表于 2015-9-2 15:03:57 | 显示全部楼层
aozima 发表于 2015-9-2 14:54
在同个已cache的sector中,当然很快。
如果新的位置还要读磁盘,那可想而知了。

按理说fat缓存时会缓存至少512字节的fat表区域,如果视频文件是连续存放的话也会有不少扇区的连续的,这个fat缓存就会连续命中,不可能出现一直性能下降的问题

而是像周期波一样

出0入0汤圆

 楼主| 发表于 2015-9-2 15:39:09 | 显示全部楼层
myxiaonia 发表于 2015-9-2 15:03
按理说fat缓存时会缓存至少512字节的fat表区域,如果视频文件是连续存放的话也会有不少扇区的连续的,这 ...

有道理

有个细节忘记说了

实际上,在一个循环中,我用了两次f_lseek,

一次是找到视频流头后用了f_lseek,因为有音频数据,要跳过音频数据。也就是说不使用跳过的这些音频数据。这些数据大约4KB,卡的就只有这一次,另一次永远也不会卡哦

另一次是用于循环读取视频流中一帧的图片数据(225KB),我一次读取10KB。这次调用f_lseek没有卡过,很流畅

出0入0汤圆

发表于 2015-9-2 16:44:50 | 显示全部楼层
开启FATFS的FAST_SEEK宏,open文件时创建 CLMT ,类似将FAT表压缩储存,以后seek就不用再去读FAT表了

/* Using fast seek feature */

    DWORD clmt[SZ_TBL];                    /* Cluster link map table buffer */

    res = f_open(fp, fname, FA_READ | FA_WRITE);   /* Open a file */

    res = f_lseek(fp, ofs1);               /* This is normal seek (cltbl is nulled on file open) */

    fp->cltbl = clmt;                      /* Enable fast seek feature (cltbl != NULL) */
    clmt[0] = SZ_TBL;                      /* Set table size */
    res = f_lseek(fp, CREATE_LINKMAP);     /* Create CLMT */
    ...

    res = f_lseek(fp, ofs2);               /* This is fast seek */

出0入0汤圆

 楼主| 发表于 2015-9-2 17:26:17 | 显示全部楼层
zzm24 发表于 2015-9-2 16:44
开启FATFS的FAST_SEEK宏,open文件时创建 CLMT ,类似将FAT表压缩储存,以后seek就不用再去读FAT表了

/* U ...

真的非常感谢你

问题总算解决了,播放视频一下子快起来了

而且这对于告诉读写大文件非常有利,现在f_lseek函数执行时间总保持在0.6ms左右,太兴奋了

相信很多人都不知道这个,学习了

出0入0汤圆

发表于 2015-9-2 18:23:10 | 显示全部楼层
0.11版里是 #define _USE_FASTSEEK    1

出0入0汤圆

发表于 2016-1-8 18:29:34 | 显示全部楼层
我以前也碰到f_lseek的定位大文件的问题, 后来多加了一个f_lseek函数, 加入延时10us, 然后没问题了, 原来是FAST_SEEK宏的原因啊.

出0入0汤圆

发表于 2018-7-23 16:58:23 | 显示全部楼层
lxl_lxl 发表于 2015-9-2 17:26
真的非常感谢你

问题总算解决了,播放视频一下子快起来了

你好,我用fastseek无法多次写入了,能不能把fastseek的那段代码分享一下

出0入0汤圆

发表于 2018-7-23 17:14:38 | 显示全部楼层
这就解决了

出0入0汤圆

发表于 2018-7-24 10:28:44 | 显示全部楼层

你好,我用fastseek无法多次写入了,你知道具体是如何解决的吗

出0入0汤圆

发表于 2018-7-27 11:39:20 | 显示全部楼层
zzm24 发表于 2015-9-2 16:44
开启FATFS的FAST_SEEK宏,open文件时创建 CLMT ,类似将FAT表压缩储存,以后seek就不用再去读FAT表了

/* U ...

15年的贴子,被我找到了,并且帮助我解决了问题,非常感谢!
/* Using fast seek function */

    DWORD clmt[SZ_TBL];                    /* Cluster link map table buffer */

    res = f_open(fp, fname, FA_READ | FA_WRITE);   /* Open a file */

    res = f_lseek(fp, ofs1);               /* This is normal seek (cltbl is nulled on file open) */

    fp->cltbl = clmt;                      /* Enable fast seek function (cltbl != NULL) */
    clmt[0] = SZ_TBL;                      /* Set table size */
    res = f_lseek(fp, CREATE_LINKMAP);     /* Create CLMT */
    ...

    res = f_lseek(fp, ofs2);               /* This is fast seek */
======================分割线:下面是我实际使用时的解决办法==============================
#define SZ_TBL  20
static DataWrite(void)//周期执行函数,周期往文件里写数据
{
       static DWORD clmt[SZ_TBL];                    /* Cluster link map table buffer */

    res = f_open(fp, fname, FA_READ | FA_WRITE);   /* Open a file */
    if(clmt[0] == 0x00)
   {
             res = f_lseek(fp, f_sizeof(fp));               /* This is normal seek (cltbl is nulled on file open) */
         faddata.cltbl = clmt;
         clmt[0] = SZ_TBL;
         res = f_lseek(fp,CREATE_LINKMAP);
  }
  else fp->cltbl = clmt;//每次f_open后,fp->cltbl会变成NULL,所以要把第clmt的地址再次赋值给cltbl
  res = f_seek(fp,f_size(fp));
  res = f_write(fp,WriteDataBuf,strlen(WriteDataBuf),&bw);
  res = f_close(fp);
}

出0入85汤圆

发表于 2018-7-27 15:08:54 | 显示全部楼层
以前没注意,学习了

出0入0汤圆

发表于 2018-7-27 15:47:29 | 显示全部楼层
学习了,谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 11:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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