Zynq PS无法读取SD卡(TF卡)异常分析及如何读写SD卡

news2024/12/27 21:57:27

        最近我正在进行一个Zynq项目,我使用了Xilinx SDK自带的系统库函数来读取SD卡中的配置信息。然而,一直读取异常。

       我进行了一系列的调试和检查,包括确认PS部分的代码正确性以及Xilffs的配置是否正确,但是问题仍然没有解决。最后,只能亲自检查同事开发的PL部分代码,希望能找到问题的原因。

       首先,分享一下本项目中导致读取异常的原因。

        原因:勾选了“CD”项,这一项是否勾选要结合原理图设计,SD卡插槽上的CD引脚是否正确连接到Zynq芯片的MIO引脚。(如下图)本项目MIO47引脚用作USB功能,并未接到SD的CD引脚上。

PL设计时勾选了SD卡插拔检测引脚

 原理图:

原理图设计该引脚用作USB功能

        通过查阅资料,总结了几个需要注意的地方:

        1、CD (Card Detect)引脚是用于检测SD卡是否插入,设计时候需要注意:

       (1)引脚连接:确保CD MIO47引脚正确连接到SD卡插槽的检测引脚上。

       (2)引脚功能配置:在PL或者PS设计中,需要将CD MIO47引脚配置为GPIO输入模式,并设置为上拉电阻或者禁用上拉电阻,以此能够正确读取引脚状态。

       (3)软件配置:如果勾选了CD项,在PS驱动程序中,需要根据GPIO来判断SD卡是否插入。

        2、WP(Write Protect)引脚是否勾选也十分关键,WP功能是检测和设置SD卡是否处于写保护状态。当WP引脚连接到GPIO引脚,并设置为高电平时,SD卡会被设置为写保护状态,即无法对其进行写入操作。如果需要防止误写入,可以通过设置WP引脚,限制对SD卡的写入权限,防止意外的数据修改或删除。

        3、Power引脚是SD卡电源引脚,用于提供电源给SD卡。

PS端驱动程序:

        1、创建工程,勾选通用FAT文件系统库,即“xilffs”。

         2,将“use_lfn”项改为“true”,默认是“false”。use_lfn是是否支持长文件名(Long File Name,LFN)。长文件名是指文件名超过8个字符(不包括扩展名)的文件名。

         当use_lfn设置为true时,文件系统可以存储和读取超过8个字符的文件名,文件名也可以使用空格、特殊字符和中文等非传统字符。

 代码如下:

#define SD_DATA_LENGTH			(256)

FATFS SD_Dev; // File System instance
char *SD_Path = "0:/";  //  string pointer to the logical drive number
char FileName[32] = "config.txt"; // name of the log
char WR_Buf[SD_DATA_LENGTH] __attribute__ ((aligned(32))); // Buffer should be word aligned (multiple of 4)
char RD_Buf[SD_DATA_LENGTH] __attribute__ ((aligned(32))); // Buffer should be word aligned (multiple of 4)

#include "ff.h" // 引入FatFs库

int SD_init()
{
    FRESULT result;
    
    // 挂载SD卡设备
    result = f_mount(&SD_Dev, SD_Path, 0);
    if (result != 0) {
        return XST_FAILURE;
    }
    
    return XST_SUCCESS;
}

int SD_read(char *FileName, char *DestinationAddress, unsigned int ByteLength)
{
    FIL file;
    FRESULT result;
    UINT BytesRd;
    
    // 打开文件
    result = f_open(&file, FileName, FA_READ);
    if (result) {
        return XST_FAILURE;
    }
    
    // 读取文件内容
    result = f_lseek(&file, 0);
    if (result) {
        return XST_FAILURE;
    }
    
    result = f_read(&file, (void*)DestinationAddress, ByteLength, &BytesRd);
    if (result) {
        return XST_FAILURE;
    }
    
    // 关闭文件
    result = f_close(&file);
    if (result) {
        return XST_FAILURE;
    }
    
    return XST_SUCCESS;
}

int SD_write(char *FileName, char *SourceAddress, unsigned int ByteLength)
{
    FIL file;
    FRESULT result;
    UINT BytesWr;
    
    // 创建文件并打开
    result = f_open(&file, FileName, FA_CREATE_ALWAYS | FA_WRITE);
    if (result) {
        return XST_FAILURE;
    }
    
    // 写入文件内容
    result = f_lseek(&file, 0);
    if (result) {
        return XST_FAILURE;
    }
    
    result = f_write(&file, (void*)SourceAddress, ByteLength, &BytesWr);
    if (result) {
        return XST_FAILURE;
    }
    
    // 关闭文件
    result = f_close(&file);
    if (result) {
        return XST_FAILURE;
    }
    
    return XST_SUCCESS;
}

 int main()
{
    int ret;

	/*SD card init*/
	SD_init();

    ret = SD_write(FileName, WR_Buf, SD_DATA_LENGTH);
    if (ret == XST_SUCCESS)
    {
        xil_printf("SD CARD written Successfully\r\n");
    }

	/*read sd data*/
	ret = SD_read(FileName, RD_Buf, SD_DATA_LENGTH);
	if(ret == XST_SUCCESS)
	{
		xil_printf("Successfully read the configuration file from the SD card.\n");
	}
	else
	{
		xil_printf("Error read SD card configuration file.\n");
	}
}

PS:查阅资料,总结了xilffs配置中主要标志位使用和设置方法:

  1. enable_exfat:启用exFAT文件系统。exFAT是一种用于大容量存储设备的文件系统,支持文件大小超过4GB。如需要使用exFAT文件系统,将这个标志位设置为1。

  2. enable_multi_partition:启用多分区。如需要在设备上创建多个分区,可以将这个标志位设置为1。

  3. fs_interface:指定文件系统接口。可选的值有XILFFS_IF_PS7_SD_0、XILFFS_IF_PS7_SD_1、XILFFS_IF_PS7_SD_2,分别对应不同的SD卡接口。你需要根据你的系统硬件配置选择适当的接口。

  4. num_logical_vol:指定逻辑卷数量。对于支持多分区的设备,你可以设置这个值来指定分区数量。

  5. read_only:设置文件系统为只读模式。如果你需要保护文件系统免受写入操作的影响,可以将这个标志位设置为1。

  6. set_fs_rpath:设置文件系统的根路径。你可以指定一个字符串作为文件系统的根目录,例如"/mnt/"。

  7. use_lfn:启用长文件名支持。如果你需要支持长文件名(超过8个字符),可以将这个标志位设置为1。

  8. use_mkfs:启用格式化文件系统的功能。如果你希望在初始化文件系统时进行格式化操作,可以将这个标志位设置为1。

  9. use_strfunc:启用字符串处理函数。如果你需要在文件系统中使用字符串处理函数,可以将这个标志位设置为1。

  10. word_access:启用字节访问模式。默认情况下,文件系统使用字节级别的访问模式。如果你需要使用字级别的访问模式,可以将这个标志位设置为1。

  11. ramfs_size:指定RAM文件系统的大小。RAM文件系统是一个基于内存的虚拟文件系统,用于存储临时文件。你可以设置这个值来指定RAM文件系统的大小。

REF:

VIVADO 7.ZYNQ读取SD卡_馍加馒头的博客-CSDN博客

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

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

相关文章

NYDIG最新报告:比特币今年上半年回报率达83.6%,远超其他资产类别

本文要点: 比特币的强劲势头延续到了二季度,本季度比特币上涨 6.8%,年初至今上涨 83.6%。 二季度末,一系列新的现货比特币 ETF 申请(尤其是 ETF 巨头贝莱德的申请)提振了比特币价格。 在多家机构提交现货 B…

POI下载excel通用方法

POI下载excel通用方法 最近遇到一个业务是需要下载excel&#xff0c;使用POI,这里记录一下实现过程 1、导包 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency>…

本周大新闻|传微软曾考虑收购Niantic;腾讯引进Quest挑战重重

本周XR大新闻&#xff0c;AR方面&#xff0c;传微软曾考虑收购AR头部公司Niantic&#xff1b;Q-PIXEL公布5000PPI可调色Micro LED&#xff1b;三星智能眼镜商标曝光&#xff1b;Humane公布首款产品Ai Pin&#xff1b;空客推企业级AR解决方案。 VR方面&#xff0c;Vision Pro销…

边缘计算那些事儿-漫谈网络切片关键技术

0、背景 网络切片作为一种比较前沿的技术&#xff0c;当前并没有太多系统的资料可以学习&#xff0c;很多的技术资料都是比较分散地分布在论文和一些技术博客中&#xff0c;笔者当前是通过论文的解读获取相关的技术信息&#xff0c;在过程中笔者总结了相关的技术栈&#xff0c;…

pytorch多分类问题 CrossEntropyLoss()函数的输入size/shape不一致问题

在使用pytorch实现一个多分类任务的时候&#xff0c;许多多分类任务在训练过程中都会有如下的代码&#xff1a; criterion nn.CrossEntropyLoss() loss criterion(output, target) # output.size : [batch_size, class_num] # target.size : [batch_size]许多的初学者会卡在…

Kubernetes 容器类型 Init - pause - sidecar - app容器

目录 Kubernetes 的容器类型 Init 初始化容器 参考文档&#xff1a;Init 容器 | Kubernetes 使用 Init 容器的情况 案例&#xff1a;定义了一个具有 2 个 Init 容器的简单 Pod 你通过运行下面的命令启动 Pod&#xff1a; 发现两个Init容器都没有运行成功 查看更多详细…

一些行业报告--From 艾瑞咨询

一些行业报告--From 艾瑞咨询 1 介绍2 机械臂行业研究 [From 艾瑞咨询 -- 中国工业机器人行业研究报告&#xff08;2023&#xff09;2.1 发展历程2.2 中国工业机器人相关政策2.3 产业链2.4 三大部分六大系统2.5 伺服&控制器 主要玩家 及 关键指标及难点2.6 减速机 主要玩家…

mysql中根据已有的表来创建新表的三种方式

mysql根据现有表创建新表 1、语法1&#xff1a;CREATE TABLE new_tbl LIKE orig_tbl; 1、1 根据departments表创建新表departments1 departments 表结果和表数据库如下 创建departments1如下 使用命令&#xff1a; CREATE TABLE departments1 LIKE departments; 这种语法&…

GEE:在地图上添加时间滑动条,以交互式可视化不同年份影像

作者:CSDN @ _养乐多_ 本文将介绍在Google Earth Engine(GEE)平台上的地图显示区域创建一个交互式界面,可以为用户添加一个时间滑动条,通过滑动条可以选择显示不同年份的遥感影像。 结果如下图所示, 文章目录 一、代码二、代码链接一、代码 // 使用滑块从图像集合中选…

Auto-Rig Pro 手指控制器骨骼(IK-FK)

选中手指控制器骨骼,在tool面板里看到snap IK-FK, IK-FK,还有snap all to IK 和 FK: 这些都是Auto-Rig Pro提供的一些工具&#xff0c;可以让您在IK&#xff08;反向动力学&#xff09;和FK&#xff08;正向动力学&#xff09;之间切换和同步。IK和FK是两种不同的绑定方式&…

43. 间断连续登录用户问题

文章目录 题目需求思路一实现一题目来源 题目需求 现有各用户的登录记录表&#xff08;login_events&#xff09;如下&#xff0c;表中每行数据为&#xff1a;一个用户何时登录了平台。 现要求统计各用户最长的连续登录天数&#xff0c;间断一天也算作连续&#xff0c;例如&a…

git安装及初步使用

git的安装 &#xff1a; 在CentOS 7.6环境下可以使用一条语句就能安装git yum -y install git如果上面命令包以下错误&#xff0c;说明权限不够 [leijiefl ~]$ yum -y install git Loaded plugins: fastestmirror You need to be root to perform this command.可以转换成ro…

神经网络学习小记录74——Pytorch 设置随机种子Seed来保证训练结果唯一

神经网络学习小记录74——Pytorch 设置随机种子Seed来保证训练结果唯一 学习前言为什么每次训练结果不同什么是随机种子训练中设置随机种子 学习前言 好多同学每次训练结果不同&#xff0c;最大的指标可能会差到3-4%这样&#xff0c;这是因为随机种子没有设定导致的&#xff0…

电源频率检测器/采用555时基电路的过流检测器电路设计

电源频率检测器 对于某些电子仪器和电气设备&#xff0c;对见六电源的频率有着一定的要求&#xff0c;电源频率高于或低于 50Hz&#xff0c;都会影响设备的正常工作&#xff0c;甚至造成仪器和设备的损坏。因此&#xff0c;对于此类设备需要装设电源频率检测装置&#xff0c;当…

Linux开发工具之【vim】

Linux开发工具之【vim】 文章目录&#xff1a; Linux开发工具之【vim】1. Linux软件包管理器yum1.1 查看软件1.2. 下载软件1.3 卸载软件 2. vim编辑器的使用2.1 vim常用模式2.2 vim基本操作2.3 vim命令模式命令集2.3.1 移动光标2.3.2 删除文字2.3.3 复制文本内容2.3.4 替换文本…

Openpose原理总结

Openpose是一种开源的实时多人姿态估计库&#xff0c;由卡耐基梅隆大学开发。它通过分析图像或视频中的人体关键点来估计人体的姿态&#xff0c;识别身体的各个部分&#xff0c;并推断出人体的姿势信息。 Openpose能够同时检测和跟踪多个人的姿态&#xff0c;可以用于人机交互、…

二.《泽诺尼亚》明文CALL

了解发包函数 1.一款网络游戏,必定是会发包的,对于PC端而言,想要进行网络通讯,就拿最简单的CS架构而言势必会调用win32 API函数或底层函数 2.这里列举出常用的API如:send sendto wsasend wspsend 3.有一些正向开发经验的同学,肯定是见过这几个函数的 4.接下来我们来看看这款…

JavaEE——介绍并简单使用线程池

文章目录 一、 什么是线程池二、Java中线程池的运用1. 创建线程池中的问题2. 标准库中线程池的使用 三、自主实现一个简单的线程池 一、 什么是线程池 所谓线程池&#xff0c;其实和字符串常量池&#xff0c;数据库连接池十分相似&#xff0c;就是设定一块区域&#xff0c;提前…

打印机常见故障解决参考方法

1、首先检查打印机电源线连接是否可靠或电源指示灯是否点亮&#xff0c;然后再次打印文件&#xff0c;仍不能打印&#xff0c;请看下一步。 2、检查打印机与计算机之间的信号传输线是否可靠连接&#xff0c;检查并重新连接&#xff0c;如果打印机仍不能打印&#xff0c;请看下一…

Java线程Thread类常用方法

文章目录 1. start()&#xff1a;启动线程&#xff0c;使其执行run()方法中的代码。2. run()&#xff1a;线程的执行逻辑&#xff0c;需要在该方法中定义线程要执行的代码。3. sleep(long millis)&#xff1a;使当前线程暂停指定的毫秒数&#xff0c;进入阻塞状态。4. join()&a…