你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】stm32--FatFs调试过程(SPIFlash)

[复制链接]
STMCU小助手 发布时间:2022-2-2 18:00
本文仅记录在初次移植完成后,遇到的问题,和解决的过程。
调试记录:
  • 问题1:f_open返回3,即磁盘没有准备好。5 D) V4 Y/ `' N  _( Z6 \! f
    • 原因:这是因为逻辑驱动器是按默认(0)初始化的,而在宏定义中把SPIFlash定义为了1。将SPIFlash定义为0即可。
      . Q% q4 Y, x3 c' {
  • 问题2:开机是否格式化?如果不格式化,SPIFlash无法创建创建文件系统;又不可能每次开机都格式化。+ |2 [4 V. b) j" N3 U$ V
    • 处理:f_getfree检测FAT卷空间,如果返回是FR_NO_FILESYSTEM,说明没有格式化过,进行格式化。
      ) o% ]' Y* K7 c2 V. y
  • 问题3:格式化失败(返回FR_DISK_ERR)【此时的BLOCK_SIZE参数是错误的】# v3 N7 g+ h3 h1 K2 V
    • 原因:diskio.c中底层写入函数入口判断错误,入口判断参数是否正常时 if(sector > SEC_MAX || sector + count > SEC_MAX) return RES_PARERR; 出错,第二个判断条件应为sector + count - 1而非sector + count。
      2 L1 l! b& F  y* y: X4 a' w
  • 问题4:只能格式化为FAT12格式。
    * {1 I( K+ ~6 d
    • 调试过程:仿真跟踪f_mkfs源代码:
    • 如果输入参数为FAT,函数中会减去63个扇区用于存放分区表,此时就只剩4033个扇区了;之后由 1.png 这段代码,sz_vol为4033,pau为1,得出n_clst为4033<4085(MAX_FAT12),于是设为FAT12格式
    • 如果输入参数为FAT+SFD,sz_vol值为4096,之后由 2.png 这段代码,pau为2,再执行1中代码,n_clst为2048,依然是FAT12格式
    • 输入参数FAT+SFD,并在输入参数中强制pau为1,倒是不会置为FAT12格式,但是格式化返回FR_MKFS_ABORTED错误。查找错误原因,发现问题来自 4.png 这段代码。sz_blk由disk指令Get_Block_Size得到,这里我把这个值设为了4096(一个扇区),这样最后得到的n_clst为0,小于MAX_FAT12,返回错误代码。实际上这个值是以扇区为单位,应设为1。1 K& e* |; F7 ]  n7 `
  • 问题5:不正确的格式化。【此时对FAT文件系统结构的理解是错误的】# [. |. x' D( h4 R3 e
    • sz_fat只有3,于是后面格式化只格式化了3个扇区。可是sz_fat和n_clst是互斥的:如果sz_fat很大就意味着n_clst很小,无法格式化为FAT16;如果n_clst格式化为FAT16那就意味着sz_fat是小于10的数。
    • 此时尝试创建文件,“果然”可以创建成功、但无法正确保存:每次重启后能载入文件系统,但获取不到之前创建的文件。
    • 于是开始走向错误的尝试路径:尝试减小单个扇区的定义大小、单次擦除多个扇区。
    • 尝试将单个扇区自定义为1k,block定义为4扇区,修改disk_read函数、disk_wirte函数、disk_ioctl函数,以及格式化函数f_mkfs的输入参数。
      0 m6 h2 _! y; r2 q( ^" R' {
      • 结果:不可行。实际操作中会有写入单个扇区的情况(分区:1系统保留区-x数据区-y页表区),如此,在写入第一个数据扇区的时候,会执行一次erase函数,擦除刚刚写入的系统保留区。类似的情况也会出现在其他地方。
      • 修改为仅在初始扇区为4的倍数时,允许擦除。如此不会擦除正确写入的数据,但有可能无法成功修改某些单个小扇区。
      • 修改为,在写入扇区时,如果判断到初始扇区不为4的倍数或结束扇区不为4的倍数,先将4k真实扇区数据读出,再擦除真实扇区,然后将读出的数据写入需写入扇区前的部分,最后将需写入的数据写入。
      • 依旧不可行,格式化能返回ok,但重启后出现无文件系统的错误,说明文件系统写入还是有问题。
        1 c2 `4 \  C& d
      : K3 E2 v  `- S
  • 解决问题5中文件无法正确保存的问题" i% w0 n) j" S* L( p7 ?
    • 通过USB程序,将模块连到电脑上格式化。
      8 c* F, C6 |! V9 ?
      • 用8k/扇区格式化,能格式化成功。但将格式化好的模块下载fatfs程序时,fatfs读取出现问题,因为fatfs最大支持的单扇区大小为4096字节。
      • 用我的电脑4k/扇区格式化,一直格式化失败,串口打印出log发现写入都没有问题,写入后的读取却读不到有效内容。
      • 在程序里面加上一段打印打码,执行对0扇区的写入后,打印写入到0扇区的内容,从而判断到底是什么导致了格式化失败。结果,加上这段代码后,格式化成功。
      • 判断为需要在写入0扇区后延时一段时间再读取才能成功。加入延时函数后,格式化没有问题了。
        3 v0 A5 ]  G) t( B- ]7 {
    • 将格式化好的模块下载fatfs程序后,读取无问题,获取剩余空间大小也没有问题。但是,在f_open创建文件、f_write进行写入操作、f_close关闭文件后,下次用f_open打开这个文件(OPEN_EXISTING选项)时,依然返回找不到文件的错误。
    • 经过各种调试,发现在disk_write函数中,每次进出打断点,这样进行的f_write和f_close操作,能成功保存文件、修改页表,下次f_open能够读到这个文件。
    • 判断是延时问题,尝试在disk_write出口处加上100ms延时,问题解决。实验发现,延时最短到15ms的时候,可以正常保存文件。最终将延时设为20ms。- }) l9 ~2 Y) X. l6 Z' P, s
  • 解决格式化失败的问题:
    & F# D2 w$ `% F4 h: M; d+ L
    • 既然无法保存的问题出自写入后的延时,那么之前的格式化之后文件无法保存的问题是否也出自这里?
    • 之前的判断认为是fatfs将页表存在末4个扇区内,所以导致文件无法保存的原因是只格式化了前面的数个扇区,没有成功格式化。现在认为这个判断是错误的。
    • 因为经过调试发现,前几个扇区都是用于存储fatfs相关内容的。之前以为是数据区的sz_fat,目前看来应该是fat文件页表;之前认为是文件页表的sz_dir,实际上是fat目录表。
    • 也就是说,fat16文件系统的结构是这样的:(参见https://blog.csdn.net/sikuon/article/details/75222224( H& I7 W0 N" b# B% i; W
      • rsv:系统保留区(0扇区的DBR,可能存在的分区表,以及其他保留扇区),位于第0--x扇区。
      • fat:文件页表区(有时会有FAT2作为FAT的备份),位于x+1--y扇区。
      • dir:文件目录表区,位于y+1--z扇区
      • data:数据区,位于z+1--末扇区4 d% u( p( M1 p6 x; `
    • 那么,昨天遇到的情况,格式化只格了前几个扇区,是正确的操作。如此说来,GET_BLOCK_SIZE的功能的确如我所理解的那样,是扇区数量。block_size就是一次性擦除的扇区数量。
    • 如此,格式化的参数有两种选择:
      # t- P  S5 J2 f& E6 k1 z4 J
      • 根据昨天的经验,用f_mkfs("", FM_FAT, 0, work_buffer, FF_MAX_SS);这样的参数格式化,只能格式化为FAT12(或许应该再试试,因为最初用这种参数格式化时,用的BLOCK_SIZE是4096--与此无关,只要不是SFD格式,都会-63扇区作为起始扇区)。
      • 根据昨天的经验,用f_mkfs("", FM_FAT+FM_SFD, 4096, work_buffer, FF_MAX_SS);这样的参数,能成功格式化为FAT16,但这是软盘格式,电脑上不一定可用。
      • 最终试验发现第一种会格式化为FAT12,第二种可行。
        : C9 @; n, B2 g0 G1 A' T/ K% D+ n

      " G  C, i4 p3 `
  • 在最开始遇到的一个问题,后来在另一个用到Fatfs的板子上又遇到了:
    7 p2 y, c  p/ m# |
    • 现象:开机f_getfree函数返回FR_NO_FILESYSTEM,进入格式化;f_mkfs函数返回FR_OK,格式化成功;下一步f_open函数又返回FR_NO_FILESYSTEM错误。
    • 原因:SPIFlash虚焊。焊好后恢复正常。( [5 v& B5 h+ A! a( Z+ \2 c
    5 \: U# c: n4 K' ~7 p: A. A9 S" y- b6 l
收藏 评论0 发布时间:2022-2-2 18:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版