基于STM32的FATFS文件系统移植
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于STM32的FATFS文件系统移植
经过将近1个月的时间,终于完成了STM32是FATFS文件系统移植,说来是够艰辛的,SDIO章节是我学习cortex m3以来消耗时间最多的章节。这里说一些个人对于SDIO的看法,其实SDIO属于意法半导体公司在cortex m3内核之外(在芯片之内)添加的功能外设,完全属于意法的杰作了。关于SD卡的读写,分为SPI模式和SD模式(专用模式),这两种模式都必须遵循SD2.0协议。SPI模式控制方法相对较为简单,操作简洁,但失去了速度;SD模式控制方法相对较为复杂一点,操作繁琐,但具有高速的特点。
FATFS文件系统是一种兼容性比较高的文件管理系统,兼容
FAT32、FAT16。关于文件系统的细节,如果认真研究的话,应该会觉得作者的伟大,惊叹代码的绝妙。
我们要想移植FATFS,首先要做的是编写基于SDIO模式的SD卡底层驱动,这部份完整的驱动代码较多,大概有2000多行,但我们首先需要克服心理作用,再长的代码只要理解之后,都很简单。意法在参考手册中介绍SDIO时,上下文比较乱,其中还夹杂讲解了一些SD2.0协议,使得初学者云里雾里。因为SDIO是属于一种完全的外设接口,所以在讲解的过程中必须与实际的外设SD卡联系起来。
STM32的SDIO接口兼容性很高,可以兼容SD1.0卡、2.0卡、MMC 卡、多媒体卡等,与多媒体卡4.2支持三种不同的数据总线模式:1位、4位和8位,在8位的模式下速度可以达到48MHZ,但在SD2.0协议中只支持两种总数总线模式:1位和4位,在SDIO中存在两种状态机:命令状态机(CPSM)和数据状态机(DPSM),两者的使能信号独立,用于控制外部双向驱动器,命令是通过CMD命令线单线串行发送的,而数据是由于DATx数据线传输(1位或4位),每当CPSM发送一条命令给卡时,如工作正常的话,卡都会有与CPSM中设置响应格式相对应的响应内容(短响应与长响应),两者的细节在下面讲到。
SDIO功能分为两个部分,一个就是SDIO适配器模块,可以实现所有MMC/SD/SD I/O卡的相关功能,如时钟的产生、命令和数据的传输;还有就是AHB总线接口操作SDIO适配器模块中的寄存器,并产生中断和DMA请求信号。上面提到的数据总线的宽度为分为1位或4位(本文是针对SD2.0协议进行主要说明),在上电复位后,系统缺省为1位数据宽度——DAT0用于数据传输。SD卡或SD I/O卡可以使用两种数据宽度模式,这两种卡的所有数据线都需要设置为复用推挽模式。命令线CMD有两种操作模式:1、MMC卡V3.31或之前版本的卡在初始化时为
复用开路模式;2、SD卡或SD I/O卡或MMC V4.2在初始化时命令传输线工作在复用推挽模式。还有就是卡的时钟线(SDIO_CK),这个时钟频率对于不同的卡需要工作在不同的范围,这个我们就不细说了。SDIO的时钟可以分为两个,分为SDIO适配器时钟
(SDIOCLK=HCLK)和AHB总线时钟(HCLK/2),还有HCLK就是SYSCLK。既然提到外设接口,那就要清楚一共有几根线与主控芯片相连,分为SDIO_CK\SDIO_CMD\SDIO_D[7:0],本文是对SD2.0卡进行论述,所以只用到了SDIO_CK/SDIO_CMD/SDIO_D[3:0],因为SD卡不支持8线模式。
SDIO适配器主要全为5个部分:适配器寄存器模块、控制单元、命令通道、数据通道、数据FIFO。这5个部分中,不同部分使用的时钟也有不同,适配器寄存器和FIFO使用HCLK/2,控制单元、命令通道和数据通道使用的是SDIOCLK=HCLK。其实这5个部分,对于初学者来说,根本分不清有何具体区别。适配器寄存器模块包含所有系统寄存器,如用于存放状态位的SDIO_STA和清除中断寄存器SDIO_ICR,对相应寄存器写入清除中断标志(产生清除信号);控制单元有于电源管理和卡的时钟分频设置;命令通道(CPSM)主要用于向卡发送相应的命令并从卡接收相应的响应内容,实现主机与卡之间的控制信息交互,这里就必须提到SDIO_CMD命令寄存器,这个寄存器就是负责向发送命令的,与该寄存器相配合的还有一个参数寄存器(发送命令参数)SDIO_ARG,命令寄存器中存放了命令索引(命令号)和对应命令的等待响应设置和CPSM等待中断请求设置(这个设置一般使用无等待,关闭命令超时控制,改为中断清除方式,关于这个命令超时控制就是设定了一定的时间,在这个时间之间必须得到响应,否则状态机将进入空闲状态),还有就是命令响应了,命令响应寄存器SDIO_RESPCMD用于保存接收到的响应命令索引(如命令发送正常,得到响应命令索引和发送的一致,作为一个控制命令的回应),对于一些带响应的命令(只有cmd0没有响应),都会返回一些参数(如返回卡状态寄存器、CSD、CID),这些参数保存在响应寄存(SDIO_RESPx 1--4)中,该寄存器有4个,对于命令的短响应只用到SDIO_RESP1,其他3个寄存器不用,对于命令长响应,4个寄存器都用到,其实命令本身就决定了是否需要响应和响应的类型,48位(短响应:参数只有32位)还是136位(长响应,参数只有127位)。命令通道每发送一个命令,都有相应的通道状态标志来反应当前命令通道的状态,如CMDREND(响应的CRC正确)CCRCFAIL (响应的CRC错误)CMDSENT(命令已经发出,命令指不需要响应的命令)CTIMEOUT(响应超时)CMDACT(正在发送命
令)。在我们编写SD卡底层驱动时最常用的就是这些标志了,每发送一次命令,都要观察这个标志位的情况,以便程序员了解当前卡对刚发的命令的反应。数据通道(DPSM)用于主机与卡之间的数据通信,这与CPSM中的命令信息都是一些二进制“数据”,其实数据与命令之间本质上是一样的,但只是用户或设备对这些二进制的定义不同,用于控制设备的二进制串称为命令,而用于交互一些具体信息的二进制串称为数据。DPSM可以选择数据总线宽度,如1位数据宽度是指每个时钟数据线D0有一位数据传输,而4位数据宽度是指每个时钟数据线D4_0有四位数据传输,8位宽度则一次8位数据传输喽(SD卡不能使用8位,一般用于多媒体卡),而系统缺省为1位宽度,还有一点要说明的就是命令线和数据线都是双向传输的,而时钟线是单向传输的。在使能数据发送或接收时,DPSM就是进行Wait_S或Wait_R状态,如发送FIFO中有数据,就会进行发送状态,或接收FIFO接收到开始位,就会进入接收状态。但这个等待发送或等待接收不能一直等,等待时间是有限制的,由相关寄存器SDIO_DTIMER设置,当DPSM进行等待状态(发送或接收)时,一个计数器从该寄存器中加载数据,进行倒计时,当计数到0时,将设置超时标志关进入空闲状态。数据状态机也有反应数据传输状态的标志位,发送FIFO状态标志有
TXFIFOF/TXFIFOE/TXFIFOHE/TXDAVL/TXUNDERR和接收FIFO状态标志有RXFIFOF/RXFIFOE/RXFIFOHF/RXDAVL/RXOVERR。关于FIFO这个名词,其实是像数据结构中讲到的队列一样,先进先出,称为数据缓冲区,用户操作时只需直接读取SDIO->FIFO即可。FIFO的数据传输分为块传输和流传输,一般使用块传输。这个数据缓冲区一共有32个字的空间,如流传输下接收的数据超过32个字,而用户没有读取的话,将产生上溢错误。在与SD卡进行数据通信时,为保证数据的高速传输,我们一般使用DMA来将FIFO中的数据搬到内存中,而不需要人为的去读取。SDIO的数据通道是半双工通信,不能同时接收和发送,有两个标志位表示当前数据通道的状态:TXACT和RXACT,前者标志数据通道在发送FIFO,后者标志数据通道正在接收数据,这两个标志位是互斥的。到这里SDIO适配器已经基本了解了,就需要对SD卡通行操作了。
上述内容,作为初学者想真正理解,还是需要在下面对SD卡进行实际操作时才能真正了解其中的含义。
首先应设置与SD相连的GPIO的模式,使用SD卡的话,就需要设置CK/CMD/DAT3/DAT2/DAT1/DAT0为复用推挽输出,开启相应端口的时钟和SDIO时钟,如使用DMA的话,还需开启DMA2时钟。接下来就