stm32--FatFs调试过程(SPIFlash)
移植方法参见我的另一篇博客:《stm32--FatFs移植(SPIFlash)》。
本文仅记录在初次移植完成后,遇到的问题,和解决的过程。
调试记录:
- 问题1:f_open返回3,即磁盘没有准备好。
- 原因:这是因为逻辑驱动器是按默认(0)初始化的,而在宏定义中把SPIFlash定义为了1。将SPIFlash定义为0即可。
- 问题2:开机是否格式化?如果不格式化,SPIFlash无法创建创建文件系统;又不可能每次开机都格式化。
- 处理:f_getfree检测FAT卷空间,如果返回是FR_NO_FILESYSTEM,说明没有格式化过,进行格式化。
- 问题3:格式化失败(返回FR_DISK_ERR)【此时的BLOCK_SIZE参数是错误的】
- 原因:diskio.c中底层写入函数入口判断错误,入口判断参数是否正常时 if(sector > SEC_MAX || sector + count > SEC_MAX) return RES_PARERR; 出错,第二个判断条件应为sector + count - 1而非sector + count。
- 问题4:只能格式化为FAT12格式。
- 调试过程:仿真跟踪f_mkfs源代码:
- 如果输入参数为FAT,函数中会减去63个扇区用于存放分区表,此时就只剩4033个扇区了;之后由这段代码,sz_vol为4033,pau为1,得出n_clst为4033<4085(MAX_FAT12),于是设为FAT12格式
- 如果输入参数为FAT+SFD,sz_vol值为4096,之后由这段代码,pau为2,再执行1中代码,n_clst为2048,依然是FAT12格式
- 输入参数FAT+SFD,并在输入参数中强制pau为1,倒是不会置为FAT12格式,但是格式化返回FR_MKFS_ABORTED错误。查找错误原因,发现问题来自这段代码。sz_blk由disk指令Get_Block_Size得到,这里我把这个值设为了4096(一个扇区),这样最后得到的n_clst为0,小于MAX_FAT12,返回错误代码。实际上这个值是以扇区为单位,应设为1。
- 问题5:不正确的格式化。【此时对FAT文件系统结构的理解是错误的】
- 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的输入参数。
- 结果:不可行。实际操作中会有写入单个扇区的情况(分区:1系统保留区-x数据区-y页表区),如此,在写入第一个数据扇区的时候,会执行一次erase函数,擦除刚刚写入的系统保留区。类似的情况也会出现在其他地方。
- 修改为仅在初始扇区为4的倍数时,允许擦除。如此不会擦除正确写入的数据,但有可能无法成功修改某些单个小扇区。
- 修改为,在写入扇区时,如果判断到初始扇区不为4的倍数或结束扇区不为4的倍数,先将4k真实扇区数据读出,再擦除真实扇区,然后将读出的数据写入需写入扇区前的部分,最后将需写入的数据写入。
- 依旧不可行,格式化能返回ok,但重启后出现无文件系统的错误,说明文件系统写入还是有问题。
- 解决问题5中文件无法正确保存的问题
- 通过USB程序,将模块连到电脑上格式化。
- 用8k/扇区格式化,能格式化成功。但将格式化好的模块下载fatfs程序时,fatfs读取出现问题,因为fatfs最大支持的单扇区大小为4096字节。
- 用我的电脑4k/扇区格式化,一直格式化失败,串口打印出log发现写入都没有问题,写入后的读取却读不到有效内容。
- 在程序里面加上一段打印打码,执行对0扇区的写入后,打印写入到0扇区的内容,从而判断到底是什么导致了格式化失败。结果,加上这段代码后,格式化成功。
- 判断为需要在写入0扇区后延时一段时间再读取才能成功。加入延时函数后,格式化没有问题了。
- 将格式化好的模块下载fatfs程序后,读取无问题,获取剩余空间大小也没有问题。但是,在f_open创建文件、f_write进行写入操作、f_close关闭文件后,下次用f_open打开这个文件(OPEN_EXISTING选项)时,依然返回找不到文件的错误。
- 经过各种调试,发现在disk_write函数中,每次进出打断点,这样进行的f_write和f_close操作,能成功保存文件、修改页表,下次f_open能够读到这个文件。
- 判断是延时问题,尝试在disk_write出口处加上100ms延时,问题解决。实验发现,延时最短到15ms的时候,可以正常保存文件。最终将延时设为20ms。
- 通过USB程序,将模块连到电脑上格式化。
- 解决格式化失败的问题:
- 既然无法保存的问题出自写入后的延时,那么之前的格式化之后文件无法保存的问题是否也出自这里?
- 之前的判断认为是fatfs将页表存在末4个扇区内,所以导致文件无法保存的原因是只格式化了前面的数个扇区,没有成功格式化。现在认为这个判断是错误的。
- 因为经过调试发现,前几个扇区都是用于存储fatfs相关内容的。之前以为是数据区的sz_fat,目前看来应该是fat文件页表;之前认为是文件页表的sz_dir,实际上是fat目录表。
- 也就是说,fat16文件系统的结构是这样的:(参见https://blog.csdn.net/sikuon/article/details/75222224)
- rsv:系统保留区(0扇区的DBR,可能存在的分区表,以及其他保留扇区),位于第0--x扇区。
- fat:文件页表区(有时会有FAT2作为FAT的备份),位于x+1--y扇区。
- dir:文件目录表区,位于y+1--z扇区
- data:数据区,位于z+1--末扇区
- 那么,昨天遇到的情况,格式化只格了前几个扇区,是正确的操作。如此说来,GET_BLOCK_SIZE的功能的确如我所理解的那样,是扇区数量。block_size就是一次性擦除的扇区数量。
- 如此,格式化的参数有两种选择:
- 根据昨天的经验,用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,第二种可行。
- 在最开始遇到的一个问题,后来在另一个用到Fatfs的板子上又遇到了:
- 现象:开机f_getfree函数返回FR_NO_FILESYSTEM,进入格式化;f_mkfs函数返回FR_OK,格式化成功;下一步f_open函数又返回FR_NO_FILESYSTEM错误。
- 原因:SPIFlash虚焊。焊好后恢复正常。
转载于:https://www.cnblogs.com/cage666/p/9206853.html
stm32--FatFs调试过程(SPIFlash)相关推荐
- STM32调试过程中出现的问题1:
STM32调试过程中出现的问题1: -\HARDWARE\KEY\key.c(47): error: #29: expected an expression if(key_up&&(K ...
- PLC、STM32单片机、PC端485modbus通信调试过程
设备明细: PLC:埃森ARS-010-32PLC,软件AR Logic Editor. 单片机:STM32F103RCT6,软件keil. 测试软件:modbus串口调试软件.modbus poll ...
- Proteus仿真stm32和51单片机,串口通信调试过程记录
前言 本文所用Proteus版本为8.10,主要内容为在Proteus中仿真stm32和51单片机进行串口通信,记录了仿真过程中遇到的问题和解决办法. 这里要注意的是,在Proteus中 ...
- STM32(Cortex-M3)启动过程+IAR中xcl及icf文件详解
一:STM32(Cortex-M3)启动过程(入口地址) ARM7和ARM9启动时从绝对地址0X00000000开始执行复位中断程序,即固定了复位后的起始地址,但中断向量表的位置是可变的. Corte ...
- stm32时钟初始化过程浅析
stm32时钟初始化过程浅析 (大致梳理了一下32启动过程中时钟的初始化过程) 加载main函数之前(启动代码中LDR R0, =__main之前),HCLK总线时钟默认上电是上一次断电前配置的频率 ...
- 学习 stm32 FATFS 系统文件函数使用和学习查看说明以及常用函数例程
学习 stm32 FATFS 文件的日常操作,本次通过SDIO模式进行存储卡的设备连接,进行数据的读取操作.之前介绍过一起SD卡的读取操作, stm32 SD(SDSC)卡的学习与SPI 模式应用(卡 ...
- STM32电路板调试Could not power up debug port
前段时间调试一块STM32的实验板,下载程序始终提示:Could not power up debug port: Control/Status register reads 000000F0. 网上 ...
- STM32——USMART调试组件实验-M4
什么是USMART? USMART是为STM32开发平台开发的一种类似Linux的shell的调试工具.具体工作过程是通过串口发送命令给单片机,然后单片机收到命令之后调用单片机里面对应的相关函数并执行 ...
- STM32的调试方式、更新程序、仿真以及补救措施
STM32的调试方式.更新程序.仿真以及补救措施 1. STM32的调试方式选择 STM32支持JTAG和SWD两种调试方式,且默认状态下这两种调试功能都是开启的. 由此我们可以知道: 如果要使用JT ...
最新文章
- 如何从功能测试转化自动化测试?
- 苹果的浏览器safari无法识别 2016-1-1这样的日期,会返回Invalid Date
- 某都计算机考研计算机组成原理,东北大学2000年考研真题-计算机组成原理
- struts深入原理之RequestProcessor与xml
- Ansible管理节点过多导致的超时问题解决方法
- CSS定位网页中的元素
- 唐骏:幸福与财富无关
- 吴恩达机器学习笔记(二) —— Logistic回归
- 深度解析容器化技术在广发证券交易系统的应用【转】
- 惠斯通电桥信号调理芯片_变频器通电后无反应,如何检查维修?
- python软件下载3版本-Python软件下载-Python最新版 v3.7.3 - 动力软件园
- Python+selenium+eclipse执行web自动化(四)控件处理
- pagerTabStrip例子
- android usb pos机,USB支持安卓系统NFC刷卡器|RFID刷卡机ACR122U
- 计算机软件工程自考,自考软件工程试题及答案2021年10月
- matlab 读取odb,求教用C++方式读取abaqus的odb数据中的问题!!!
- 觅知blibli专业版弹幕播放器开源无加密JSON解析版-后台功能一键管理-开源版22-8-24
- mt6573的DSI 接口
- 近端梯度法(Proximal Gradient Method, PG)
- Gateway杂谈:线上引流和灰度发布
热门文章
- Photon服务器引擎入门
- python基础之模块之os模块
- Oracle DataGuard数据备份方案详解
- C#在线打开编辑保存Excel文件[pageoffice]
- @Controller 不能访问到
- 如何从Alfresco中提取Language Pack
- Linq to Oracle 使用教程(七)将数据库的存储过程映射到方法
- linux tcp cork,Socket选项系列之TCP_CORK(转)
- IDEA启动hadoop报Could not locate executable null\bin\winutils.exe in the Hadoop binaries.错误的解决办法
- deephash项目代码使用指北