查看: 409  |  回复: 0
基于STM32+CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试(下...

主题

回复
发表于2023-03-03 15:23:33 | 显示全部楼层
1# 电梯直达

四、移植FATFS文件系统前面第3章,完成了SD NAND的驱动代码编写,这一章节实现FATFS文件的移植。

4.1 FATFS文件系统介绍(1)介绍FatFs 是一种完全免费开源的 FAT 文件系统模块,专门为小型的嵌入式系统而设计。它完全用标准C 语言编写,所以具有良好的硬件平台立性,可以移植到 8051、 PIC、 AVR、 SH、 Z80、 H8、 ARM 等系列单片机上而只需做简单的修改。它支持 FATl2、 FATl6 和 FAT32,支持多个存储媒介;有独立的缓冲区,可以对多个文件进行读/写,并特别对 8 位单片机和 16 位单片机做了优化。

(2)特点【1】Windows兼容的FAT文件系统【2】不依赖于平台,易于移植【3】代码和工作区占用空间非常小【4】多种配置选项【5】多卷(物理驱动器和分区)【6】多ANSI/OEM代码页,包括DBCS【7】在ANSI/OEM或Unicode中长文件名的支持【8】RTOS的支持【9】多扇区大小的支持【10】只读,最少API,I/O缓冲区等等

(3)移植性fatfs模块是ANSI C(C89)编写的。 没有平台的依赖, 编译器只要符合ANSI C标准就可以编译。

fatf模块假设大小的字符/短/长8/16/32位和int是16或32位。 这些数据类型在integer.h文件中定义。这些数据类型在大多数的编译器中定义都符合要求。 如果现有的定义与编译器有任何冲突发生时,需要自己解决。

4.2 下载源码下载地址:http://elm-chan.org/fsw/ff/00index_e.html点击输入图片描述(最多30字)FATFS有两个版本,一个大版本,一个小版本。小版本主要用于8位机(内存小)使用。下载图:点击输入图片描述(最多30字)

4.3 源码结构介绍将下载的源码解压后可以得到两个文件夹: doc 和 src。 doc 里面主要是对 FATFS 的介绍(离线文档—英文和日文),而 src 里面才是我们需要的源码。其中,与平台无关的是:ffconf.h     FATFS配置文件ff.h        应用层头文件ff.c        应用层源文件diskio.h    硬件层头文件interger.h  数据类型定义头文件option      可选的外部功能(比如支持中文等)

与平台相关的代码:

diskio.c     底层接口文件(需要用户提供)

FATFS 模块在移植的时候,我们一般只需要修改 2 个文件,即 ffconf.h 和 diskio.c。FATFS模块的所有配置项都是存放在 ffconf.h 里面,我们可以通过配置里面的一些选项,来满足自己的需求。点击输入图片描述(最多30字)

最顶层是应用层,使用者无需理会 FATFS 的内部结构和复杂的 FAT 协议,只需要调用FATFS 模块提供给用户的一系列应用接口函数,如 f_open, f_read, f_write 和 f_close 等,就可以在 PC 上读写文件那样简单。

中间层 FATFS 模块, 实现了 FAT 文件读/写协议。 FATFS 模块提供的是 ff.c 和 ff.h。除非有必要,使用者一般不用修改,使用时将头文件直接包含进去即可。

需要我们编写移植代码的是 FATFS 模块提供的底层接口,它包括存储媒介读/写接口 ( disk、I/O) 和供给文件创建修改时间的实时时钟。

4.4 下载源码并加入到工程先准备好一个有SD NAND驱动代码的STM32工程(代码前面第3章已经贴了),接着就完成下面的步骤。点击输入图片描述(最多30字)打开KEIL工程,添加FATFS文件源码:点击输入图片描述(最多30字)

点击输入图片描述(最多30字)

加入.h文件主要是方便配。cc936.c 用于支持中文。4.5 修改代码进行移植(1)修改diskio.c文件点击输入图片描述(最多30字)注释掉现在不需要的用到的文件,因为我们现在用的是SD卡,与USB,ATA,MMC卡没关系。

并加入一个新的宏 :

#define SD 0

定义SD卡的物理驱动器号为0。

修改 disk_status函数,该函数主要是用来获取磁盘状态。现在未用到,可以直接把函数体内代码删除。

修改截图:点击输入图片描述(最多30字)代码示例:

#include "diskio.h"  /* fatf底层API */#include "sd.h"      /* SD卡驱动头文件  *//* 定义每个驱动器的物理驱动器号*/#define SD    0

/*-----------------------------------------------------------------------*//* 获取设备(磁盘)状态                                                     *//*-----------------------------------------------------------------------*/

DSTATUS disk_status (BYTE pdrv/* 物理驱动识别 */){   return 0;  //该函数现在无需用到,直接返回0}

修改disk_initialize函数,添加SD卡的初始化,其他不用到的代码直接删掉,该函数成功返回0,失败返回1。修改截图:点击输入图片描述(最多30字)代码示例:

/*-----------------------------------------------------------------------*//* 初始化磁盘驱动                                                        *//*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (BYTE pdrv/* 物理驱动识别 */){DSTATUS stat;int result;

switch (pdrv) {case SD :            //选择SD卡stat=SD_Init();   //初始化SD卡-用户自己提供}if(stat)return STA_NOINIT;  //磁盘未初始化return 0; //初始化成功}

修改disk_read函数,加入SD卡读任意扇区的函数(需要用户自己提供),其他不用到的选项可以删掉。点击输入图片描述(最多30字)

修改代码如下:/*-----------------------------------------------------------------------*//* 读扇区                                                                *//*-----------------------------------------------------------------------*/DRESULT disk_read (BYTE pdrv,/* 物理驱动编号 - 范围0-9*/BYTE *buff,/* 数据缓冲区存储读取数据 */DWORD sector,  /* 扇区地址*/UINT count/* 需要读取的扇区数*/){DRESULT res;int result;switch (pdrv) {case SD:  res=SD_Read_Data((u8*)buff,sector,count);  //读SD扇区函数--用户提供  return res; //在此处可以判错误}return RES_PARERR;  //无效参数}

修改disk_write 函数,添加写扇区函数:点击输入图片描述(最多30字)代码:/*-----------------------------------------------------------------------*//* 写扇区                                                                *//*-----------------------------------------------------------------------*/

#if _USE_WRITEDRESULT disk_write (BYTE pdrv,  /* 物理驱动号*/const BYTE *buff,       /* 要写入数据的首地址 */DWORD sector,   /* 扇区地址 */UINT count   /* 扇区数量*/){DRESULT res;int result;

switch (pdrv) {case SD:res=SD_Write_Data((u8*)buff,sector,count); //写入扇区  return res;}return RES_PARERR;  //无效参数}#endif

修改disk_ioctl 函数,填充ioctl命令功能。这些功能是标准的命令,在diskio.h有定义。点击输入图片描述(最多30字)代码如下:

/*-----------------------------------------------------------------------*//* 其他函数                                              *//*-----------------------------------------------------------------------*/

#if _USE_IOCTLDRESULT disk_ioctl (BYTE pdrv,/* 物理驱动号 */BYTE cmd,  /* 控制码  */void *buff/* 发送/接收数据缓冲区地址 */){DRESULT res;int result;

switch (pdrv) {case SD: switch(cmd) { case CTRL_SYNC:      //等待写过程 SD_CS(0);          //选中SD卡 if(SD_Wait_Ready())result = RES_ERROR;/*等待卡准备好*/     else res = RES_OK;     //成功 SD_CS(1);            //释放SD卡                        break;   case GET_SECTOR_SIZE://获取扇区大小   *(DWORD*)buff = 512;         res = RES_OK;     //成功        break;  case GET_BLOCK_SIZE:    //获取块大小*(WORD*)buff = 8;      //块大小(扇区为单位),一块等于8个扇区         res = RES_OK;         break;  case GET_SECTOR_COUNT: //获取总扇区数量        *(DWORD*)buff = SD_Get_Sector_Count();        res = RES_OK;        break; default:  //命令错误        res = RES_PARERR;        break; }return res;}return RES_PARERR;  //返回状态}

(2)修改ffconf.h文件需要注意的一些宏配置:

#define _CODE_PAGE936   //采用中文GBK编码       (64行)#define_USE_LFN3     //动态的堆上工作             (93行)#define_MAX_LFN255   /*_USE_LFN选项开关LFN(长文件名)特性。#define _VOLUMES1     /* 支持的磁盘数量(逻辑驱动器)。 */   (142行)#define_MIN_SS512                                  (165行)#define_MAX_SS512   /*这些选项配置支持扇区大小的范围。(512,1024, 4096*/ #define _FS_NORTC    0    /*启用RTC时间功能*/   (202行)#define _NORTC_MON    1#define _NORTC_MDAY1#define _NORTC_YEAR2015 //年  /*需要实现:get_fattime()函数*/

ffconf.h 文件源码:

/*---------------------------------------------------------------------------//  FatFs - FAT文件系统模块配置文件  R0.11a (C)ChaN, 2015/---------------------------------------------------------------------------*/

#define _FFCONF 64180/* 版本识别*/

/*---------------------------------------------------------------------------// 功能配置/---------------------------------------------------------------------------*/

#define _FS_READONLY0/* 这个选项开关只读配置。(0:读/写或1:只读)   /只读配置删除编写API函数,f_write(),f_sync(),   / f_unlink(),f_mkdir(),f_chmod(),f_rename(),f_truncate(),f_getfree()   /写和可选的功能. */


#define _FS_MINIMIZE0/*此选项定义删除一些基本的API函数极小化水平。  /   / 0:所有基本功能都是激活的。  / 1:f_stat(),f_getfree(),f_unlink(),f_mkdir(),f_chmod(),f_utime(),   / f_truncate()和f_rename()函数删除。  / 2:f_opendir(),f_readdir()和f_closedir()中除了1。  / 3:f_lseek()函数删除了2。*/


#define_USE_STRFUNC1/*这个选项开关字符串函数,f_gets(),f_putc(),f_puts()和 / f_printf()。  /   / 0:禁用字符串函数。  / 1:启用没有LF-CRLF转换。  / 2:启用LF-CRLF(回车换行)转换。*/


#define _USE_FIND0/*这个选项开关过滤目录读取特性和相关功能,   / f_findfirst()和f_findnext()。(0:禁用或1:启用)*/


#define_USE_MKFS1/* 这个选项开关f_mkfs()函数。(0:禁用或1:启用) */


#define_USE_FASTSEEK1/* 这个选项开关快速寻求功能。(0:禁用或1:启用) */


#define _USE_LABEL1/*   磁盘卷标这个选项开关功能,f_getlabel()和f_setlabel()。  /(0:禁用或1:启用) */


#define_USE_FORWARD0/*  这个选项开关f_forward()函数。(0:禁用或1:启用)   /启用它,_FS_TINY需要设置为1. */



主题

回复
  • 温馨提示: 标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考: 社区发帖规则
  • 您当前输入了 0 个文字。还可以输入 8000 个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

禁言/删除

X
请选择禁言时长:
是否清除头像:
禁言/删除备注:
昵 称:
 
温馨提示:昵称只能设置一次,设置后无法修改。
只支持中文、英文和数字。

举报

X
请选择举报类型:
请输入详细内容:

顶部