2016-03-26 3 views
1

Я нахожусь на ZedBoard, и я пытаюсь писать на SD-карте. Я работаю над встроенной системой, и у меня нет операционной системы, я бегу безболезненно.FatFS f_write не работает

Я могу нормально читать с SD-карты, это не проблема.

Но когда я triy читать, у меня есть странное поведение:

  • f_write возвращает FR_OK
  • м.т. (байт написано) переменная правильно
  • создается файл (я могу видеть его когда я читаю SD-карту с моего ПК)

Но когда я прочитал файл, он пуст.

Вот мой код:

void WriteFile(char const* fileName, char* buffer, size_t size) 
{ 
    FIL file; 
    FATFS fs; 
    UINT bw; 
    FRESULT fr; 

    f_mount(&fs, "", 0); 
    f_open(&file, fileName, FA_WRITE | FA_CREATE_ALWAYS); 
    fr = f_write(&file, buffer, size, &bw); 
    if (size != bw || fr != FR_OK) 
     PRINT(("Error in writing !\n")); 
    f_close(&file); 
    f_mount(NULL, "", 0); 
} 

И я вызываю метод так:

WriteFile("Hello.txt", "Hello World !", 13); 

Любая идея, что я делаю не так?

+0

FatFs делает не предоставлять низкоуровневые устройства ввода/вывода - вы должны предоставить это самим сторонним разработчикам (например, платному или чип-вендору), поэтому, возможно, это проблема, хотя трудно понять, как создать файл , Также FatFs можно настроить как файловую систему «только для чтения», но опять-таки файл был создан таким образом, что, похоже, это не так. В любом случае представляется вероятным, что проблема не на уровне кода, который вы представили, а скорее на уровне уровня конфигурации библиотеки, так как он стоит, вы вряд ли получите ответ «вот ваша проблема». – Clifford

+0

У меня такая же проблема, как у Aymen, но когда я пытаюсь использовать f_write в текстовом файле, созданном на моем компьютере, я могу перезаписать содержимое этого файла. Но я не могу заставить его работать с пустым файлом, созданным с помощью f_open. – Frostbite

+0

@Frostbite: Когда вы говорите, переписываете, вы имеете в виду добавить в него свои собственные данные, а не просто пустой файл? Интересно, я не пробовал это ... Но, прочитав ваше сообщение, я вспомнил, что должен обновить вопрос до ответа, потому что нашел для меня рабочее решение. – Aymen

ответ

1

Я нашел небольшой взлом, который ответил на мою проблему:
В принципе, он не записывается на SD-карту, потому что буфер еще не заполнен (в API уровня низкого уровня XILINX).
Так что я сделал довольно просто: я пишу данные один раз. И хотя размер файла не равен или больше размера записанных данных, я пишу 0 (по блокам 32)
Кроме того, еще одна важная вещь: данные, которые вы пишете, ДОЛЖНЫ быть выровнены по 32 байтам! \ Вот мой (рабочий) код:

size_t SizeOfFile(char const *path) 
{ 
    FILE *fp = fopen(path, "r"); 
    fseek(fp, 0, SEEK_END); 
    size_t fsize = (size_t) ftell(fp); 
    fclose(fp); 
    return fsize; 
} 

void WriteFile(char const* fileName, char* buffer, size_t size) 
{ 
    size_t allignement = (size + 32 - 1) & ~ (32 - 1); // We must allign by 32 
    char* Buffer_logger = pleb_malloc(allignement); 
    pleb_memset(Buffer_logger, 0, allignement); 
    pleb_memcpy(Buffer_logger, buffer, size); 

    unsigned int BytesWr; 
    size_t accum = 0; 
    result = f_open(&file, fileName, FA_CREATE_ALWAYS | FA_WRITE | FA_READ); 
    if (result != 0) 
    { 
     return; 
    } 

    sprintf(Buffer_logger, "%s", buffer); 

    while (SizeOfFile(fileName) == 0) 
    { 
     // Open log for writing 
     result = f_open(&file, fileName, FA_WRITE); 
     if (result != 0) 
     { 
      return; 
     } 

     // Point to the EOF 
     result = f_lseek(&file, accum); 
     if (result != 0) 
     { 
      return; 
     } 

     // Write to log 
     result = f_write(&file, (const void*) Buffer_logger, size, &BytesWr); 
     if (result != 0) 
     { 
      return; 
     } 

     accum += accum + strlen(Buffer_logger); 

     //Close file. 
     result = f_close(&file); 
     if (result != 0) 
     { 
      return; 
     } 

     pleb_memset(Buffer_logger, 0, allignement); 

     size = 32; 
     pleb_memset(Buffer_logger, 0, size); 
    } 
    pleb_free(Buffer_logger); 
    PRINT(("Data written to log Successfully\r\n")); 
} 
+0

Проблема была в добавлении к файлу с данными, которые были написаны не 32-битовыми. Всякий раз, когда запись пересекает границу размера блока, она либо добавляет 2 байта, либо удаляет 2 байта из моих данных. Исправлена ​​проблема с 32-разрядными данными. Этот ответ помог мне найти проблему! Благодаря! –

0

Вы можете просто очистить буфер (f_sync):

 FRESULT result; 
     FATFS fs; 
     FIL file; 

     const char string[] = "Hallo world\0"; 
     uint16_t written = 0; 
     FILINFO fno; 

     /* Open or create a log file and ready to append */ 
     printf("mount:%d",f_mount(&fs, "", 1)); 
     printf("open: %d", f_open(&file, "log.txt", FA_WRITE | FA_OPEN_ALWAYS)); 
     printf("stat: %d", f_stat("log3.txt", &fno)); 
     printf("write: %d wr: %d", f_write(&file, string, 11, &written), written); 
     printf("flush: %d", f_sync(&file)); 
     printf("close: %d", f_close(&file)); /* close performs sync before close */ 
0

у меня была та же проблема FatFs создал файл, но Wouldnt писать какие-либо данные. Никаких ошибок, вызванных функциями fatfs, поэтому я застрял в течение 2 дней, тогда я обнаружил, что если я поставил точку останова после отправки 512-байтового блока на уровне ввода-вывода, в моем коде его функция send_datablock (buff, 0xFE)) это сработает.

Я обнаружил, что после записи блока данных СД нужно времени, чтобы фактически записать этот блок во внутренний флэш см

http://elm-chan.org/docs/mmc/mmc_e.html

в разделе Single Block Написать напряженный период DO линия, вы должны ждать этот период заканчивается, прежде чем отправлять какие-либо другие команды (т. е. писать один блок CMD24), иначе SD отбрасывает последний CMD24, поэтому вы теряете данные, которые вы только что отправили.

я поставил петлю ожидания в конце функции send_datablock как этот

/* if not accepted, return with error */ 
    if((data & 0x1F) != 0x05) 
    { 
     return 0; 
    } 
    else 
    { 
     /* wait for SD to finish writing data */ 
     tmr = 5000; 
     do 
     { 
      data = get_response(SDEXIChannel); 
      if(data != 0x00) 
      { 
       break; 
      } 
      udelay(100); 
      tmr--; 
     } while(0 != tmr); 

     /* did we time out ? if so return with error */ 
     if(tmr == 0) 
     { 
      return 0; 
     } 

, который, как представляется, исправили мою проблему, и теперь я могу записывать файлы на SD-карте, во всяком случае надеюсь, что спасает кого-то два дней отладки!

0

У меня была такая же проблема с попыткой записи на SD с использованием Xilinx SoC, как ZedBoard. Я не смог написать свои данные на SD-карте, даже если:

  • Все функции успешны.

  • Мне удалось удалить и создать файл (так что я не был доступен только для чтения).

  • Когда я прочитал, что я написал на карточке (с f_lseek, чтобы вернуться к 0 и f_read), я прочитал правильные данные.

Каждый раз, когда я читал файл после перезагрузки, он был пуст.

Я пробовал предыдущие решения, но никто из них не работал. Ответ steve поставил меня на правильный путь.

ИСПРАВЛЕНИЕ: Мне нужно было написать объемом 256 байт, чтобы мои данные были фактически записаны на SD. 256 байт - это размер страницы на моей SD-карте, поэтому это имеет большой смысл.

Если запись не кратная 256, она не будет записывать все данные. Ex:

Bytes писал с помощью f_write -> Bytes на самом деле записывается в файл

512 -> 512

480 -> 256

255 -> 0

256 -> 256

Надеюсь, это поможет кому-то :)

+0

Это не отвечает на вопрос. Если у вас есть другой вопрос, вы можете задать его, нажав [Ask Question] (http://stackoverflow.com/questions/ask). Вы также можете [добавить щедрость] (http://stackoverflow.com/help/privileges/set-bounties), чтобы привлечь больше внимания к этому вопросу, как только у вас будет достаточно [репутации] (http://stackoverflow.com/help/ Что-репутация).- [Из обзора] (/ review/low-quality-posts/15910234) – madlymad

+0

@madlymad Я думаю, что OP сделал опечатку при написании вопроса: ... Но когда я triy, чтобы ** читать **, у меня есть ... по коду он хочет писать в файл и не может этого сделать. Поэтому я думаю, что мой ответ хорошо реагирует на: _Любая идея, что я делаю неправильно? _ Почему, почему «Hello World!» размером 13 байт не будет записано в файл. Является ли мой отредактированный ответ более ясным? – JSPrevost

Смежные вопросы