OpenEdv-开源电子网

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

FAT 0.13 f_mount(&fs,"",1)挂载失败的原因

[复制链接]

4

主题

116

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4089
金钱
4089
注册时间
2017-11-15
在线时间
331 小时
发表于 2018-2-28 16:01:16 | 显示全部楼层 |阅读模式
本帖最后由 IdeaMing 于 2018-2-28 16:18 编辑

这两天学着用了一下FATS文件系统,虽然工作中没用到,但是对个人的经验积累还是有用的。看了一下,代码并不多,但是精简啊,指针跳来跳去的一不小心就晕了。
所以也遇到了不少问题啊。

这里就讲一下我遇到的第一步就懵逼的问题。

那就是
FRESULT f_mount (
        FATFS* fs,                        /* Pointer to the filesystem object (NULL:unmount)*/
        const TCHAR* path,        /* Logical drive number to be mounted/unmounted */
        BYTE opt                        /* Mode option 0o not mount (delayed mount), 1:Mount immediately */
)
使用的是SDIO带闪迪1GTF卡,根据说明和0.9版本使用例程我这样写f_mount(&fs , "" , 1);
返回值0没有问题,高兴的想读个文件试试。
res =f_open(&fsrc,"0:/test.txt",FA_OPEN_EXISTING | FA_READ); // 打开文件
结果返回13

上面就是我杠上的原因,挂载成功了你却告诉我没有文件系统。
然后跟踪f_open函数里面调用了find_volume 判断逻辑驱动号,如果需要的话就挂载。
继续跟踪find_volume里面调用了vol = get_ldnumber获取逻辑驱动号  返回的是0
然后回到find_volume
fs->pdrv = LD2PD(vol),修改了pdrv.
然后下一句是

stat = disk_initialize(fs->pdrv);好吧,这里终于到了接口文件diskio.c里面.

跟踪进去一看,
[mw_shl_code=c,true]DSTATUS disk_initialize (
        BYTE pdrv                                /* Physical drive nmuber to identify the drive */
)
{
        DSTATUS stat;
        int result;

        switch (pdrv) {
        case DEV_RAM :
//                result = RAM_disk_initialize();
                // translate the reslut code here
                return stat;
        case DEV_MMC :
//                result = MMC_disk_initialize();
                // translate the reslut code here
                return stat;
        case DEV_USB :
//                result = USB_disk_initialize();
                // translate the reslut code here
                return stat;
        }
        return STA_NOINIT;
}
[/mw_shl_code]
根据传入参数0,到了case DEV_RAM: 问题来了,我是TF卡啊,这里应该是case DEV_MMC:啊。
那这就好理解了,传入参数有问题,应该是1.
这个传入参数是从这里出来的vol = get_ldnumber那就进这个函数仔细看吧。

int get_ldnumber (            /* Returns logical drive number(-1:invalid drive) */
         const TCHAR** path        /*Pointer to pointer to the path name */
)

输入参数是path地址,我的地址是    "0:/test.txt"   ,
程序里判断句
QQ截图20180228161314.jpg
i = *tp++,也就是地址冒号前的'0'
经过下面的一段

QQ截图20180228161459.jpg
i  -='0';  // i = 0;
所以返回的vol就成了0!!!好嘛!原来是这里啊。
那我就改成res = f_open(&fsrc,"1:/test.txt",FA_OPEN_EXISTING |FA_READ);
擦,结果错误返回的是11FR_INVALID_DRIVE 逻辑驱动号错误???
好,继续查,找到在f_mount里面

         /*Get logical drive number */
         vol= get_ldnumber(&rp);
         if(vol < 0) return FR_INVALID_DRIVE;

意思我的 get_ldnumber返回的不是1

开启调试模式返回的竟然是0XFFFFFFF   -1
又到get_ldnumber里面看到
if ((i -= '0') < FF_VOLUMES) {        /* If drive id is found, get the valueand strip it */

这里FF_VOLUMES ffconfig.h里面定义的是1

#define FF_VOLUMES                1
/* Number of volumes (logical drives) to beused. (1-10) */

导致我的i -= '0',   i =1;  不满足< FF_VOLUMES导致返回了vol的初始化值 -1.

那好啊,我修改一下FF_VOLUMES =2

擦,结果返回了错误12,逻辑驱动没有工作区域,那我刚才挂载的呢!等等,我刚才挂载的是地址是默认地址""  ,而默认地址是0:啊。来来来,赶快修改成
f_mount(&fs,"1:",1);


编译,下载!见证奇迹的时刻到了,成功读到了文件。

回头总结一下问题,主要是逻辑驱动号没弄好,因为diskio.c的默认分了三种类型的存储类型RAM/MMC/USB
而默认的是RAM所以,如果在不修改它的框架情况下,就要逻辑驱动号对应。

TF卡对应MMC所以要地址要是   1:         ,ffconfig里默认了只有一个逻辑驱动号0所以需要修改设置

FF_VOLUMES = 2
程序这样写
f_mount(&fs,"1:",1);
f_open(&fsrc,"1:/test.txt",FA_OPEN_EXISTING| FA_READ);



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

使用道具 举报

0

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
80
金钱
80
注册时间
2018-3-8
在线时间
11 小时
发表于 2018-3-9 09:34:55 | 显示全部楼层
回复 支持 反对

使用道具 举报

5

主题

52

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1038
金钱
1038
注册时间
2018-8-11
在线时间
114 小时
发表于 2018-10-6 14:10:07 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

4

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2020-5-14
在线时间
16 小时
发表于 2020-12-10 17:09:11 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-24 03:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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