Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Fatfs и битые сектора
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Nikitoc
Доброго времени суток. Собственно вопрос в теме. Никак не могу понять каким образом данная ФС помечает сбойные сектора? О том, что они маскируются вначале контроллером SD-карты рассказывали aaarrr и zltigo. Но когда запас на замену истощается эти сектора вылазят наружу и становятся головной болью ФС. В исходниках FatFs встречается, например такая запись (внутри функции f_write):
Код
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
    ABORT(fp->fs, FR_DISK_ERR);

где:
Код
#define LEAVE_FF(fs, res)    return res
#define    ABORT(fs, res)        { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }

Я так понимаю, что в случае неудачной записи, в структуре данного объекта FIL выставляется флаг FA_ERROR. И функция f_write возвращает FR_DISK_ERR. А дальше тупик. Объясните, пожалуйста, как будет вести себя FatFs при попытке повторной записи по данному адресу? Отмечается ли данный сектор как сбойный в FAT?
goodwin
Ну во-первых такую флэшку надо выбрасывать немедленно - самый лучший вариант wink.gif
А во вторых, на уровне файловой системы есть понятие сбойные кластеры.
Т.е. весь кластер помечается в таблице FAT, как сбойный.
Правда не в курсе, присутствует ли это дело в полном объеме в FatFS...
Nikitoc
Цитата(goodwin @ Nov 4 2010, 00:17) *
Правда не в курсе, присутствует ли это дело в полном объеме в FatFS...

Вот-вот, и я о том-же. Придется, наверное, программно симулировать такую ошибку и смотреть на поведение программы. Но все же очень хочется перед этим выслушать мнение человека, который с этим сталкивался. С наскока разобраться в исходниках FatFs сложновато, хотя и написано вроде доступно :-)
Nixon
Непонятно с чего вы решили, что проблемой сбойных секторов должна заниматься файловая система. Максимум что она должна делать, так это информировать пользователя об ошибках чтения/записи. И все. Для всего остального пишите аналог утилиты chkdsk или чего-то подобного.
Nikitoc
Цитата(Nixon @ Nov 4 2010, 13:41) *
Непонятно с чего вы решили, что проблемой сбойных секторов должна заниматься файловая система.

Ну, собственно на эту мысль меня навела спецификация FAT32. По крайней мере эта вот цитата:
Цитата
There is also a special “BAD CLUSTER” mark. Any cluster that contains the “BAD CLUSTER” value in its FAT entry is a cluster that should not be placed on the free list because it is prone to disk errors. The “BAD CLUSTER” value is 0x0FF7 for FAT12, 0xFFF7 for FAT16, and 0x0FFFFFF7 for FAT32.

Я так подозреваю, должны быть функции файловой системы, которые эти значения записывают в таблицу. Или же это задача программиста?
Nikitoc
Мда. Немного покопавшись в исходниках я обнаружил две функции работающие с содержимым FAT:
Код
DWORD get_fat (    /* 0xFFFFFFFF:Disk error, 1:Interal error, Else:Cluster status */
    FATFS *fs,    /* File system object */
    DWORD clst    /* Cluster# to get the link information */
)

и
Код
FRESULT put_fat (
    FATFS *fs,    /* File system object */
    DWORD clst,    /* Cluster# to be changed in range of 2 to fs->max_clust - 1 */
    DWORD val    /* New value to mark the cluster */
)

согласно которым, кластеру (в таблице) может быть присвоено 4 значения:
0 - свободен для записи;
1 - неправильно указан адрес кластера (внутренняя ошибка);
собственно адрес следующего кластера;
и 0xFFFFFFFF - ошибка во время доступа к данным на носителе;
Это последнее значение меня немного удивляет (и окончательно запутывает), т.к. согласно спецификации FAT оно означает последний файл кластера. Как обозначается последний кластер файла в FatFs я пока не понял. Любые подсказки приветствуются.


Ага, разобрался: последний кластер помечается как 0x0FFFFFFF. Просто очень похоже на 0xFFFFFFFF, поэтому сразу не заметил.
Что же. Придется дописать маркировку "битого сектора" самому :-) Хотя жаль, конечно, что это не реализовано в FatFs.
sigmaN
Да это нигде не реализовано.
Вам же сказали, что существуют отдельные утилиты проверки фс, которые в том числе помечают кластер как сбойный.
Ну а при чтении/записи фс уже понимает, что этот кластер ни купить ни продать и он там так и болтается там в таблице и никто его не трогает больше.

Или вы хотели,чтоб фс на ходу при ошибках отмечала сбойные кластеры?
_Pasha
Цитата(sigmaN @ Nov 8 2010, 03:50) *
Или вы хотели,чтоб фс на ходу при ошибках отмечала сбойные кластеры?

Если на это есть время, то запись -верификация - отбраковка кластера легко может быть дописана. Другое дело, что обычно пишут/читают приличные потоки с помощью очень маленького буфера, тут не до грибочков smile.gif
Nikitoc
Цитата(sigmaN @ Nov 8 2010, 03:50) *
Или вы хотели,чтоб фс на ходу при ошибках отмечала сбойные кластеры?

В точку. Хотя, помучившись недельку, я вообщем-то уже подумываю о том, чтобы сделать отдельную функцию типа CHDISK (как мне и советовали).
jorikdima
У вас 100 лет прибор работать будет? Или бьете все время в один сектор/файл? Если второе, то проще иметь логику выбора сектора куда писать и периодически менять его. Если второе, то вас скорее всего не будет через 100 лет smile.gif
Nikitoc
Танцы с бубном продолжаются. Недавно я столкнулся со таким приколом на FatFS: если на карточку записать несколько файлов посредством функций этой файловой системы, а потом удалить в Windows какой-нибудь (или все) файлик с этой карты, то FatFs освободившееся пространство не увидит. f_getfree возвращает такое же количество свободных кластеров как и до удаления файла. Интересно, откуда ноги растут? У кого-то такое уже было? При этом винда, естественно, все освободившееся пространство видит.
P.S. Карточка перед записью форматировалась как жесткий диск, средствами FatFs.
_4afc_
Цитата(Nikitoc @ Dec 16 2010, 01:47) *
Танцы с бубном продолжаются. Недавно я столкнулся со таким приколом на FatFS: если на карточку записать несколько файлов посредством функций этой файловой системы, а потом удалить в Windows какой-нибудь (или все) файлик с этой карты, то FatFs освободившееся пространство не увидит. f_getfree возвращает такое же количество свободных кластеров как и до удаления файла. Интересно, откуда ноги растут? У кого-то такое уже было? При этом винда, естественно, все освободившееся пространство видит.
P.S. Карточка перед записью форматировалась как жесткий диск, средствами FatFs.


Поподробнее порядок действий опишите. Как вы одновременно работаете в Windows и микроконтроллером? Windows какой?

Что делает функция f_getfree? Считывает всю FAT таблицу и пробегая по ней суммирует все свободные кластеры? Обе таблицы?
Nikitoc
Цитата(_4afc_ @ Dec 16 2010, 14:24) *
Поподробнее порядок действий опишите. Как вы одновременно работаете в Windows и микроконтроллером? Windows какой?

Есть мой девайс с подключенным разъемом SD. Вставляю карту в него и выполняю все вышеописанные операции форматирования и записи. Вставляю затем эсдшку в картридер и удаляю некоторые файлы. Windows XP (если форматировать с ее помощью - то карта форматируется как дискета, без MBR). На карте FAT32.
Цитата
Что делает функция f_getfree? Считывает всю FAT таблицу и пробегая по ней суммирует все свободные кластеры? Обе таблицы?

Вызывает chk_mount, а та в свою очередь вычитывает fsi сектор (его адрес находит в PBR, кажется) и по внутреннему полю этого сектора определяет количество свободных кластеров:
Код
   /* Get fsinfo if available */
   if (fmt == FS_FAT32) {
       fs->fsi_flag = 0;
      fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo);
      if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK &&
         LD_WORD(fs->win+BS_55AA) == 0xAA55 &&
         LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 &&
         LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) {
            fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free);
            fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count);
      }
   }

Я подозреваю, конечно, что Windows это делает по другому, но как не знаю. Если можно расскажите, как делать правильно.


DL36
Сравните значение поля FSI_Free_Count (488 4) сектора FSInfo до и после стирания, может оно?
Nikitoc
Цитата(DL36 @ Dec 18 2010, 23:55) *
Сравните значение поля FSI_Free_Count (488 4) сектора FSInfo до и после стирания, может оно?

Ну да, оно-то - оно. Значение это не меняется. Видимо придется просто подсчитывать кластеры в FAT со значением 0x00.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.