RT-Thread 记录(十六、SFUD 组件 — SPI Flash 的读写)
前言
RT-Thread 专栏更新至今,从开发环境到内核到设备模型,其实我们已经把使用 RT-Thread 的基础知识都讲过一遍,认真学习的朋友实际上都已经可以使用 RT-Thread 完成一些实际小项目了。
上一篇文章最后说过,RT-Thread 有一个很大的特点在于他的生态比一般的 RTOS 完善,我们在实际应用中,有许许多多现成的官方或者很多开发者提供的组件或者软件包,我们可以直接导入工程进行使用。
针对我们 RT-Thread 实际应用,很多时候不仅是要知道基本的理论,还需要真正的知道怎么实际“用”起来。基于本专栏的开发环境 RT-Thread Studio,本文开始我们来测试几个典型的 组件与软件包,来看看他们实际是如何使用的。
我们刚讲完 SPI 设备,本文就从与 SPI 设备相关的组件 SFUD 组件说起。
☆
说明,对于 RT-Thread 记录 中组件与软件包部分的文章,我并不计划讲太多的原理,因为我们的最终目的还是在于应用,在之间讲解 RT-Thread 的基础中,为了让大家更明白 RT-Thread 内核以及 I/O 设备模型,也没少分析源码以及讲解实现原理,核心的部分都是自己研究源码。
对于 组件与软件包 部分,我侧重点会在与的记录测试使用的过程,使得我们能够快速上手。
☆
本 RT-Thread 专栏记录的开发环境:
RT-Thread 记录(一、RT-Thread 版本、RT-Thread Studio 开发环境 及 配合 CubeMX 开发快速上手)
https://xie.infoq.cn/article/44be1057caace7a6a2c4c4b59
RT-Thread 记录(二、RT-Thread 内核启动流程 — 启动文件和源码分析)
https://xie.infoq.cn/article/44be1057caace7a6a2c4c4b59
RT-Thread 内核篇系列博文链接:
RT-Thread 记录(三、RT-Thread 线程操作函数及线程管理与 FreeRTOS 的比较)
https://xie.infoq.cn/article/1d2e8e030ae689d6b8ee44b05
RT-Thread 记录(四、RT-Thread 时钟节拍和软件定时器)
https://xie.infoq.cn/article/3198c9b741782036bfd6e54e9
RT-Thread 记录(五、RT-Thread 临界区保护
https://xie.infoq.cn/article/7a41020e03184950664df7391
RT-Thread 记录(六、IPC 机制之信号量、互斥量和事件集)
https://xie.infoq.cn/article/1f49bfd6c69377deb9eee838f
RT-Thread 记录(七、IPC 机制之邮箱、消息队列)
https://xie.infoq.cn/article/360b04e7bc6024917afecef1d
RT-Thread 记录(八、理解 RT-Thread 内存管理)
https://xie.infoq.cn/article/bd5d8f8a19fa11ea9feacf34d
RT-Thread 记录(九、RT-Thread 中断处理与阶段小结)
https://xie.infoq.cn/article/3da9530cfac06feece3523a0c
RT-Thread 设备篇系列博文链接:
RT-Thread 记录(十、全面认识 RT-Thread I/O 设备模型)
https://xie.infoq.cn/article/40536d29988d683c78b4ba5ff
RT-Thread 记录(十一、I/O 设备模型之 UART 设备 — 源码解析)
https://xie.infoq.cn/article/38bb4bf15cb81f1fdb060b29e
RT-Thread 记录(十二、I/O 设备模型之 UART 设备 — 使用测试)
https://xie.infoq.cn/article/1df47f3ae5174dfcb418b07b6
RT-Thread 记录(十三、I/O 设备模型之 PIN 设备)
https://xie.infoq.cn/article/af3ff1066f61cddeb134c3c88
RT-Thread 记录(十四、I/O 设备模型之 ADC 设备)
https://xie.infoq.cn/article/2eda5e23a77db3a60d2595d97
RT-Thread 记录(十五、I/O 设备模型之 SPI 设备)
一、SFUD 组件简介
SFUD (全称 Serial Flash Universal Driver)是一款开源的串行 SPI Flash 通用驱动库。
1.1 基本简介
基础介绍借用官方的说明:由于现有市面的串行 Flash 种类居多,各个 Flash 的规格及命令存在差异, SFUD 就是为了解决这些 Flash 的差异现状而设计,让我们的产品能够支持不同品牌及规格的 Flash,提高了涉及到 Flash 功能的软件的可重用性及可扩展性,同时也可以规避 Flash 缺货或停产给产品所带来的风险。
在 RT-Thread 中,SFUD 组件的 SPI 驱动是以 RTThread 的 I/O 设备模型框架为基础设计的。
使用 SFUD 组件,我们不用自己写 SPI Flash 的驱动。
支持 SPI/QSPI 接口、面向对象(同时支持多个 Flash 对象)、可灵活裁剪、扩展性强、支持 4 字节地址。
☆ SFUD 是个开源的组件,对于该组件真正权威的参考说明就是该组件作者写好的 README.md
文件(永远要记住第一作者的文档、官方的文档永远是最具有参考价值的)。☆
使用 RT-Thread Studio 打开 README 文件如下图,基本的介绍,函数使用,说明该有的都有,大家可自行查看:
本文不深入分析源码实现原理,对于理论只做简单说明。这里关于理论的分析说明推荐几篇文章,在文章说明理论基础的时候也参考了下面的文章:
RT-Thread中flash管理 — [SFUD组件 和 FAL驱动组件介绍]
1.2 SFUD 对 Flash 的管理
我们以前讲过,面向对象思想的程序设计,一般都会使用一个结构体 表示一个对象,我们讲过的线程、IPC 机制,I/O 设备都有他们的设备控制块结构体。
对于 SPI Flash 设备,SFUD 也定义了一个结构体 sfud_flash
进行管理,其位置和内容如下图:
在这个对象控制块中,有一个成员为 chip
,其类型为芯片信息的结构体sfud_flash_chip
,如下图:
在 SFUD 组件中,已经定义好了一些支持的 chip 信息,如下图:
基本上包括了市面上通用的 SPI Flash 芯片,如果使用的 flash 不支持 SFUD 组件,可根据 README 文件自行添加。
简单的概述就到这里,下面我们来看看 SFUD 组件提供的操作函数。
二、SFUD 组件操作函数
根据 SFUD 组件的 README 文件,SFUD 组件提供的 API 框架图如下:
这里要说明一下,上面的 API 是 SFUD 对外标准的通用 API,就是不管用什么系统,或者使用裸机,移植好了 SFUD 组件这些 API 都可以使用。
对于我们使用的 RT-Thread 来说,访问设备的函数就是 SFUD 设备的标准 API。
但是对于初始化相关的部分来说,RT-Thread 官方给我们写好了标准的驱动函数。
2.1 初始化相关函数
在工程文件中,与 RT-Thread 初始化驱动文件如下:
其提供的函数有(对于 RT-Thread 中初始化相关的函数使用,在本文后面使用测试小节会有详细示例说明):
函数我们不做深入分析,大家需要学会使用,以前有很多文章都有源码分析说明,源码自己查看,比如其中比较关键的一个函数 rt_sfud_flash_probe_ex
:
2.2 设备访问函数
设备访问函数,SFUD 组件中 README 文件都有说明的,函数使用的注意事项可查看组件说明文件。
这里统一列一下方便以后复制使用:
2.2.1 读数据
2.2.2 擦除数据
部分擦除:
全片擦除:
2.2.3 写数据
直接写:
先擦除再写:
2.2.4 Flash 状态相关
读取 Flash 状态:
修改 Flash 状态:
三、使用测试
本小节说明一下在 RT-Thread Studio 上使用 SFUD 组件的步骤,然后我们使用示例进行基本的测试:
3.1 使用步骤
3.1.1 使能 SPI 设备
根据文章 RT-Thread 记录(十五、I/O 设备模型之 SPI 设备)接描述 https://xie.infoq.cn/article/33dcc6fdc5169c287078a2bbb 中 《3.1 SPI 设备使用步骤》说明使能 SPI 总线。
注册 SPI 总线设备,使用list_device
可查看结果:
.
3.1.2 使能 SFUD 组件包
和使能 SPI 设备一样,在 RT-Thread Studio 打开 RT-Thread Settings 打开 SFUD 组件使能,如下图:
使能完成,我们在应用层就可直接调用上一小节将的 SFUD 操作函数了。
在工程中, SFUD 组件相关的程序位置如下:
.
3.1.3 挂载 SFUD 设备
在使用 SFUD 设备前,需要挂载,类似把 SPI 设备挂载至 SPI 总线上一样,使用如下操作:
忘了另外一块开发板不是 W25Q128 而是 W25Q64,所以最终找到的是 W25Q64DW。
这里有个小问题说明一下, DBG 定义的问题,自己把 mian 里面的注释稍微修改一下:
.
3.1.4 应用程序查找设备
使用 rt_sfud_flash_find
或者 rt_sfud_flash_find_by_dev_name
获取设备句柄:
.
3.1.5 使用 API 进行读写操作
完成上述步骤,就可以根据自己的应用,使用上面介绍的 SFUD 组件操作函数访问设备部分进行 Flash 的操作了。
比如:
3.2 读写测试
在上面的使用步骤说明中,其实我已经把自己做的简单测试都说了一遍,这里我们上一下测试部分代码,然后看一下测试效果:
测试结果:
测试细节说明:
在测试的时候我使用了一个按键线程写 flash,最开始的时候使用的是 512 字节大小的线程栈:
使用函数sfud_erase_write
会比 sfud_write
函数占用更多的内存。
结语
本文我们从上一篇文章刚学完的 SPI 设备相关的 SFUD 组件开始,接触到了 RT-Thread 的组件与软件包,可以看出,对于常用的设备使用 RT-Thread 开发有多么的方便了。
但是前提当然是得对 RT-Thread 的面向对象的思想,I/O 设备模型等基础有一定的认识,如果只是为了使用,看一篇文章即可,如果是为了理解掌握,还得多多了解 RT-Thread 基础相关知识,比如博主的 RT-Thread 专栏 = =! O(∩_∩)O 哈哈~
再次申明一下,对于组件与软件包,因为都是大佬开发者们写好的驱动,所以我偏向的重点是在于学会使用,说明文档在每个组件或者软件包都有作者详细的说明,那才是最好的参考资料。
希望大家多多支持!本文就到这里,谢谢!
版权声明: 本文为 InfoQ 作者【矜辰所致】的原创文章。
原文链接:【http://xie.infoq.cn/article/d163b38baf9f10c289cd8a361】。文章转载请联系作者。
评论