реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Fatfs и битые сектора, Как помечаются сбойные сектора в этой ФС?
Nikitoc
сообщение Nov 3 2010, 20:37
Сообщение #1


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Доброго времени суток. Собственно вопрос в теме. Никак не могу понять каким образом данная ФС помечает сбойные сектора? О том, что они маскируются вначале контроллером 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?
Go to the top of the page
 
+Quote Post
goodwin
сообщение Nov 3 2010, 21:17
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 481
Регистрация: 1-08-05
Пользователь №: 7 267



Ну во-первых такую флэшку надо выбрасывать немедленно - самый лучший вариант wink.gif
А во вторых, на уровне файловой системы есть понятие сбойные кластеры.
Т.е. весь кластер помечается в таблице FAT, как сбойный.
Правда не в курсе, присутствует ли это дело в полном объеме в FatFS...
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Nov 3 2010, 21:59
Сообщение #3


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Цитата(goodwin @ Nov 4 2010, 00:17) *
Правда не в курсе, присутствует ли это дело в полном объеме в FatFS...

Вот-вот, и я о том-же. Придется, наверное, программно симулировать такую ошибку и смотреть на поведение программы. Но все же очень хочется перед этим выслушать мнение человека, который с этим сталкивался. С наскока разобраться в исходниках FatFs сложновато, хотя и написано вроде доступно :-)
Go to the top of the page
 
+Quote Post
Nixon
сообщение Nov 4 2010, 09:41
Сообщение #4


Гуру
******

Группа: Админы
Сообщений: 2 736
Регистрация: 17-06-04
Из: Киев
Пользователь №: 48



Непонятно с чего вы решили, что проблемой сбойных секторов должна заниматься файловая система. Максимум что она должна делать, так это информировать пользователя об ошибках чтения/записи. И все. Для всего остального пишите аналог утилиты chkdsk или чего-то подобного.


--------------------
Вам помочь или не мешать?
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Nov 4 2010, 10:16
Сообщение #5


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Цитата(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.

Я так подозреваю, должны быть функции файловой системы, которые эти значения записывают в таблицу. Или же это задача программиста?
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Nov 4 2010, 15:49
Сообщение #6


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Мда. Немного покопавшись в исходниках я обнаружил две функции работающие с содержимым 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.

Сообщение отредактировал Nikitoc - Nov 4 2010, 16:29
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Nov 7 2010, 23:50
Сообщение #7


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Да это нигде не реализовано.
Вам же сказали, что существуют отдельные утилиты проверки фс, которые в том числе помечают кластер как сбойный.
Ну а при чтении/записи фс уже понимает, что этот кластер ни купить ни продать и он там так и болтается там в таблице и никто его не трогает больше.

Или вы хотели,чтоб фс на ходу при ошибках отмечала сбойные кластеры?


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Nov 8 2010, 07:04
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



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

Если на это есть время, то запись -верификация - отбраковка кластера легко может быть дописана. Другое дело, что обычно пишут/читают приличные потоки с помощью очень маленького буфера, тут не до грибочков smile.gif
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Nov 12 2010, 22:12
Сообщение #9


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



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

В точку. Хотя, помучившись недельку, я вообщем-то уже подумываю о том, чтобы сделать отдельную функцию типа CHDISK (как мне и советовали).
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Nov 12 2010, 22:38
Сообщение #10


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



У вас 100 лет прибор работать будет? Или бьете все время в один сектор/файл? Если второе, то проще иметь логику выбора сектора куда писать и периодически менять его. Если второе, то вас скорее всего не будет через 100 лет smile.gif
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Dec 15 2010, 19:47
Сообщение #11


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Танцы с бубном продолжаются. Недавно я столкнулся со таким приколом на FatFS: если на карточку записать несколько файлов посредством функций этой файловой системы, а потом удалить в Windows какой-нибудь (или все) файлик с этой карты, то FatFs освободившееся пространство не увидит. f_getfree возвращает такое же количество свободных кластеров как и до удаления файла. Интересно, откуда ноги растут? У кого-то такое уже было? При этом винда, естественно, все освободившееся пространство видит.
P.S. Карточка перед записью форматировалась как жесткий диск, средствами FatFs.

Сообщение отредактировал Nikitoc - Dec 15 2010, 20:01
Go to the top of the page
 
+Quote Post
_4afc_
сообщение Dec 16 2010, 07:24
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 262
Регистрация: 13-10-05
Из: Санкт-Петербург
Пользователь №: 9 565



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


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

Что делает функция f_getfree? Считывает всю FAT таблицу и пробегая по ней суммирует все свободные кластеры? Обе таблицы?
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Dec 16 2010, 09:38
Сообщение #13


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



Цитата(_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 это делает по другому, но как не знаю. Если можно расскажите, как делать правильно.


Go to the top of the page
 
+Quote Post
DL36
сообщение Dec 18 2010, 16:55
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 460
Регистрация: 5-10-06
Из: Херсон
Пользователь №: 21 006



Сравните значение поля FSI_Free_Count (488 4) сектора FSInfo до и после стирания, может оно?
Go to the top of the page
 
+Quote Post
Nikitoc
сообщение Dec 19 2010, 16:06
Сообщение #15


Местный
***

Группа: Validating
Сообщений: 207
Регистрация: 14-01-09
Из: Днепропетровск
Пользователь №: 43 367



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

Ну да, оно-то - оно. Значение это не меняется. Видимо придется просто подсчитывать кластеры в FAT со значением 0x00.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 13:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.01476 секунд с 7
ELECTRONIX ©2004-2016