SFUD是什么
关于SFUD库的介绍,其开源链接(gitee,github)已经详细的阐述了.
这里是截取自它的一部分介绍:
SFUD 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多,各个 Flash 的规格及命令存在差异, SFUD 就是为了解决这些 Flash 的差异现状而设计,让我们的产品能够支持不同品牌及规格的 Flash,提高了涉及到 Flash 功能的软件的可重用性及可扩展性,同时也可以规避 Flash 缺货或停产给产品所带来的风险。
主要特点:支持 SPI/QSPI 接口、面向对象(同时支持多个 Flash 对象)、可灵活裁剪、扩展性强、支持 4 字节地址
资源占用
标准占用:RAM:0.2KB ROM:5.5KB
最小占用:RAM:0.1KB ROM:3.6KB
设计思路:
什么是 SFDP :它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B (点击这里查看)。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数。
不支持 SFDP 怎么办 :如果该 Flash 不支持 SFDP 标准,SFUD 会查询配置文件 ( /sfud/inc/sfud_flash_def.h ) 中提供的 Flash 参数信息表 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 2.5 添加库目前不支持的 Flash)。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。
详细的可以查看开源链接(gitee,github);
为什么选择 SFUD
避免项目因 Flash 缺货、Flash 停产或产品扩容而带来的风险;
越来越多的项目将固件存储到串行 Flash 中,例如:ESP8266 的固件、主板中的 BIOS 及其他常见电子产品中的固件等等,但是各种 Flash 规格及命令不统一。使用 SFUD 即可避免,在相同功能的软件平台基础下,无法适配不同 Flash 种类的硬件平台的问题,提高软件的可重用性;
简化软件流程,降低开发难度。现在只需要配置好 SPI 通信,即可畅快的开始玩串行 Flash 了;
可以用来制作 Flash 编程器/烧写器
开始copy代码
这篇文章的重点就是来移植这个库,所以我就不多介绍了,直接开搞。
- 首先先下载好立创梁山派附带的资料,等下要用到里面的提供的demo来作为我们的工程模板。
- 我们使用 005-串口打印信息 这个作为我们的工程模板,然后在从015_spi中复制一份spi的代码,作为我们的flash驱动代码,还要下载一份sfud的源代码。
总共就是以上三个东西就ok啦。
- 接下啦,按照下图,将文件添加到你的工程中进来,如果这一部分操作不会的话,可以学一下立创推出的教程,我这里就不再赘述啦。
- 接下来就是对代码进行小小的修改
对bsp_spi.c文件按照我自己的代码风格进行了小小的修改和裁剪,因为这个SFUD十分完善,只需要我们提供这个spi的读取接口函数就ok了。
#include "bsp_spi.h"
void bsp_spi4_init(void)
{
//SPI参数定义结构体
spi_parameter_struct spi_init_struct;
rcu_periph_clock_enable(RCU_GPIOF); // 使用F端口
rcu_periph_clock_enable(RCU_SPI4); // 使能SPI4
//引脚复用
gpio_af_set(GPIOF, GPIO_AF_5, GPIO_PIN_7);
gpio_af_set(GPIOF, GPIO_AF_5, GPIO_PIN_8);
gpio_af_set(GPIOF, GPIO_AF_5, GPIO_PIN_9);
//引脚模式
gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_mode_set(GPIOF, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
//输出模式
gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
//开启CS引脚时钟
rcu_periph_clock_enable(RCU_GPIOF);
//配置CS引脚模式
gpio_mode_set(GPIOF, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_6);
//配置CS输出模式
gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
//W25Q64不选中