rt-thread(5.0版本)之sfud组件的使用问题记录(w25q128存储模块)

前言

  1. 记录一下5.0版本时使用官方推荐的函数与底层驱动存在的不兼容问题

在这里插入图片描述

相关宏定义

// -----------------------------SPI 组件
#define RT_USING_SPI
#define RT_USING_SFUD
#define RT_SFUD_USING_SFDP
#define RT_SFUD_USING_FLASH_INFO_TABLE
#define RT_SFUD_SPI_MAX_HZ 50000000
#define RT_DEBUG_SFUD

使用旧的api函数

硬件驱动(使用的SPI1)

//
// Created by shchl on 2024/3/20.
//
#include "board.h"
#ifdef RT_USING_SPI
/**
* @brief SPI MSP Initialization
* This function configures the hardware resources used in this example
* @param hspi: SPI handle pointer
* @retval None
*/
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if(hspi->Instance==SPI1)
    {
#ifdef BSP_USING_SPI1
        /* USER CODE BEGIN SPI1_MspInit 0 */

        /* USER CODE END SPI1_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_SPI1_CLK_ENABLE();

        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**SPI1 GPIO Configuration
        PB3     ------> SPI1_SCK
        PB4     ------> SPI1_MISO
        PB5     ------> SPI1_MOSI
        */
        GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

        /* USER CODE BEGIN SPI1_MspInit 1 */

        /* USER CODE END SPI1_MspInit 1 */
#endif
    }

}

#endif

w25q128驱动组件

//
// Created by shchl on 2024/3/20.
//

#include "board_w25q128.h"
#include "board.h"
#include "drv_spi.h"
#include "spi_flash_sfud.h"


static int rt_hw_spi_flash_init(void) {

    if (RT_EOK != rt_hw_spi_device_attach("spi1", "spi10", GPIOB, GPIO_PIN_14)) {
        LOG_E("Failed to attach the spi device.");
        return -RT_ERROR;
    }
    if (RT_NULL == rt_sfud_flash_probe("W25Q128BV", "spi10")) {
        LOG_E("Failed to probe the W25Q128.");
        return -RT_ERROR;
    };

    return RT_EOK;
}

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

测试结果(ok)

在这里插入图片描述

使用5.0版本之后(官方推荐函数)

硬件驱动(同上)

w25q128驱动组件

//
// Created by shchl on 2024/3/20.
//

#include "board_w25q128.h"
#include "board.h"
#include "drv_spi.h"
#include "spi_flash_sfud.h"

static int rt_hw_spi_flash_init(void)
{
    struct rt_spi_device *spi_device = RT_NULL;

    spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
    if(RT_NULL == spi_device)
    {
        LOG_E("Failed to malloc the spi device.");
        return -RT_ENOMEM;
    }
    if (RT_EOK != rt_spi_bus_attach_device_cspin(spi_device, "spi10", "spi1",GET_PIN(B, 14), RT_NULL))
    {
        LOG_E("Failed to attach the spi device.");
        return -RT_ERROR;
    }
    if (RT_NULL == rt_sfud_flash_probe("W25Q128BV", "spi10"))
    {
        LOG_E("Failed to probe the W25Q128BV.");
        return -RT_ERROR;
    };

    return RT_EOK;
}

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

运行结果(出现错误)

在这里插入图片描述

原因分析

在这里插入图片描述在这里插入图片描述

驱动调整(针对5.0版本,总共修改2处)

在这里插入图片描述
在这里插入图片描述

修改后的函数

static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
    HAL_StatusTypeDef state;
    rt_size_t message_length, already_send_length;
    rt_uint16_t send_length;
    rt_uint8_t *recv_buf;
    const rt_uint8_t *send_buf;

    RT_ASSERT(device != RT_NULL);
    RT_ASSERT(device->bus != RT_NULL);
    RT_ASSERT(device->bus->parent.user_data != RT_NULL);
    RT_ASSERT(message != RT_NULL);

    struct stm32_spi *spi_drv =  rt_container_of(device->bus, struct stm32_spi, spi_bus);
    SPI_HandleTypeDef *spi_handle = &spi_drv->handle;
    struct stm32_hw_spi_cs *cs = device->parent.user_data;

    if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS))
    {
        if (cs) {
            if (device->config.mode & RT_SPI_CS_HIGH)
                HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_SET);
            else
                HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_RESET);
        } else {
            if (device->config.mode & RT_SPI_CS_HIGH)
                rt_pin_write(device->cs_pin, PIN_HIGH);
            else
                rt_pin_write(device->cs_pin, PIN_LOW);
        }
    }

    LOG_D("%s transfer prepare and start", spi_drv->config->bus_name);
    LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
          spi_drv->config->bus_name,
          (uint32_t)message->send_buf,
          (uint32_t)message->recv_buf, message->length);

    message_length = message->length;
    recv_buf = message->recv_buf;
    send_buf = message->send_buf;
    while (message_length)
    {
        /* the HAL library use uint16 to save the data length */
        if (message_length > 65535)
        {
            send_length = 65535;
            message_length = message_length - 65535;
        }
        else
        {
            send_length = message_length;
            message_length = 0;
        }

        /* calculate the start address */
        already_send_length = message->length - send_length - message_length;
        send_buf = (rt_uint8_t *)message->send_buf + already_send_length;
        recv_buf = (rt_uint8_t *)message->recv_buf + already_send_length;

        /* start once data exchange in DMA mode */
        if (message->send_buf && message->recv_buf)
        {
            if ((spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG) && (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG))
            {
                state = HAL_SPI_TransmitReceive_DMA(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length);
            }
            else
            {
                state = HAL_SPI_TransmitReceive(spi_handle, (uint8_t *)send_buf, (uint8_t *)recv_buf, send_length, 1000);
            }
        }
        else if (message->send_buf)
        {
            if (spi_drv->spi_dma_flag & SPI_USING_TX_DMA_FLAG)
            {
                state = HAL_SPI_Transmit_DMA(spi_handle, (uint8_t *)send_buf, send_length);
            }
            else
            {
                state = HAL_SPI_Transmit(spi_handle, (uint8_t *)send_buf, send_length, 1000);
            }

            if (message->cs_release && (device->config.mode & RT_SPI_3WIRE))
            {
                /* release the CS by disable SPI when using 3 wires SPI */
                __HAL_SPI_DISABLE(spi_handle);
            }
        }
        else
        {
            memset((uint8_t *)recv_buf, 0xff, send_length);
            if (spi_drv->spi_dma_flag & SPI_USING_RX_DMA_FLAG)
            {
                state = HAL_SPI_Receive_DMA(spi_handle, (uint8_t *)recv_buf, send_length);
            }
            else
            {
                /* clear the old error flag */
                __HAL_SPI_CLEAR_OVRFLAG(spi_handle);
                state = HAL_SPI_Receive(spi_handle, (uint8_t *)recv_buf, send_length, 1000);
            }
        }

        if (state != HAL_OK)
        {
            LOG_I("spi transfer error : %d", state);
            message->length = 0;
            spi_handle->State = HAL_SPI_STATE_READY;
        }
        else
        {
            LOG_D("%s transfer done", spi_drv->config->bus_name);
        }

        /* For simplicity reasons, this example is just waiting till the end of the
           transfer, but application may perform other tasks while transfer operation
           is ongoing. */
        while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY);
    }

    if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
    {
        if (cs) {
            if (device->config.mode & RT_SPI_CS_HIGH)
                HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_RESET);
            else
                HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_SET);
        } else {
            if (device->config.mode & RT_SPI_CS_HIGH)
                rt_pin_write(device->cs_pin, PIN_LOW);
            else
                rt_pin_write(device->cs_pin, PIN_HIGH);
        }
    }

    return message->length;
}

测试结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/472611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

生骨肉冻干喂养有哪些优点?对猫身体好的生骨肉冻干分享

随着科学养猫知识的普及,生骨肉冻干喂养越来越受到养猫人的青睐。生骨肉冻干不仅符合猫咪的饮食天性,还能提供均衡的营养,有助于维护猫咪的口腔和消化系统健康。很多铲屎官看到了生骨肉冻干喂养的好处,打算开始生骨肉冻干喂养&…

ES 常见面试题及答案

目录 es 写入数据流程 es 删除数据流程 es 读数据流程 es 部署的服务有哪些角色 es 的实现原理 es 和lucence 关系 如何提高写入效率 提高搜索效率 es doc value指的啥 分片指的啥,定义后可不可义再修改 深分页如何优化 对于聚合操作是如何优化的 元数据…

微服务高级篇(二):分布式事务+Seata架构

文章目录 一、分布式事务理论基础1.1 CAP定理1.2 BASE理论 二、初始Seata2.1 Seata的架构2.2 部署TC【事务协调者】服务2.3 微服务集成Seata 三、实践3.1 XA模式3.1.1 原理3.1.2 实现 3.2 AT模式3.2.1 原理3.2.2 脏写问题以及解决方案【全局锁超时处理】3.2.3 实现 3.3 TCC模式…

机器人路径规划:基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(提供Python代码)

迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略&#…

【漏洞复现】Progress Kemp LoadMaster 命令注入漏洞(CVE-2024-1212)

0x01 产品简介 Progress Kemp LoadMaster是一款高性能的应用交付控制器,具有可扩展性,支持实体硬件和虚拟机的负载均衡。它提供了当今应用服务所需的各种功能,包括深度用户验证、资安防护(如WAF/IPS/DDoS防护)以及零信…

Cannot run program “C:\Program Files\Java\jdk-17\bin\java.exe“

错误提示:Cannot run program “C:\Program Files\Java\jdk-17\bin\java.exe” 解决办法: 检查环境变量是否配置是否正确检查项目环境是否正确,可能会出现多个JDK版本,将不需要的删除

Spring Cloud(Finchley版本)系列教程(四) 断路器(Hystrix)

Spring Cloud(Finchley版本)系列教程(四) 断路器(Hystrix) 为了更好的浏览体验,欢迎光顾勤奋的凯尔森同学个人博客http://www.huerpu.cc:7000 一、断路器Hystrix hystrix是Netlifx开源的一款容错框架,防雪崩利器,具备服务降级,…

如何实现在固定位置的鼠标连点

鼠大侠的鼠标连点功能是免费的 浏览器搜索下载鼠大侠,指定连点间隔和启动快捷键 点击设置,指定点击位置

2024年熔化焊接与热切割证模拟考试题库及熔化焊接与热切割理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年熔化焊接与热切割证模拟考试题库及熔化焊接与热切割理论考试试题是由安全生产模拟考试一点通提供,熔化焊接与热切割证模拟考试题库是根据熔化焊接与热切割最新版教材,熔化焊接与热切割大…

部分字符函数与字符串函数的讲解

说到字符函数,我们见过很多,比如strlen,strcpy,strcat...... 这时候就会有人说还有sizeof,其实sizeof不是库函数,他其实是操作符 但是你听说过以下库函数么? 所以说字符串的函数有很多&#xff…

Photomator:专业级照片编辑的利器

Photomator软件是一款功能强大的照片编辑和管理工具,专注于提供高质量的图像处理体验和便捷的工作流程。以下是关于Photomator软件功能特色的详细介绍: 高级颜色调整功能:Photomator提供了大量前沿的颜色调整工具,包括AI驱动的自…

【数据结构】单链表详解

前言 为了解决顺序表存在的一些问题,我们引入了单链表~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 顺序表存在一定的问题 与顺序表的对比 认识链表 链表结构 打印节点 头文件SList.h 源…

opencv安装(C++)并配置vs

准备工作: 1.opencv安装包(此教程使用4.9) 2.visual studio(此教程使用vs2019) opencv安装: 1、下载opencv: 1.1 官网下载:Releases - OpenCV 1.2 百度网盘:链接:https://pan.baidu.com/s/1NpEoFjbbyQJtFD…

HANA VIEW 用 ABAP 创建CDS VIEW,在生成ODATA

这里我们做ADT来创建 场景介绍:把hana中的一个底表,创建成ABAP的 CDS VIEW ,在把CDS VIEW 生成 OData 服务。 一、创建CDS Table Function 红框内根据自身情况填写 选择 Define Table Function with Parameters 创建 Data Definition 完整代码,定义 结构 , 也可以定义参…

基于springboot+vue的火锅店管理系统

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 ​主要内容:毕业设计(Javaweb项目|小程序|Pyt…

javaSwing推箱子游戏

一、简介 策略性游戏可以锻炼人的思维能力还能缓解人的压力,使人们暂时忘却生活当中的烦恼,增强人们的逻辑思维能力,游戏的艺术美也吸引着越来越多的玩家和厂商,寓教于乐,在放松人们心情的同时还可以活跃双手。在人类…

支小蜜校园防欺凌系统怎么识别到学生打架?

校园欺凌行为已经成为一个全球性的社会问题,它不仅影响了学生的身心健康,也破坏了校园的和谐氛围。为了有效预防和应对这一现象,许多学校开始引入校园防欺凌系统。那么,校园防欺凌系统是如何识别到学生打架的呢?本文将…

腾讯云轻量2核2G3M服务器优惠价61元一年性能测评

阿里云轻量应用服务器2核2G3M带宽优惠价一年61元,100%CPU性能,3M带宽下载速度384KB/秒,40GB SSD系统盘,月流量200GB,折合每天6.6GB流量,超出月流量包的流量按照0.8元每GB的价格支付流量费,地域节…

网络——入门基础

目录 协议 网络协议 OSI七层模型 网络传输基本流程 网络传输流程图 局域网通信 数据包的封装和解包 广域网通信 网络地址管理 IP地址 MAC地址 协议 关于什么是局域网,什么是广域网,我这里就不过多赘述了,我们直接来谈一下什么…

数据结构:10、排序

本文将会介绍8种排序,并在文章末附上代码 一、排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,…