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

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

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

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

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

Zynq PS无法读取SD卡(TF卡)异常分析及如何读写SD卡_第1张图片 PL设计时勾选了SD卡插拔检测引脚

 原理图:

Zynq PS无法读取SD卡(TF卡)异常分析及如何读写SD卡_第2张图片 原理图设计该引脚用作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”。

Zynq PS无法读取SD卡(TF卡)异常分析及如何读写SD卡_第3张图片

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

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

Zynq PS无法读取SD卡(TF卡)异常分析及如何读写SD卡_第4张图片

 代码如下:

#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博客

你可能感兴趣的:(FPGA,debug,嵌入式硬件,zynq,SD卡,FPGA,TF卡,FPGA,SD卡)