贵阳市建设厅官方网站,企业免费网站优化方案,phpcms移动端网站怎么做,wordpress免邮箱验证文件系统简介
简介可以不看#xff0c;直接看移植步骤 文件系统是介于应用层和底层间的模糊层。底层提供API#xff0c;比如说使用SDIO或者SPI等读写一个字节。文件系统把这些API组合包装起来#xff0c;并且提供一些列函数#xff0c;我们可以使用这些函数进行更进一步的…文件系统简介
简介可以不看直接看移植步骤 文件系统是介于应用层和底层间的模糊层。底层提供API比如说使用SDIO或者SPI等读写一个字节。文件系统把这些API组合包装起来并且提供一些列函数我们可以使用这些函数进行更进一步的对存储设备的操作。
底层操作单片机外设读写。需要我们进行配置。 中层中间层 FATFS 模块实现了 FAT 文件读写协议。一般不管 顶层文件系统提供给我们的函数库我们就是要使用这些。 FATFS的实现过程(白色框中的内容是需要我们自己实现的也就是底层设备的输入输出以及最高层的用户应用程序蓝色框由fatfs提供)
源码获取
FATFS 的源码及英文详述大家可以在http://elm-chan.org/fsw/ff/00index_e.html 这个网站下载。下载解压之后的根目录下有这么两个文件夹源码和帮助文档。 DOC文件夹下有Fatfs提供的具体函数的使用方法 SRC文件的构成如下 Fatfs的源码阅读可以参考《零死角玩转 STM32F103—指南者》中的阅读提示如果只是想使用那么只需要看如何移植
移植FATFS 准备工作
背景两个文件 ffconf.h diskio.c
FATFS 模块在移植的时候我们一般只需要修改 2 个文件即 ffconf.h 和 diskio.c ffconf.h :FATFS模块的所有配置项都是存放在 ffconf.h 里面我们可以通过配置里面的一些选项来满足自己的需求.FATFS 的说明文档里面有很详细的介绍
以spi读写flash为例在实现了spi往flash中读写单个字节的底层代码之后就可以进行fatfs的移植了。
0.创建一个新的工程并且实现简单的点灯spi操作等功能。
1.准备一份工程源码称为SPI—FatFs。将。将 FatFs 源码中的 src 文件夹整个文件夹拷贝一份至“SPI—FatFs 文件系统\USER\”文件夹下并修改名为“FATFS”。文件夹名字没有固定名称这里只是方便书写。
2.打开工程文件,并将 FatFs 组件文件添加到工程中需要添加有 ff.c、diskio.c 和cc936.c 三个文件. 3.添加 FATFS 文件夹到工程的 include 选项中。打开工程选项对话框选择“C/C”选项下的“Include Paths”项目在弹出路径设置对话框中选择添加“FATFS”文件夹 4.修改 diskio.c 文件和 ffconf.h 文件,diskio.c 文件内容是与底层设备输入输出接口函数文件不同硬件设计驱动就不同需要的文件也不同FatFs默认使用日语我们想要支持简体中文需要 修改 FatFs 的配置即修改 ffconf.h 文件。
FatFs 底层设备驱动函数
文件系统实现中间模糊层提供上层函数给用户使用。需要用户实现底层接口。diskio.c 文件内容就是与底层接口相关的。
移植需要用户支持函数一般只有前六个需要使用 disk_statusdisk_initializedisk_read是必要配置的。 disk_writeget_fattimedisk_ioctl (CTRL_SYNC)是实现创建文件、修改文件需要的。 为支持简体中文长文件名称需要添加 ff_convert 和 ff_wtoupper 函数实际这两个已经在 cc936.c 文件中实现我们只要直接把 cc936.c 文件添加到工程中就可以。
移植FATFS 主要步骤
1.配置数据类型在 integer.h 里面去定义好数据的类型。这里需要了解你用的编译器的数据类型并根据编译器定义好数据类型。
2.配置通过 ffconf.h 配置 FATFS 的相关功能以满足你的需要。
3.函数编写打开 diskio.c进行底层驱动编写需要编写 5 个接口函数。
配置integer.h 以定义数据类型(一般不需要)
我们使用的是 MDK5.34 编译器数据类型和 integer.h 里面定义的一致所以此步我们不需要做任何改动。
配置 ffconf.h 选择模式
关于 ffconf.h 里面的相关配置配置修改为我们需要的值即可其他的配置用默认配置。
1 #define _USE_MKFS 1 //格式化功能选择为使用 FatFs 格式化功能需要把它设置为 1。
2 #define _CODE_PAGE 936 //语言功能选择并要求把相关语言文件添加到工程宏。为支持简体中文文件名需要使用“936” 指的是把 cc936.c 文件添加到工程中
3 #define _USE_LFN 2 //长文件名支持默认不支持长文件名这里配置为 2支持长文件名并指定使用栈空间为缓冲区。
4 #define _VOLUMES 2 //指定物理设备数量
5 #define _MIN_SS 512 //指定扇区大小的最小值和最大值。SD 卡扇区大小一般都为 512字节SPI Flash芯片扇区大小一般设置为 4096字节
6 #define _MAX_SS 4096 //指定扇区大小的最小值和最大值为每个设备定义一个物理编号 #define ATA 0 // 预留 SD 卡使用#define SPI_FLASH 1 // 外部 SPI Flash实现五个函数
设备状态获取(disk_status)、设备初始化(disk_initialize)、扇区读取(disk_read)、扇区写(disk_write)、其他控制(disk_ioctl)。
disk_initialize
函数名称disk_initialize函数原型DSTATUS disk_initialize(BYTE Drive)功能描述初始化磁盘驱动器函数参数Drive指定要初始化的逻辑驱动器号即盘符应当取值 0~9返回值函数返回一个磁盘状态作为结果对于磁盘状态的细节信息请参考 disk_status函数所在文件ff.c实例disk_initialize(0); /* 初始化驱动器 0 */注意事项disk_initialize 函数初始化一个逻辑驱动器为读/写做准备函数成功时返回值的 STA_NOINIT 标志被清零应用程序不应调用此函数否则卷上的 FAT 结构可能会损坏如果需要重新初始化文件系统可使用 f_mount 函数在 FatFs 模块上卷注册处理时调用该函数可控制设备的改变此函数在 FatFs 挂在卷时调用应用程序不应该在 FatFs 活动时使用此函数
DSTATUS disk_status (BYTE pdrv /* 物理编号 */)
{
DSTATUS status STA_NOINIT;
switch (pdrv) {case ATA: /* SD CARD 预留也可以*/break;case SPI_FLASH: /* SPI Flash 状态检测读取 SPI Flash 设备 ID */if (sFLASH_ID SPI_FLASH_ReadID()) {/* 设备 ID 读取结果正确 */status ~STA_NOINIT;} else { /* 设备 ID 读取结果错误 */status STA_NOINIT;}break;default:status STA_NOINIT;}return status;}注意点 SPI_FLASH_ReadID函数由用户自己实现目的是检测设备是否已经就绪。
disk_status
函数名称disk_status函数原型DRESULT disk_status (BYTE Drive)功能描述返回当前磁盘驱动器的状态函数参数Drive指定要确认的逻辑驱动器号即盘符应当取值 0~9返回值磁盘状态返回下列标志的组合FatFs 只使用 STA_NOINIT 和 STA_PROTECTEDSTA_NOINIT 表明磁盘驱动未初始化下面列出了产生该标志置位或清零的原因置位系统复位磁盘被移除和磁盘初始化函数失败。清零磁盘初始化函数成功.STA_NODISK表明驱动器中没有设备安装磁盘驱动器后总为0 STA_PROTECTED表明设备被写保护不支持写保护的设备总为 0当STA_NODISK 置位时非法所在文件ff.c实例disk_status(0); /* 获取驱动器 0 的状态 */
DSTATUS disk_initialize (BYTE pdrv /* 物理编号 */)
{ uint16_t i;DSTATUS status STA_NOINIT;switch (pdrv) {case ATA: /* SD CARD */break;case SPI_FLASH: /* SPI Flash */SPI_FLASH_Init(); /* 初始化 SPI Flash */i500;/* 延时一小段时间 */while (--i);SPI_Flash_WAKEUP();/* 唤醒 SPI Flash */status disk_status(SPI_FLASH);/* 获取 SPI Flash 芯片状态 */break;default:status STA_NOINIT;}return status;
}注意点 SPI_FLASH_Init();SPI_Flash_WAKEUP();都是由用户自己实现的底层功能具体需要参照Flash对应的要求进行编写(一般也就是按着一定的规则发送数据字节过去所以一般编程顺序是线实现单字节的spi收发再按照要求编写多字节的功能再嵌入文件系统)
disk_read
函数名称disk_read函数原型DRESULT disk_read (BYTE Drive, BYTE* Buffer, DWORD SectorNumber, BYTE SectorCount)功能描述从磁盘驱动器上读取扇区函数参数Drive指定逻辑驱动器号即盘符应当取值 0~9 Buffer指向存储读取数据字节数组的指针需要为所读取字节数的大小扇区统计的扇区大小是需要的注FaFts 指定的内存地址并不总是字对齐的如果硬件不支持不对齐的数据传输函数里需要进行处理SectorNumber指定起始扇区的逻辑块LBA上的地址SectorCount指定要读取的扇区数取值 1~128返回值RES_OK(0)函数成功RES_ERROR读操作期间产生了任何错误且不能恢复它RES_PARERR非法参数RES_NOTRDY磁盘驱动器没有初始化所在文件ff.c
DRESULT disk_read (BYTE pdrv, /* 设备物理编号(0..) */BYTE *buff, /* 数据缓存区 */DWORD sector, /* 扇区首地址 */UINT count /* 扇区个数(1..128) */)
{DRESULT status RES_PARERR;switch (pdrv) {case ATA: /* SD CARD */break;case SPI_FLASH:sector512;/* 扇区偏移 2MB外部 Flash 文件系统空间放在 SPI Flash 后面 6MB 空间 */SPI_FLASH_BufferRead(buff, sector 12, count12);status RES_OK;break;default:status RES_PARERR;}return status;}注意点 参数pdrv 为设备物理编号用户自定义,buff:BYTE 类型指针变量buff指向用来存放读取到数据的存储区首地址,sector 是一个 DWORD 类型变量指定要读取数据的扇区首地址。count 是一个 UINT 类型变量指定扇区数量。 数据类型BYTE 类型实际是 unsigned char 类型DWORD 类型实际是 unsigned long 类型UINT类型实际是 unsigned int 类型类型定义在 integer.h 文件中。 偏移 板使用的 SPI Flash 芯片型号为 W25Q64FV每个扇区大小为 4096 个字节(4KB)总共有8M字节空间若。要从Flash的首地址开始存放文件系统则不需要偏移。 只将后部分6MB空间分配给FatFs使用即 FatFs 是从 2MB 空间开始为实现这个效果需要将所有的读写地址都偏移 512 个扇区空间 SPI_FLASH_BufferRead():读flash的底层程序实现在指定地址读取指定长度的数据示例
/**
* brief 读取 FLASH 数据
* param pBuffer存储读出数据的指针
* param ReadAddr读取地址
* param NumByteToRead读取数据长度
* retval 无
*/
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{SPI_FLASH_CS_LOW(); /* 选择 FLASH: CS 低电平 */SPI_FLASH_SendByte(W25X_ReadData); /* 发送 读 指令 */SPI_FLASH_SendByte((ReadAddr 0xFF0000) 16) /* 发送 读 地址高位 */SPI_FLASH_SendByte((ReadAddr 0xFF00) 8); /* 发送 读 地址中位 */SPI_FLASH_SendByte(ReadAddr 0xFF); /* 发送 读 地址低位 */while (NumByteToRead--)/* 读取数据 */{*pBuffer SPI_FLASH_SendByte(Dummy_Byte);/* 读取一个字节*/pBuffer;/* 指向下一个字节缓冲区 */}SPI_FLASH_CS_HIGH();/* 停止信号 FLASH: CS 高电平 */
}disk_write
函数名称disk_write函数原型DRESULT disk_write (BYTE Drive, const BYTE* Buffer, DWORD SectorNumber, BYTE SectorCount)功能描述向磁盘写入一个或多个扇区函数参数Drive指定逻辑驱动器号即盘符应当取值 0~9Buffer指向要写入字节数组的指针注FaFts 指定的内存地址并不总是字对齐的如果硬件不支持不对齐的数据传输函数里需要进行处理SectorNumber指定起始扇区的逻辑块LBA上的地址SectorCount指定要写入的扇区数取值 1~128返回值RES_OK(0)函数成功RES_ERROR写操作期间产生了任何错误且不能恢复它RES_WRPER媒体被写保护RES_PARERR非法参数RES_NOTRDY磁盘驱动器没有初始化所在文件ff.c注意事项只读配置中不需要此函数
DRESULT disk_write (BYTE pdrv, /* 设备物理编号(0..) */const BYTE *buff, /* 欲写入数据的缓存区 */DWORD sector, /* 扇区首地址 */UINT count /* 扇区个数(1..128) */
)
{uint32_t write_addr;DRESULT status RES_PARERR;if (!count) {return RES_PARERR; /* Check parameter */}switch (pdrv) {case ATA: /* SD CARD */break;case SPI_FLASH:/* 扇区偏移 2MB外部 Flash 文件系统空间放在 SPI Flash 后面 6MB 空间 */sector512;write_addr sector12;SPI_FLASH_SectorErase(write_addr);//对于Flash 先擦除再写SPI_FLASH_BufferWrite((u8 *)buff,write_addr,count12);//写status RES_OK;break;default:status RES_PARERR;}return status;}SPI_FLASH_SectorErase SPI_FLASH_BufferWrite用户实现
disk_ioctl
函数名称disk_ioctl函数原型DRESULT disk_ioctl (BYTE Drive, BYTE Command, void* Buffer)功能描述控制设备指定特性和除了读/写外的杂项功能函数参数Drive指定逻辑驱动器号即盘符应当取值 0~9Command指定命令代码Buffer指向参数缓冲区的指针取决于命令代码不使用时指定一个 NULL指针返回值RES_OK(0)函数成功RES_ERROR写操作期间产生了任何错误且不能恢复它RES_PARERR非法参数RES_NOTRDY磁盘驱动器没有初始化所在文件ff.c注意事项CTRL_SYNC确保磁盘驱动器已经完成了写处理当磁盘 I/O 有一个写回缓存立即刷新原扇区只读配置下不适用此命令GET_SECTOR_SIZE返回磁盘的扇区大小只用于 f_mkfs()GET_SECTOR_COUNT返回可利用的扇区数_MAX_SS ≥ 1024 时可用GET_BLOCK_SIZE获得擦除块大小只用于 f_mkfs()CTRL_ERASE_SECTOR强制擦除一块的扇区_USE_ERASE 0 时可用
DRESULT disk_ioctl (
BYTE pdrv, /* 物理编号 */
BYTE cmd, /* 控制指令 */
void *buff /* 写入或者读取数据地址指针 */
)
{DRESULT status RES_PARERR;switch (pdrv) {case ATA: /* SD CARD */break;case SPI_FLASH:switch (cmd) {/* 扇区数量1536*4096/1024/10246(MB) */case GET_SECTOR_COUNT:*(DWORD * )buff 1536;break;/* 扇区大小 */case GET_SECTOR_SIZE :*(WORD * )buff 4096;break;/* 同时擦除扇区个数 */case GET_BLOCK_SIZE :*(DWORD * )buff 1;break;}status RES_OK;break;default:status RES_PARERR;}return status;}参数pdrv 为设备物理编号cmd 为控制指令包括发出同步信号、获取扇区数目、获取扇区大小、获取擦除块数量等等指令buff 为指令对应的数据指针。 cmd:对 于 SPI Flash 芯 片 为 支 持 FatFs 格 式 化 功 能 需 要 用 到 获 取 扇 区 数 量(GET_SECTOR_COUNT)指令和获取擦除块数量(GET_BLOCK_SIZE)。另外SD 卡扇区大小为 512 字节SPI Flash 芯片一般设置扇区大小为 4096 字节所以需要用到获取扇区大小(GET_SECTOR_SIZE)指令。 文章转载自: http://www.morning.gbpanel.com.gov.cn.gbpanel.com http://www.morning.rhsg.cn.gov.cn.rhsg.cn http://www.morning.qlkzl.cn.gov.cn.qlkzl.cn http://www.morning.kysport1102.cn.gov.cn.kysport1102.cn http://www.morning.lmxrt.cn.gov.cn.lmxrt.cn http://www.morning.bnbzd.cn.gov.cn.bnbzd.cn http://www.morning.rtlrz.cn.gov.cn.rtlrz.cn http://www.morning.wptdg.cn.gov.cn.wptdg.cn http://www.morning.rfmzc.cn.gov.cn.rfmzc.cn http://www.morning.bxyzr.cn.gov.cn.bxyzr.cn http://www.morning.gkdhf.cn.gov.cn.gkdhf.cn http://www.morning.bhdyr.cn.gov.cn.bhdyr.cn http://www.morning.lwqst.cn.gov.cn.lwqst.cn http://www.morning.ntnml.cn.gov.cn.ntnml.cn http://www.morning.mjkqj.cn.gov.cn.mjkqj.cn http://www.morning.sbrpz.cn.gov.cn.sbrpz.cn http://www.morning.mysmz.cn.gov.cn.mysmz.cn http://www.morning.prprz.cn.gov.cn.prprz.cn http://www.morning.hlhqs.cn.gov.cn.hlhqs.cn http://www.morning.btqqh.cn.gov.cn.btqqh.cn http://www.morning.wnzgm.cn.gov.cn.wnzgm.cn http://www.morning.skql.cn.gov.cn.skql.cn http://www.morning.jghty.cn.gov.cn.jghty.cn http://www.morning.qphgp.cn.gov.cn.qphgp.cn http://www.morning.klyyd.cn.gov.cn.klyyd.cn http://www.morning.rnxw.cn.gov.cn.rnxw.cn http://www.morning.qfmcm.cn.gov.cn.qfmcm.cn http://www.morning.litao4.cn.gov.cn.litao4.cn http://www.morning.qxmpp.cn.gov.cn.qxmpp.cn http://www.morning.cjsrg.cn.gov.cn.cjsrg.cn http://www.morning.jhkzl.cn.gov.cn.jhkzl.cn http://www.morning.sjqml.cn.gov.cn.sjqml.cn http://www.morning.lveyue.com.gov.cn.lveyue.com http://www.morning.xpqyf.cn.gov.cn.xpqyf.cn http://www.morning.kgtyj.cn.gov.cn.kgtyj.cn http://www.morning.nlwrg.cn.gov.cn.nlwrg.cn http://www.morning.gqmhq.cn.gov.cn.gqmhq.cn http://www.morning.rlns.cn.gov.cn.rlns.cn http://www.morning.pumali.com.gov.cn.pumali.com http://www.morning.wanjia-sd.com.gov.cn.wanjia-sd.com http://www.morning.wlstn.cn.gov.cn.wlstn.cn http://www.morning.qrhh.cn.gov.cn.qrhh.cn http://www.morning.nqbs.cn.gov.cn.nqbs.cn http://www.morning.rbffj.cn.gov.cn.rbffj.cn http://www.morning.rqqlp.cn.gov.cn.rqqlp.cn http://www.morning.mrqwy.cn.gov.cn.mrqwy.cn http://www.morning.srbl.cn.gov.cn.srbl.cn http://www.morning.dwkfx.cn.gov.cn.dwkfx.cn http://www.morning.pbygt.cn.gov.cn.pbygt.cn http://www.morning.bmncq.cn.gov.cn.bmncq.cn http://www.morning.bprsd.cn.gov.cn.bprsd.cn http://www.morning.krkwp.cn.gov.cn.krkwp.cn http://www.morning.hptbp.cn.gov.cn.hptbp.cn http://www.morning.bnlch.cn.gov.cn.bnlch.cn http://www.morning.yrpd.cn.gov.cn.yrpd.cn http://www.morning.qflcb.cn.gov.cn.qflcb.cn http://www.morning.yxbrn.cn.gov.cn.yxbrn.cn http://www.morning.zgqysw.cn.gov.cn.zgqysw.cn http://www.morning.rycbz.cn.gov.cn.rycbz.cn http://www.morning.nwgkk.cn.gov.cn.nwgkk.cn http://www.morning.ygqjn.cn.gov.cn.ygqjn.cn http://www.morning.mzrqj.cn.gov.cn.mzrqj.cn http://www.morning.rjrh.cn.gov.cn.rjrh.cn http://www.morning.yrmpr.cn.gov.cn.yrmpr.cn http://www.morning.rqxmz.cn.gov.cn.rqxmz.cn http://www.morning.gqryh.cn.gov.cn.gqryh.cn http://www.morning.hxwhyjh.com.gov.cn.hxwhyjh.com http://www.morning.tkxyx.cn.gov.cn.tkxyx.cn http://www.morning.kzpxc.cn.gov.cn.kzpxc.cn http://www.morning.spfh.cn.gov.cn.spfh.cn http://www.morning.kqnwy.cn.gov.cn.kqnwy.cn http://www.morning.jqzns.cn.gov.cn.jqzns.cn http://www.morning.mngyb.cn.gov.cn.mngyb.cn http://www.morning.wcqxj.cn.gov.cn.wcqxj.cn http://www.morning.lqypx.cn.gov.cn.lqypx.cn http://www.morning.lflsq.cn.gov.cn.lflsq.cn http://www.morning.rftk.cn.gov.cn.rftk.cn http://www.morning.bmfqg.cn.gov.cn.bmfqg.cn http://www.morning.c7513.cn.gov.cn.c7513.cn http://www.morning.jtkfm.cn.gov.cn.jtkfm.cn