野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 10939|回复: 7

FatFS挂载SD卡失败。

[复制链接]
发表于 2016-11-6 23:13:09 | 显示全部楼层 |阅读模式
本帖最后由 ggafish 于 2016-11-6 23:17 编辑

按照咱们的视频教程移植SD卡驱动和FatFS驱动,SD卡使用金士顿。移植完成后测试,SD_Init()函数执行正常。
当用2G SD卡时,读出cardinfo blocksize 是1024 , fmount()函数失败,
错误代码是1,FR_DISK_ERR,                        /* (1) A hard error occurred in the low level disk I/O layer */
换了一张2G SD卡,结果也是失败,错误代码1.
当用32G SD时,读出cardinfo blocksize 是512 ,  fmount()函数执行成功。

移植时没有加入字节对齐的代码,因为我还没有进行文件操作,只是挂载,应该不是字节对齐的问题吧?


这个要从哪里查找问题? 我的板子不是咱们的野火,SDIO接口没有复用WIFI,
板子SDIO是专用SDIO接口的。

回复

使用道具 举报

 楼主| 发表于 2016-11-6 23:31:23 | 显示全部楼层
经过调试,发现在fmount中调用的一个函数,
在下图那里发生了错误,这个是什么意思?应该怎么解决?fmt == 4 会返回一个错误代码1.
1.png

回复 支持 反对

使用道具 举报

发表于 2016-11-7 08:54:34 | 显示全部楼层
在底层的SDIO驱动有很多地方是默认用512来读写的,例如设置卡大小命令、读写命令,要把它改进一下,修改成根据cardInfo结构体里获得的成员值大小来设置才行

回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-7 12:18:49 | 显示全部楼层
本帖最后由 ggafish 于 2016-11-7 12:30 编辑
flyleaf 发表于 2016-11-7 08:54
在底层的SDIO驱动有很多地方是默认用512来读写的,例如设置卡大小命令、读写命令,要把它改进一下,修改成 ...

我原来的代码是可以的,一直用2G SD卡,ff10版本。
只是前面用的时候diskio.c是直接复制网上一个工程的,
发现可以运行,就直接用了,也没好好学习。

我看了咱们教程,然后下载了ff12版本的,按照教程来移植,就出现这个问题了。
我个人观点不应该啊,新版本应该是兼容旧版本的,不会说原来可以用,升级了反而不能用了。

感觉我在移植上出了问题,但是就那么几句代码,挺简单的,也不知道从哪里找问题。fmount()函数还不会调用write read函数,会调用disk_ioctl,所以我只能认为是disk_ioctl里面的代码我写错了。
代码如下: 请帮忙看看。对了,我的SD卡编号是1.
1.png

2.png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-7 12:29:47 | 显示全部楼层
本帖最后由 ggafish 于 2016-11-7 12:48 编辑

SD初始化代码如下:  2G SD卡读出的blocksize是1024
4.png

3.png

1.png
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-7 13:32:00 | 显示全部楼层
我找到问题出在哪里了,容我调试完之后再发出来。
回复 支持 反对

使用道具 举报

发表于 2016-11-7 13:56:00 | 显示全部楼层
ffconf.h 有个配置块大小,要把它设置大于卡的块大小
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-7 22:37:02 | 显示全部楼层
flyleaf 发表于 2016-11-7 13:56
ffconf.h 有个配置块大小,要把它设置大于卡的块大小

是的,我配置的是
#define        _MIN_SS                512
#define        _MAX_SS                4096


#define _VOLUMES        2
/* Number of volumes (logical drives) to be used. */



SD卡的擦除,单块和多块读写测试都成功了,用的是标准库1.7版本的官方示例代码。
现在看来问题就出在diskio.c中的移植代码上。
经过单步调试我现在已经把问题进一步范围缩小了。


fmount()函数会调用一个find_volume(); find_volume()这个函数会调用disk_ioctl(),
disk_ioctl()函数中,关于SD卡的代码我是这样实现的:
case DEV_SD :
                switch(cmd)
                {
                        case CTRL_SYNC:
                                break;
                        //扇区数量
                        case GET_SECTOR_COUNT:
                                *(DWORD*)buff = SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize;
                                break;
                        //扇区大小
                        case GET_SECTOR_SIZE:
                                *(WORD*)buff = SDCardInfo.CardBlockSize;
                                break;
                        //擦除时多少个扇区
                        case GET_BLOCK_SIZE:
                                *(DWORD*)buff = 1;
                                break;
                        case CTRL_TRIM:
                                break;
                        default:
                          break;

之后find_volume()又调用了disk_read()
我的disk_read()是这样实现的:
case DEV_SD :
                status = SD_ReadMultiBlocks(buff, sector*SDCardInfo.CardBlockSize, SDCardInfo.CardBlockSize, count);
                  if(status != SD_OK)
                                break;
                  status = SD_WaitReadOperation();
                  if(status != SD_OK)
                                break;
                        while(SD_GetStatus() != SD_TRANSFER_OK);
                        res = RES_OK;
                        break;


经过调试就是在上面红色的代码处出错的,我想是不是传入的参数有问题呢?
32G卡是可以执行成功的,2G卡就失败。
前面已经说了,2G读出的blocksize是1024,32G读出的blocksize是512.
不知道是啥问题。

回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-15 08:14 , Processed in 0.036912 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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