当前位置: 首页 > news >正文

立创梁山派--移植开源的SFUD和FATFS实现SPI-FLASH文件系统

本文主要是在sfud的基础上进行fatfs文件系统的移植,并不对sfud的移植再进行过多的讲解了哦,所以如果想了解sfud的移植过程,请参考我的另外一篇文章:传送门

正文开始咯

  • 首先我们需要先准备资料准备好,这里对于fatfs的移植,我参考的是野火的教程。所以我在文章末尾也会给出相关的教程链接。
    我们需要的东西有:一份实现了sfud库的裸机代码,这个可以从我上篇文章的文末连接中获取,这里我也将代码的链接贴出:传送门, 还有一份fatfs源码,这个为了和野火的教程保持移植,这里用的是跟野火教程版本一致的fatfs源码,这里的源码可以在文末的链接开源代码链接中获取。
  • 开始移植
    打开fatfs代码
    在这里插入图片描述
    我们将其添加到我们的工程中
    在这里插入图片描述
    添加文件路径#在这里插入图片描述

对于fatfs的介绍,野火的教程中都有详细的介绍,这里就不再赘述了。其实它的移植是比较简单的,只需要修改diskio.c文件中的相关接口函数和ffconf.h配置文件。

  • 打开diskio.c文件
    首先包含我们需要的头文件,定义我们要操作的flash
#include "bsp_spi.h"
#include "sfud.h"
const sfud_flash *flash1;#define W25Q64 0xEF16 //根据板载的spiflash来修改 /* 为每个设备定义一个物理编号 */
#define ATA			    0     // 预留SD卡使用
#define SPI_FLASH		1     // 外部SPI Flash

对需要修改的函数进行说明

//获取状态函数
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 (W25Q64 == spi4_flash_readID()){/* 设备ID读取结果正确 */status &= ~STA_NOINIT;}else{/* 设备ID读取结果错误 */status = STA_NOINIT;;}break;default:status = STA_NOINIT;}return status;
}

初始化函数

DSTATUS disk_initialize(BYTE pdrv /* 物理编号 */
)
{uint16_t i;DSTATUS status = STA_NOINIT;switch (pdrv){case ATA: /* SD CARD */break;case SPI_FLASH: /* SPI Flash */sfud_init();flash1 = sfud_get_device_table() + 0; //对应到设备表的第一个// printf("%0x\n", spi4_flash_readID());//如果不清楚设备id的话,可以在这里打印一下status = disk_status(SPI_FLASH); //获取设备状态break;default:status = STA_NOINIT;}return status;
}

读取函数

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://这里的左移12位,等于4096,因为flash的一个扇区是4k字节sfud_read(flash1, sector << 12, count << 12, buff);status = RES_OK;break;default:status = RES_PARERR;}return status;
}

写入函数

#if _USE_WRITE
DRESULT disk_write(BYTE pdrv,        /* 设备物理编号(0..) */const BYTE *buff, /* 欲写入数据的缓存区 */DWORD sector,     /* 扇区首地址 */UINT count        /* 扇区个数(1..128) */
)
{DRESULT status = RES_PARERR;if (!count){return RES_PARERR; /* Check parameter */}switch (pdrv){case ATA: /* SD CARD */break;case SPI_FLASH:sfud_erase(flash1, sector << 12, 4096); // SPI_FLASH都是要先擦除为1才能写sfud_write(flash1, sector << 12, count << 12, (uint8_t *)buff);status = RES_OK;break;default:status = RES_PARERR;}return status;
}
#endif

设备信息函数

#if _USE_IOCTL
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){//扇区数量就是例如我这里是8M的flash//那就是 8 * 1024 * 1024 (字节)/ 4096(一个扇区的大小) = 2048(扇区数)case GET_SECTOR_COUNT:*(DWORD *)buff = 2048; //这里是你的扇区数量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;
}
#endif

获取时间函数

//这里是获取时间函数,后续如果有需要的话,可以使用rtc的时间
__weak DWORD get_fattime(void)
{/* 返回当前时间戳 */return ((DWORD)(2015 - 1980) << 25) /* Year 2015 */| ((DWORD)1 << 21)           /* Month 1 */| ((DWORD)1 << 16)           /* Mday 1 */| ((DWORD)0 << 11)           /* Hour 0 */| ((DWORD)0 << 5)            /* Min 0 */| ((DWORD)0 >> 1);           /* Sec 0 */
}
  • 对于ffconf.h主要是修改一下宏定义即可
    在这里插入图片描述

到这里就已经是移植好啦

然后就可以开始进行测试啦
main.c文件

#include "main.h"
#include "bsp_led.h"
#include "bsp_usart.h"
#include "gd32f4xx.h"
#include "sys.h"
#include "systick.h"
#include <stdio.h>#include "bsp_spi.h"
#include <sfud.h>#include "ff.h"FATFS fs;													/* FatFs文件系统对象 */
FIL fnew;													/* 文件对象 */
FRESULT res_flash;                /* 文件操作结果 */
UINT fnum;            					  /* 文件成功读写数量 */
BYTE ReadBuffer[1024]={0};        /* 读缓冲区 */
BYTE WriteBuffer[] =              /* 写缓冲区*/
"欢迎使用野火STM32 F429开发板 今天是个好日子,新建文件系统测试文件\r\n";  /*!\brief    main function\param[in]  none\param[out] none\retval     none
*/
int main(void)
{systick_config();led_gpio_config(); // led初始化usart_gpio_config(115200U);/* SFUD initialize */
//    if (sfud_init() == SFUD_SUCCESS)
//    {
//       sfud_demo(0, sizeof(sfud_demo_test_buf), sfud_demo_test_buf);
//    }printf("****** 这是一个SPI FLASH 文件系统实验 ******\r\n");//在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化res_flash = f_mount(&fs,"1:",1);/*----------------------- 格式化测试 ---------------------------*/  /* 如果没有文件系统就格式化创建创建文件系统 */if(res_flash == FR_NO_FILESYSTEM){printf("》FLASH还没有文件系统,即将进行格式化...\r\n");/* 格式化 */res_flash=f_mkfs("1:",0,0);							if(res_flash == FR_OK){printf("》FLASH已成功格式化文件系统。\r\n");/* 格式化后,先取消挂载 */res_flash = f_mount(NULL,"1:",1);			/* 重新挂载	*/			res_flash = f_mount(&fs,"1:",1);}else{printf("《《格式化失败。》》\r\n");while(1);}}else if(res_flash!=FR_OK){printf("!!外部Flash挂载文件系统失败。(%d)\r\n",res_flash);printf("!!可能原因:SPI Flash初始化不成功。\r\n");printf("请下载 SPI—读写串行FLASH 例程测试,如果正常,在该例程f_mount语句下if语句前临时多添加一句 res_flash = FR_NO_FILESYSTEM; 让重新直接执行格式化流程\r\n");while(1);}else{printf("》文件系统挂载成功,可以进行读写测试\r\n");}/*----------------------- 文件系统测试:写测试 -----------------------------*//* 打开文件,如果文件不存在则创建它 */printf("\r\n****** 即将进行文件写入测试... ******\r\n");	res_flash = f_open(&fnew, "1:FatFs读写测试文件.txt",FA_CREATE_ALWAYS | FA_WRITE );if ( res_flash == FR_OK ){printf("》打开/创建FatFs读写测试文件.txt文件成功,向文件写入数据。\r\n");/* 将指定存储区内容写入到文件内 */res_flash=f_write(&fnew,WriteBuffer,sizeof(WriteBuffer),&fnum);if(res_flash==FR_OK){printf("》文件写入成功,写入字节数据:%d\n",fnum);printf("》向文件写入的数据为:\r\n%s\r\n",WriteBuffer);}else{printf("!!文件写入失败:(%d)\n",res_flash);}    /* 不再读写,关闭文件 */f_close(&fnew);}else{	printf("!!打开/创建文件失败。\r\n");}/*------------------- 文件系统测试:读测试 ------------------------------------*/printf("****** 即将进行文件读取测试... ******\r\n");res_flash = f_open(&fnew, "1:FatFs读写测试文件.txt", FA_OPEN_EXISTING | FA_READ); 	 if(res_flash == FR_OK){printf("》打开文件成功。\r\n");res_flash = f_read(&fnew, ReadBuffer, sizeof(ReadBuffer), &fnum); if(res_flash==FR_OK){printf("》文件读取成功,读到字节数据:%d\r\n",fnum);printf("》读取得的文件数据为:\r\n%s \r\n", ReadBuffer);	}else{printf("!!文件读取失败:(%d)\n",res_flash);}		}else{printf("!!打开文件失败。\r\n");}/* 不再读写,关闭文件 */f_close(&fnew);	/* 不再使用文件系统,取消挂载文件系统 */f_mount(NULL,"1:",1);while (1){}
}
效果如下

在这里插入图片描述
origin_url=image-4.png&pos_id=img-2thXHWxj-1721718767616)

移植成功

相关的开源代码:gitee

如果对你有所帮助的话,请给我点一个star,嘿嘿

相关文章:

立创梁山派--移植开源的SFUD和FATFS实现SPI-FLASH文件系统

本文主要是在sfud的基础上进行fatfs文件系统的移植&#xff0c;并不对sfud的移植再进行过多的讲解了哦&#xff0c;所以如果想了解sfud的移植过程&#xff0c;请参考我的另外一篇文章&#xff1a;传送门 正文开始咯 首先我们需要先准备资料准备好&#xff0c;这里对于fatfs的…...

MySQL之视图和索引实战

1.新建数据库 mysql> create database myudb5_indexstu; Query OK, 1 row affected (0.01 sec) mysql> use myudb5_indexstu; Database changed 2.新建表 1.学生表student&#xff0c;定义主键&#xff0c;姓名不能重名&#xff0c;性别只能输入男或女&#xff0c;所在…...

快速参考:用C# Selenium实现浏览器窗口缩放的步骤

背景介绍 在现代网络环境中&#xff0c;浏览器自动化已成为数据抓取和测试的重要工具。Selenium作为一个强大的浏览器自动化工具&#xff0c;能够与多种编程语言结合使用&#xff0c;其中C#是非常受欢迎的选择之一。在实际应用中&#xff0c;我们常常需要调整浏览器窗口的缩放…...

MyBatis 插件机制、分页插件如何实现的

MyBatis 插件机制允许开发者在 SQL 执行的各个阶段&#xff08;如预处理、执行、结果处理等&#xff09;中插入自定义逻辑&#xff0c;从而实现对 MyBatis 行为的扩展和增强。以下是 MyBatis 插件运行原理的详细介绍&#xff1a; 插件接口 MyBatis 插件通过实现 org.apache.i…...

CentOS6.0安装telnet-server启用telnet服务

CentOS6.0安装telnet-server启用telnet服务 一步到位 fp"/etc/yum.repos.d" ; cp -a ${fp} ${fp}.$(date %0y%0m%0d%0H%0M%0S).bkup echo [base] nameCentOS-$releasever - Base baseurlhttp://mirrors.163.com/centos-vault/6.0/os/$basearch/http://mirrors.a…...

H5+CSS+JS工作性价比计算器

工作性价比&#xff1d;平均日新x综合环境系数/35 x(工作时长&#xff0b;通勤时长—0.5 x摸鱼时长) x学历系数 如果代码中的公式不对&#xff0c;请指正 效果图 源代码 <!DOCTYPE html> <html> <head> <style> .calculator { width: 300px; padd…...

Linux:基础命令学习

目录 一、ls命令 实例&#xff1a;-l以长格式显示文件和目录信息 实例&#xff1a;-F根据文件类型在列出的文件名称后加一符号 实例&#xff1a; -R 递归显示目录中的所有文件和子目录。 实例&#xff1a; 组合使用 Home目录和工作目录 二、目录修改和查看命令 三、mkd…...

遇到Websocket就不会测了?别慌,学会这个Jmeter插件轻松解决....

websocket 是一种双向通信协议&#xff0c;在建立连接后&#xff0c;websocket服务端和客户端都能主动向对方发送或者接收数据&#xff0c;而在http协议中&#xff0c;一个request只能有一个response&#xff0c;而且这个response也是被动的&#xff0c;不能主动发起。 websoc…...

高性能 Java 本地缓存 Caffeine 框架介绍及在 SpringBoot 中的使用

在现代应用程序中&#xff0c;缓存是一种重要的性能优化技术&#xff0c;它可以显著减少数据访问延迟&#xff0c;降低服务器负载&#xff0c;提高系统的响应速度。特别是在高并发的场景下&#xff0c;合理地使用缓存能够有效提升系统的稳定性和效率。 Caffeine 是一个高性能的…...

Http 和 Https 的区别(图文详解)

在现代网络通信中&#xff0c;保护数据的安全性和用户的隐私是至关重要的。HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是两种常见的网络通信协议&#xff0c;但它们在数据保护方面的能力存在…...

DP学习——外观模式

学而时习之&#xff0c;温故而知新。 外观模式 角色 2个角色&#xff0c;外观类&#xff0c;子系统类。 个人理解 感觉就是对外接口封装&#xff0c;这个是封装一个功能的对外接口&#xff0c;越简单越好&#xff0c;提供给第三方用。 应用场景 封装为对外库时&#xff…...

Vue3 + Vite 打包引入图片错误

1. 具体报错 报错信息 报错代码 2. 解决方法 改为import引入&#xff0c;注意src最好引用为符引入&#xff0c;不然docker部署的时候可能也会显示不了 <template><img :src"loginBg" alt""> </template><script langts setup> …...

搭建NFS、web、dns服务器

目录 1、搭建一个nfs服务器&#xff0c;客户端可以从该服务器的/share目录上传并下载文件 服务端配置&#xff1a; 客户端测试&#xff1a; 2、搭建一个Web服务器&#xff0c;客户端通过www.haha.com访问该网站时能够看到内容:this is haha 服务端配置&#xff1a; 客户端…...

C++的UI框架和开源项目介绍

文章目录 1.QT2.wxWidgets3.Dear ImGui 1.QT QT的开源项目&#xff1a;QGIS&#xff08;地理信息系统&#xff09; https://github.com/qgis/QGIS?tabreadme-ov-file 2.wxWidgets wxWidgets的开源项目&#xff1a;filezilla https://svn.filezilla-project.org/svn/ wxWidg…...

SpringBoot连接PostgreSQL+MybatisPlus入门案例

项目结构 一、Java代码 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mave…...

vue3里将table表格中的数据导出为excel

想要实现前端对表格中的数据进行导出&#xff0c;这里推荐使用xlsx这个依赖库实现。 1、安装 pnpm install xlsx 2、使用 import * as XLSX from "xlsx"; 直接在组件里导入XLSX库&#xff0c;然后给表格table通过ref创建响应式数据拿到table实例&#xff0c;将实…...

【算法】分布式共识Paxos

一、引言 在分布式系统中&#xff0c;一致性是至关重要的一个问题。Paxos算法是由莱斯利兰伯特&#xff08;Leslie Lamport&#xff09;在1990年提出的一种解决分布式系统中一致性问题的算法。 二、算法原理 Paxos算法的目标是让一个分布式系统中的多个节点就某个值达成一致。算…...

软考:软件设计师 — 5.计算机网络

五. 计算机网络 1. OSI 七层模型 层次名称主要功能主要设备及协议7应用层实现具体的应用功能 POP3、FTP、HTTP、Telent、SMTP DHCP、TFTP、SNMP、DNS 6表示层数据的格式与表达、加密、压缩5会话层建立、管理和终止会话4传输层端到端的连接TCP、UDP3网络层分组传输和路由选择 三…...

C++ //练习 15.28 定义一个存放Quote对象的vector,将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。

C Primer&#xff08;第5版&#xff09; 练习 15.28 练习 15.28 定义一个存放Quote对象的vector&#xff0c;将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&am…...

Midjourney绘画提示词精选

Midjourney绘画提示词精选 在探索Midjourney这一强大的AI绘画工具时&#xff0c;选择合适的提示词是创作出令人惊艳作品的关键。这些提示词不仅能够帮助Midjourney理解你的创作意图&#xff0c;还能引导它生成出符合你期望的图像。以下是对Midjourney绘画提示词的精选与解析&a…...

Kylin中的RBAC:为大数据安全加把锁

Kylin中的RBAC&#xff1a;为大数据安全加把锁 Apache Kylin是一个开源的分布式分析引擎&#xff0c;旨在为Hadoop平台提供快速的大数据量SQL查询能力。随着企业对数据安全和访问控制需求的增加&#xff0c;基于角色的访问控制&#xff08;Role-Based Access Control&#xff…...

DDoS 攻击下的教育网站防护策略

随着互联网的普及&#xff0c;教育网站成为学生和教师获取信息、进行在线学习的重要平台。然而&#xff0c;这些网站也成为了网络攻击的目标&#xff0c;尤其是分布式拒绝服务&#xff08;DDoS&#xff09;攻击。本文将探讨DDoS攻击对教育网站的影响&#xff0c;并提出一系列有…...

Android13以太网静态IP不保存的问题

最近在做Amlogic T982的样机&#xff0c;关于以太网部分&#xff0c;系统Settings只有一个Ethernet的条目&#xff0c;没有其他任何信息&#xff0c;什么以太网mac地址&#xff0c;开关&#xff0c;IP地址&#xff0c;子网掩码&#xff0c;默认网关&#xff0c;dns, 设置代理&a…...

Redis 7.x 系列【31】LUA 脚本

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Redis 版本 7.2.5 源码地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目录 1. 概述2. 常用命令2.1 EVAL2.2 SCRIPT LOAD2.3 EVALSHA2.4 SCRIPT FLUSH2.5 其他 3. …...

mysql中You can’t specify target table for update in FROM clause错误

mysql中You can’t specify target table for update in FROM clause错误 You cannot update a table and select directly from the same table in a subquery. mysql官网中有这句话&#xff0c;我们不能在一个语句中先在子查询中从某张表查出一些值&#xff0c;再update这张表…...

Linux Vim最全面的教程

Vim 是一个非常强大的文本编辑器&#xff0c;它在 Linux 环境中尤其受欢迎。Vim 支持高度定制&#xff0c;并且拥有丰富的功能&#xff0c;包括多级撤销、宏、脚本语言支持等。下面是关于 Vim 的一个较为全面的教程。 Vim 的启动 要启动 Vim&#xff0c;你可以在终端中输入 v…...

setsockopt选项对tcp速度

GPT-4 (OpenAI) 每个setsockopt调用都涉及到一个套接字描述符&#xff0c;一个指定网络层的常数&#xff08;如IPPROTO_IP, IPPROTO_TCP, IPPROTO_IPV6, SOL_SOCKET等&#xff09;&#xff0c;一个指定需配置的选项的常数&#xff0c;一个指向配置值的指针&#xff0c;以及那个…...

HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 多选题序号3

基础认证题库请移步&#xff1a;HarmonyOS应用开发者基础认证题库 注&#xff1a;有读者反馈&#xff0c;题库的代码块比较多&#xff0c;打开文章时会卡死。所以笔者将题库拆分&#xff0c;单选题20个为一组&#xff0c;多选题10个为一组&#xff0c;题库目录如下&#xff0c;…...

bool数组的理解和应用[C++]

文章目录 bool数组的用法bool数组的定义声明bool数组的初始化访问和修改数组元素遍历数组 运用bool数组简单代码 在今天做题中发现了bool类不仅能用于函数类型还能用于数组类型&#xff0c;好奇查了查发现bool还有很多用处&#xff1a;基本变量&#xff0c;在枚举类型中会用到&…...

JavaScript模拟滑动手势

双击回到顶部 左滑动 右滑动 代码展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Gesture…...