文件系统灵活用——智能家居DIY连载教程3

基于RTThread的学习(三):正点原子潘多拉 QSPI 通信 W25Q128 实验 这里注意:你所买的开发板对应的qspi 连接的是否是cubemx 上边显示的,如果不是你需要将引脚复用为你的开发板上原理图的引脚;比如:正点原子潘多拉 stm32l475vet6的原理图我们就需要找到运力图的引脚将其复用;将QSPI使能之后保存工程,并生成代码; 阅读详情

Hi,各位小伙伴,DIY 活动已经来到了第三周!前两周的任务大家都完成了吗?本周将会迎来新的挑战——文件系统。本文将从 SPI Flash 和 SD Card 两方面给大家讲解如何使用文件系统,以及针对本次 DIY 做出的一些优化,会大大增强系统性能,一起来看看吧~

回顾上期:

1、智能家居DIY连载教程(1)——如何正确使用 Sensor 框架

2、智能家居DIY连载教程(2)——在实际项目中运用消息队列与邮箱

正文共:7308 字 14 图

预计阅读时间:20分钟

1.第三周任务概览

我们来看一下第三周的任务:

了解 RT-Thread 文件系统,在接收节点中使用文件系统,存放来自发送节点发送过来的数据。

上述任务比较单一,只是文件系统而已。不过,能巧妙灵活的把文件系统用好用对,可不是一件轻松的事情。

2.RT-Thread 文件系统简要介绍

DFS 是 RT-Thread 提供的虚拟文件系统组件,全称为 Device File System,即设备虚拟文件系统,文件系统的名称使用类似 UNIX 文件、文件夹的风格。

RT-Thread DFS 组件的主要功能特点有:

  • 为应用程序提供统一的 POSIX 文件和目录操作接口:read、write、poll/select 等。

  • 支持多种类型的文件系统,如 FatFS、RomFS、DevFS 等,并提供普通文件、设备文件、网络文件描述符的管理。

  • 支持多种类型的存储设备,如 SD Card、SPI Flash、Nand Flash 等。

DFS 的层次架构如下图所示,主要分为 POSIX 接口层、虚拟文件系统层和设备抽象层。如下图:

DFS 的更多内容,请在 RT-Thread 文档中心中查看:https://www.rt-thread.org/document/site/ (由于微信无法插入外部链接,请将以上链接复制至外部浏览器打开)

3. 在 SPI Flash 上使用文件系统

3.1 准备工作

以正点原子的潘多拉开发板 (Iot Board) 为例,教大家在 SPI Flash 上使用文件系统。

值得一提的是,RT-Thread 已经将 libc 那套文件系统接口对接到 DSF 上了,在 env 工具中开启 libc 和 DFS 即可,本次教程使用 libc 的那套接口进行文件的打开/关闭、读取/写入。

在 menuconfig 中开启 libc:

1RT-Thread Components  --->
2    POSIX layer and C standard library  --->
3        [*] Enable libc APIs from toolchain

在 meunconfig 中开启 DFS,本教程使用 elmfatfs 文件系统,需要将 elmfatfs 挂载到 RT-Thread 的 DFS 上,所以 elmfatfs 也要开启:

1RT-Thread Components  --->
2    Device virtual file system  --->
3        [*] Using device virtual file system
4        [*]   Enable elm-chan fatfs

当然,不要忘记在 meunconfig 中开启 SPI Flash:

1Hardware Drivers Config  --->
2    Onboard Peripheral Drivers  --->
3        [*] Enable QSPI FLASH (W25Q128 qspi1)

潘多拉开发板上的 SPI Flash 使用的是 QSPI 接口,还需要在 meunconfig 中把 QSPI 接口开启:

1Hardware Drivers Config  --->
2    On-chip Peripheral Drivers  --->
3        [*] Enable QSPI BUS

退出 menuconfig 后需要输入 “scons --target=mdk5” 更新工程。

3.2 文件系统的挂载

本次 DIY 使用的文件系统是 elmfatfs,elmfatfs 需要在块设备上才能进行文件操作。潘多拉板子上的 SPI Flash 是 W25Q128,我们需要将 W25Q128 注册成块设备,才能使用 elmfatfs 进行文件操作。如下示例代码:

1static int rt_hw_qspi_flash_with_sfud_init(void)
2{
3    stm32_qspi_bus_attach_device("qspi1", "qspi10", RT_NULL, 4, w25qxx_enter_qspi_mode, RT_NULL);
4    if (RT_NULL == rt_sfud_flash_probe("W25Q128", "qspi10"))
5        return -RT_ERROR;
6    return RT_EOK;
7}
8INIT_COMPONENT_EXPORT(rt_hw_qspi_flash_with_sfud_init);

在 FinSH 中输入 “list_decive”,即可看到 W25Q128 注册成了块设备了,并挂载在 QSPI 上:

W25Q128 注册成了块设备后,就能将 elmfatfs  这个文件系统挂载到 RT-Thread 的 DFS 上了,如下示例代码:

1dfs_mount("W25Q128", "/", "elm", 0, 0)


3.3 文件操作

到此为止,我们就可以使用 libc 的接口进行文件操作了,将接收到的数据以文件方式存放到 W25Q128 里面去,举个简单的例子,如下示例代码:

1FILE *recvdata_p0;
2recvdata_p0 = fopen("recvdata_p0.csv", "a+");
3if (recvdata_p0 != RT_NULL)
4{
5    fputs((char *)RxBuf_P0, recvdata_p0);
6    fputs("\n", recvdata_p0);
7    fclose(recvdata_p0);
8}

在 Finsh 中输入 “ls” 可以查看当前文件系统中的文件目录,如下图:

输入 “cat XXX” 可以查看文件内容,如下图:

简单的几步就可以进行文件操作了,RT-Thread 的文件系统还是相当易用的。

4. 在 SD Card 上使用文件系统

4.1 准备工作

以正点原子的潘多拉开发板 (Iot Board) 为例,教大家在 SD Card 上使用文件系统。

和上面的 SPI Flash 一样,在 menuconfig 中开启相关选项:SD Card,SPI(潘多拉板子的 SD 卡是用 SPI 驱动的而不是 SDIO),libc,DFS,elmfatfs。

4.2 文件系统的挂载

与 SPI Flash 一样,需要将 SD Card 注册成块设备,才能挂载文件系统。如下示例代码:

1static int rt_hw_spi1_tfcard(void)
2{
3    __HAL_RCC_GPIOC_CLK_ENABLE();
4    rt_hw_spi_device_attach("spi1", "spi10", GPIOC, GPIO_PIN_3);
5    return msd_init("sd0", "spi10");
6}
7INIT_DEVICE_EXPORT(rt_hw_spi1_tfcard);

在 FinSH 中输入 “list_decive”,即可看到 SD Card 注册成了块设备了,并挂载在 SPI 上:

SD Card 注册成了块设备后,就能将 elmfatfs  这个文件系统挂载到 RT-Thread 的 DFS 上了,如下示例代码:

1dfs_mount("sd0", "/", "elm", 0, 0)

需要注意的是,如果大家手头的板子是使用 SDIO 接口来驱动 SD Card 的,那么将 SD Card 注册成块设备将不用我们操心,RT-Thread 源码中的 “...rt-thread\components\drivers\sdio\block_dev.c” 文件中,会将 SD Card 注册成块设备的。当然,文件系统的挂载还是需要我们手动敲代码去实现的。

4.3 文件操作

与 SPI Flash 一样,可以直接使用 libc 的接口进行文件操作,如下示例代码:

1FILE *recvdata_p0;
2recvdata_p0 = fopen("recvdata_p0.csv", "a+");
3if (recvdata_p0 != RT_NULL)
4{
5    fputs((char *)RxBuf_P0, recvdata_p0);
6    fputs("\n", recvdata_p0);
7    fclose(recvdata_p0);
8}

5. 针对本次 DIY 的一些优化

5.1 优化1

将文件系统用起来,进行文件操作,是一件相对比较容易的事情。不过当将文件系统运用到实际项目中的时候,往往会因为一些需求或者说是其他因素,导致事情不那么好办。就拿这个 DIY 来说,如果就像上面的示例代码这么用文件系统,虽然系统能正常工作,但是会带来一些问题:

  • 众所周知,文件的操作是需要占用大量时间和资源的,通俗来说就是慢,像文件的读,写,打开,创建等,都是比较慢的。如果发送节点发数据过来,接收节点每收到一条数据,就用文件系统记录这个数据,这样会导致系统性能下降。如何保证减少文件操作次数,提高系统性能,又能保证每条数据都不丢失呢?

这里使用 ringbuffer 来避免这个问题。

ringbuffer 是一种先进先出的 FIFO 环形缓冲区,DIY 的接收节点工程中,我们创建了两个线程去工作,一个是 nrf24l01_thread 线程,用于接收来自发送节点的数据,另一个是 DFS_thread 线程,用于利用文件系统保存数据的。并且创建一个 4KB 大小的一个 ringbuffer:

1static struct rt_ringbuffer *recvdatabuf;
2recvdatabuf = rt_ringbuffer_create(4069); /* ringbuffer的大小是4KB */

每当 nrf24l01_thread 线程接收到一条数据,就存放到 ringbuffer 中去:

1rt_ringbuffer_put(recvdatabuf, (rt_uint8_t *)str_data, strlen(str_data));

在DFS_thread 线程中,我们设置一个 ringbuffer 的阈值,这里我将阈值设置成了 ringbuffer 大小的一半,当写入的数据达到了 ringbuffer 的阈值之后,就将 ringbuffer 中所有的数据统统写入文件中去:

 1/* 判断写入的数据大小到没到所设置的ringbuffer的阈值 */
 2if (rt_ringbuffer_data_len(recvdatabuf) > (4096 / 2))
 3{
 4    /* 到阈值就直接写数据 */
 5    recvdatafile_p0 = fopen("recvdata_p0.csv", "ab+");
 6    if (recvdatafile_p0 != RT_NULL)
 7    {
 8        while(rt_ringbuffer_data_len(recvdatabuf))
 9        {
10            size = rt_ringbuffer_get(recvdatabuf, (rt_uint8_t *)writebuffer, (4096 / 2));
11            fwrite(writebuffer, 1, size, recvdatafile_p0);
12        }
13        fclose(recvdatafile_p0);
14    }
15}

这么做,就可以尽可能的减少了文件的操作,提高了系统的性能,同时又保证每一条数据都不会丢失。

5.2 优化2

但是,还有一个问题:

  • 如果发送节点很久很久才发数据过来,或者说是接收节点很久很久才收到数据,那么 ringbuffer 要很久很久才能到阈值。如果这时候,已经写了整整一天的数据进 ringbuffer 中了,只差一点点就要到阈值了,很快就可以将数据写入到文件中去了,这时候偏偏断电了!整整一天的数据白白丢失了,心痛吗?

当然,掉电丢数据这种情况是不可以避免的,但是我们可以通过一些算法优化(姑且叫它算法吧),尽可能的减少丢失数据的可能。

解决思路是:定个固定时间,计时,如果时间一到,此时数据还没写满 ringbuffer 的阈值,这时候就不管数据到没到阈值了,直接将 ringbuffer 里的数据全部写入文件中去。要实现这个思路需要搭配事件集 (event) 使用。

在 nrf24l01_thread 线程中,每收到一个数据,就发送一个事件:

 1while (1)
 2{
 3    if (!rx_pipe_num_choose())
 4    {
 5        /* 通过sscnaf解析收到的数据 */
 6        if(sscanf((char *)RxBuf_P0, "%d,+%f", &buf.timestamp, &buf.temperature) != 2)
 7        {
 8            /* 通过sscnaf解析收到的数据 */
 9            if(sscanf((char *)RxBuf_P0, "%d,-%f", &buf.timestamp, &buf.temperature) != 2)
10            {
11                continue;
12            }
13            buf.temperature = -buf.temperature;
14        }
15        sprintf(str_data, "%d,%f\n", buf.timestamp, buf.temperature);
16        /* 将数据存放到ringbuffer里 */
17        rt_ringbuffer_put(recvdatabuf, (rt_uint8_t *)str_data, strlen(str_data));
18        /* 收到数据,并将数据存放到ringbuffer里后,才发送事件 */
19        rt_event_send(recvdata_event, WRITE_EVENT);
20    }
21    rt_thread_mdelay(30);
22}

在DFS_thread 线程中,通过接收两次事件,并设置接收事件的超时时间,达到计时的目的:

 1\while (1)
 2{
 3    /* 接收感兴趣的事件WRITE_EVENT,以永久等待方式去接收 */
 4    if (rt_event_recv(recvdata_event, WRITE_EVENT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &set) != RT_EOK)
 5        continue;
 6    do
 7    {
 8        /* 接收感兴趣的事件WRITE_EVENT,以1000ms超时方式接收 */
 9        if (rt_event_recv(recvdata_event, WRITE_EVENT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, rt_tick_from_millisecond(1000), &set) == RT_EOK)
10        {
11            /* 判断写入的数据大小到没到所设置的ringbuffer的阈值 */
12            if (rt_ringbuffer_data_len(recvdatabuf) > THRESHOLD)
13            {
14                /* 到阈值就直接写数据 */
15                recvdatafile_p0 = fopen("recvdata_p0.csv", "ab+");
16                if (recvdatafile_p0 != RT_NULL)
17                {
18                    while(rt_ringbuffer_data_len(recvdatabuf))
19                    {
20                        size = rt_ringbuffer_get(recvdatabuf, (rt_uint8_t *)writebuffer, THRESHOLD);
21                        fwrite(writebuffer, 1, size, recvdatafile_p0);
22                    }
23                    fclose(recvdatafile_p0);
24                }
25            }
26            /* 阈值没到就继续接收感兴趣的事件WRITE_EVENT,以1000ms超时方式接收 */
27            continue;
28        }
29        /* 1000ms到了,还没有收到感兴趣的事件,这时候不管到没到阈值,直接写 */
30        recvdatafile_p0 = fopen("recvdata_p0.csv", "ab+");
31        if (recvdatafile_p0 != RT_NULL)
32        {
33            while(rt_ringbuffer_data_len(recvdatabuf))
34            {
35                size = rt_ringbuffer_get(recvdatabuf, (rt_uint8_t *)writebuffer, THRESHOLD);
36                fwrite(writebuffer, 1, size, recvdatafile_p0);
37            }
38            fclose(recvdatafile_p0);
39        }
40    } while(0);
41}

这样就尽最大力度的解决了掉电丢失数据的可能了。当然,第二次接收事件的超时时间可以根据自己需求设定长短。

6. 开源代码

为了更进一步便于大家学习,第三周任务的代码已经开源啦~

项目地址:https://github.com/willianchanlovegithub/DIY_projects_base_on_RT-Thread(由于微信无法插入外部链接,请将以上链接复制至外部浏览器打开)

7. 注意事项

  • 第三周的源码中,只上传了两个 demo 工程,均是本次 DIY 中接收节点的代码

    • RECEIVE(stm32l475-atk-pandora)(SD_Card) 是在 SD Card 上使用文件系统的 demo

    • RECEIVE(stm32l475-atk-pandora)(SPI_Flash) 是在 SPI Flash 上使用文件系统的 demo

  • 发送节点的代码,在第二周的 demo 工程中有,这里不再重复上传相同 demo 工程

  • SPI Flash 的 sector 大小为 4096 字节,需要在 menuconfig 中修改:

SD Card 的 sector 大小为 512 字节,需要在 menuconfig 中修改:

 

#题外话# 喜欢RT-Thread不要忘了在GitHub上留下你的STAR哦,你的star对我们来说非常重要!链接地址:https://github.com/RT-Thread/rt-thread

你可以添加微信18917005679为好友,注明:公司+姓名,拉进 RT-Thread 官方微信交流群

RT-Thread


让物联网终端的开发变得简单、快速,芯片的价值得到最大化发挥。Apache2.0协议,可免费在商业产品中使用,不需要公布源码,无潜在商业风险。

长按二维码,关注我们

看这里,求赞!求转发!

点击阅读原文进入GitHub

AT32 MCU QSPI使用指南 AT32 MCU QSPI使用指南 前言 本应用入门指南主要介绍以下几部分内容: 基于雅特力提供的 V2.x.x 的 BSP 板级支持包来进行 QSPI 的命令端口的配置及操作 基于雅特力提供的 V2.x.x 的 BSP 板级支持包来进行 QSPI 的 XIP 端口的配置及操作 XIP 端口扩展 ROM/RAM 应用 数据加解密 下载算法文件的制作 支持型号列表: AT32F435xx AT32F437xx 目录 简介… 10 时钟源 … 10 函数接口表 … 10 命令端口 … 12 协议说明… 12 阅读详情

相关推荐

Ubuntu系统全盘备份——TimeShift的安装与使用

所以如果有那天你不小心作了个大死,并且幸运到还能打开GNOME桌面和Timeshift(只要不是执行sudo rm -f /*这样的自杀程序)的时候,点击你要恢复的那个备份文件再点击Restore,经过短暂的重启后你的系统就成功恢复了。打开软件后,会有一些初始化设置,只需要一直点击 Next。根据自己电脑的内存大小决定是自动备份还是手动备份。当然,对于虚拟机用户来说,没有比在客户机直接拷贝虚拟磁盘文件更棒的方式了。点击左上角的 Create,就会执行备份操作。最下面的意思就是说不会自动备份需要手动操作。

琉璃轻纱的博客 4703

【RTT】SPI Flash 与文件系统(1):SFUD

   参考文档(国内):SFUD 参考文档    一、概述   SFUD,即 Serial Flash Universal Driver,是一款开源的串行 SPI Flash 通用驱动库。   具体的描述可以查看上面的参考手册。    二、SFDP   SFDP 是 JEDEC(固态技术协会)制定的串行 Flash 功能的参数表标准。   该标准规定了,每个 Flash 中会存在一个 参数表 ,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。   如果要知道当前你所使用

h451884098的博客 1755

NR RRC协议(2)---RRC连接建立流程

RRC连接建立目的是建立SRB1 RRC连接建立还用于将初始NAS消息从UE传送到网络 RRC连接的初始阶段期间,不激活AS安全性 RRC连接建立由UE侧发起

crg2046的博客 1957

rtthread studio与正点原子apollo(13)--QSPI设备之flash存储器

rtthread;qspi

hfh8130的博客 1054

基于PLC1200与CB1241的RS485从站Modbus Rtu通信实战指南

本文提供了一份详细的西门子S7-1200 PLC与CB1241 RS485通讯板实现Modbus RTU从站通信的实战指南。内容涵盖从硬件接线、博途软件组态、关键参数设置到程序调试与测试的全过程,重点解析了Modbus_Slave指令配置与数据块映射,帮助工程师快速掌握工业自动化系统中的数据采集与设备接入技术。

Apple的专栏 796

深入CRSF协议数据包:手撕STM32代码,教你像调试串口一样分析ELRS遥控数据流

本文深入解析CRSF协议数据包,通过手撕STM32代码,教你如何像调试串口一样分析ELRS遥控数据流。从硬件准备到数据包捕获状态机设计,再到高级数据分析技巧和实战应用,全面覆盖CRSF协议的解析与优化,帮助开发者构建稳定可靠的通信系统。

weixin_29194693的博客 337

小熊派移植RT-Thread 的app代码

前言 在上一篇我们已经讲解了如何移植RT-FOTA到小熊派开发板。本篇我们将继续移植RT-Thread,实现app代码的移植开发,并将BootLoader和app一起烧录到开发板,完成BootLoader到app的跳转动作。 一、创建RT-Thread工程 这里我使用RT-Thread studio创建了STM32L431的工程。接下来的操作都在rtthread studio中进行。 具体的教程可以看RT-Thread的 官方文档 创建工程时已经配置了log串口为UART1,所以编译之后就会有日志1s一次的

weixin_46214189的博客 1792

一文帮你彻底搞懂ARM Debug Interface之SWD(转)

ARM的文档写的已经很好了,但是关于上电以后的第一时间应该怎么操作,依然写的不够清晰,导致我第一次用的时候还是费了一些周折。今天做一个详细的梳理,希望能够帮助到更多的朋友。BTW, ARM_Cortex-M0/3 DesignStart系列会持续更新,只是中间可能会穿插其他知识点。SWD是Serial Wire Debug的简称,翻译成中文是”串行线调试”。

2302_79847220的博客 6861

RT_threadのQSPI总线设备驱动W25Q

本文仅仅记录使用RTT的QSPI总线设备驱动W25Q

qq_40993639的博客 2105

Jev模型入门:从API接入到本地部署的完整实践指南

大模型的应用方式正从单一聊天窗口转向复杂的自动化工作流,而推理模型因具备指令跟随与结构化输出能力,成为构建Agent和数据处理管线的关键组件。Jev作为面向通用场景的推理模型,不仅提供了OpenAI兼容的API接口,还支持本地量化部署,兼顾隐私、可控性与长期成本。本文从模型定位出发,明确Jev与基座模型的差异,随后介绍密钥管理、API调用、参数调优,并深入演示基于Ollama与llama.cpp的本地部署流程,包括GGUF模型文件与chat template的匹配要点。针对实践中的常见问题,如密钥泄露、ma

weixin_29057237的博客 359

新手强化学习—深入解析 YOLOv13 项目包中的文件结构和各文件作用

YOLOv13是YOLO系列最新发布的计算机视觉模型。在这篇博客中,我将深入分析YOLOv13中各个文件的作用,对整个项目的文件结构有更清晰的认识。

Limiiiing的博客 482

基于 RT-Thread 的智能家居 DIY 教程连载(3)——文件系统灵活用

智能家居 DIY 教程连载(3) 文件系统 so easy Hi,各位小伙伴,DIY 活动已经来到了第三周!前两周的任务大家都完成了吗?本周将会迎来新的挑战——文件系统。本文将从 SPI Flash 和 SD Card 两方面给大家讲解如何使用文件系统,以及针对本次 DIY 做出的一些优化,会大大增强系统性能,一起来看看吧~ 本文目录 第三周任务回顾 RT-Thread 文件系统...

MRccCHEN的博客 2244

SPRD Android 14 通过属性控制系统设置显示双栏或者单栏

SPRD Android 14 通过属性控制系统设置显示双栏或者单栏

m0_60898338的博客 1118

智能家居 DIY 教程连载4——手把手教你连云

云乃万物互联之本Hi,各位小伙伴,DIY 活动已经来到了尾声,第四周的任务是整个项目中最有趣也是最重要的部分——物联网。本周的任务完成之后,也就意味着整个项目就完全做完啦,是不是迫不及待...

rtthreadiotos的博客 765

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

嵌入式使用RTOS到底是不是大势所趋?

嵌入式设备网络化、功能复杂化的趋势,使越来越多的、过去可以用裸奔实现的嵌入式产品,产生了应用操作系统的需求。芯片成本的连续下降,以及cpu性能和内存资源...

Peter的专栏 1005

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

【文章回看】公众号系列文章合辑

感谢大家的关注,在这里提前祝您五一劳动节快乐~本期我们特别筛选了公众号历史推送中部分的精彩内容,欢迎大家回看!目前公众号内容包括但不限于(由于内容太多只能筛选部分系列内容,有其他需要的小...

FILLMOREad的博客 817

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

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

野火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引脚可控制写保护功能,当该引脚为低电平时,禁止写入数据。我们直接接电源,不使用写保护功能。

weixin_46158019的博客 1806

STM32的QSPI通信

首先说说FLASH,不管是QSPI Flash还是SPI Flash说的实际上是一种闪存芯片,比如最常见的W25Q128(下图),真正不同的是SPI协议与QSPI协议罢了。可以看到下图的芯片,2、3、5、7这四个引脚是可以复用的,根据不同的通信协议变换功能。

指尖动听知识库 1517

RT-Thread 组件-C库LIBC-POSIX标准-Pthread线程-动态模块①

动态模块为 RT-Thread 提供了动态加载程序模块的机制,因为也独立于内核编译,所以使用方式比较灵活。从实现上讲,这是一种将内核和动态模块分开的机制,通过这种机制,内核和动态模块可以分开编译,并在运行时通过内核中的模块加载器将编译好的动态模块加载到内核中运行。.mo 则是编译出来时以 .mo 做为后缀名的可执行动态模块;它可以被加载,并且系统中会自动创建一个主线程执行这个动态模块中的 main 函数;同时这个 main(int argc, char**argv) 函数也可以接受命令行上的参数。

华为奋斗者精神 1513

RT-Thread 学习笔记(六)--- 开启基于SPI Flash的elmfat文件系统(上)

软件环境:Win7,Keil MDK 4.72a, IAR EWARM 7.2, GCC 4.2,Python 2.7 ,SCons 2.3.2 硬件环境:Armfly STM32F103ZE-EK v3.0开发板 参考文章:RT-Thread编程指南 在RT-Thread默认的是SD卡作为文件系统挂载,代码如下: /* Filesystem Initi

aping_cs_dn的专栏 1万+

STM32H743使用QSPI驱动W25Q128JV芯片(正点原子例程修改)

当前项目中需要使用到STM32H743和外部SPI FLASH,在评估过程中使用的是正点原子的阿波罗开发板 但是好巧不巧的画原理图和制板的同事在选型的时候虽说保留了QSPI相同的借口,但是芯片改选了W25Q128,(可能是为了成本考虑),但是在实际调试过程中遇到了问题 仍旧使用原子哥的例程,但是写入数据后再读取会出现丢前3字节的情况。上网查了相关资料,发现W25Q256的4字节地址,128是3字节地址,则在w25qxx.c作了如下修改: //QPI,写扇区擦除指令,地址为0,无数据_24位地址_4线

ly_dapanglian的博客 7149

STM32L4使用QSPI驱动spiFLASH(W25Q64)

STM32L4使用QSPI驱动spiFLASH(W25Q64) 一、什么是QSPI QSPI 即Quad SPI,是一种专用的通讯接口,连接单、双或四(条数据线)SPI FLASH 存储器。 简单的来说,QSPI就是为了驱动SPI_FLASH所设计的专用的通信协议,他和标准的SPI协议有很多相似的地方,但是我认为将它看作一种单独的通信协议更好理解。 QSPI可以工作在单数据线、双数据线或四条数据线...

qq_38113006的博客 7380

rtthread qspi w25q256

查询qspi配置过程 文件路径: /drivers/board.h /*-------------------------- QSPI CONFIG BEGIN --------------------------*/ /** if you want to use qspi you can use the following instructions. * * STEP 1, open qspi driver framework support in the RT-Thread Settings fi

lyq308152569的博客 2757

STM32之SPI与QSPI学习笔记

QSPI接口简介 QSPI是Queued SPI的简写,是Motorola公司推出的SPI接口的扩展,比SPI应用更加广泛。 在SPI协议的基础上,Motorola公司对其功能进行了增强,增加了队列传输机制,推出了队列串行外围接口协议(即QSPI协议)。 QSPI是一种专用的通信接口,连接单、双或四(条数据线)SPI FLASH存储器。    ...

zhouyuming_hbxt的博客 2万+

【STM32H7教程】第82章 STM32H7的QSPI总线应用之QSPI Flash执行程序(BOOT+APP方式)

完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第82章 STM32H7的QSPI总线应用之QSPI Flash执行程序(BOOT+APP方式) 本章节为大家讲解QSPI Flash执行程序。 目录 第82章 STM32H7的QSPI总线应用之QSPI Flash执行程序(BOOT+APP方式) 82.1 初学者重要提示 82.2 下载算法存放位置 82.3 QSPI Flash的...

Simon223的博客 5833

利用RT-thread 在STM32F407在W25Q128上实现虚拟文件系统

一:环境 STM32F407板子上有一个W25Q128的flash芯片。通过SPI连接在一起 W25Q128 (128M-bit),被组织为65536个可编程的页,每页256bytes。擦除方式分为16页一组(即一个扇区4kbytes),128页一组(即8个扇区32kbytes),256页一组(即16个扇区或1个块64kbytes),或整个芯片擦除。该芯片有4096个可擦除扇区,或256个可擦除块。该芯片支持 standard spi,Dual/Quad I/O SPI 接在MCU的 PB3 PB4

kayshi的博客 2637
上一篇: TCP/IP Over USB 用USB传输以太网数据,给你的MCU加个网卡
下一篇: 基于STM32F407的STM32通用BootLoader使用经验
RT-Thread物联网操作系统
博客等级 码龄6年 2万+粉丝 392原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值