OpenEdv-开源电子网

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

FatFs mount返回FR_NO_FILESYSTEM

[复制链接]

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-1-19
在线时间
11 小时
发表于 2020-3-18 02:51:47 | 显示全部楼层 |阅读模式
10金钱
如题,每次挂载SPI flash都返回FR_NO_FILESYSTEM,先调用f_mkfs格式化也没用。
FatFs使用的是目前最新的R0.14。
硬件使用板载W25Q128 SPI Flash,底层函数移植没有问题,参照原子哥的例程修改的,已验证能正确读写数据。

跟踪调试,发现,每次都在:f_mount(xxx, "0:", 1)  -->  mount_volume("0:", xxx, 0)  -->  find_volume(xxx, 0)  -->  check_fs(xxx, 0)  -->  if (ld_word(fs->win + BS_55AA) != 0xAA55) return 3;这里返回3
这个内容其实就是,读取扇区0,然后判断是否以55AA结尾。理论上应该是,但是实际上是0000;

然后f_mkfs格式化,能正常格式化,但是跟踪调试的时候,发现,其FAT数据缓存(我也不太清楚是MBR还是啥),是写到63扇区的,然后再初始化根目录啥的。


因为对FAT了解还不是很深,不太明白上面是不是一个正常操作,为什么会写到63扇区,然后从0扇区读数据进行校验?

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

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2020-3-18 17:20:41 | 显示全部楼层
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-1-19
在线时间
11 小时
 楼主| 发表于 2020-3-18 20:06:38 | 显示全部楼层
自己再顶!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2020-3-19 00:53:44 | 显示全部楼层
全片擦除,再试下。另外,确认你的flash读写都要正常才行哦
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-1-19
在线时间
11 小时
 楼主| 发表于 2020-3-19 01:48:29 | 显示全部楼层
正点原子 发表于 2020-3-19 00:53
全片擦除,再试下。另外,确认你的flash读写都要正常才行哦

原子哥好敬业,这么晚

刚刚找到一个问题,void W25QXX_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite),这个函数,最后一个参数NumByteToWrite类型,被我不小心写成u8了。

我自己测试没问题,之前只是写几个字节,所以没问题,但是FatFs经常一写就是1个扇区,所以这个参数更多时候是256,然后保存成8位就是0了,所以根本没写进去!!!

我一直以为底层读写函数测试过了,所以一直没往这方面想,自然也没去调试它,结果被它搞了2天!

但是,关于FatFs的挂载和格式化,还是不行,整片擦除也没用。

我把f_mount(xxx, "0:", 1)  -->  mount_volume("0:", xxx, 0)  -->  find_volume(xxx, 0)  -->  check_fs(xxx, 0),我把最后一步的check_fs的参数,直接改成check_fs(xxx, 63)就能正常挂载了,我不知道是我没理解还是R0.14版本的FatFs的bug

后续有没有别的问题我也不知道,文件读写还没测试,今天先睡了,明天再看
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-1-19
在线时间
11 小时
 楼主| 发表于 2020-3-19 02:03:02 | 显示全部楼层
正点原子 发表于 2020-3-19 00:53
全片擦除,再试下。另外,确认你的flash读写都要正常才行哦

对了,诡异的是,我还没改FatFs源文件里面的check_fs的参数的时候,刚开始,有几次还能读出来SPI Flash内的文件系统,里面的目录树也能读得出来(买的你们的最小系统板,内部已经有文件系统了),后来再试几次,就没用了

这个再试几次过程中,底层代码,上层的初始化参数什么的都没改过,唯一改过的是读取目录树的部分(当时写的读目录树的代码部分有问题,正在调试),主函数的流程是 : 挂载SPI Flash, (是否需要格式化,其实当时的格式化根本没成功,什么都没写进去,因为前面说的底层写flash的函数错误),读剩余空间,读目录树(唯一修改的就是这部分)。

在前面若干次测试的时候,偶尔几次能读得出来剩余空间,然后试了几次后,就不行了。在这几次测试时,唯一我知道的写入操作就是格式化操作(实际没写进去;但是我不知道的写入操作存不存在?那些读取函数会不会内部写入?就不清楚了),实际上闪存内的内容应该都没变,但是后来就是怎么都挂载不了了,一直报FR_NO_FILESYSTEM,也就是本帖开头所述的问题。

不过这个诡异的现象也没法追溯了,现在搞来搞去,flash内的数据完全变掉了,我的程序代码也都改掉了,原始代码也都没了。反正写在这里给大家看看,如果哪位大牛能知道原因的,也可以回复一下,给大家分享一下
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2020-3-20 01:09:56 | 显示全部楼层
LeoCheng 发表于 2020-3-19 02:03
对了,诡异的是,我还没改FatFs源文件里面的check_fs的参数的时候,刚开始,有几次还能读出来SPI Flash内 ...

是我们开发板的话,下载我们例程就可以恢复才对。
前提是全片擦除一次FLASH
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-1-19
在线时间
11 小时
 楼主| 发表于 2020-3-20 16:54:35 来自手机 | 显示全部楼层
正点原子 发表于 2020-3-20 01:09
是我们开发板的话,下载我们例程就可以恢复才对。
前提是全片擦除一次FLASH

嗯,只有一个最小系统板,我试下
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2020-1-19
在线时间
11 小时
 楼主| 发表于 2020-3-22 02:33:51 | 显示全部楼层
正点原子 发表于 2020-3-20 01:09
是我们开发板的话,下载我们例程就可以恢复才对。
前提是全片擦除一次FLASH

关于这个问题,可以结贴了:

写到63扇区的原因:
格式化时没选FM_SFD选项。新的FatFs,其格式化函数定义为FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len);其opt参数的fmt字段,其注释为/* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */因此,该选项不仅要选择FM_FAT,还要或上一个FM_SFD,即:FM_FAT | FM_SFD.
普通磁盘,由于其0扇区为MBR或GPT引导扇区,因此,其FAT文件系统数据不能写到0扇区,FatFs默认是写到63扇区(如果使能了FF_MULTI_PARTITION,会根据引导扇区内的分区表来确定其位置)。
SFD超级软盘,由于只有一个分区,因此,其FAT文件系统数据可以直接写到0扇区。

从0扇区读取数据验证的原因:
SFD超级软盘,其0扇区即为FAT文件系统数据。
普通磁盘,0扇区保存了MBR或GPT的分区表,因此,为了找到目标卷,必须从0扇区读出分区表,然后根据分区表找到目标分区(卷)所在的扇区,进而读取到FAT文件系统数据。而MBR引导扇区,其末尾2字节也是55AA(GPT引导扇区不确定,但是为了兼容,应该也是一样的,只不过其引导程序不保存在首扇区而已),因此挂载卷的时候,会首先验证引导扇区是否有效(即末尾是否55AA),无效,则返回3,即:if (ld_word(fs->win + BS_55AA) != 0xAA55) return 3;

而我之前在SPI Flash已有出厂数据和文件系统的时候,验证首扇区末尾55AA失败。其原因还是底层IO驱动有问题。SPI的读函数,我给增加了一个ReadWriteBytes的函数,即一次读写多个数据(为了减少函数调用开销)。问题就出在该函数上。
其代码如下:
  1. byte SPIDriver_ReadWriteBytes(SPI_TypeDef* spi, byte* Data, ushort Count, bool WriteOrRead) {
  2.         byte rt = 0;
  3.         if (WriteOrRead)
  4.                 for (ushort i = 0; i < Count; ++i) {
  5.                         while ((spi->SR & SPI_I2S_FLAG_TXE) == RESET && rt++ < SPI_Driver_RetryTimes);
  6.                         if ((spi->SR & SPI_I2S_FLAG_TXE) == RESET)
  7.                                 return 0xFF;
  8.                         spi->DR = Data[i];
  9.                         while ((spi->SR & SPI_I2S_FLAG_RXNE) == RESET && rt++ < SPI_Driver_RetryTimes);
  10.                         if ((spi->SR & SPI_I2S_FLAG_RXNE) == RESET)
  11.                                 return 0xFF;
  12.                         rt = spi->DR;
  13.                 }
  14.         else for (ushort i = 0; i < Count; ++i) {
  15.                 while ((spi->SR & SPI_I2S_FLAG_TXE) == RESET && rt++ < SPI_Driver_RetryTimes);
  16.                 if ((spi->SR & SPI_I2S_FLAG_TXE) == RESET)
  17.                         return 0xFF;
  18.                 spi->DR = 0xFF;
  19.                 while ((spi->SR & SPI_I2S_FLAG_RXNE) == RESET && rt++ < SPI_Driver_RetryTimes); // 总是在该处超时
  20.                 if ((spi->SR & SPI_I2S_FLAG_RXNE) == RESET)
  21.                         return 0xFF;
  22.                 Data[i] = spi->DR;
  23.         }
  24.         return 0;
  25. }
复制代码

该代码,其在读取数据时,会有一定的几率导致:前面一段数据是正常的(一般约250B左右),后面就会在注释处超时(spi->SR的SPI_I2S_FLAG_RXNE始终不置位,调试器的SPI窗口已经关闭了,非调试模式也不行),然后返回0xFF。然后调用处也没加返回值的错误判断,导致输入缓冲区后半段数据根本没有刷新,所以是0000。然后这也就能解释,为什么刚开始的时候,会有几次能够成功挂载上去了(发生超时有一定的概率,后来为什么每次都挂载不了,具体也不清楚,难道是发生超时的概率升高了?)
后来,还是老老实实地改用
  1. for(; len > 0; --len)
  2.         *data++ = SPIDriver_ReadWriteByte(dev->SPI, 0xFF);
复制代码

这种方式,然后万事大吉。


所以新问题来了,为什么上面一段函数会偶尔在注释处超时?
回复

使用道具 举报

6

主题

315

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1669
金钱
1669
注册时间
2018-1-29
在线时间
160 小时
发表于 2020-3-23 09:26:53 来自手机 | 显示全部楼层
用fatfs v0.12或者 v0.13试试。 我的程序用fatfs v0.14也不好使。
回复

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2020-3-23 12:46:34 来自手机 | 显示全部楼层
Fatfs新版本下有问题,说明你们的驱动还是不够稳定啊
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-23 04:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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