Распределение областей диска
В этом разделе описано внутреннее устройство флеш-диска.
Флеш-диск состоит из нескольких областей. Каждая область включает один или несколько флеш-секторов. Физический размер сектора - 264 байта, из которых для данных используется только 256. Два последних байта каждого сектора хранят контрольную сумму. Остальные шесть байт в основном не используются, за исключением областей FRT и FAT (см. ниже), где они выполняют полезную функцию.
Во флеш-диске есть следующие области:
- Сектор BOOT, всегда расположенный в логическом секторе №0 (то есть это самый верхний физический сектор флеш-памяти - об этом рассказано в разделе Совместное использование флеш-памяти приложением и данными). Загрузочный сектор содержит сведения о размерах остальных областей диска.
- Область таблицы файловых записей (FRT).
- Область таблицы размещения файлов (FAT).
- Область данных - собственно секторы данных файлов.
- Область журнала транзакций - кэширует изменённые секторы во время дисковой транзакции. Эта область существует, только если диск отформатирован методом fd.formatj.
- Сектор END BOOT - хранит те же данные, что и сектор BOOT, но расположен за областью данных.

Область FRT
Каждая файловая запись занимает 64 байта, поэтому в одном секторе области FRT помещается четыре записи. Если при форматировании вы указали, что хотите хранить 15 разных файлов, метод fd.format (или fd.formatj) округлит это число до 16 файлов. Для них потребуется четыре сектора. Фактически выделяется всегда вдвое больше секторов. Это нужно для выравнивания износа секторов, о котором объект fd. заботится самостоятельно. По той же причине число выделенных секторов никогда не бывает меньше восьми.
Максимальное число файлов, которое хранит объект fd., - 64. Поэтому максимальный размер области FRT равен (64 / 4) * 2 = 32 сектора. Таким образом, размер области FRT всегда лежит в пределах от восьми до 32 секторов в зависимости от максимального числа файлов, которое нужно хранить на диске.
Область FAT
Каждый сектор FAT содержит 128 записей FAT по 2 байта. Поэтому один сектор FAT вмещает данные о размещении 128 секторов области данных диска. Чтобы улучшить выравнивание износа секторов, число секторов, выделяемых под область FAT, снова вдвое больше необходимого. Таким образом, на каждые 128 секторов области данных диска приходится два сектора в области FAT. Под FAT всегда выделяется не менее 16 секторов.
Пример: пусть область данных содержит 1 100 секторов. Тогда нужно 1 100 / 128 = девять секторов FAT. Объект fd. выделит вдвое больше этого минимума, то есть будет подготовлено 18 секторов FAT. Теперь предположим, что секторов данных всего 500. Для них нужно четыре сектора FAT, а после удвоения - восемь. Это меньше минимальных 16 секторов FAT, которые выделяются всегда, поэтому объект fd. всё равно выделит 16 секторов.
Пример расчёта размещения и ёмкости
Метод fd.format принимает в качестве входного параметра общее число секторов, которое должен занимать диск. Исходя из него и заданного максимального числа файлов метод рассчитывает размер каждой области диска. Рассмотрим это на реальном примере:
Допустим, вы вызываете fd.formatj(1300,41,100) - то есть хотите, чтобы диск занимал 1 300 секторов и хранил 41 файл, а область журнала содержала 100 свободных секторов. Каким будет размер областей FRT, FAT и данных?
Сначала fd.formatj вычитает два сектора на BOOT и END BOOT, которые должны присутствовать всегда. Остаётся 1 298 секторов.
Затем вычитается область журнала - остаётся 1 198 секторов.
Далее fd.formatj определяет размер области FRT: 41 округляется до 44, получается (44 / 4) * 2 = 22 сектора (это больше минимума в восемь, поэтому корректировать число не нужно). Остаётся 1 198 - 22 = 1176 секторов.
Сколько секторов FAT нужно теперь? 1 176 / 128 = 9,18 (то есть 10). Фактическое число удваивается, поэтому нужно 20 секторов (это больше минимума в 16, так что корректировать число не нужно). Остаётся 1 176 - 20 = 1 156 секторов данных. Именно это значение вернёт свойство fd.capacity (только чтение) (см. Проверка параметров диска).
Одна небольшая оговорка...
Теперь рассмотрим более хитрый пример. Допустим, вы вызываете fd.format(1301,4). Легко подсчитать, что на области FAT и данных вместе приходится 1 301 сектор. Как их разделить?
Будь у вас 1 300 секторов, проблем бы не было. Из них 1 280 пошли бы на область данных и 20 - на FAT. Десять «необходимых» секторов FAT вместе вмещают 10 * 128 = 1 280 записей - как раз под размер области данных. Число секторов FAT всегда удваивается, поэтому FAT получит 20 секторов. Всё помещается идеально!
Для 1 301 сектора хорошего решения нет. Если отдать этот лишний сектор области данных, для области FAT понадобятся ещё два сектора, а их нет. Выделять лишний сектор под FAT бессмысленно: число секторов данных не растёт, значит, дополнительный сектор FAT не нужен. Следовательно, значение 1 301 нам фактически не подходит. То же относится к 1 302, а вот 1 303 снова подходит: три лишних сектора позволяют отдать один сектор области данных и добавить два сектора в область FAT (помните, что FAT всегда растёт «парами»?).
Метод fd.format избегает этой ловушки: если запрошенный вами общий размер диска оказывается одним из «проблемных» значений, он корректируется в меньшую сторону. Так, при вызове fd.format(1302,4) результат будет таким же, как при fd.format(1300,4). Это отражает свойство fd.totalsize (только чтение).
Зачем нужен сектор END BOOT
Сектор END BOOT нужен для одной цели - определить, не залезло ли ваше приложение на флеш-диск. Как уже объяснялось, в устройствах с общей флеш-памятью прошивка с приложением и область данных находятся в одной флеш-микросхеме. Секторы области данных отсчитываются от самого верхнего физического сектора флеш-памяти. Поэтому сектор END BOOT - самый «близкий» к вашему приложению. Если приложение вырастет и займёт часть места, ранее принадлежавшего флеш-диску, сектор END BOOT будет перезаписан. Объект fd. обнаружит это при монтировании и вернёт код состояния 3 - PL_FD_STATUS_FORMAT_ERR.