[大问题的解决!]!!!用FatFS的朋友们注意了啊,福利来了!

2019-07-20 04:43发布

以前用FatFS的时候有没有发现在使用大容量卡(4G以上)的时候,卡里存了4G以上的东西,新存的文件就不能被正确读取了呢?!
这是因为大家移植的FatFS都是32位寻址的,只能读到4G以下地址的东西,4G以上的东西虽然文件分配表还有分配,但是却没有这么大的地址去读取。
怎么办呢?让我们来解决这个问题吧!

首先,打开SDIO/SPI总线驱动SD卡的底层文件:

sd.h-------------------
sd.c-------------------

在文件里找到下面的几个函数(类似的也行):
SD_Error SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize);
SD_Error SD_ReadMultiBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SD_WriteBlock(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize);
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);

看到Addr的参数了吗?这是地址,现在我们把它改成64位的,像这样:

SD_Error SD_ReadBlock(uint8_t *readbuff, uint64_t ReadAddr, uint16_t BlockSize);
SD_Error SD_ReadMultiBlocks(uint8_t *readbuff, uint64_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
SD_Error SD_WriteBlock(uint8_t *writebuff, uint64_t WriteAddr, uint16_t BlockSize);
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint64_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);

现在,SD卡的底层就改造好了,我们接着改造FatFS:
打开FatFS目录下的integer.h

找到下面几行代码:
/* These types must be 32-bit integer */
typedef long  LONG;
typedef unsigned long  ULONG;
typedef unsigned long  DWORD;

现在稍稍修改一下,变成这样:
/* These types must be 64-bit integer */
typedef long long LONG;
typedef unsigned long long ULONG;
typedef unsigned long long DWORD;

就是把unsigned long 无符号长整型变成unsigned long long 无符号64位长整型。
现在整体改造完毕,可以试试往SD卡里先写5~6G数据,然后再写个文本,现在读就不会读出乱码啦!
原先32位寻址时,最大支持4GBytes的寻址,现在的寻址空间扩大了4294967295倍,你的SD卡再怎么大都不会出错啦!



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
46条回答
KC_CEC
1楼-- · 2019-07-21 00:57
 精彩回答 2  元偷偷看……
KC_CEC
2楼-- · 2019-07-21 06:50
 精彩回答 2  元偷偷看……
正点原子
3楼-- · 2019-07-21 12:06
没问题的,对大容量卡来说,这里是要除以512,再送给ARG的。
具体看代码:
[mw_shl_code=c,true]//SD卡写多个块 //buf:数据缓存区 //addr:写地址 //blksize:块大小 //nblks:要写入的块数 //返回值:错误状态 SD_Error SD_WriteMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks) { SD_Error errorstatus = SD_OK; u8 power = 0, cardstate = 0; u32 timeout=0,bytestransferred=0; u32 count = 0, restwords = 0; u32 tlen=nblks*blksize; //总长度(字节) u32 *tempbuff = (u32*)buf; if(buf==NULL)return SD_INVALID_PARAMETER; //参数错误 SDIO->DCTRL=0x0; //数据控制寄存器清零(关DMA) SDIO_Send_Data_Cfg(SD_DATATIMEOUT,0,0,0); //清除DPSM状态机配置 if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了 if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)//大容量卡 { blksize=512; addr>>=9; } [/mw_shl_code] 看到那个>>9了么?

就是除以512.
另外,我实测16GB,8GB SD卡,都很好的读写,没有任何问题。
KC_CEC
4楼-- · 2019-07-21 17:46
回复【10楼】正点原子:
---------------------------------
分析得真好,赞!
 精彩回答 2  元偷偷看……
高粱是哪个梁
6楼-- · 2019-07-22 00:57
 精彩回答 2  元偷偷看……

一周热门 更多>