MicroZed не может записать на SD-карту библиотеку xilfs

Я использую плату разработки MicroZed с Xilinx Zynq 7010 и пытаюсь записать на SD-карту без какой-либо ОС, просто используя xilffs (файловая система LibXil).

Чтобы проверить это, я использую этот xilffs_polled_example.c тестовый файл, предоставленный Xilinx, но на этом этапе тест не проходит:

// 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-карта находится в неправильном режиме/формате. Я отформатировал SD-карту как FAT32 с помощью Windows 10, и если бы 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;
}

person Charles Clayton    schedule 13.03.2017    source источник
comment
MicroZed — это операционная система или что-то подобное? Итак, это не Linux/*nix (совместимая с POSIX ОС), верно?   -  person 0andriy    schedule 13.03.2017
comment
MicroZed — это плата разработки для SoC, поэтому она имеет FPGA и процессор ARM A9. Я надеюсь сделать это только с голым железом и без ОС.   -  person Charles Clayton    schedule 13.03.2017
comment
О да, я понял. Я бы предложил обновить пост, чтобы поделиться этой информацией.   -  person 0andriy    schedule 13.03.2017


Ответы (3)


Я наткнулся на ту же проблему в моем дизайне. Функция записи в xilfs не работает.

Короче говоря, проблема в diskio.c, он ведет себя неправильно во время последовательной записи. Либо карта, либо DMA могут по-прежнему быть заняты, а аппаратные функции-оболочки никогда не проверяют, свободны ли они.

Пока нет хорошего и стабильного решения, но добавление usleep(200) перед XSdPs_WritePolled() в disk_write() помогает.

Это источник BSP, чтобы отредактировать его, вам нужно создать локальный репозиторий с вашей копией xilffs и добавить его в список локальных репозиториев (инструменты xilinx -> репозитории), затем отредактировать diskio.c в локальном репо и заново сгенерировать bsp(s) .

person hitomi2500    schedule 12.07.2017
comment
Хорошо, что есть решение. - person Charles Clayton; 12.07.2017

Похоже, что корень проблемы заключается в контроллере PS SD, который не может правильно сообщить о своем статусе при выполнении передачи данных и переходит в непредсказуемое поведение, если запрашивается статус слишком рано. Простое ожидание 200 мкс решает проблему, возможно, ожидание прерывания также может решить эту проблему, но это не проверено.

Вот патч для xsdps.c в sdps_v3_2, этот надо называть меньше, чем delay в diskio.c в xilffs. Опять же, вам нужно разветвить библиотеку xsdps в локальное репо, чтобы она пережила регенерацию 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 errata, но есть много других ошибок контроллера SD, и все они помечены как «не будут исправлены, потому что это ядро ​​​​стороннего производителя». Довольно странное заявление, если вы спросите меня, но давайте остановимся на этом.

Возможно, я углублюсь в дело и сообщу здесь, если возникнет что-то примечательное.

person hitomi2500    schedule 18.08.2017

Исправлена ​​проблема.

Карта Micro SD емкостью 16 ГБ, поставляемая с MicroZed, по-видимому, не работает с этим кодом. Я заменил эту SD-карту на дешевую на 1 ГБ, которая шла со старым телефоном, отформатировал ее таким же образом, и теперь код работает.

Я оставлю вопрос открытым для тех, кто объяснит, в чем проблема.

person Charles Clayton    schedule 13.03.2017
comment
Привет, Чарльз, так ты понял, почему SD-карта на 1 ГБ работает, а не на 16 ГБ? У меня такая же проблема с Zedboard, и я использую SD-карту на 32 ГБ. Я могу смонтировать, открыть файл, прочитать и закрыть, но он просто отказывается записывать на SD-карту. Все, что я вижу, это пустой файл, который он открыл для записи и закрыл, но в нем нет данных. - person bFig8; 19.06.2017
comment
То, что вы описываете, было моей конкретной проблемой. Боюсь, у меня никогда не получалось работать с другой SD-картой. В то время 1 ГБ подходил для моих целей, и я пошел дальше. Я сделал сообщение об этом на форум xilinx в то время, когда вы, возможно, сможете найти объяснение. - person Charles Clayton; 19.06.2017