OpenEdv-开源电子网

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

Petit Fatfs 中pf_lseek问题,文件越大,时间越久。

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2019-9-11
在线时间
6 小时
发表于 2021-12-23 09:27:20 | 显示全部楼层 |阅读模式
1金钱
求助各位大佬。!!!
Petit Fatfs 轻量级SD卡中的pf_lseek有段这个函数。
现在在SD卡中创建了个100MB的文件,SD卡格式化为FAT32的
我想从末尾开始写fs->fptr大概要在0x06300000->0x06400000之间
然后我pf_lseek(0x06350000)
调试发现ofs就是我写的0x6350000。
但是bcs只有512个字节也就是0x200
也就是说执行这一遍函数ofs每次才判断512个字节,然后get_fat函数里面又要用到SPI读取的函数,导致pf_lseek越大这段执行就越久。
尝试过直接删除该段函数, 让fs->fptr = ofs;但是fs->curr_clust 又应该等于多少。
有大佬帮忙看看怎么优化比较好吗?
                while (ofs > bcs) {                        /* Cluster following loop */
                        clst = get_fat(clst);                /* Follow cluster chain */
                        if (clst <= 1 || clst >= fs->n_fatent) ABORT(FR_DISK_ERR);
                        fs->curr_clust = clst;
                        fs->fptr += bcs;
                        ofs -= bcs;
                }


FRESULT pf_lseek (
        DWORD ofs                /* File pointer from top of file */
)
{
        CLUST clst;
        DWORD bcs, sect, ifptr;
        FATFS *fs = FatFs;


        if (!fs) return FR_NOT_ENABLED;                /* Check file system */
        if (!(fs->flag & FA_OPENED)) return FR_NOT_OPENED;        /* Check if opened */

        if (ofs > fs->fsize) ofs = fs->fsize;        /* Clip offset with the file size */
        ifptr = fs->fptr;
        fs->fptr = 0;
        if (ofs > 0) {
                bcs = (DWORD)fs->csize * 512;                /* Cluster size (byte) */
                if (ifptr > 0 &&
                        (ofs - 1) / bcs >= (ifptr - 1) / bcs) {        /* When seek to same or following cluster, */
                        fs->fptr = (ifptr - 1) & ~(bcs - 1);        /* start from the current cluster */
                        ofs -= fs->fptr;
                        clst = fs->curr_clust;
                } else {                                                        /* When seek to back cluster, */
                        clst = fs->org_clust;                        /* start from the first cluster */
                        fs->curr_clust = clst;
                }
                while (ofs > bcs) {                                /* Cluster following loop */
                        clst = get_fat(clst);                /* Follow cluster chain */
                        if (clst <= 1 || clst >= fs->n_fatent) ABORT(FR_DISK_ERR);
                        fs->curr_clust = clst;
                        fs->fptr += bcs;
                        ofs -= bcs;
                }
                fs->fptr += ofs;
                sect = clust2sect(clst);                /* Current sector */
                if (!sect) ABORT(FR_DISK_ERR);
                fs->dsect = sect + (fs->fptr / 512 & (fs->csize - 1));
        }

        return FR_OK;
}
#endif


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

369

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4241
金钱
4241
注册时间
2020-7-24
在线时间
714 小时
发表于 2021-12-23 09:55:37 | 显示全部楼层
回复

使用道具 举报

6

主题

890

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1477
金钱
1477
注册时间
2020-8-19
在线时间
335 小时
发表于 2021-12-23 11:16:57 | 显示全部楼层
帮顶  
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2019-9-11
在线时间
6 小时
 楼主| 发表于 2021-12-23 11:38:54 | 显示全部楼层
谢谢两位兄弟的帮顶,根据几次调试,试着修改。修改之后如下列,能够做到快速移动指针。ofs为要移动到的位置,bcs为格式化时选择的分配单元大小。我注释掉的原先代码,应该时有帮忙判断坏道的吧,本人也不是很能理解。如果有大佬有更好的优化方法可以提出,在此感谢。
//                while (ofs > bcs) {                                /* Cluster following loop */
//                        clst = get_fat(clst);                /* Follow cluster chain */
//                        if (clst <= 1 || clst >= fs->n_fatent) ABORT(FR_DISK_ERR);
//                        fs->curr_clust = clst;
//                        fs->fptr += bcs;
//                        ofs -= bcs;
//                }
        fs->curr_clust = clst + (ofs / bcs);
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 09:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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