基于HC32F460petb芯片给FLASH安装fat文件系统

FAT(File Allocation Table)文件系统是一种用于磁盘驱动器、USB闪存驱动器、软盘等存储设备的文件系统。FAT文件系统主要有两种变体:FAT12和FAT16,它们后来被FAT32所取代。FAT32文件系统是对FAT16的扩展,支持更大的文件和磁盘分区。
FAT文件系统的核心是其文件分配表(FAT),这是一个表格,它记录了磁盘上每个簇的使用情况。簇是磁盘上的一组连续扇区,用于存储文件数据。在FAT文件系统中,每个文件和目录都占用一个或多个簇,并且FAT表记录了这些簇的使用情况。
以下是FAT文件系统的一些关键特点:
1. **簇分配**:FAT文件系统通过簇来管理文件数据。文件和目录信息存储在簇中,并且FAT表记录了哪些簇被文件和目录占用。
2. **文件分配表(FAT)**:FAT是一个表,它列出了每个簇的使用情况。FAT表中有两种类型的簇:空簇(未使用的簇)和已分配簇(被文件或目录占用的簇)。
3. **根目录**:FAT文件系统中的每个磁盘分区都有一个根目录,其中包含文件和目录的目录项。每个目录项都包含文件或目录的名称、大小、起始簇号等信息。
4. **文件大小限制**:FAT文件系统的文件大小受限于簇的大小。例如,FAT12和FAT16支持的最大文件大小为2GB,而FAT32支持的最大文件大小为2TB。
5. **兼容性**:FAT文件系统与不同的操作系统兼容,包括Windows、Linux和macOS。这使得FAT文件系统成为跨平台文件共享的理想选择。
6. **简单性**:FAT文件系统相对简单,易于实现和维护。这使得它成为许多嵌入式系统、旧计算机和便携式存储设备的首选文件系统。
7. **性能**:FAT文件系统具有较好的性能,因为它不需要复杂的索引结构来访问文件。文件数据直接存储在磁盘上的簇中,这使得文件访问速度较快。
FAT文件系统在历史上非常流行,但随着技术的发展,更高级的文件系统如NTFS(用于Windows)、EXT4(用于Linux)和APFS(用于macOS)等逐渐取代了FAT文件系统。然而,由于其简单性和广泛的兼容性,FAT文件系统仍然在一些旧设备和特殊应用中得到使用。

目前单片机中用的最多的文件系统就是fat32,得益于正点原子和野火的大量资料,让我们很快的就能开发出来相关的功能,本篇用来记录一次fat32的移植过程,芯片采用的是华大的PETB,flash才采用的是GD25Q40,虽然是GD系列的存储芯片,但是命令上基本兼容W25Q系列。

fat32源码的下载,可以从github下载:strawberryhacker/fat32: Tiny FAT32 file system implementation. (github.com)

也可以从官网下载,(不知道为什么我在家的电脑打不开fat官网,有遇到类似情况的小伙伴告诉我解决方案!

可以配置ffconf.h的修改,可以参考其他博文。

这里只看diskio的移植:

/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs     (C)ChaN, 2019        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control modules to the FatFs module with a defined API.       */
/*-----------------------------------------------------------------------*/#include "ff.h"			/* Obtains integer types */
#include "diskio.h"		/* Declarations of disk functions */#include "ev_hc32f460_lqfp100_v2_w25qxx.h"
/* Definitions of physical drive number for each drive */
#define DEV_RAM		0	/* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC		1	/* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB		2	/* Example: Map USB MSD to physical drive 2 */// jinyuhang 本篇移植,只考虑了外部falsh,后续考虑SD卡
/*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/DSTATUS disk_status (BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{DSTATUS stat=RES_OK;// BSP_W25QXX_Init();return stat;// int result;// switch (pdrv) {// case DEV_RAM :// 	result = RAM_disk_status();// 	// translate the reslut code here// 	return stat;// case DEV_MMC :// 	result = MMC_disk_status();// 	// translate the reslut code here// 	return stat;// case DEV_USB :// 	result = USB_disk_status();// 	// translate the reslut code here// 	return stat;// }// return STA_NOINIT;
}/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/DSTATUS disk_initialize (BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{// DSTATUS stat;// int result;// switch (pdrv) {// case DEV_RAM :// 	result = RAM_disk_initialize();// 	// translate the reslut code here// 	return stat;// case DEV_MMC :// 	result = MMC_disk_initialize();// 	// translate the reslut code here// 	return stat;// case DEV_USB :// 	result = USB_disk_initialize();// 	// translate the reslut code here// 	return stat;// }// return STA_NOINIT;DSTATUS stat=RES_OK;BSP_W25QXX_Init();return stat;
}/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/DRESULT disk_read (BYTE pdrv,		/* Physical drive nmuber to identify the drive */BYTE *buff,		/* Data buffer to store read data */LBA_t sector,	/* Start sector in LBA */UINT count		/* Number of sectors to read */
)
{
//	DRESULT res;
//	int result;// switch (pdrv) {// case DEV_RAM :// 	// translate the arguments here// 	result = RAM_disk_read(buff, sector, count);// 	// translate the reslut code here// 	return res;// case DEV_MMC :// 	// translate the arguments here// 	result = MMC_disk_read(buff, sector, count);// 	// translate the reslut code here// 	return res;// case DEV_USB :// 	// translate the arguments here// 	result = USB_disk_read(buff, sector, count);// 	// translate the reslut code here// 	return res;// }//	return RES_PARERR;BSP_W25QXX_Read(sector * 512U, buff, (uint32_t)count * 512U);return RES_OK;
}/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/
static void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{uint16_t pageremain;pageremain = (uint16_t)(256U - WriteAddr % 256U);if (NumByteToWrite <= pageremain) {pageremain = NumByteToWrite;}for (;;) {(void)BSP_W25QXX_Write(WriteAddr, pBuffer, pageremain);if (NumByteToWrite == pageremain) {break;} else { //NumByteToWrite>pageremainpBuffer += pageremain;WriteAddr += pageremain;NumByteToWrite -= pageremain;if (NumByteToWrite > 256U) {pageremain = 256U;} else {pageremain = NumByteToWrite;}}}
}
static uint8_t u8CopybackBuf[W25Q64_SECTOR_SIZE];static void SpiFlashWrite(uint8_t *pbuf, uint32_t WriteAddr, uint16_t NumByteToWrite)
{uint32_t secpos;uint16_t secoff;uint16_t secremain;uint16_t i;uint8_t *pu8CbBuf;pu8CbBuf = u8CopybackBuf;secpos = WriteAddr / W25Q64_SECTOR_SIZE;secoff = (uint16_t)(WriteAddr % W25Q64_SECTOR_SIZE);secremain = (uint16_t)(W25Q64_SECTOR_SIZE - secoff);if (NumByteToWrite <= secremain) {/* less than 4K */secremain = NumByteToWrite;}for (;;) {(void)BSP_W25QXX_Read(secpos * W25Q64_SECTOR_SIZE, pu8CbBuf, W25Q64_SECTOR_SIZE);/* check if blank sector */for (i = 0U; i < secremain; i++) {if (pu8CbBuf[secoff + i] != 0XFFU) {break;}}if (i < secremain) {/* not blank, need erase */(void)BSP_W25QXX_EraseSector(secpos * W25Q64_SECTOR_SIZE);/* backup first */for (i = 0U; i < secremain; i++) {pu8CbBuf[i + secoff] = pbuf[i];}/* write back after erase */W25QXX_Write_NoCheck(pu8CbBuf, secpos * W25Q64_SECTOR_SIZE, (uint16_t)W25Q64_SECTOR_SIZE);} else {W25QXX_Write_NoCheck(pbuf, WriteAddr, secremain);}if (NumByteToWrite == secremain) {break;} else {/* next sector */secpos++;secoff = 0U;pbuf += secremain;WriteAddr += secremain;NumByteToWrite -= secremain;if (NumByteToWrite > W25Q64_SECTOR_SIZE) {secremain = (uint16_t)W25Q64_SECTOR_SIZE;} else {secremain = NumByteToWrite;}}}
}#if FF_FS_READONLY == 0DRESULT disk_write (BYTE pdrv,			/* Physical drive nmuber to identify the drive */const BYTE *buff,	/* Data to be written */LBA_t sector,		/* Start sector in LBA */UINT count			/* Number of sectors to write */
)
{
//	DRESULT res;
//	int result;//	// switch (pdrv) {
//	// case DEV_RAM :
//	// 	// translate the arguments here//	// 	result = RAM_disk_write(buff, sector, count);//	// 	// translate the reslut code here//	// 	return res;//	// case DEV_MMC :
//	// 	// translate the arguments here//	// 	result = MMC_disk_write(buff, sector, count);//	// 	// translate the reslut code here//	// 	return res;//	// case DEV_USB :
//	// 	// translate the arguments here//	// 	result = USB_disk_write(buff, sector, count);//	// 	// translate the reslut code here//	// 	return res;
//	// }//	return RES_PARERR;SpiFlashWrite(( BYTE *)buff, sector * 512U,  (uint32_t)count * 512U);return RES_OK;
}#endif/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/DRESULT disk_ioctl (BYTE pdrv,		/* Physical drive nmuber (0..) */BYTE cmd,		/* Control code */void *buff		/* Buffer to send/receive control data */
)
{DRESULT res;
//	int result;switch (pdrv) {case DEV_RAM :// Process of the command for the RAM drivereturn res;case DEV_MMC :// Process of the command for the MMC/SD cardreturn res;case DEV_USB :// Process of the command the USB drivereturn res;}return RES_PARERR;
}//
DWORD get_fattime (void)
{return 0;
}

主要实现初始化,读和写的函数就可以了,如果大家看了关于USB的例程的话,就会发现这里的读写函数就是USB-msc例程中的读写函数,完全可以使用。也得到了一个经验:USB的msc功能需要配置的读写和fat32需要的读写接口都是一样的,想想这个事情也合理,USB读取U盘也是fat32格式。

实测功能正常。需要注意的是,fat32是单片机读写flash的操作,USB的msc操作是通过USB主机如电脑读写flash的操作,这两个操作应该是独立的,否则会有冲突。在实际的项目中,如果接上USB,那么单片机内部的fat32就不应该再发生读写等冲突的操作了。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/825538.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 调用C++dll时,出现“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”

当C#调用C编写的DLL时出现“尝试读取或写入受保护的内存”错误时&#xff0c;这个问题通常是由于以下几个方面引起的&#xff1a; 数据类型不匹配&#xff1a; DLL接口中的参数类型没有正确映射到C#。例如&#xff0c;C中的指针类型可能需要通过IntPtr在C#中传递&#xff0c;并…

怎么找平台?伦敦金交易平台查询

在过去的一个星期里&#xff0c;伦敦金价格再创辉煌&#xff0c;一举突破2400大关&#xff0c;并且将历史新高刷新至2431。虽然随后金价出现较大幅度的下跌&#xff0c;但对多数投资者而言&#xff0c;这不是下跌而是回调。回调之后&#xff0c;伦敦金的涨势将继续。既然有这么…

安卓手机APP开发__媒体开发部分__媒体源

安卓手机APP开发__媒体开发部分__媒体源 目录 概述 定制媒体源的创建 基于播放列表的API的媒体源 高级的媒体源的组合 概述 在ExoPlayer&#xff0c;媒体的每一个部分都能表示为一个媒体项。 然而内部来看&#xff0c;播放器需要媒体源的实例来播放内容。 播放器使用一个…

shell流程控制语句

1 test test 条件 条件为真返回 0&#xff0c;条件为假返回 1 [ 条件 ] test 能够理解3种类型的表达式 1.文件测试 2.字符串比较 3.数字比较 文件测试 -f存在且是普通文件-d存在且是目录-h存在且是符号链接-b块设备-c字符设备-e文件存在 字符串 -n STRING字符串长度不为零…

neo4j使用详解(终章、neo4j的java driver使用模板及工具类——<可用于生产>)

Neo4j系列导航: neo4j安装及简单实践 cypher语法基础 cypher插入语法 cypher插入语法 cypher查询语法 cypher通用语法 cypher函数语法 neo4j索引及调优 neo4j java Driver等更多 1. 简介 本文主要是java使用neo4j driver操作neo4j的模板项目及非常有用的工具类,主要包括: 图…

我三战华东师范大学的同桌真的很牛

标题党一下&#xff0c;其实是我的一个关系很好的高中同桌死磕华东师范大学三年&#xff0c;最终第二名上岸的故事。 其实我们是同一届的&#xff0c;我为了早点走选择了个排名还行的双非院校就走了&#xff0c;而我这个同桌相当有毅力&#xff0c;他能坚持这么久我其实很佩服&…

微信小程序开发一(常用的标签)

去微信公众平台注册账号确定怎么操作去网上找找 网址&#xff1a;微信公众平台 (qq.com)https://mp.weixin.qq.com/https://mp.weixin.qq.com/ 微信开放文档中找到工具栏下载微信开发者工具 网址&#xff1a;微信开发者工具&#xff08;稳定版 Stable Build&#xff09;下载地…

vue3 文件分片上传

base 64 分片上传文件 <template><div><input type"file" change"onFileSelected" /><button v-if"file && !isUploading" click"startUpload">开始上传</button><button v-if"isUplo…

Go 之获取变量类型

Python 可以通过 type 快速获取变量类型。Ruby 也可以通过 class 方法快速获取变量类型。 lists [1, 2, 3, 4, 5] print(type(lists)) # <class list>lists [1, 2, 3, 4, 5] puts lists.class # Array 那么 Go 有哪些获取变量类型的方法呢&#xff1f; fmt.Printf(&…

JavaWeb开发02-MYSQL-DDL-DML-DQL-多表设计-多表查询-事务-索引

一、MySQL概述 通过SQL语句可以操作数据库 关系型数据库&#xff1a; 只要是关系型数据库就可以用SQL语句这一统一标准进行操作数据库 1.MYSQL数据模型 客户端通过SQL语句交给了数据库管理系统DBMS&#xff0c;进行相应操作&#xff0c;创建一个一个数据库&#xff0c;体现为一…

如何理解信创产品?成为信创产品?

信创产品是指运用信息技术手段创造的产品&#xff0c;它是数据安全、网络安全的基础&#xff0c;也是新基建的重要组成部分。信创产品包括了IT基础设施如CPU芯片、服务器、存储、交换机、路由器、各种云和相关服务内容&#xff1b;基础软件如数据库、操作系统、中间件&#xff…

JRT在线初始化完善

之前实现的在线初始化留了个尾巴&#xff0c;那就是环境下载页构造zip包的时候没修改JRTBrowser的连接串地址为当前网站&#xff0c;这样就要求网站部署好之后给用户下载之前有人要把服务器的浏览器地址配置好。这样就增加一个运维工作&#xff0c;如果忘了或者不知道的人就会导…

利用H.264码流传输摄像头地理位置信息

目录 1. 引言2. NALU格式介绍3. SEI格式介绍4. 举例5. 推广1. 引言 摄像头的应用范围越来越广泛,从安防监控到视频会议,它们在我们的日常生活中起着关键作用。除了视频图像本身,摄像头还可以提供其他有用的信息,例如摄像头的地理位置。本文将讨论如何利用H.264码流传输摄像…

if __name__ == ‘__main__‘ 是个什么鬼?

有句话经典的概括了这段代码的意义&#xff1a; “Make a script both importable and executable” 意思就是说让你写的脚本模块既可以导入到别的模块中用&#xff0c;另外该模块自己也可执行。 咋一看&#xff0c;其实我也不理解到底是个什么球意思&#xff0c;这里我们写两个…

nuxt3使用记录四:加载静态资源时路径的写法研究

在上一篇记录了NUXT进行SSG构建时&#xff0c;不仅会构建纯静态的html文件&#xff0c;也会构建一堆js文件。而如果网页中有加载静态资源&#xff0c;如图片&#xff0c;这时就需要注意了&#xff0c;不能简单的使用官网说的<img src"~/assets/img/nuxt.png" alt&…

2024年华中杯数学建模C题思路与论文助攻

C 题 基于光纤传感器的平面曲线重建算法建模 光纤传感技术是伴随着光纤及光通信技术发展起来的一种新型传感器术。它是以光波为传感信号、光纤为传输载体来感知外界环境中的信号&#xff0c;其 基本原理是当外界环境参数发生变化时&#xff0c;会引起光纤传感器中光波参量&am…

Linux进阶---常见符号及其含义、常见报错

一、常见符号及其含义&#xff08;重要&#xff09; 二、 常见报错 • 找不到文件、文件不存在&#xff1a;No such file or directory • 没有权限 &#xff1a;Permission denied • 命令不存在 &#xff1a;command not found 1.找不到文件、文件不存在&#xff1a;No s…

logstash迁移es自建数据到pass服务

1 安装 下载对应版本的tar文件 https://www.elastic.co/cn/downloads/past-releases#logstash解压 tar -zvxf logstash-6.8.23-linux-x86_64.tar.gz 2 配置 修改Logstash的堆内存使用vi config/jvm.options&#xff0c;修改Logstash配置文件config/jvm.options&#xff0c;增…

AI智能电销机器人是什么?能给我们带来哪些便利?

科技的飞速发展&#xff0c;让很多“懒人”的幻想变成了现实&#xff0c;越来越多的人工智能产品被发明出来甚至完全替代日常生活中的工作。比如在电销行业&#xff0c;很多企业选择AI智能电销机器人进行外呼。那么你了解多少AI智能电销机器人呢&#xff1f;和小编kelaile520一…

声明v.s.定义

参考&#xff1a;http://t.csdnimg.cn/1xnzA 变量的定义&#xff1a;用于为变量分配存储空间&#xff0c;还可以为变量指定初始值&#xff0c;在程序中&#xff0c;变量有且仅有一个定义。变量的声明&#xff1a;用于向程序表明变量的类型和名字。在程序中&#xff0c;变量可以…