STM32H7使用FileX库BUG,SD卡挂载失败

news2024/12/27 11:54:59

问题描述:

使用STM32H7+ThreadX+FileX,之前使用swissbit牌的存储卡可正常使用,最近项目用了金士顿的存储卡,发现无法挂载文件系统。

原因分析:

调试过程发现,关闭D-Cache可以挂载使用exfat文件系统。
FileX对SD卡读写接口全部位于fx_stm32_sdio_driver.c中,查看该文件可以发现在读写函数中已经考虑到使用Cache与DMA的情况,如下代码所示。

SCB_InvalidateDCache_by_Addr((uint32_t*)scratch, DEFAULT_SECTOR_SIZE);
SCB_InvalidateDCache_by_Addr((uint32_t*)media_ptr->fx_media_driver_buffer, num_sectors * DEFAULT_SECTOR_SIZE);

SCB_InvalidateDCache_by_Addr()函数用于将该地址D-Cache无效化,无效化的意思是将Cache Line 标记为无效,等同于删除操作。这样下次读写该地址数据时,D-Cache中无此数据,CPU直接对SRAM读写数据,保证CPU读取到的数据是真实的。
源码分析:
以读取函数为例:

        case FX_DRIVER_READ:
        {
            media_ptr->fx_media_driver_status = FX_IO_ERROR;
            //TX_DISABLE /* disable interrupts */
           if ((ULONG)(media_ptr->fx_media_driver_buffer) & 0x03)
           {
              if (sd_read_data(media_ptr, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
                                media_ptr->fx_media_driver_sectors, 1) == FX_SUCCESS)
              {
                  media_ptr->fx_media_driver_status = FX_SUCCESS;
              }
           }
           ……

if ((ULONG)(media_ptr->fx_media_driver_buffer) & 0x03)判断读取地址是否4字节对齐,因为使用MDMA读写SD卡需要地址4字节对齐,并对sd_read_data()函数传入相应值。
sd_read_data()函数如下:

static UINT sd_read_data(FX_MEDIA *media_ptr, ULONG start_sector, UINT num_sectors, UINT use_scratch_buffer)
{
    INT i = 0;
    UINT status;
    if (use_scratch_buffer)
    {
        memset(scratch, '\0', DEFAULT_SECTOR_SIZE);
        for (i = 0; i < num_sectors; i++)
        {
            status = BSP_SD_ReadBlocks_DMA((uint32_t*)scratch, start_sector++, 1);

            if (status != BSP_ERROR_NONE)
            {
                status = FX_IO_ERROR;
                break;
            }

            if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) != TX_SUCCESS)
            {
                status = FX_BUFFER_ERROR;
                break;
            }
            else
            {
#if (ENABLE_CACHE_MAINTENANCE == 1)
                SCB_InvalidateDCache_by_Addr((uint32_t*)scratch, DEFAULT_SECTOR_SIZE);
#endif

                _fx_utility_memory_copy(scratch, media_ptr->fx_media_driver_buffer, DEFAULT_SECTOR_SIZE);
                media_ptr->fx_media_driver_buffer += DEFAULT_SECTOR_SIZE;
            }
        }

        if (i == num_sectors)
        {
            status = FX_SUCCESS;
        }
    }
    else
    {
        status = BSP_SD_ReadBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, start_sector, num_sectors);

        if (status == BSP_ERROR_NONE)
        {
            if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) == TX_SUCCESS)
            {
#if (ENABLE_CACHE_MAINTENANCE == 1)
                SCB_InvalidateDCache_by_Addr((uint32_t*)media_ptr->fx_media_driver_buffer, num_sectors * DEFAULT_SECTOR_SIZE);
#endif
                status = FX_SUCCESS;
            }
            else
            {
                status =  FX_BUFFER_ERROR;
            }
        }
    }

    return status;
}

根据传入参数判断,若传输地址不是4字节对齐,则使用内部定义的一块32字节对齐的地址作为中转站,先用MDMA读取到数据,再将数据拷贝到用户提供地址。else分支若地址已经是4字节对齐,则直接使用用户提供的地址进行MDMA传输。
然而else分支的代码存在一个bug,当用户传入的地址为4字节对齐时,进入else分支,在MDMA传输完成后,进行SCB_InvalidateDCache_by_Addr()操作。但是该函数要求传入的地址为32字节对齐,因为Cortex-M7内核的Cache line大小为8个字。所以当传入的地址为4字节对齐但非32字节对齐时,SCB_InvalidateDCache_by_Addr()调用传入的参数不符合要求,D-Cache缓存清除错误,使CPU读取到缓存中错误的值。
在这里插入图片描述

解决方案:

在判断地址是否4字节对齐的地方,改成判断地址是否32字节对齐(即0x03改成0x1f),共修改2行代码,在代码中搜索media_ptr->fx_media_driver_buffer即可找到。

if ((ULONG)(media_ptr->fx_media_driver_buffer) & 0x1f)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

edu邮箱官方购买渠道手把手选购指南记录

教育优惠&#xff0c;是一项针对于在校大学生和教职员工推出的特殊优惠活动。一些公司会将旗下产品或服务以一定的折扣&#xff0c;甚至免费提供给高校师生。想想自己上大学的时候啥都不知道,毕业后才发现浪费了这么多优秀的资源.如果你还是一名在校大学生&#xff0c;那么就不…

小程序总结

第一章 微信小程序概述 1.1 认识微信小程序 简介&#xff1a;微信&#xff08;WeChat)是腾讯公司于2011年1月21日推出的一款为智能终端提供即时通信服务的应用程序&#xff0c;于2017年1月上线。 优势&#xff1a;1. 无需安装 2. 触手可及 3. 用完即走 4. 无需卸载…

日志框架整合SpringBoot保姆级教程+日志文件拆分(附源码)

目录 介绍 日志概述 日志文件 调试日志 系统日志 日志框架 日志框架的作用 日志框架的价值 流行的日志框架 SLF4J日志门面 介绍 环境搭建简单测试 集成log4j logback Logback简介 Logback中的组件 Logback配置文件 日志输出格式 控制台输出日志 输出日志到…

WebServer项目介绍文章【四叶专属】

Linux项目实战C轻量级Web服务器源码分析TinyWebServer 书接上文&#xff0c;学习开源项目的笔记没想到居然有不少阅读量&#xff0c;后面结合另一个前端开源项目简单做了点修改&#xff0c;没想到居然有需要的同学&#xff0c;那么我就专门为四叶开一篇文章吧&#xff0c;【源码…

【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序(万字博文)

系列文章目录 【网络通信基础】网络中的常见基本概念 【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序&#xff08;万字博文&#xff09; 【网络原理】UDP协议的报文结构 及 校验和字段的错误检测机制&#xff08;CRC算法、MD5算法&#xff09; 文章目…

RANSAC 配准算法

RANSAC 配准算法 1. 简介2. RANSAC步骤3. RANSAC原理4. RANSAC的优缺点5. 代码实现6. 参考 1. 简介 先讲一下背景吧。 点云配准&#xff08;Point Cloud Registration&#xff09;指的是输入两幅点云 (source 和 target) &#xff0c;输出一个变换使得变换后的source和target…

【Unity】苹果(IOS)开发证书保姆级申请教程

前言 我们在使用xcode出包的时候&#xff0c;需要用到iOS证书(.p12)和描述文件(.mobileprovision) 开发证书及对应的描述文件用于开发阶段使用&#xff0c;可以直接将 App 安装到手机上&#xff0c;一个描述文件最多绑定100台测试设备 1.证书管理 进入网站Apple Developer &…

在ubuntu20.04下迁移anaconda的目录,试验不行后,换成软连接

一、原因 随着不断的搭建不同的算法环境&#xff0c;原本在固态硬盘上安装的anaconda上占用空间越来越多。导致可用的固态硬盘空间越来越少&#xff0c;又因安装的环境太多&#xff0c;重新搭建比较费时费力。有没有直接将当前已经搭建好环境的anaconda 迁移到另外的目录呢&…

程序员过了35岁没人要?“这行越老越香”

程序员35岁失业&#xff1f;参加完OceanBase开发者大会&#xff0c;我又悟了&#xff01; 周六参加了OceanBase2024 开发者大会的现场&#xff0c;来之前我其实挺忐忑的&#xff0c;我觉得一个数据库产品的发布会&#xff0c;能有什么新鲜的东西&#xff1f; 踏入酒店的那一刻&…

monorepo搭建记录

最终文件效果 1、准备环境 npm pnpm 2、创建文件夹npm init vite // 名字可以为main&#xff08;自定义&#xff09; 创建主应用main npm init vite // 名字可以为main monorepo下创建文件夹web 创建辅助应用 例&#xff1a;react-demo&#xff0c;具体步骤&#xff1a;1、 cd…

深入理解JavaScript:对象什么时候创建

&#x1f31f; 我们在chrome浏览器中debug程序。为了好debug我们会写一些在日常开发中基本不会采用的代码书写方式。 JavaScript中创建对象有3中方式&#xff1a; 1、对象字面量&#xff1b; 2、new&#xff1b; 3、Object.create(对象)&#xff1b; 1、使用new创建对象 fun…

10分钟揭秘摘要抽取:探索信息提炼的奥秘

Introduction 本文分别介绍摘要数据集&#xff0c;摘要分类&#xff0c;摘要架构&#xff0c;相关baseline。并介绍若干篇EMNLP2023论文&#xff0c;介绍其最新工作。 1.数据集 1.1 文本摘要 DUC/TAC 英文|数据集较小|适用于传统摘要方法的评估 Gigaword 英文|启发式规则构…

【数据结构与算法】8.二叉树的基本概念|前序遍历|中序遍历|后序遍历

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 |《MySQL探索之旅》 |《Web世界探险家》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更…

【Linux】iptables的应用

iptables 防火墙 防火墙是一种网络安全系统&#xff0c;它位于内部网络与外部网络&#xff08;如互联网&#xff09;之间&#xff0c;通过实施预定义的安全策略来控制网络间的通信。防火墙的主要目标是保护内部网络资源免受未经授权的访问、攻击或潜在威胁&#xff0c;同时允…

经风靡全球的 PHP 为何逐渐失去优势?

TIOBE 编程语言人气指数发布更新&#xff0c;并提出“PHP 的魔力是否正在消散&#xff1f;”的灵魂拷问。今年 4 月&#xff0c;PHP 在 TIOBE 编程语言指数榜上仅位列第 17&#xff0c;“成为其有史以来的最低排位”。 暴露 PHP 人气急剧下滑的还不只是 TIOBE 榜单。在年度 Sta…

到底什么是爬虫

1. 引言 在数据驱动的世界里&#xff0c;网络爬虫&#xff08;Web Crawling&#xff09;技术扮演着获取和处理网上数据的关键角色。无论是为了数据分析、机器学习项目的数据集构建还是简单地监测网页变化&#xff0c;学习如何创建一个基本的网页爬虫可以大大提升你的工作效率和…

JAVASE基础语法(异常、常用类)

一、异常 1.1 什么是异常 异常就是指不正常。是指代码在运行过程中可能发生错误&#xff0c;导致程序无法正常运行。 package com.atguigu.exception;public class TestException {public static void main(String[] args) {int[] arr {1,2,3,4,5};System.out.println(&quo…

【c++】探究C++中的list:精彩的接口与仿真实现解密

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章来到list有关部分&#xff0c;这一部分函数与前面的类似&#xff0c;我们简单讲解&#xff0c;重难点在模拟实现时的迭代器有关实现 目录 1.List介绍2.接…

CSS3新增特性(二)

四、2D 转换 • 属性名&#xff1a;transform &#xff08;可用于制作2D转换&#xff0c;也可用于制作3D转转换&#xff1b;2D转换是平面上的转换&#xff0c;3D转换是在三维立体空间的转换&#xff09; • 作用&#xff1a;对元素进行水平或垂直方向的移动、缩放、旋转、拉长…

你们项目日志是如何处理的???

ELK日志采集系统 1.什么是ELK ELK 是一套流行的数据搜索、分析和可视化解决方案&#xff0c;由三个开源项目组成&#xff0c;每个项目的首字母合起来形成了“ELK”这一术语&#xff1a; Elasticsearch (ES): Elasticsearch 是一个基于 Apache Lucene 构建的分布式、实时搜索与…