SkillAgentSearch skills...

SFUD

An using JEDEC's SFDP standard serial (SPI) flash universal driver library | 一款使用 JEDEC SFDP 标准的串行 (SPI) Flash 通用驱动库

Install / Use

/learn @armink/SFUD
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

SFUD (Serial Flash Universal Driver) 串行 Flash 通用驱动库


0、SFUD 是什么

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 的全部操作。

1、为什么选择 SFUD

  • 避免项目因 Flash 缺货、Flash 停产或产品扩容而带来的风险;
  • 越来越多的项目将固件存储到串行 Flash 中,例如:ESP8266 的固件、主板中的 BIOS 及其他常见电子产品中的固件等等,但是各种 Flash 规格及命令不统一。使用 SFUD 即可避免,在相同功能的软件平台基础下,无法适配不同 Flash 种类的硬件平台的问题,提高软件的可重用性;
  • 简化软件流程,降低开发难度。现在只需要配置好 SPI 通信,即可畅快的开始玩串行 Flash 了;
  • 可以用来制作 Flash 编程器/烧写器

2、SFUD 如何使用

2.1 已支持 Flash

下表为所有已在 Demo 平台上进行过真机测试过的 Flash。显示为 不支持 SFDP 标准的 Flash 已经在 Flash 参数信息表中定义,更多不支持 SFDP 标准的 Flash 需要大家以后 共同来完善和维护 (Github|OSChina|Coding)

如果觉得这个开源项目很赞,可以点击 项目主页 右上角的 Star ,同时把它推荐给更多有需要的朋友。

|型号|制造商|容量|最高速度|SFDP 标准|QSPI 模式|备注| |:--:|:----:|:--:|:--:|:--:|:--:|----| |W25Q40BV|Winbond|4Mb|50Mhz|不支持|双线|已停产| |W25Q80DV|Winbond|8Mb|104Mhz|支持|双线|| |W25Q16BV|Winbond|16Mb|104Mhz|不支持|双线| by slipperstree| |W25Q16CV|Winbond|16Mb|104Mhz|支持|未测试|| |W25Q16DV|Winbond|16Mb|104Mhz|支持|未测试| by slipperstree| |W25Q32BV|Winbond|32Mb|104Mhz|支持|双线|| |W25Q64CV|Winbond|64Mb|80Mhz|支持|四线|| |W25Q128BV|Winbond|128Mb|104Mhz|支持|四线|| |W25Q256FV|Winbond|256Mb|104Mhz|支持|四线|| |MX25L3206E|Macronix|32Mb|86MHz|支持|双线|| |MX25L3233F|Macronix|32Mb|133MHz|支持|未测试|by JiapengLi| |KH25L4006E|Macronix|4Mb|86Mhz|支持|未测试| by JiapengLi| |KH25L3206E|Macronix|32Mb|86Mhz|支持|双线|| |SST25VF016B|Microchip|16Mb|50MHz|不支持|不支持| SST 已被 Microchip 收购| |M25P40|Micron|4Mb|75Mhz|不支持|未测试| by redocCheng| |M25P80|Micron|8Mb|75Mhz|不支持|未测试| by redocCheng| |M25P32|Micron|32Mb|75Mhz|不支持|不支持|| |EN25Q32B|EON|32Mb|104MHz|不支持|未测试|| |GD25Q16B|GigaDevice|16Mb|120Mhz|不支持|未测试| by TanekLiang | |GD25Q32C|GigaDevice|32Mb|120Mhz|不支持|未测试| by gaupen1186 | |GD25Q64B|GigaDevice|64Mb|120Mhz|不支持|双线|| |S25FL216K|Cypress|16Mb|65Mhz|不支持|双线|| |S25FL032P|Cypress|32Mb|104Mhz|不支持|未测试| by yc_911 | |S25FL164K|Cypress|64Mb|108Mhz|支持|未测试|| |A25L080|AMIC|8Mb|100Mhz|不支持|双线|| |A25LQ64|AMIC|64Mb|104Mhz|支持|支持|| |F25L004|ESMT|4Mb|100Mhz|不支持|不支持|| |PCT25VF016B|PCT|16Mb|80Mhz|不支持|不支持|SST 授权许可,会被识别为 SST25VF016B| |AT45DB161E|ADESTO|16Mb|85MHz|不支持|不支持|ADESTO 收购 Atmel 串行闪存产品线| |NM25Q128EV|Nor_Mem|128Mb|未测试|不支持|未测试|SFDP可能会读取到信息后识别为超过32Gb| |P25D40H|PUYA|4Mb|未测试|支持|未测试|by Shan| |P25Q80H|PUYA|8Mb|未测试|支持|未测试|by Shan|

注:QSPI 模式中,双线表示支持双线快读,四线表示支持四线快读。

一般情况下,支持四线快读的 FLASH 也支持双线快读。

2.2 API 说明

先说明下本库主要使用的一个结构体 sfud_flash 。其定义位于 /sfud/inc/sfud_def.h。每个 SPI Flash 会对应一个该结构体,该结构体指针下面统称为 Flash 设备对象。初始化成功后在 sfud_flash->chip 结构体中会存放 SPI Flash 的常见参数。如果 SPI Flash 还支持 SFDP ,还可以通过 sfud_flash->sfdp 看到更加全面的参数信息。以下很多函数都将使用 Flash 设备对象作为第一个入参,实现对指定 SPI Flash 的操作。

2.2.1 初始化 SFUD 库

将会调用 sfud_device_init ,初始化 Flash 设备表中的全部设备。如果只有一个 Flash 也可以只使用 sfud_device_init 进行单一初始化。

注意:初始化完的 SPI Flash 默认都 已取消写保护 状态,如需开启写保护,请使用 sfud_write_status 函数修改 SPI Flash 状态。

sfud_err sfud_init(void)

2.2.2 初始化指定的 Flash 设备

sfud_err sfud_device_init(sfud_flash *flash)

|参数 |描述| |:----- |:----| |flash |待初始化的 Flash 设备|

2.2.3 使能快速读模式(仅当 SFUD 开启 QSPI 模式后可用)

当 SFUD 开启 QSPI 模式后,SFUD 中的 Flash 驱动支持使用 QSPI 总线进行通信。相比传统的 SPI 模式,使用 QSPI 能够加速 Flash 数据的读取,但当数据需要写入时,由于 Flash 本身的数据写入速度慢于 SPI 传输速度,所以 QSPI 模式下的数据写入速度提升并不明显。

所以 SFUD 对于 QSPI 模式的支持仅限于快速读命令。通过该函数可以配置 Flash 所使用的 QSPI 总线的实际支持的数据线最大宽度,例如:1 线(默认值,即传统的 SPI 模式)、2 线、4 线。

设置后,SFUD 会去结合当前设定的 QSPI 总线数据线宽度,去 QSPI Flash 扩展信息表 中匹配最合适的、速度最快的快速读命令,之后用户在调用 sfud_read() 时,会使用 QSPI 模式的传输函数发送该命令。

sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width)

| 参数 | 描述 | | :-------------- | :------------------------------------------- | | flash | Flash 设备 | | data_line_width | QSPI 总线支持的数据线最大宽度,例如:1、2、4 |

2.2.4 获取 Flash 设备对象

在 SFUD 配置文件中会定义 Flash 设备表,负责存放所有将要使用的 Flash 设备对象,所以 SFUD 支持多个 Flash 设备同时驱动。设备表的配置在 /sfud/inc/sfud_cfg.hSFUD_FLASH_DEVICE_TABLE 宏定义,详细配置方法参照 2.3 配置方法 Flash)。本方法通过 Flash 设备位于设备表中索引值来返回 Flash 设备对象,超出设备表范围返回 NULL

sfud_flash *sfud_get_device(size_t index)

|参数 |描述| |:----- |:----| |index |Flash 设备位于 FLash 设备表中的索引值|

2.2.5 读取 Flash 数据

sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data)

|参数 |描述| |:----- |:----| |flash |Flash 设备对象| |addr |起始地址| |size |从起始地址开始读取数据的总大小| |data |读取到的数据|

2.2.6 擦除 Flash 数据

注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 sfud_flash->chip.erase_gran 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。

sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size)

|参数 |描述| |:----- |:----| |flash |Flash 设备对象| |addr |起始地址| |size |从起始地址开始擦除数据的总大小|

2.2.7 擦除 Flash 全部数据

sfud_err sfud_chip_erase(const sfud_flash *flash)

|参数 |描述| |:----- |:----| |flash |Flash 设备对象|

2.2.8 往 Flash 写数据

sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data)

|参数 |描述| |:----- |:----| |flash |Flash 设备对象| |addr |起始地址| |size |从起始地址开始写入数据的总大小| |data |待写入的数据|

2.2.9 先擦除再往 Flash 写数据

注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 sfud_flash->chip.erase_gran 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。

sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data)

|参数 |描述| |:----- |:----| |flash |Flash 设备对象| |addr

View on GitHub
GitHub Stars1.6k
CategoryDevelopment
Updated9h ago
Forks507

Languages

C

Security Score

100/100

Audited on Apr 1, 2026

No findings