stm32单片机基于rt-thread 的 串行 Flash 通用驱动库 SFUD 的使用

1024程序员节|征文

在这里插入图片描述

一、sfud 通用驱动库介绍

SFUD 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多,各个 Flash 的规格及命令存在差异, SFUD 就是为了解决这些 Flash 的差异现状而设计,能够支持不同品牌及规格的 Flash,提高了涉及到 Flash 功能的软件的可重用性及可扩展性,同时也可以规避 Flash 缺货或停产给产品所带来的风险。
主要特点
支持 SPI/QSPI 接口、面向对象(同时支持多个 Flash 对象)、可灵活裁剪、扩展性强、支持 4 字节地址
资源占用
1、标准占用:RAM:0.2KB ROM:5.5KB
2、最小占用:RAM:0.1KB ROM:3.6KB
设计思路
1、什么是 SFDP :它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B (点击这里查看)。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数。
2、不支持 SFDP 怎么办 :如果该 Flash 不支持 SFDP 标准,SFUD 会查询配置文件 ( /sfud/inc/sfud_flash_def.h ) 中提供的 Flash 参数信息表 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。

二、SPI Flash 硬件介绍

野火stm32f407 开发板原理图如下:
在这里插入图片描述

在这里插入图片描述FLASH芯片(型号:W25Q128)是一种使用SPI通讯协议的NOR FLASH存储器,它的CS/CLK/DIO/DO引脚分别连接到了 STM32对应的SDI引脚NSS/SCK/MOSI/MISO上,其中STM32的NSS引脚是一个普通的GPIO,不是SPI的专用NSS引脚,所以程序中要使用软件控制的方式。
FLASH芯片中还有WP和HOLD引脚。WP引脚可控制写保护功能,当该引脚为低电平时,禁止写入数据。我们直接接电源,不使用写保护功能。HOLD引脚可用于暂停通讯,该引脚为低电平时,通讯暂停,数据输出引脚输出高阻抗状态,时钟和数据输入引脚无效。我们直接接电源,不使用通讯暂停功能。
关于FLASH芯片的更多信息,可参考其数据手册《W25Q128》。

三、使用流程

参考官方文档<在潘多拉上使用 SFUD 操作 Flash>
SFUD 的使用流程图,首先需要移植 SFUD 组件、对 flash 进行初始化,然后再进行应用:根据名称获取 sfud_dev,对 sfud_dev 进行擦写读的操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、软件系统配置和测试

Env 配置
使用 SFUD 操作 Flash,需要在 Env 中打开: QSPI 或 SPI 总线、SFUD 组件
在片上外设中,SPI1 使能。也可以选择 soft spi。
在这里插入图片描述

在这里插入图片描述
在组件中,选中 SFUD 组件,打开调试信息(可选),保存并生成工程。
在这里插入图片描述
编译下载到开发板,可以看到 SPI1 总线。
在这里插入图片描述
挂载 SPI FLASH W25Q128 到 SPI 总线.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方式一:

#include <drv_spi.h>
#include "spi_flash_sfud.h"static int rt_hw_spi_flash_init(void)
{//rt_hw_spi_device_attach():SPI 驱动会注册 SPI 总线,SPI 设备需要挂载到已经注册好的 SPI 总线上//  V4.1.1版本 也有此函数  和 RT-Thread 5.0.0 的函数有区别//往总线 spi1 上挂载一个 spi10 从设备if (RT_EOK !=  rt_hw_spi_device_attach("spi1",  "spi10", GPIOG, GPIO_PIN_6)){rt_kprintf("Failed to attach the spi device.");return -RT_ERROR;}//使用 SFUD 探测 spi10 从设备,并将 spi10 连接的 flash 初始化为块设备,名称 W25Q128if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi10")){rt_kprintf("Failed to probe the W25Q128.");return -RT_ERROR;}return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
方式二:
参考 rt_hw_spi_device_attach 函数的使用,调用rt_spi_bus_attach_device 函数,代码示例如下:

#include <drv_spi.h>
#include "spi_flash_sfud.h"#define CS_PIN   GET_PIN(G, 6)static struct stm32_hw_spi_cs  spi_cs;   static int rt_hw_spi_flash_init(void)
{struct rt_spi_device *spi_device = RT_NULL;spi_cs.GPIOx=GPIOG;spi_cs.GPIO_Pin= GPIO_PIN_6;rt_pin_mode(CS_PIN, PIN_MODE_OUTPUT);   rt_pin_write(CS_PIN, PIN_HIGH);spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));if(RT_NULL == spi_device){rt_kprintf("Failed to malloc the spi device.");return -RT_ENOMEM;}//   //此函数是RT-Thread 5.0.0 添加的新函数,如果低于5.0.0版本不支持这个函数。
//    if (RT_EOK != rt_spi_bus_attach_device_cspin(spi_device, "spi10", "spi1",GET_PIN(G, 6), RT_NULL))
//    {
//        rt_kprintf("Failed to attach the spi device.");
//        return -RT_ERROR;
//    }
//  if (RT_EOK !=  rt_spi_bus_attach_device(spi_device,  "spi10", "spi1", (void*)&spi_cs)){rt_kprintf("Failed to attach the spi device.");return -RT_ERROR;}//不配置也行,也可以使用默认配置{spi_device->bus->owner = spi_device;   {struct rt_spi_configuration cfg;cfg.data_width = 16;cfg.mode =  RT_SPI_MODE_1 | RT_SPI_MSB;cfg.max_hz = 40 * 1000 *1000; /* 40M,SPI max 42MHz, 3-wire spi */if(spi_device->bus->owner==RT_NULL){rt_kprintf("RT_OK\r\n");}rt_kprintf("owner= %d\r\n",*spi_device->bus->owner);rt_spi_configure(spi_device, &(cfg));}}if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi10")){rt_kprintf("Failed to probe the W25Q128.");return -RT_ERROR;}return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);

在这里插入图片描述

参考:
https://github.com/armink/SFUD

SPI 设备使用示例

SPI 设备

https://gitee.com/lgy4647/SFUD

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

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

相关文章

【OpenAI】第六节(语音生成与语音识别技术)从 ChatGPT 到 Whisper 的全方位指南

前言 在人工智能的浪潮中&#xff0c;语音识别技术正逐渐成为我们日常生活中不可或缺的一部分。随着 OpenAI 的 Whisper 模型的推出&#xff0c;语音转文本的过程变得前所未有的简单和高效。无论是从 YouTube 视频中提取信息&#xff0c;还是将播客内容转化为文本&#xff0c;…

K8S系列-Kubernetes网络

一、Kubernetes网络模型 ​ Kubernetes网络模型设计的一个基础原则是&#xff1a;每个Pod都拥有一个独立的IP地址&#xff0c;并假定所有Pod都在一个可以直接连通的、扁平的网络空间中&#xff0c;不管它们是否运行在同一个Node&#xff08;宿主机&#xff09;中&#xff0c;都…

【Java SE 题库】LeetCode 热题 100--->两数之和

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. 题目 2. 解析 2.1 判断两个数相加是否等于目标值 2.2 相等后&#xff0c;如何返回两个下标 3. 代码 4. 小结 取于力扣-->LeetCode 热题 100 - 学…

nginx的配置

nginx 通过nginx来进行配置&#xff0c;功能如下 通过nginx的反向代理功能访问后端的网关资源通过nginx的静态服务器功能访问前端静态页面 nginx配置步骤&#xff1a; ①&#xff1a;解压下载下来的nginx的压缩包nginx-1.18.0.zip&#xff0c;安装完成并启动后&#xff0c;访…

面经之一:Synchronized与ReentrantLock区别

Synchronized与ReentrantLock是Java中用于实现线程同步的两种主要机制&#xff0c;它们各有特点和适用场景。以下是它们的主要区别&#xff1a; 实现方式&#xff1a; Synchronized&#xff1a;是Java语言内置的关键字&#xff0c;通过JVM层面的监视器&#xff08;Monitor&…

基于vue3封装了一个coverflow轮播图(层叠轮播图)组件

最近公司有这个需求, 但是网上找了一圈 , 没有合适的能用在vue3里面的、且长这样的组件, 干脆自己动手写了一个; 效果如下, 可以适配多张图片 ,小于五张会是平铺展示; 大于五张按顺序轮播 , 每次切换有动画 <template><div class"Swiper"><div v-i…

COSCon'24 志愿者招募令:共创开源新生活!

亲爱的开源爱好者们&#xff0c; 第九届中国开源年会&#xff08;COSCon24&#xff09;即将在北京中关村国家自主创新示范区会议中心于2024年11月2日至3日隆重举行。今年的主题是“Open Source, Open Life&#xff5c;开源新生活”&#xff0c;旨在探索开源技术如何在各个领域推…

APP综合应用之业务场景脚本测试任务(5)--多重继承与总结

在脚本中&#xff0c;有三个子类继承自父类Test_login,那么怎么同时获得三个子类的继承呢&#xff1f; 1、多重继承 下面用Test_flowdriver的子类继承自上面的三个子类。 新建一个工作流驱动的文件testtest_run_workflowV1.py 主要是创建驱动类时&#xff0c;要把三个子类都继…

VisionPro —— CogBlobTool斑点工具详解

一 CogBlobTool 简介 CogBlobTool 一个用于斑点检测和分析的工具。可以使用该工具检查图像的区域&#xff0c;并定位由灰度值有限范围内的像素组成的特征&#xff0c;这些特征的形状通常是不可预测的。检测和分析这些特征或斑点的过程称为斑点分析。您可以使用blob分析来提供有…

【C++】——list 容器的解析与极致实现

人的一切痛苦&#xff0c;本质上都是对自己的无能的愤怒。 —— 王小波 目录 1、list 介绍 2、list的使用 2.1 list 的构造 2.2 iterator 的使用 2.3 list 的修改 2.4一些特殊接口 2.5 迭代器失效问题 3、实现list 3.1底层结构 结点类 list类 迭代器类 3.2功能接…

MYSQL-SQL-04-DCL(Data Control Language,数据控制语言)

DCL&#xff08;数据控制语言&#xff09; DCL英文全称是Data Control Language(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访问权限。 一、管理用户 1、查询用户 在MySQL数据库管理系统中&#xff0c;mysql 是一个特殊的系统数据库名称&#xff0c;它并不…

信息安全工程师(54)网络安全审计主要产品与技术指标

前言 网络安全审计是对网络系统进行全面的安全评估和检查&#xff0c;以发现网络安全漏洞和威胁&#xff0c;并采取相应的措施进行修补和防护的重要过程。 一、网络安全审计主要产品 域智盾 简介&#xff1a;一款企业级功能强大的网络监控和审计工具&#xff0c;能够持续监控网…

ElasticSearch分片

本文内容参考了田雪松老师编著的《Elastic Stack应用宝典》 ElasticSearch作为一个搜索引擎&#xff0c;会存储海量的数据。而存储海量的数据&#xff0c;就要解决如何存储的问题&#xff0c;并且保证数据不会丢失&#xff0c;同时还需要保证数据检索的效率&#xff0c;尽可能…

【Linux】总线-设备-驱动模型

背景 前面&#xff0c;我们介绍了写驱动代码的一些常规步骤&#xff0c;并且也写了最基本的驱动代码&#xff0c;但是那些代码存在着问题&#xff0c;我们将硬件的信息都写进了驱动里了&#xff0c;如果我们在杂项设备驱动中控制led&#xff0c;那么会在硬件操作接口中包含硬件…

WPF+MVVM案例实战-设备状态LED灯变化实现

文章目录 1、项目创建2、UI界面布局1. MainWindow.xaml2、颜色转换器实现2.MainViewModel.cs 代码实现 3、运行效果4.源代码下载 1、项目创建 打开 VS2022 &#xff0c;新建项目 Wpf_Examples&#xff0c;创建各层级文件夹&#xff0c;安装 CommunityToolkit.Mvvm 和 Microsof…

STMicroelectronics 意法半导体芯片选型表

意法半导体作为全球知名的半导体厂商&#xff0c;其产品广泛应用于各个领域&#xff0c;从消费电子到工业控制&#xff0c;从汽车电子到通信设备&#xff0c;都能看到意法半导体芯片的身影。在电子硬件设计领域&#xff0c;芯片的选型至关重要。亿配芯城&#xff08;ICgoodFind…

(3) c++基本代码

main函数 main函数只有可执行程序才需要&#xff0c;如果是动态库等则无需main函数。 main函数标准的写法是 #include <iostream> using namspace std; int main(void) {// 业务代码return 0; } 当然以上代码只是最简单的案例&#xff0c;其中代表main函数值是int&#…

网络编程(21)——通过beast库快速实现http服务器

目录 二十一、day21 1. 头文件和作用域重命名 2. reponse时调用的一些函数 3. http_connection a. 构造函数 b. start() c. process_request() d. create_response() e. create_post_response() f. write_response() 4. Server 5. 主函数 6. 测试 1&#xff09;测…

参加了十多个面试,一个offer也没拿到...为什么?

前几天&#xff0c;一个小伙伴留言说&#xff1a;自己面试了10多家企业了&#xff0c;愣是没有拿到一个offer&#xff0c;究竟是哪里出了问题&#xff1f; 这两天笔者抽空整理好了答案&#xff0c;借这位同学的问题&#xff0c;给大家做一个简单的剖析&#xff1a;为什么参加了…

【Blender】 学习笔记(一)

文章目录 参考概念原点 Origin游标 轴心点坐标操作默认快捷键两个比较好用的功能渲染器元素不可选&#xff08;防止误选&#xff09; 参考 参考b站视频&#xff1a;【Kurt】Blender零基础入门教程 | Blender中文区新手必刷教程(已完结) 概念 模型、灯光、摄像机 原点 Origin…