簡體   English   中英

MicroZed無法使用xilffs庫寫入SD卡

[英]MicroZed failing to write to SD card with xilffs library

我正在將MicroZed開發板與Xilinx Zynq 7010配合使用,並且嘗試使用xilffs (LibXil胖文件系統)庫在沒有任何操作系統的情況下寫入SD卡。

為了對其進行測試,我使用了Xilinx提供的xilffs_polled_example.c測試文件,但此刻測試失敗:

// Write data to file.
Res = f_write(&fil, (const void*)SourceAddress, FileSize, &NumBytesWritten);
if (Res) {
    xil_printf("6: Failed to write data to file\n");
    return XST_FAILURE;
}

但是,如果我將該測試注釋為數據驗證測試,則其他所有操作均成功:

2: Successful mount
3: Successfully created FAT volume
4: Successfully opened file with permissions
5: Successfully put pointer at beginning of file
skip write test
7:Successfully put pointer back to beginning of file
8: Successfully read data from file
skip data verification
10: Successfully closed file

我以為SD卡的模式/格式錯誤可能是一個問題。 我已使用Windows 10將SD卡格式化為FAT32,如果SD卡處於只讀模式,我認為該測試也會失敗:

SD_File = (char *)FileName;
Res = f_open(&fil, (char *)FileName, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
if (Res) {
    xil_printf("4: Failed to open file with permissions\n");
    return XST_FAILURE;
}

下面是我的代碼,除了要調試的打印語句外,它與鏈接文件基本相同。 有人對這個問題可能有什么理論嗎?

int FfsSdPolledExample(void)
{
    FRESULT Res;
    UINT NumBytesRead;
    UINT NumBytesWritten;
    u32 BuffCnt;
    u32 FileSize = (8*1024*1024);
    //TCHAR *Path = "0:/";
    const char *Path = "0:/";

    Platform = XGetPlatform_Info();
    if (Platform == XPLAT_ZYNQ_ULTRA_MP) {
         // Since 8MB in Emulation Platform taking long time, reduced
         // file size to 8KB.
        FileSize = 8*1024;
    }

    for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
        SourceAddress[BuffCnt] = TEST + BuffCnt;
    }

    // Register volume work area, initialize device
    Res = f_mount(&fatfs, Path, 0);
    if (Res != FR_OK) {
        xil_printf("2: Failed to mount\n");
        return XST_FAILURE;
    }
    xil_printf("2: Successful mount\n");

    // Path - Path to logical driver, 0 - FDISK format.
    // 0 - Cluster size is automatically determined based on Vol size.
    Res = f_mkfs(Path, 0, 0);
    if (Res != FR_OK) {
        xil_printf("3: Failed to create FAT volume\n");
        return XST_FAILURE;
    }
    xil_printf("3: Successfully created FAT volume\n");

    // Open file with required permissions.
    // Here - Creating new file with read/write permissions. .
    // To open file with write permissions, file system should not
    // be in Read Only mode.
    SD_File = (char *)FileName;

    Res = f_open(&fil, (char *)FileName, FA_CREATE_ALWAYS | FA_WRITE | FA_READ);
    if (Res) {
        xil_printf("4: Failed to open file with permissions\n");
        return XST_FAILURE;
    }
    xil_printf("4: Successfully opened file with permissions\n");

    // Pointer to beginning of file
    Res = f_lseek(&fil, 0);
    if (Res) {
        xil_printf("5: Failed to put pointer at beginning of file\n");
        return XST_FAILURE;
    }
    xil_printf("5: Successfully put pointer at beginning of file\n");

    // Write data to file.
    /*
    Res = f_write(&fil, (const void*)SourceAddress, FileSize,
            &NumBytesWritten);
    if (Res) {
        xil_printf("6: Failed to write data to file\n");
        return XST_FAILURE;
    }
    xil_printf("6: Successfully written data to file\n");
    */

    //Pointer to beginning of file .
    Res = f_lseek(&fil, 0);
    if (Res) {
        xil_printf("7: Failed to put pointer back to beginning of file\n");
        return XST_FAILURE;
    }
    xil_printf("7: Successfully put pointer back to beginning of file\n");

    //Read data from file.
    Res = f_read(&fil, (void*)DestinationAddress, FileSize,
            &NumBytesRead);
    if (Res) {
        xil_printf("8: Failed to read data from file\n");
        return XST_FAILURE;
    }
    xil_printf("8: Successfully read data from file\n");

    // Data verification
    /*
    for(BuffCnt = 0; BuffCnt < FileSize; BuffCnt++){
        if(SourceAddress[BuffCnt] != DestinationAddress[BuffCnt]){
            xil_printf("9: Data verification failed\n");
            return XST_FAILURE;
        }
    }
    xil_printf("9: Data verification passed\n");
    */

    //Close file.
    Res = f_close(&fil);
    if (Res) {
        xil_printf("10: Failed to close file\n");
        return XST_FAILURE;
    }
    xil_printf("10: Successfully closed file\n");

    return XST_SUCCESS;
}

我在設計中偶然發現了同樣的問題。 xilffs中的寫入功能似乎已損壞。

長話短說,問題出在diskio.c中,在連續寫入過程中行為不當。 卡或DMA可能仍然很忙,並且硬件包裝器功能從不檢查它們是否空閑。

到目前為止,還沒有一個好的,穩定的解決方案,但是在disk_write()中的XSdPs_WritePolled()之前添加usleep(200)會有所幫助。

這是一個BSP源,要對其進行編輯,您需要使用xilffs的副本創建一個本地存儲庫,並將其添加到本地存儲庫列表(xilinx工具->存儲庫),然后在本地存儲庫中編輯diskio.c並重新生成bsp。 。

問題的根源似乎是PS SD控制器,它無法在執行數據傳輸時正確報告其狀態,並且如果過早要求狀態,則會進入無法預測的行為。 只需等待200us即可解決問題,也許等待中斷也可以解決此問題,但這未經測試。

這是sdps_v3_2中xsdps.c的補丁程序,應該稱其為小於xilffs中diskio.c的延遲。 同樣,您需要將xsdps lib派生到本地存儲庫中,以使其在BSP再生后仍能生存。 請記住,這不是解決方案,而只是一個非最佳的解決方法。

*** D:/A15D/Vivado/A1550_Zynq/A1550_Zynq.sdk/local_repo/drivers/sdps_v3_2/src/a Wed Jun 14 05:24:28 2017
--- D:/A15D/Vivado/A1550_Zynq/A1550_Zynq.sdk/local_repo/drivers/sdps_v3_2/src/b Fri Aug 18 10:15:01 2017
***************
*** 87,92 ****
--- 87,94 ----
  #include "sleep.h"

  /************************** Constant Definitions *****************************/
+ #define CMD_TIMEOUT             200
+ 
  #define XSDPS_CMD8_VOL_PATTERN    0x1AAU
  #define XSDPS_RESPOCR_READY   0x80000000U
  #define XSDPS_ACMD41_HCS  0x40000000U
***************
*** 1066,1071 ****
--- 1068,1074 ----
        }
    }

+   usleep(CMD_TIMEOUT);
    XSdPs_WriteReg16(InstancePtr->Config.BaseAddress, XSDPS_CMD_OFFSET,
            (u16)CommandReg);

我沒有在zynq勘誤表中找到該特定錯誤,但是還有許多其他SD控制器錯誤,所有這些錯誤都被標記為“不會被修復,因為它是第三方核心”。 如果您問我,這是一個很奇怪的說法,但是讓我們留待它。

我將進一步探討案例,如果有什么值得注意的事情,請在這里報告。

解決了該問題。

MicroZed隨附的16GB Micro SD卡顯然不適用於此代碼。 我將該SD卡換成了舊手機隨附的便宜1GB記憶卡,並用相同的方式對其進行了格式化,現在代碼可以正常工作了。

我將向任何人開放該問題,並提供有關問題所在的解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM