RT-Thread:SPI万能驱动 SFUD 驱动Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动

关键词:SFUD,FLASH,W25Q64,W25Q128,STM32F407

说明:RT-Thread 系统 使用 SPI万能驱动 SFUD 驱动 Flash W25Q64,通过 STM32CubeMX 配置 STM32 SPI 驱动。

提示:SFUD添加后的存储位置

1.打开RT-Thread Setting SPI SFUD

打开 SFUD ,SPI

右键-详细配置

SFUD的配置 放置于如下头文件 rtconfig.h

2.开启board.h/stm32F1xx_hal_config.h中关于SPI的宏定义

STEP 1:第一步打开RT-Thread Setting SPI SFUD 中已经操作实现。

STEP 2:定义与spi总线相关的宏,例如#define BSP_USING_SPI1

STEP 4:修改您的stm32xxxx_hal_config.h文件以支持spi外围设备。 定义与外围设备相关的宏,例如#define HAL_SPI_MODULE_ENABLED

STEP 3:将由stm32cubemx生成的stm32xxxx_hal_msp.c的spi init函数复制到board.c文件的末尾,例如void HAL_SPI_MspInit(SPI_HandleTypeDef * hspi)

如下复制过程,将由stm32cubemx生成的 SPI 驱动部分代码全部复制到 board.c文件的末尾

3.stm32cubemx SPI 驱动生成过程

如何打开 stm32cubemx 建工程的过程就不讲解,直接讲关于SPI的配置过程

根据对应的STM32芯片打开一个工程配置SPI部分

时钟配置

 时钟树配置

SPI接口设置

输出项目设置

代码生成器 设置

生成代码

打开文件夹

SPI.C文件夹内便是生成的关于SPI接口的配置驱动代码

4.编译烧录后 发送命令 list_device 可以看到SPI总线 SPI1 已经注册到系统

5.SPI从设备驱动编写

SPI的总线设备已经注册完毕,接下来需要进行SPI从设备驱动编写,这里直接使用开发板板载的SPI Flash W25Q64进行测试,

新建 w25q_test.c

#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include "drv_spi.h"
#include "spi_flash_sfud.h"

static int rt_hw_spi_flash_init(void)
{
    __HAL_RCC_GPIOB_CLK_ENABLE();
    rt_hw_spi_device_attach("spi1", "spi10", GPIOC, GPIO_PIN_0);// spi10 表示挂载在 spi3 总线上的 0 号设备,PC0是片选,这一步就可以将从设备挂在到总线中。

    if (RT_NULL == rt_sfud_flash_probe("W25Q64", "spi10"))  //注册块设备,这一步可以将外部flash抽象为系统的块设备
    {
        return -RT_ERROR;
    };

    return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);

        不支持 SFDP 标准的 Flash 已经在 Flash 参数信息表中定义,sfud_flash_def.h 文件有关于 flash 芯片的配置信息,配置中有的型号可以直接定义使用;配置中没有,且不支持SFDP的Flash 可以自己添加。

        注意:上述代码中的 "W25Q64" 与下截图的型号无关,进过测试,将"W25Q64" 改为"W25Q664" 编译烧录后,串口打印的数据任然一样,打印信息是 SFUD 自动探测读出的 Flash 的信息。具体原理不清楚。

编译后烧录,串口会显示 FLASH 的注册信息

SFUD打印了 基本Flash参数表信息

 \ | /
- RT -     Thread Operating System
 / | \     4.0.2 build Jul  3 2020
 2006 - 2019 Copyright by rt-thread team
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud.c:862) The flash device manufacturer ID is 0xEF, memory type ID is 0x40, capacity ID is 0x17.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:132) Check SFDP header is OK. The reversion is V1.5, NPN is 0.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:175) Check JEDEC basic flash parameter header is OK. The table id is 0, reversion is V1.5, length is 16, parameter table pointer is 0x000080.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:203) JEDEC basic flash parameter table info:
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:204) MSB-LSB  3    2    1    0
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0001] 0xFF 0xF9 0x20 0xE5
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0002] 0x03 0xFF 0xFF 0xFF
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0003] 0x6B 0x08 0xEB 0x44
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0004] 0xBB 0x42 0x3B 0x08
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0005] 0xFF 0xFF 0xFF 0xFE
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0006] 0x00 0x00 0xFF 0xFF
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0007] 0xEB 0x40 0xFF 0xFF
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0008] 0x52 0x0F 0x20 0x0C
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:207) [0009] 0x00 0x00 0xD8 0x10
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:215) 4 KB Erase is supported throughout the device. Command is 0x20.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:234) Write granularity is 64 bytes or larger.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:245) Target flash status register is non-volatile.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:271) 3-Byte only addressing.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:305) Capacity is 8388608 Bytes.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:312) Flash device supports 4KB block erase. Command is 0x20.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:312) Flash device supports 32KB block erase. Command is 0x52.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud_sfdp.c:312) Flash device supports 64KB block erase. Command is 0xD8.
[SFUD] Find a Winbond flash chip. Size is 8388608 bytes.
[SFUD] (../rt-thread/components/drivers/spi/sfud/src/sfud.c:840) Flash device reset success.
[SFUD] W25Q64 flash device is initialize success.
[SFUD] Probe SPI flash W25Q64 by SPI device spi10 success.
msh >

6.SFUD命令介绍

        通过串口发送 sf 命令,可以查到关于 SFUD 系统的命令,可以通过命令对Flash进行读写、擦除等操作。

msh >sf
Usage:
sf probe [spi_device]           - probe and init SPI flash by given 'spi_device'
sf read addr size               - read 'size' bytes starting at 'addr'
sf write addr data1 ... dataN   - write some bytes 'data' to flash starting at 'addr'
sf erase addr size              - erase 'size' bytes starting at 'addr'
sf status [<volatile> <status>] - read or write '1:volatile|0:non-volatile' 'status'
sf bench                        - full chip benchmark. DANGER: It will erase full chip!
sf probe [spi_device]           - 探测命令:使用如 sf probe spi10 ,就能探测到挂载的spi10设备
sf read addr size               - 读flash:使用如 sf read 00 100 ,表示从地址00开始读100个字节
sf write addr data1 ... dataN   - 写flash:使用如 sf write 17 01 02 03 04 05 06 07 08 09 10 11 ,表示从17地址开始写入后面这些数据
sf erase addr size              - 擦除命令:
sf status [<volatile> <status>] - 查询状态:查询状态寄存器的值
                        - 全芯片基准测试。 危险:它将擦除整个芯片!

7.SFUD 测试程序

#include "user_cfg.h"

/*
W25Q128介绍
W25Q128是华邦公司推出的大容量SPI FLASH产品,W25Q128的容量为128M bit,该系列还有W25Q80/16/32/64等。
W25Q128将16M的容量分为256个块(Block),每个块大小为64K字节,每个块又分为16个扇区(Sector),每个扇区4K个字节。
W25Q128的最小擦除单位为一个扇区,也就是每次必须擦除4K个字节。这样我们需要给W25Q128开辟一个至少4K的缓存区,这样对SRAM要求比较高,要求芯片必须有4K以上SRAM才能很好的操作。
W25Q128的擦写周期多达10W次,具有20年的数据保存期限,支持电压为2.7~3.6V,
W25Q128支持标准的SPI,还支持双输出/四输出的SPI,最大SPI时钟可以到80Mhz(双输出时相当于160Mhz,四输出时相当于320M),更多的W25Q128的介绍,请参考W25Q128的DATASHEET。
 */


/* SPI Flash 驱动 */
static int rt_hw_spi_flash_init(void)
{
    //__HAL_RCC_GPIOB_CLK_ENABLE();
    /* 往总线 spi1 上挂载一个 spi10 从设备 */
    rt_hw_spi_device_attach("spi1", "spi10", GPIOA, GPIO_PIN_4);/*spi10 表示挂载在 spi3 总线上的 0 号设备,PC0是片选,这一步就可以将从设备挂在到总线中。*/

    /* 使用 SFUD 探测 spi10 从设备,并将 spi10 连接的 flash 初始化为块设备,名称 W25Q64DW */
    if (RT_NULL == rt_sfud_flash_probe("W25Q128JV", "spi10"))  /* 注册块设备,这一步可以将外部flash抽象为系统的块设备*/
    {
        return -RT_ERROR;
    };

    return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init);



void W25Q_Flash_test(void)
{
    sfud_err result;
    uint8_t *read_data;  // 读取到的数据
    uint8_t *write_data; // 将要写入的数据
    sfud_flash *sfud_dev = NULL;

    sfud_dev = rt_sfud_flash_find("spi10"); // 获取 sfud_dev
    // 或者 sfud_dev = rt_sfud_flash_find_by_dev_name("W25Q128");

    /*擦除 Flash 数据;flash: Flash 设备对象;addr:起始地址;size:从起始地址开始擦除数据的总大小*/
    sfud_erase(sfud_dev, 0, 1024);           // 擦除从 0 开始的 4096 字节

    write_data = rt_malloc(4096);              // 内存申请,函数会从系统堆空间中找到合适大小的内存块,然后把内存块可用地址返回给用户。
    rt_memset(write_data, 1, 4096);            // 作用是在一段内存块中填充某个给定的值,将  write_data 32 个地址填入1

    /*往 Flash 写数据:flash:Flash 设备对象;addr:起始地址;size:从起始地址开始写入数据的总大小;data:待写入的数据*/
    sfud_write(sfud_dev, 0, 4096, write_data); // 将数据 32 字节的 write_data 从 0 开始写入 flash

    read_data = rt_malloc(4096);
    rt_memset(read_data, 0, 4096);
    for (uint16_t var = 0; var < 4096; ++var)
    {
        rt_kprintf("var = %d ,data = %d \n",var,read_data[var]) ;
    }

    /*读取 Flash 数据; flash: Flash 设备对象 ;addr: 起始地址;size:从起始地址开始读取数据的总大小;data:读取到的数据*/
    sfud_read(sfud_dev, 0, 4096, read_data);   // 读取从 0 开始的 32 字节,存入 read_data

    for (uint16_t var = 0; var < 4096; ++var)
    {
        rt_kprintf("var = %d ,data = %d \n",var,read_data[var]) ;
    }
}

<think>嗯,用户在使用MySQL时遇到了一个问题:在刷存储过程的时候,里面的注释被过滤掉了,导致存储过程没有注释。这确实会影响代码的可读性和维护性。我需要仔细分析可能的原因,并提供有效的解决方案。 首先,我得回忆一下MySQL处理存储过程和注释的相关机制。可能用户在创建存储过程时,使用了某些工具或客户端,这些工具可能在执行时自动去除了注释。比如,使用mysql命令行客户端时,是否有参数会影响注释的处理?或者存储过程中的注释语法是否正确? 然后,考虑MySQL的服务器变量。记得有一个叫做`sql_notes`的变量,如果设置为OFF,可能会影响警告信息的处理,但不确定是否与注释有关。另外,可能和`--comments`这个客户端选项有关。在mysql客户端中,默认情况下可能不会保留注释,需要显式启用。 接下来,用户可能是在使用某种迁移工具或脚本,比如mysqldump导出的SQL文件,再导入时注释被过滤。这时候需要检查导出和导入时的参数设置,确保保留注释。 另外,存储过程本身的注释语法是否正确也很重要。MySQL支持两种注释方式:`--`和`#`,以及`/* */`块注释。如果用户的注释写法有误,可能会导致解析错误,从而被服务器忽略。例如,`--`后面必须跟有空格,否则可能不被识别为注释。 可能的解决方案包括: 1. 在导入时使用mysql客户端的`--comments`选项,确保保留注释。 2. 检查存储过程中的注释语法是否正确,特别是`--`后面是否有空格。 3. 验证导出工具(如mysqldump)是否默认保留了注释,或者在导出时添加`--comments`参数。 4. 检查MySQL服务器的版本,是否存在已知的bug导致注释被过滤,考虑升级或应用补丁。 还需要考虑用户的具体操作步骤,例如他们是如何创建或导入存储过程的。如果是通过PHPMyAdmin或其他图形化工具,可能需要检查工具的设置是否有过滤注释的选项。此外,查看错误日志或警告信息,可能会提供线索,比如是否有语法错误导致注释被忽略。 最后,建议用户提供一个具体的例子,说明他们如何执行存储过程的创建,以及注释是如何书写的,这样可以更准确地诊断问题。同时,测试不同的注释格式和客户端选项,确认哪种方式能够保留注释,从而找到根本原因并解决。</think>针对MySQL存储过程注释被过滤的问题,以下是分步解决方案: ===== 原因分析 ===== 1. **客户端参数限制**:mysql命令行默认过滤注释(尤其是单行注释) 2. **注释语法错误**:使用了不规范的注释符号 3. **导出工具配置**:mysqldump等工具未启用保留注释参数 ===== 解决方案 ===== 一、强制保留注释(推荐) ```bash # 执行SQL脚本时添加--comments参数 mysql -u用户 -p --comments < 存储过程.sql ``` 二、验证注释规范 1. 正确单行注释: ```sql -- 这里必须有空格(规范写法) # 井号注释无需空格 ``` 2. 正确块注释: ```sql /* 这是规范的 多行注释 */ ``` 三、检查导出配置(适用mysqldump) ```bash # 导出时保留注释 mysqldump -u用户 -p --comments --routines > 备份.sql ``` 四、验证执行结果 ```sql -- 查看存储过程定义 SHOW CREATE PROCEDURE 存储过程名称; ``` ===== 补充说明 ===== 1. **客户端版本验证**: ```bash mysql --version # 建议使用5.7+版本 ``` 2. **注释过滤场景**: - 使用`DELIMITER`时确保注释在有效区间内 - 避免在`BEGIN...END`块首行写单行注释 ===== 测试案例 ===== ```sql DELIMITER $$ CREATE PROCEDURE test_comment() BEGIN -- 这是有效注释(带空格) # 这也是有效注释 /* 多行注释 测试 */ SELECT 1; END$$ DELIMITER ; ``` 执行时若使用`--comments`参数,上述注释将完整保留。可通过`SHOW CREATE PROCEDURE test_comment`查看效果。 建议通过命令行直接验证参数效果,可准确定位问题根源。如果仍存在注释丢失,请检查MySQL服务器日志是否有解析警告。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值