Драйвер FSD для FAT от компании Analog Devices Печать
Добавил(а) microsin   

В этой статье приведен перевод документации драйвера FAT для процессоров Blackfin от компании Analog Devices (ADI), adi_fat.pdf [1]. Оригинал этого документа можно найти в каталоге установки VisualDSP++, см. папку Blackfin\docs\drivers\fsd\fat\. В терминологии Analog Devices драйверы такого рода называются драйверами файловой системы (File System Driver, FSD) [2]. Этот драйвер не работает напрямую с аппаратурой носителя данных, но зато разбирается с деталями формата и организации конкретной файловой системы (в данном случае это FAT12, FAT16, FAT32).

Драйвер FAT FSD ADI предоставляет функционал, удовлетворяющий спецификации, которую требует служба файловой системы Analog Devices (File System Service, FSS) [3]. Описанный драйвер совместим с томами (volume), отформатированными как FAT12, FAT16, FAT32, и использующими адресацию секторов но номерам логических блоков (Logical Block Address, LBA), чтобы определить абсолютное место расположения данных на физическом носителе.

ADI. Аббревиатура, обозначающая авторство компании Analog Devices. Часто используется как префикс для имен функций и макросов библиотек этой компании.

FSD. File System Driver, драйвер файловой системы в терминологии ADI.

FSS. File System Service, служба файловой системы. Это библиотека ADI, предназначенная работать оберткой над другими библиотеками с целью облегчения и стандартизации доступа к файловым системам и системам хранения данных.

LBA. Logical block addressing, общая схема для указания места нахождения блоков данных, хранящихся на компьютерных устройствах хранения (чаще всего это жесткие диски). LBA в частности применяет простую линейную схему адресации; блоки находятся по целочисленному индексу, где первый блок LBA 0, второй LBA 1, и так далее. Стандарт IDE включает в себя 22-битную адресацию LBA как опцию, что было в дальнейшем расширено до 28 бит в релизе ATA-1 (1994) и до 48 бит в релизе ATA-6 (2003), тогда как размер записей в дисковых и структурах данных в памяти, содержащих адрес, обычно - 32 или 64 бита. Большинство жестких дисков, выпущенных после 1996 года, реализует логическую адресацию блоков LBA (из Википедии).

PID. Physical Interface Driver, драйвер физического интерфейса. Библиотека (часто низкоуровневая, работающая непосредственно со встроенными аппаратными устройствами процессора Blackfin), предназначенная для физического доступа к носителю данных.

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

Например на дисках, которые используют секторы размером 512 байт, кластер размером 512 байт содержит 1 сектор, в то время как кластер на 4 килобайта содержит 8 секторов.

Кластер является самым маленьким логическим количеством пространства диска, которое можно выделить для хранения файла. Хранение маленьких файлов на файловых системах с большим размером кластеров приведет к бесполезной трате дискового пространства; такое потерянное пространство называют шлаком. Для размеров кластера, которые являются небольшими по сравнению со средним размером файла, потраченное впустую пространство за файл будет статистически приблизительно половиной размера кластера; для больших размеров кластера потраченное впустую пространство станет больше. Однако большие размеры кластеров уменьшают нагрузку на обработку блоков и фрагментацию, что в общей статистике увеличивает скорость чтения и записи. Типичные размеры кластеров находятся в диапазоне от 1 сектора (512 байт) до 128 секторов (64 килобайте).

Кластер не обязатель но должен быть физически непрерывным на диске; он может занимать больше одной дорожки или, если используется чередование секторов (interleaving), может даже иметь прерывание в пределах трека. Это не должно быть перепутано с фрагментацией, поскольку секторы все еще логически непрерывны.

Термин кластер (cluster) был изменен на блок выделения (allocation unit) в DOS 4.0. Однако термин кластер все еще широко используется.

Раздел (partition). Физическая область на носителе данных, предназначенная после монтирования работать как отдельный логический диск, или том. На диске может быть один раздел, а может быть несколько. Термины том и раздел часто путают, потому что по сути они означают почти одно и то же.

Сектор. В технологиях устройств хранения данных компьютеров сектором считается кусочек дорожки магнитного диска или оптического диска. Каждый сектор хранит фиксированное количество данных, к которым может получить доступ пользователь. Традиционно это 512 байт для жестких дисков (HDD) и 2048 байт для оптических дисков CD-ROM и DVD-ROM. Новейшие HDD используют 4096-байтные (4 килобайта) секторы, что известно как Advanced Format (AF) (из Википедии).

Сектор является минимальной единицей хранения данных на жестком диске. Все файлы должны занимать не менее одного сектора, независимо от реального размера файла. Однако на практике операционные системы работают с блоками данных, которые распространяются на несколько секторов.

Геометрически слово "сектор" означает порцию диска, определяемую центром диска и находящуся в области между двумя радиусами, проходящими через центр диска, что выглядит как кусок торта. Для терминологии хранения данных на диске сектором считается не вся эта область, а дуга, образованная пересечением дорожки и этого геометрического сектора.

Том (volume). Раздел, смонтированный для работы с ним, т. е. для чтения / записи файлов и директорий.

Драйвер FAT FSD удовлетворяет следующим требованиям:

1. Предоставляет несколько экземпляров драйвера, при этом каждый экземпляр представляет смонтированный раздел (partition), который в этой документации (и обычно в других источниках) называется томом (Volume).

2. Каждый экземпляр драйвера FAT поддерживает концепцию текущей рабочей директории (current working directory, CWD), так что запросы либо к перемещению CWD, либо к открытию файла могут выражаться относительно CWD. Говоря по-русски, поддерживаются как абсолютные, так и относительные пути доступа к объектам файловой системы (файлам и папкам).

3. Внутренний дескриптор файла определен для уникальной идентификации подходящих данных для каждого открытого файла. Указатель на эту внутреннюю структуру назначен полю FSD_data_handle структуры ADI_FSS_FILE_DESCRIPTOR при открытии файла.

4. Драйвер FAT FSD возвратит FALSE в ответ на запрос ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT.

5. Драйвер FAT FSD возвратит либо ADI_FSS_RESULT_SUCCESS на команду:

   { ADI_FSD_CMD_GET_FILE_SYSTEM_SUPPORT, (void*)FileSystemType }

когда сопутствующее значение *FileSystemType равно ADI_FSS_FSD_TYPE_FAT(1), либо ADI_FSS_RESULT_NOT_SUPPORTED в ответ на все другие значения, на которые указывает FileSystemType.

6. Драйвер FAT FSD поддерживает все команды, описанные в секции "Обязательные команды, относящиеся к драйверу FAT FSD".

7. Драйвер FAT FSD динамически поддерживает оба режима работы, как блочный, так и произвольный (arbitrary), в зависимости от возможностей нижележащего драйвера PID для выполнения передач данных в фоновом режиме, как это может быть определено по ответу на команду ADI_FSS_CMD_GET_BACKGRND_XFER_SUPPORT. Драйвер FAT передает этот ответ службе FSS, когда сам получает команду ADI_FSS_CMD_GET_BACKGRND_XFER_SUPPORT.

Блочный режим предназначен для использования совместно с системой файлового кэша (FSS File Cache), когда подразумевается, что операции перемещения данных запрашиваются в блоках, размер которых диктуется размером кластера смонтированного раздела. В этом режиме данные могут передаваться напрямую между носителем (media) и буфером запроса, без применения промежуточного буфера, который требуется внутри драйвера FAT FSD. Драйвер FAT FSD поддерживает размер кластера для FSS в ответ на команду ADI_FSD_CMD_GET_BLOCK_SIZE.

С другой стороны, в произвольном (arbitrary) режиме файловый кэш не участвует в работе, и драйвер FAT FSD может ожидать запросы на произвольные количества данных. В этом случае драйвер FAT FSD использует свои буферы для удержания содержимого текущего кластера файла.

[Быстрый старт]

В таблице ниже перечислены ресурсы Системных Служб (System Services) и драйверов устройств (Device Driver) [4], которые требуется установить в заголовочном файле adi_ssl_init.h.

Вторичные обработчики прерываний (Secondary Interrupt Handlers)  Нет
Каналы DMA Нет
Драйверы устройств (Device Drivers) Один на том FAT
Семафоры Два на том FAT
Флаги callback Нет

Регистрация драйвера FAT FSD для FSS. Чтобы добавить драйвер FAT FSD к службе FSS, подключите заголовок драйвера FAT FSD (файл adi_fat.h) в исходный код приложения, опционально выбрав структуру определений по умолчанию ADI_FAT_Def, например:

#define _ADI_FAT_DEFAULT_DEF_#include < drivers/fsd/fat/adi_fat.h >

Затем добавьте следующую пару команда-значение в таблицу конфигурирования службы FSS перед вызовом adi_fss_Init():

   { ADI_FSS_CMD_ADD_DRIVER, (void*)&ADI_FAT_Def },

Подробности по предоставлению своей структуры определений см. в разделе "Открытие и конфигурирование драйвера FAT FSD".

Требования к динамическому выделению памяти (FAT16/FAT32). В следующей таблице показаны объемы выделения памяти для имеющихся операций.

Операция Размер (в байтах)
Экземпляр драйвера FAT
Экземпляр драйвера, базовые данные (один ра раздел) 248
+ монтирование FAT16/FAT32 + 512 + размер кластера
Временные буферы BPB (только во время операции монтирования) + 512
Доступ к файлу
Открытие файла FAT16/FAT32, базовое требование, блочный режим 596
Открытие файла FAT16/FAT32, дополнительно для arbitrary-режима размер кластера
Открытие файла FAT16/FAT32, дополнительно для режима записи 512 + размер кластера
Временные буферы директории (для поиска директории) 512 + размер кластера
Доступ к директории
Открытие директории FAT16/FAT32 596 + размер кластера
Временные буферы директории (для поиска директории) 512 + размер кластера

Используемые заголовки. Перечисленные ниже файлы представляют API драйвера устройства и функции исходного кода.

services/services.h. Эти файлы содержат все определения, прототипы функций и т. д. для библиотеки Системных Служб (System Services Library, SSL) компании Analog Devices.

drivers/adi_dev.h. Этот файл содержит все определения, прототипы функций и т. д. для Менеджера Устройств [5] (Device Manager) и общей информации по драйверам устройств.

services/fss/adi_fss.h. Этот файл содержит все определения, прототипы функций и т. д. для службы файловой системы FSS [3].

drivers/pid/fat/adi_fat.h. В этом файле содержатся все определения, прототипы функций и т. п. для соответствующего драйвера PID.

string.h. Этот файл содержит все определения, прототипы функций и т. д. для функций копирования данных по памяти.

ctype.h. Этот файл содержит все определения, прототипы функций для функций языка C, связанных с типами.

Файлы исходного кода. Исходный код драйвера содержится в следующих файлах, размещенных в каталоге инсталляции VisualDSP++: Blackfin/lib/src/drivers/fsd/adi_fat.c. Этот код может быть опционально скомпилирован с макросом ADI_USE_FAT_FORMAT, определенным для предоставления функций форматирования. Однако рекомендуется оставить этот макрос не определенным для подключения в распространяемых библиотеках драйверов устройств.

[Драйверы низкого уровня]

Драйвер PID. Это специальный драйвер физического устройства, который используется для передачи данных в физический носитель (physical media) и из него. Хендл устройства для PID передается драйверу FAT FSD следующей парой команда-значение, например:

   { ADI_FSD_CMD_SET_PID_HANDLE, (void*)< PID-handle > }

Подробности см. в документе "Generic PID Design Document" (или в его переводе [6]).

[Требуемые ресурсы]

Драйверы устройств обычно потребляют некоторое количество системных ресурсов. Эта секция описывает ресурсы, требуемые для драйвера FAT FSD.

В описании ниже, если не указано нечто обратное, этот драйвер устройства использует Системные Службы для доступа к требуемой аппаратуре. Информация в этом разделе может быть полезной в определении ресурсов, которые требуются драйверу от Системных Служб, такие как количество обработчиков прерываний или количество каналов DMA и т. п.

Работа с памятью. Все требования к памяти, кроме структур данных, созданных в стеке, удовлетворяются динамически через вызовы функций централизованного API FSS: _adi_fss_malloc(), _adi_fss_realloc() и _adi_fss_free(). Эти функции являются обертками для либо для функций по умолчанию libc: heap_malloc(), heap_realloc() и heap_free(), или для функций, предоставленных приложением, как это определено в конфигурации службы FSS. Этим способом разработчик может предоставить функции управления памятью, чтобы организовать выделение памяти фиксированными, заранее известными блоками.

Службой FSS поддерживается два типа куч: куча кэша (cache heap) для буферов данных, таких как источник данных или место назначения передач DMA, и общая куча (general heap) для хранения таких данных, как данные экземпляров объектов. При конфигурировании драйвера FAT FSD, разработчики могут указать только индекс кучи для кучи кэша; драйвер FAT FSD должен использовать общую кучу, которая была определена в службе FSS, для хранения всех своих структур. Если куча кэша не определена, то драйвер FAT FSD будет использовать общую кучу FSS.

Значение для индекса кучи кэша устанавливается следующей парой команда-значение:

   { ADI_FSS_CMD_SET_CACHE_HEAP_ID, (void*)CacheHeapIndex }

Здесь CacheHeapIndex это либо индекс в массиве heap_table_t heap_table (см. файл < имя_проекта >_heaptab.c), либо индекс, полученный вызовом функции heap_install:

static u8 myheap[1024];
#define MY_HEAP_ID 1234
...
int CacheHeapIndex = heap_install ((void *)&myheap, sizeof(myheap), MY_HEAP_ID);

Использование настраиваемых куч [7] может зависеть от окружения, в котором ведется разработка. Если выбранное окружение не поддерживает настраиваемые кучи, то подпрограммы FSS будут модифицированы для игнорирования аргумента индекса кучи.

В следующей таблице детализированы требования к количеству выделяемой памяти для каждой связанной операции.

Таблица 2. На какие операции выделяется динамически память драйвером FAT FSD.

Операция Размер (в байтах)
Драйвер FAT
Экземпляр драйвера, базовые данные (один на раздел) 248
+ монтирование FAT16/FAT32 + 512 + размер кластера
+ монтирование FAT12 + 1024 + размер кластера
Временные буферы BPB (только во время операции монтирования) + 512
Доступ к файлу
Открытие файла FAT12, базовое требование, блочный режим 1108
Открытие файла FAT16/FAT32, базовое требование, блочный режим 596
Открытие файла FAT12, дополнительно для arbitrary-режима 1084 + размер кластера
Открытие файла FAT16/FAT32, дополнительно для arbitrary-режима 512 + размер кластера
Открытие файла FAT12, дополнительно для режима записи 1084 + размер кластера
Открытие файла FAT16/FAT32, дополнительно для режима записи 512 + размер кластера
Временные буферы директории (для поиска директории) FAT12 1084 + размер кластера
Временные буферы директории (для поиска директории) FAT16/FAT32 512 + размер кластера
Доступ к директории
Открытие директории FAT12 1108 + размер кластера
Открытие директории FAT16/FAT32 596 + размер кластера
Временные буферы директории (для поиска директории) 512 + размер кластера

Следующая таблица дает пример выделений памяти для тома FAT16, у которого размер кластера 8192 байта (том размером 257..512 мегабайт):

На что тратится память Пик Длительно
Смонтированный том 9464 8952
Открытый файл (чтение), блочный режим 9300 596
Открытый файл (чтение), arbitrary-режим 17492 8788

Прерывания. Драйвер FAT FSD не использует специфических обработчиков прерываний. Нижележащий драйвер PID может использовать специфические прерывания. За подробностями обратитесь к документации на соответствующий драйвер PID.

DMA. Драйвер FAT FSD не поддерживает DMA напрямую. Нижележащий драйвер PID может использовать DMA. За подробностями обратитесь к документации на соответствующий драйвер PID.

Таймеры. Драйвер FAT FSD не использует специфические таймеры. Таймеры и callback-ки для них могут использоваться нижележащим драйвером PID. За подробностями обратитесь к документации на соответствующий драйвер PID.

Семафоры. Драйвер FAT FSD требует 2 семафоров, один для семафора блокировки (Lock Semaphore), чтобы в любой момент времени обеспечить исключительный доступ к драйверу FAT FSD только для одного процесса, и еще один для сигнализирования об окончании внутренних передач данных. Для создания всех семафоров и манипулирования ими используется Служба Семафоров.

Часы реального времени (Real-Time Clock, RTC). Драйвер FAT FSD требует использования службы часов реального времени (RTC Service).

Программируемые флаги. Драйвером FAT FSD не используются программируемые флаги. Нижележащий драйвер PID может использовать программируемые флаги. За подробностями обратитесь к документации на соответствующий драйвер PID.

Выводы процессора. Драйвером FAT FSD не используются программируемые флаги. Нижележащий драйвер PID может использовать выводы для доступа к физическому носителю данных (media). За подробностями обратитесь к документации на соответствующий драйвер PID.

[Поддерживаемые функции драйвера устройства]

Направление данных. В таблице ниже перечислены направления данных, которые поддерживает драйвер.

Таблица 3. Поддерживаемые направления данных.

ADI_DEV_DIRECTION Описание
ADI_DEV_DIRECTION_INBOUND Поддерживает прием данных в устройство.
ADI_DEV_DIRECTION_BIDIRECTIONAL Поддерживаются оба направления данных.

Методы потока. Драйвер FAT FSD поддерживает только один метод потока: цепочка буферов ADI_DEV_MODE_CHAINED.

Типы буферов. Драйвер FAT FSD поддерживает только одномерный линейный буфер (ADI_DEV_1D_BUFFER). Он обернут структурой супербуфера FSS (FSS Super Buffer Structure). Поля структуры буфера ADI_DEV_1D_BUFFER:

CallbackParameter - здесь всегда содержится адрес структуры супербуфера FSS.
ProcessedFlag - это поле не используется драйвером FAT FSD.
pAdditionalInfo - это поле не используется драйвером FAT FSD.

Идентификаторы команд (Command ID). Здесь перечислены команды, которые поддерживаются драйвером FAT. Эти команды делятся на 3 секции. Первая секция описывает команды, которые напрямую поддерживаются Драйвером Устройств (Device Manager) [5]. Вторая описывает общие команды, которые драйвер поддерживает. Последняя секция описывает обязательные команды драйвера FSD, реализованные драйвером FAT FSD.

Команды отправляются драйверу устройства функцией adi_dev_Control(), которая принимает 3 аргумента:

DeviceHandle - параметр типа ADI_DEV_DEVICE_HANDLE, который уникально идентифицирует драйвер устройства. Этот хендл предоставляется для клиента на вызове при возврате из функции adi_dev_Open().
CommandID - параметр типа u32, который указывает идентификатор команды.
Value - параметр типа void *, смысл которого зависит от значения CommandID.

Секции ниже перечисляют CommandID, поддерживаемые драйвером, и назначение параметра Value для каждого кода CommandID.

Команды, поддерживаемые Менеджером Устройств. Перечисленные ниже команды непосредственно обрабатываются Менеджером Устройств. Таким образом, все драйверы поддерживают эти команды.

ADI_DEV_CMD_TABLE. Задает таблицу пар команда-значение, передаваемых драйверу. Параметр Value определяет адрес таблицы (ADI_DEV_CMD_VALUE_PAIR *).

ADI_DEV_CMD_END. Обозначает конец таблицы команд. Параметр Value игнорируется (может быть равен NULL).

ADI_DEV_CMD_PAIR. Передает одну пару команда-значение. Параметр Value определяет адрес этой пары (ADI_DEV_CMD_PAIR *).

ADI_DEV_CMD_SET_SYNCHRONOUS. Разрешает/запрещает синхронный режим для драйвера. Value: TRUE/FALSE.

ADI_DEV_CMD_GET_INBOUND_DMA_CHANNEL_ID. Вернет значение идентификатора канала DMA (DMA channel ID) для входящего потока данных драйвера. Value: указатель u32* (ячейка памяти, куда будет сохранен channel ID).

ADI_DEV_CMD_GET_OUTBOUND_DMA_CHANNEL_ID. Вернет значение идентификатора канала DMA (DMA channel ID) для исходящего потока данных драйвера. Value: указатель u32* (ячейка памяти, куда будет сохранен channel ID).

ADI_DEV_CMD_SET_INBOUND_DMA_CHANNEL_ID. Команда установит значение идентификатора канала DMA (DMA channel ID) для входящего потока данных драйвера. Value: ADI_DMA_CHANNEL_ID (DMA channel ID, идентификатор канала DMA).

ADI_DEV_CMD_SET_OUTBOUND_DMA_CHANNEL_ID. Команда установит значение идентификатора канала DMA (DMA channel ID) для исходящего потока данных драйвера. Value: ADI_DMA_CHANNEL_ID (DMA channel ID, идентификатор канала DMA).

ADI_DEV_CMD_SET_DATAFLOW_METHOD. Задает метод потока данных. Как уже упоминалось, поддерживается только один метод потока данных: ADI_DEV_MODE_CHAINED. Value: значение из перечисления ADI_DEV_MODE (поддерживается только значение ADI_DEV_MODE_CHAINED).

Общие команды. Идентификаторы команд, описанные в этой секции, являются общими для многих драйверов устройств. Ниже в списке приведены команды такого рода, поддерживаемые драйвером FAT FSD.

ADI_DEV_CMD_SET_DATAFLOW. Разрешает/запрещает поток данных через устройство. Обязательная для использования команда. Value: TRUE/FALSE.

ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT. Позволяет узнать, поддерживается ли драйвер устройства периферийным DMA. Команда имеет важное значение. Value: u32* (указывает на ячейку памяти, куда будет сохранено значение TRUE или FALSE).

Обязательные команды, относящиеся к драйверу FAT FSD. Перечисленные ниже идентификаторы поддерживаются драйвером FAT FSD. Для файловых систем, предназначенных только для чтения, не требуется использовать команды, относящиеся к операциям записи.

[Операции с файлами]

ADI_FSD_CMD_OPEN_FILE. Файл указывается полем pFullFileName структуры ADI_FSS_FILE_DESCRIPTOR, которое задает путь до открываемого файла. Драйвер FAT FSD выделяет память для своего внутреннего дескриптора файла, и присваивает его адрес полю FSD_data_handle структуры ADI_FSS_FILE_DESCRIPTOR. При возврате драйвер FAT FSD записывает в поле fsize размер файла, как он читается с носителя данных. Если файл не может быть найден, и установлен бит 8 флага режима дескриптора файла FSS (File Descriptor), то тогда файл будет создан и будет считаться, что он существует. Если файл обнаружен, и установлен бит 9 флага режима, то файл открывается и его содержимое сбрасывается так, что файл оказывается пустым. Value: адрес структуры ADI_FSS_FILE_DESCRIPTOR, идентифицирующей открываемый файл.

ADI_FSD_CMD_CLOSE_FILE. Закрывает файл, который идентифицирован структурой ADI_FSS_FILE_DESCRIPTOR. Драйвер FAT FSD освобождает память, выделенную для своего внутреннего дескриптора, и очищает поле FSD_data_handle структуры ADI_FSS_FSD_FILE_DEF. Value: адрес структуры ADI_FSS_FILE_DESCRIPTOR, идентифицирующей закрываемый файл.

ADI_FSD_CMD_SEEK_FILE. Драйвер выполнит позиционирование в определенное место файла, задаваемое значениями в структуре ADI_FSS_SEEK_REQUEST. Value: адрес структуры ADI_FSS_SEEK_REQUEST, идентифицирующую обрабатываемый файл и параметры позиционирования.

[Операции с директориями]

ADI_FSD_CMD_CHANGE_DIR. Настраивает текущую рабочую директорию так, как это указано в структуре связанного списка ADI_FSS_FULL_FNAME, переданной через аргумент Value. Value: адрес структуры ADI_FSS_FULL_FNAME, определяющей имя пути директории, в которую нужно перейти.

ADI_FSD_CMD_MAKE_DIR. Создает новую директорию в файловой системе по пути (pathname), указанном в в структуре связанного списка ADI_FSS_FULL_FNAME, переданной через аргумент Value. Текущая рабочая директория драйвера FAT FSD остается неизменной. Value: адрес структуры ADI_FSS_FULL_FNAME, определяющей имя пути директории, в которую нужно создать.

ADI_FSD_CMD_REMOVE_DIR. Удаляет запись директории в файловой системе. Удаляемая директория задается через путь, указанный в структуре связанного списка ADI_FSS_FULL_FNAME, переданной через аргумент Value. Текущая рабочая директория драйвера FAT FSD остается неизменной. Value: адрес структуры ADI_FSS_FULL_FNAME, определяющей имя пути директории, в которую нужно удалить.

ADI_FSD_CMD_OPEN_DIR. Открывает директорию, указанную полем pFullFileName структуры связанного списка ADI_FSS_FILE_DESCRIPTOR, где задан путь до открываемой директории. Драйвер FAT FSD выделяет память для своего внутреннего дескриптора файлов, и присваивает его адрес полю FSD_data_handle структуры ADI_FSS_FILE_DESCRIPTOR. При возврате драйвер FAT FSD присваивает полю fsize размер файла, как он читается с носителя данных. Для работы с открытой директорией можно использовать только команды доступа к директории; функцию adi_dev_Read использовать нельзя. Value: адрес структуры ADI_FSS_DIR_DEF, идентифицирующей открываемую директорию.

ADI_FSD_CMD_CLOSE_DIR. Закрывает директорию, идентифицируемую структурой ADI_FSS_DIR_DEF. Value: адрес структуры ADI_FSS_DIR_DEF идентифицирует директорию, которая должна быть закрыта.

ADI_FSD_CMD_READ_DIR. Читает следующую запись директории и заполняет структуру dirent, связанную со структурой ADI_FSS_DIR_DEF. Поле tellpos структуры ADI_FSS_DIR_DEF должно быть установлено в позицию файла текущей записи, и поле curpos связанной структуры ADI_FSS_FILE_DESCRIPTOR используется для указания на место в директории, находящейся сразу после последней прочитанной записи директории. Value: адрес структуры ADI_FSS_DIR_DEF, идентифицирующей читаемую директорию.

ADI_FSD_CMD_SEEK_DIR. Перемещает указатель текущей позиции внутри открытой директории в позицию, заданную полем tellpos структуры ADI_FSS_DIR_DEF, указанной через аргумент Value. При возврате поле curpos связанной структуры ADI_FSS_FILE_DESCRIPTOR указывает в то же место, что и поле tellpos. Value: задает структуру ADI_FSS_DIR_DEF, идентифицирующую директорию для обработки.

ADI_FSD_CMD_REWIND_DIR. Отматывает текущую позицию указателя открытой директории в её начало, сбрасывая оба поля: tellpos в структуре ADI_FSS_DIR_DEF (на которую указывает аргумент Value), и поле curpos связанной структуры ADI_FSS_FSD_FILE_DEF. Value: адрес структуры ADI_FSS_DIR_DEF, идентифицирующей отматываемую в начало директорию.

[Операции по обслуживанию файловой системы]

ADI_FSD_CMD_REMOVE. Удаляет файл и связанную запись директории в файловой системе. Файл определяется полем pathname структуры связанного списка ADI_FSS_FULL_FNAME, указанной через аргумент Value. Текущая рабочая директория драйвера FAT FSD остается неизменной. Value: адрес структуры ADI_FSS_FULL_FNAME, определяющей путь до удаляемого файла.

ADI_FSD_CMD_RENAME. Переименовывает или перемещает в новое место по системе каталогов файл или директорию, идентифицируемую полем pSource указанной структуры ADI_FSS_RENAME_DEF. Новое имя целевой директории идентифицируется полем pTarget той же структуры. Value: адрес структуры ADI_FSS_RENAME_DEF, где определены имена переименовываемого файла и либо его новое имя, либо новое место, куда файл или директория должны быть перенесены.

ADI_FSD_CMD_GET_FILE_SYSTEM_SUPPORT. Возвратит ADI_FSS_RESULT_SUCCESS, если в сопровождающем 32-битном слове Value записано значение ADI_FSS_FSD_TYPE_FAT (1); иначе будет возвращен код ADI_FSS_RESULT_NOT_SUPPORTED. Value: уникальный идентификатор, определяющий файловую систему.

ADI_FSD_CMD_MOUNT_VOLUME. Инструктирует драйвер FAT FSD читать загрузочную запись (Boot Record, или BIOS Parameter Block) тома по заданному номеру сектора LBA, и переместиться в корневую директорию тома (root directory). Value: - номер сектора LBA, определяющий начало требуемого тома, в соответствии с таблицей разделов (Partition Table).

ADI_FSD_CMD_UNMOUNT_VOLUME. Инструктирует драйвер FAT FSD размонтировать том. Value: недоступно.

ADI_FSD_CMD_SET_PID_HANDLE. Инструктирует драйвер FAT FSD использовать драйвер устройства, определенный в параметре Value как ADI_DEV_DEVICE_HANDLE, чтобы читать/записывать данные физического носителя. Value: адрес ADI_DEV_DEVICE_HANDLE, идентифицирующий драйвер устройства, используемый для чтения/записи физического носителя данных (physical media).

ADI_FSS_CMD_GET_BACKGRND_XFER_SUPPORT. Запрашивает драйвер FAT FSD вернуть TRUE или FALSE в зависимости от возможности для драйвера поддерживать фоновую передачу данных. Возвращенное значение зависит от нижележащего драйвера PID, которому должна быть передана эта команда. Value: предоставленное клиентом место для сохранения результата.

ADI_FSS_CMD_GET_DATA_ELEMENT_WIDTH. Запрашивает драйвер FAT FSD вернуть ширину (в байтах), которая определяет каждый элемент данных. Возвращенное значение будет зависеть от нижележащего драйвера PID, которому должна быть передана эта команда. Value: предоставленное клиентом место для сохранения результата.

ADI_FSS_CMD_ACQUIRE_LOCK_SEMAPHORE. Запрос драйверу FAT FSD предоставить семафор блокировки (Lock Semaphore), чтобы дать вызывающему модулю исключительный доступ к функциям перемещения данных драйвера PID. Value: NULL.

ADI_FSS_CMD_RELEASE_LOCK_SEMAPHORE. Запрос драйверу FAT FSD освободить семафор блокировки, предоставленный в ответ на команду ADI_FSS_CMD_ACQUIRE_LOCK_SEMAPHORE. Value: NULL.

ADI_FSS_CMD_SET_CACHE_HEAP_ID. Инструктирует экземпляр драйвера FAT FSD использовать предоставленный индекс кучи (Heap Index) для динамически выделяемых кэшей данных. По умолчанию драйвер использует общую кучу FSS. Value: индекс требуемой кучи.

ADI_FSD_CMD_GET_BLOCK_SIZE. На выходе драйвер FAT FSD вернет размер в байтах самой малой значимой единицы данных для файла, кластера (Cluster size). Value: адрес ячейки памяти, куда при возврате будет записана информация размера.

ADI_FSD_CMD_GET_TYPE_STRING. Инструктирует драйвер FAT FSD предоставить адрес строки, описывающей драйвер. Эта строка будет предоставлена в стандартной кодировке ASCII. Value: при возврате здесь будет адрес строки, завершающейся нулем (NULL terminated string, ASCIIZ-строка). Будет возвращена либо строка "FAT12", либо "FAT16", либо "FAT32".

ADI_FSD_CMD_GET_LABEL. Инструктирует драйвер FAT FSD предоставить адрес строки текста, где содержится метка из 11 символов. Эта метка будет предоставлена в стандартной кодировке ASCII. Value: при возврате здесь будет адрес строки метки, соответствующей либо идентификатору тома (volume ID) в корневой директории, либо это будет идентифицировано блоком параметров BIOS (BIOS parameter block) смонтированного тома.

Команды, специфические для драйвера FAT FSD. Для драйвера FAT FSD не определено каких-то специальных команд, отражающих специфику FAT.

Семафор блокировки. Драйвер FAT FSD поддерживает один семафор блокировки (Lock Semaphore), чтобы предотвратить одновременный доступ со стороны нескольких потоков. Этот семафор блокировки предоставляется процессу при поступлении следующей пары команда-значение:

   { ADI_FSS_CMD_ACQUIRE_LOCK_SEMAPHORE, NULL },

И освобождается семафор при поступлении следующей пары команда-значение:

   { ADI_FSS_CMD_RELEASE_LOCK_SEMAPHORE, NULL },

Семафор завершения процесса перемещения данных. Драйвер FAT FSD поддерживает один семафор, чтобы сообщать о событии окончании передачи данных. Этот хендл семафора назначается полю SemaphoreHandle структуры супербуфера файловой системы (FSS Super Buffer), когда перемещение данных инициируется внутри драйвера FAT FSD. Как только буфер был поставлен в очередь с драйвером PID, драйвер FAT FSD ожидает на этом семафоре, когда завершится передача данных. При поступления callback-события ADI_PID_EVENT_DEVICE_INTERRUPT драйвер FAT FSD проверит это значение и сравнит его со значением, находящимся в супербуфере, и при совпадении опубликует этот семафор. Подробности см. в следующей секции "События callback".

События callback. Драйвер FAT FSD не генерирует события callback, он просто обрабатывает буферы, предоставляемые службой FSS, и передает их драйверу PID, который будет генерировать событие callback при завершении обработки данных. Однако драйвер FAT FSD предоставляет callback-функцию, которая должна быть вызвана из FSS в ответ на события ADI_DEV_EVENT_BUFFER_PROCESSED и ADI_PID_EVENT_DEVICE_INTERRUPT, генерируемые драйвером PID. Дополнительно он предоставляет значимый хендл, чтобы передать его как первый аргумент в эту callback-функцию. Обычно этот хендл будет адресом данных экземпляра драйвера FAT FSD. Эти значения назначаются полям FSDCallbackFunction и FSDCallbackHandle в супербуфере FSS перед постановкой очереди цепочки буферов с драйвером PID.

Другие аргументы для callback-функции предоставляются так же, как и для всех функций типа ADI_DCB_CALLBACK_FN:

void FSDCallback (void* Handle, u32 Event, void *pArg);

Драйвер FAT FSD предполагает, что значение pArg указывает на структуру супербуфера FSS для подбуфера, у которого завершилась передача данных.

Если драйвер FAT FSD владеет семафором, находящимся в супербуфере FSS, то он будет публиковать его в ответ на событие ADI_PID_EVENT_DEVICE_INTERRUPT. Тогда в ответ на то же событие он должен либо предоставить следующий запрос LBA в цепочке (когда последующее значение SectorCount не равно 0), либо освободить семафор блокировки PID на конце цепочки.

[Коды возврата]

Все API-функции драйвера устройства возвращают код состояния, показывающий успех или неудачу завершения. При неудаче возвращаемый код показывает причину ошибки. В этом разделе перечислены коды возврата, которые драйвер устройства может возвратить клиенту. Возвращаемое значение ADI_DEV_RESULT_SUCCESS или ADI_FSS_RESULT_SUCCESS означает успешное завершение, и все другие значения означает либо некую ошибку, либо какой-то другой информативный результат. Значения ADI_DEV_RESULT_SUCCESS и ADI_FSS_RESULT_SUCCESS всегда равны 0. Все другие значения не нулевые.

Коды возврата делятся на 2 секции. Первая описывает коды возврата, которые являются общими для многих драйверов устройств. Другая секция описывает коды возврата, относящиеся именно к драйверу FAT FSD. Код клиента должен подготовить обработку каждого из кодов возврата, описанного в этих секциях.

Обычно приложение сразу проверяет код результата на равенство ADI_DEV_RESULT_SUCCESS, предпринимая отдельные корректирующие действия, когда возвращаемое значение не равно ADI_DEV_RESULT_SUCCESS. Например:

if (adi_dev_Xxxx(...) == ADI_DEV_RESULT_SUCCESS)
{
   // Нормальная обработка, успешное завершение функции
   ...
}
else
{
   // Здесь должна быть обработка ошибки
   ...
}

Общие коды возврата. Здесь описаны коды возврата, которые являются общими для многих драйверов устройств. Список ниже перечисляет все общие коды возврата, поддерживаемые драйвером FAT FSD.

ADI_DEV_RESULT_SUCCESS. Функция завершилась успешно.

ADI_DEV_RESULT_NOT_SUPPORTED. Эта функция не поддерживается драйвером.

ADI_DEV_RESULT_DEVICE_IN_USE. Запрашиваемое устройство уже используется.

ADI_DEV_RESULT_NO_MEMORY. Недостаточно памяти.

ADI_DEV_RESULT_BAD_DEVICE_NUMBER. Недопустимый номер устройства.

ADI_DEV_RESULT_DIRECTION_NOT_SUPPORTED. Устройство не может быть открыто в указанном направлении.

ADI_DEV_RESULT_BAD_DEVICE_HANDLE. Недопустимый хендл драйвера устройства.

ADI_DEV_RESULT_BAD_MANAGER_HANDLE. Недопустимый хендл Менеджера Устройств.

ADI_DEV_RESULT_BAD_PDD_HANDLE. Недопустимый хендл физического драйвера.

ADI_DEV_RESULT_INVALID_SEQUENCE. Запрошенное действие не находится в правильной последовательности с другими действиями.

ADI_DEV_RESULT_ATTEMPTED_READ_ON_OUTBOUND_DEVICE. Клиент попытался предоставить входящий буфер для устройства, открытого только для исходящего трафика.

ADI_DEV_RESULT_ATTEMPTED_WRITE_ON_INBOUND_DEVICE. Клиент попытался предоставить исходящий буфер для устройства, открытого только для входящего трафика.

ADI_DEV_RESULT_DATAFLOW_UNDEFINED. Пока не был задан метод потока данных.

ADI_DEV_RESULT_DATAFLOW_INCOMPATIBLE. Этот метод потока не совместим с запрошенным действием.

ADI_DEV_RESULT_BUFFER_TYPE_INCOMPATIBLE. Это устройство не поддерживает тип предоставленного буфера.

ADI_DEV_RESULT_NON_TERMINATED_LIST. Цепочка предоставленных буферов не завершена NULL.

ADI_DEV_RESULT_NO_CALLBACK_FUNCTION_SUPPLIED. Не была предоставлена необходимая callback-функция.

ADI_DEV_RESULT_REQUIRES_BIDIRECTIONAL_DEVICE. Требуется открытие устройства для двунаправленного трафика.

Коды возврата, специфичные для драйвера FAT FSD. Эти коды поддерживаются и обрабатываются драйвером FAT, они уникальны для этого драйвера.

ADI_FSS_RESULT_BAD_NAME. Недопустимое имя файла/директории.

ADI_FSS_RESULT_NOT_FOUND. Указанный файл/директория не найдены в файловой системе.

ADI_FSS_RESULT_OPEN_FAILED. Указанный файл не может быть открыт из-за ошибки.

ADI_FSS_RESULT_CLOSE_FAILED. Указанный файл не может быть закрыт.

ADI_FSS_RESULT_MEDIA_FULL. Операция не может быть завершена, потому что физический носитель данных переполнен.

ADI_FSS_RESULT_NO_MEMORY. Недостаточно свободной памяти кучи для удовлетворения запроса на динамическое выделение памяти.

[Структуры данных]

Следующие структуры данных используются совместно с вышеперечисленными командами. Все они, кроме одной, определены в заголовке FSS, файл < services/fss/adi_fss.h >.

Точки входа в драйвер (Device Driver Entry Points, ADI_DEV_PDD_ENTRY_POINT). Эта структура используется в общем для всех драйверов, удовлетворяющих модели драйвера устройств компании Analog Devices (ADI Device Driver model), чтобы определить точки входа для драйвера устройства. Она определена в модуле исходного кода драйвера FAT FSD, файл adi-fat.c, и декларирована как переменная extern в заголовке драйвера FAT FSD, файл adi-fat.h, где присутствие имени защищено от повторного включения в исходном коде драйвера FAT FSD следующим образом:

• В модуле исходного кода и перед оператором #include для заголовочного файла определяется макрос __ADI_FAT_C__.

• В файле заголовка применяется блок защитного включения, обрамляющий декларацию extern:

#if !defined(__ADI_FAT_C__)
extern ADI_DEV_PDD_ENTRY_POINT ADI_FAT_EntryPoint;
...
#endif

Пары команда-значение, ADI_DEV_CMD_VALUE_PAIR. Эта структура используется как общая для всех драйверов, удовлетворяющих модели ADI Device Driver, и она используется главным образом для начальной конфигурации драйвера. Драйвер FAT FSD должен поддерживать все 3 метода передачи пар команда-значение:

adi_dev_control( ..., ADI_DEV_CMD_TABLE, (void*)< адрес-таблицы-пар-команда-значение > );
adi_dev_control( ..., ADI_DEV_CMD_PAIR, (void*)< адрес-пары-команда-значение > );
adi_dev_control( ..., < команда >, (void*)< связанное-с-командой-значение > );

В заголовочном файле драйвера FAT FSD (файл adi-fat.h) не определена таблица по умолчанию.

Структура определения устройства (Device Definition Structure, ADI_FSS_DEVICE_DEF). Эта структура используется для инструктирования службы FSS о том, как открыть и конфигурировать драйвер FAT FSD. Её содержимое в сущности это тот же объем элементов, переданных как аргументы в вызов adi_dev_Open(). Структура определена в заголовке службы FSS, файл adi_fss.h, следующим образом:

typedef struct
{
   u32                     DeviceNumber;
   ADI_DEV_PDD_ENTRY_POINT *pEntryPoint;
   ADI_DEV_CMD_VALUE_PAIR  *pConfigTable;
   void                    *pCriticalRegionData;
   ADI_DEV_DIRECTION       Direction;
   ADI_DEV_DEVICE_HANDLE   DeviceHandle;
   ADI_FSS_VOLUME_IDENT    DefaultMountPoint;
} ADI_FSS_DEVICE_DEF;

Значение полей этой структуры показано в следующей таблице:

DeviceNumber Определяет, какое периферийное устройство используется. Это значение равно аргументу DeviceNumber, который нужен для вызова adi_dev_Open(). Драйвер FAT FSD игнорирует это значение.
pEntryPoint Это указатель на точку входа драйвера устройства, и сюда передается тот же аргумент pEntryPoint, который нужно передать в функцию adi_dev_Open(). Для драйвера FAT FSD это значение должно быть назначено на &ADI_FAT_EntryPoint.
pConfigTable Это указатель на таблицу пар команда-значение для конфигурирования драйвера FAT FSD. Значение по умолчанию равно NULL для драйвера FAT FSD.
pCriticalRegionData Это указатель на аргумент, который должен быть передан Системным Службам через вызов функции adi_int_EnterCriticalRegion(). В настоящий момент эта фича не используется, и здесь должно быть передано значение NULL.
Direction Это аргумент для определения направления передачи данных, требуемый для вызова adi_dev_Open(). Для драйвера FAT FSD это значение должно быть ADI_DEV_DIRECTION_BIDIRECTIONAL.
DeviceHandle Это ячейка для внутреннего использования, чтобы сохранить хендл драйвера устройства, который был возвращен из вызова adi_dev_Open(). Перед инициализацией этот параметр должен быть установлен в NULL.
DefaultMountPoint Буква по умолчанию диска для томов, управляемых драйвером FAT FSD.

Инстанциация по умолчанию этой структуры декларирована в заголовке драйвера FAT FSD, файл adi_fat.h, и защищена от повторного включения в исходном коде драйвера FAT FSD. Она должна подключаться только в модуле приложения, если разработчик определил макрос _ADI_FAT_DEFAULT_DEF_:

#if !defined(__ADI_FAT_C__)
...
#if defined(_ADI_FAT_DEFAULT_DEF_)
static ADI_FSS_DEVICE_DEF ADI_FAT_Def = { ... };
...
#endif
...
#endif

Дескриптор файла (FSS File Descriptor, ADI_FSS_FILE_DESCRIPTOR). Эта структура передается драйверу FAT FSD для всех операций по открытию файлов. Она определена в заголовке FSS, файл adi_fss.h, следующим образом:

typedef struct
{
   ADI_FSS_FULL_FNAME        *pFullFileName;
   u32                       curpos;
   u32                       fsize;
   int                       mode;
   ADI_FSS_FSD_DATA_HANDLE   FSD_data_handle;
   ADI_DEV_DEVICE_HANDLE     FSD_device_handle;
   void                      *pCriticalRegionData;
   ADI_FSS_CACHE_DATA_HANDLE Cache_data_handle;
} ADI_FSS_FILE_DESCRIPTOR;

Значение полей этой структуры показано в следующей таблице:

pFullFileName Связанный список, содержащий полное имя файла.
curpos Текущая байтовая позиция в открытом файле.
fsize Общий размер файла в байтах. При открытии файла это значение должно быть установлено в значение, записанное в файловой записи директории.
mode Режим доступа, в котором открывается файл.
FSD_data_handle Драйвер FAT FSD должен присвоить этому полю адрес внутренней структуры данных, которая уникально идентифицирует состояние открытого файла в соответствующих терминах файловой системы.
FSD_device_handle Здесь должен быть хендл устройства (Device Handle), идентифицирующий драйвер FAT FSD, и он должен быть тот же самый, что и третий аргумент вызова adi_pdd_Open().
pCriticalRegionData Указатель на данные критического региона. В настоящее время это не используется.
Cache_data_handle Этот хендл зарезервирован для использования с модулем файлового кэша.

Структура полного имени файла ADI_FSS_FULL_FNAME. Содержит связанный список, определяющий пут к файлу. Если путь абсолютный, то поле name первой записи связанного списка будет NULL, иначе путь будет интерпретирован как относительный к текущей рабочей директории. Структура определена в заголовке adi_fss.h следующим образом:

typedef struct ADI_FSS_FULL_FNAME
{
   struct ADI_FSS_FULL_FNAME *pNext;
   struct ADI_FSS_FULL_FNAME *pPrevious;
   ADI_FSS_WCHAR             *name;
   u32                       namelen;
} ADI_FSS_FULL_FNAME;

Значение полей этой структуры показано в следующей таблице:

pNext Следующий элемент в связанном списке.
pPrevious Предыдущий элемент в связанном списке.
name Имя элемента текущего пути (это имя директории или файла).
namelen Длина имени элемента текущего пути.

Структура супербуфера FSS (FSS Super Buffer Structure, ADI_FSS_SUPER_BUFFER). Супербуфер используется как обертка над структурой ADI_DEV_1D_BUFFER. Так что у структуры ADI_FSS_SUPER_BUFFER первым полем идет структура ADI_DEV_BUFFER, и эти две структуры имеют общий адрес. Поэтому адрес супербуфера может быть использован в вызовах adi_dev_Read/adi_dev_Write, и следует понимать, что указатель на супербуфер может быть разыменован, чтобы получить доступ к его содержимому.

На каждой стадии процесса обработки, от файлового кэша драйвера FAT FSD до драйвера PID, супербуфер может на всем пути предоставить подходящую информацию. Поля структуры супербуфера описаны в таблице ниже, где красным цветом показаны поля, относящиеся к файловому кэшу, зеленым цветом показаны поля драйвера FAT FSD, и синим цветом показаны поля, относящиеся к драйверу PID. Поле запроса LBA (LBA Request) устанавливается драйвером FAT FSD для запросов, поступающих как от кэша, так и драйвера FAT FSD, или в драйвере PID для его внутренних запросов.

Инициирующий супербуфер модуль обнулит его поля, которые не используются.

Вот определение структуры супербуфера:

typedef struct ADI_FSS_SUPER_BUFFER
{
   ADI_DEV_1D_BUFFER       Buffer;
   struct adi_cache_block  *pBlock;
   u8                      LastInProcessFlag;
   ADI_FSS_LBA_REQUEST     LBARequest;
   ADI_SEM_HANDLE          SemaphoreHandle;
   ADI_FSS_FILE_DESCRIPTOR *pFileDesc;
   ADI_DCB_CALLBACK_FN     FSDCallbackFunction;
   void                    *FSDCallbackHandle;
   ADI_DCB_CALLBACK_FN     PIDCallbackFunction;
   void                    *PIDCallbackHandle;
} ADI_FSS_SUPER_BUFFER;

Здесь поля определены следующим образом:

Buffer Структура ADI_DEV_BUFFER, требуемая для перемещения данных. Обратите внимание, что это не поле указателя. Это поле должно быть установлено драйвером FAT FSD только в том случае, когда запрос на передачу данных предназначен ему.
SemaphoreHandle Хендл семафора для публикации после завершения перемещения данных. Это должно быть установлено драйвером FAT FSD только в том случае, если запрос передачи данных предназначен ему, и тогда сюда должно быть записано значение хендла семафора, сохранное в данных экземпляра драйвера FAT FSD. См. секции ниже для описания работы семафоров.
LBARequest Структура ADI_FSS_LBA_REQUEST для связанного буфера. Драйвер FAT FSD отвечает за установку значений в этой структуре независимо от того, был ли запрос сгенерирован внутри драйвера FAT FSD, или передан из модуля файлового кэша. Если буфер формирует часть цепочки, и он может быть показан как несколько следующих друг за другом подбуферов, то драйвер FAT FSD может опционально комбинировать запросы LBA, чтобы покрыть некоторое количество подбуферов. В этом случае значение SectorCount каждого подбуфера, который является представленным запросом LBA предыдущего подбуфера, должен быть обнулен.
pBlock Используется в файловом кэше FSS. Это значение не должно изменяться драйвером FAT FSD. Для внутренних передач драйвера FAT FSD эти поля должны быть установлены в NULL.
LastinProcessFlag
pFileDesc
FSDCallbackFunction Это поле устанавливается драйвером FAT FSD в адрес callback-функции, вызываемой при событии завершения передачи данных.
FSDCallbackHandle Это поле устанавливается драйвером FAT FSD в адрес подходящей структуры для передачи как первый аргумент в функцию, определенную полем FSDCallbackFunction.
PIDCallbackFunction Эти поля зарезервированы для использования драйвером PID.
PIDCallbackHandle

Структура запроса LBA (LBA Request, ADI_FSS_LBA_REQUEST). Эта структура используется для передачи запроса на некоторое количество секторов, которое должно быть прочитано из устройства. Адрес инстанциации этой структуры должен быть отправлен драйверу PID либо командой ADI_PID_CMD_SEND_LBA_READ_REQUEST, либо командой ADI_PID_CMD_SEND_LBA_WRITE_REQUEST перед разрешением потока данных в PID. Структура определена в хедере FSS, файл adi_fss.h, следующим образом:

typedef struct ADI_FSS_LBA_REQUEST
{
   u32                  SectorCount;
   u32                  StartSector;
   u32                  DeviceNumber;
   u32                  ReadFlag;
   ADI_FSS_SUPER_BUFFER *pBuffer;
} ADI_FSS_LBA_REQUEST;

Значение полей этой структуры показано в следующей таблице:

SectorCount Количество секторов в передаваемом блоке данных.
StartSector Начальный сектор передаваемого блока в формате LBA.
DeviceNumber Номер устройства в цепочке на шине. Эта информация доступна в момент монтирования драйвера FAT FSD через структуру ADI_FSS_VOLUME_DEF.
ReadFlag Флаг, показывающий, что передаваемые данные относятся к операции чтения. Если это так, что значение этого поля должно быть равно 1. Если операция записи, то значение этого поля должно быть 0.
pBuffer Адрес связанного подбуфера ADI_FSS_SUPER_BUFFER.

Структура определения тома ADI_FSS_VOLUME_DEF. Эта структура содержит информацию, требуемую для монтирования подходящей файловой системы определенного тома. Она определена в хедере FSS, файл adi_fss.h, следующим образом:

typedef struct
{
   u32 FileSystemType;
   u32 StartAddress;
   u32 VolumeSize;
   u32 SectorSize;
   u32 DeviceNumber;
} ADI_FSS_VOLUME_DEF;

Значение полей этой структуры показано в следующей таблице:

FileSystemType Тип файловой системы тома. Должен соответствовать идентификатору, сохраненному в модуле FSS (см. раздел "Типы файловых систем").
StartAddress Начальный сектор тома/раздела (volume/partition) в формате адресации секторов LBA.
VolumeSize Количество секторов, содержащихся в томе.
SectorSize Количество байт в секторе тома.
DeviceNumber Количество устройств на шине. Например, драйвер Parallel ATA должен поддерживать 2 устройства в одной цепочке: Master (где DeviceNumber=0) и Slave (DeviceNumber=1). Это значение должно использоваться для заполнения поля DeviceNumber структуры запроса LBA.

Структура запроса на позиционирование ADI_FSS_SEEK_REQUEST. Содержит параметры позиционирования и информацию о файле, в котором происходит позиционирование. Структура определена в заголовке FSS, файл adi_fss.h, следующим образом:

typedef struct
{
   ADI_FSS_FILE_DESCRIPTOR *pFileDesc;
   int                     whence;
   long                    offset;
} ADI_FSS_SEEK_REQUEST;

Значение полей этой структуры показано в следующей таблице:

pFileDesc Указатель на файловый дескриптор FSS для файла, с которым происходит манипуляция.
whence Флаг, определяющий начальную точку операции позиционирования: 0 позиционировать от начала файла, 1 позиционировать относительно текущей позиции, 2 позиционировать относительно конца файла.
Offset Количество байт от начальной позиции позиционирования (смещение).

Структура определения каталога ADI_FSS_DIR_DEF. Содержит информацию, относящуюся к открытой директории. Структура определена в заголовке FSS, файл adi_fss.h, следующим образом:

typedef struct
{
   ADI_FSS_FILE_DESCRIPTOR *pFileDesc;
   ADI_FSS_DIR_ENTRY       entry;
   u32                     tellpos;
} ADI_FSS_DIR_DEF;

Значение полей этой структуры показано в следующей таблице:

pFileDesc Указатель на файловый дескриптор FSS для файла, с которым происходит манипуляция.
entry Описание текущей записи. ADI_FSS_DIR_ENTRY это просто определение типа структуры dirent, который определен в заголовке dirent.h. Драйвер FAT FSD должен заполнить эту структуру данными, интерпретированными из специфики записи директории связанной файловой системы.
tellpos Позиция файла текущей записи директории.

Структура записи в каталоге ADI_FSS_DIR_ENTRY. Содержит информацию, относящуюся к текущей записи директории. Структура определена в заголовке FSS, файл adi_fss.h, следующим образом:

struct dirent
{
   ino_t         d_ino;
   off_t         d_off;
   unsigned char d_namlen;
   unsigned char d_type;
   char          d_name[256];
   u32           d_size;
   struct tm     DateCreated;
   struct tm     DateModified;
   struct tm     DateLastAccess;
};

Значение полей этой структуры показано в следующей таблице:

d_ino Серийный номер файла (File Serial Number).
d_off Смещение до следующей записи директории.
d_namlen Длина имени записи минус завершающий символ \0.
d_type Тип: DT_REG для обычного файла, или DT_DIR для подкаталога.
d_name Имя записи, 256 символов максимум.
d_size Размер файла в байтах.
DateCreated Дата и время, когда был создан файл.
DateModified Дата и время, когда файл был изменен последний раз.
DateLastAccess Дата и время, когда к файлу был доступ последний раз.

Структура для операции переименования ADI_FSS_RENAME_DEF. Определяет имена источника (source) и места назначения (target) операции переименования. Если источник это файл, и цель это директория, то файл просто перемещается в указанную директорию. Структура определена в заголовке FSS, файл adi_fss.h, следующим образом:

typedef struct
{
   ADI_FSS_FULL_FNAME *pSource;
   ADI_FSS_FULL_FNAME *pTarget;
} ADI_FSS_RENAME_DEF;

Значение полей этой структуры показано в следующей таблице:

pSource Указатель на связанный список, содержащий путь исходного файла/директории.
pTarget Указатель на связанный список, содержащий путь места назначения файла/директории.

Структура определения формата ADI_FSS_FORMAT_DEF. Определяет информацию, необходимую для форматирования раздела. Эта структура определена в заголовке службы FSS, файл adi_fss.h, следующим образом:

typedef struct
{
   ADI_FSS_VOLUME_IDENT ident;
   ADI_FSS_WCHAR        *label;
   u32                  label_len;
   u32                  OptionMask;
   ADI_FSS_VOLUME_DEF   VolumeDef;
} ADI_FSS_FORMAT_DEF;

Значение полей структуры показано в следующей таблице:

ident Уникальный идентификатор для смонтированного тома. Это поле игнорируется драйвером FAT FSD.
label Метка, которую получает раздел, состоящая из 11 символов ASCII. Эта метка записывается как запись первой директории (со значением атрибута 0x08) в корневой (root) директории. Она никогда не появляется в списке объектов директории.
label_len Длина метки label.
OptionMask Это поле определяет тип файловой системы для реализации. Это значение задается макросом ADI_FSS_FMT_OPTION_VALUE(FILESYS,TYPE), который определен в файле adi_fss.h, где FILESYS должен быть всегда быть значением ADI_FSS_FSD_TYPE_FAT для драйвера FAT FSD, и значение TYPE должно быть 0 для FAT12, 1 для FAT16 и 2 для FAT32.
VolumeDef Структура ADI_FSS_VOLUME_DEF для этого раздела.

[Типы файловых систем]

Следующее перечисление дает уникальные значения для различных файловых систем. Драйвер FAT FSD поддерживает только файловую систему ADI_FSS_FSD_TYPE_FAT.

enum
{
   ADI_FSS_FSD_TYPE_UNKNOWN      = 0,
   ADI_FSS_FSD_TYPE_FAT          = 1,
   ADI_FSS_FSD_TYPE_CDDATA_MODE1 = 2,
   ADI_FSS_FSD_TYPE_CDDATA_MODE2 = 3,
   ADI_FSS_FSD_TYPE_CDAUDIO      = 4,
   ADI_FSS_FSD_TYPE_UDF          = 5,
   ADI_FSS_FSD_TYPE_YAFFS        = 6,
};

Здесь перечислены следующие файловые системы:

ADI_FSS_FSD_TYPE_UNKNOWN Неизвестная файловая система.
ADI_FSS_FSD_TYPE_FAT FAT12, FAT16, FAT32.
ADI_FSS_FSD_TYPE_CDDATA_MODE1 Компакт-диск (CD) ISO 9660, формат желтая книга (Yellow Book Data) для Mode 1 и Mode 2 Form 1.
ADI_FSS_FSD_TYPE_CDDATA_MODE2 Компакт-диск (CD) ISO 9660, формат желтая книга (Yellow Book Data) для Mode 2 Form 2.
ADI_FSS_FSD_TYPE_CDAUDIO Компакт-диск (CD) ISO 9660, формат красная книга (Red Book Data) для данных CD Audio.
ADI_FSS_FSD_TYPE_YAFFS "Немного другая" файловая система FLASH (Yet another Flash File System) от Aleph One для памяти NAND flash.

[Открытие и конфигурирование драйвера FAT FSD]

В этом разделе описаны настройки конфигурации по умолчанию для драйвера FAT FSD и дополнительные конфигурационные настройки этого драйвер, которые должно сделать приложение клиента.

Регистрация драйвера FAT FSD для службы файловой системы (FSS). Чтобы добавить драйвер FAT FSD для FSS, должен быть определен экземпляр структуры ADI_FSS_DEVICE_DEF, например ADI_FAT_Def (см. выше описание этой структуры), и его адрес должен быть передан функции adi_fss_init() как часть таблицы конфигурации FSS:

   { ADI_FSS_CMD_ADD_DRIVER, (void*)&ADI_FAT_Def },

Эта структура потребует адрес структуры точки входа драйвера FAT FSD, ADI_FAT_EntryPoint (см. описание структур выше), которая определена в заголовке драйвера FAT FSD, файл < drivers/fsd/fat/adi_fat.h >. Например, структуры для конфигурации драйвера FAT должны быть следующие:

ADI_DEV_CMD_VALUE_PAIR ADI_FAT_ConfigTable [] =
{
   { ADI_FSS_CMD_SET_CACHE_HEAP_ID, (void*)1 },
   { ADI_DEV_CMD_END, NULL },
}; 
ADI_FSS_DEVICE_DEF ADI_FAT_Def =
{
   0,
   &ADI_FAT_EntryPoint,
   ADI_FAT_ConfigTable,
   NULL,
   ADI_DEV_DIRECTION_BIDIRECTIONAL,
   'C'
};

Процедура открытия драйвера. Служба файловой системы Analog Devices (File System Service, FSS) автоматически откроет драйвер FAT FSD вызовом функции adi_dev_Open() при детектировании присутствия тома с данными. Аргументы для этого вызова предоставлены структурой ADI_FSS_DEVICE_DEF (см. выше описание этой структуры).

После этого драйвер FAT FSD отправит команду ADI_FSD_CMD_GET_FILE_SYSTEM_SUPPORT с одним из значений из перечисления, чтобы определить тип файловой системы тома (см. выше секцию "Типы файловых систем"; для обычных дисков с возможностью чтения и записи это будет значение ADI_FSS_FSD_TYPE_FAT). Драйвер FAT FSD должен сравнить возвращенное значение со своим внутренним значением ADI_FSS_FSD_TYPE_FAT и возвратить при совпадении ADI_FSS_RESULT_SUCCESS.

Если вызов был не успешен, то драйвер FAT FSD будет закрыт, иначе ему должны далее поступить команды в следующем порядке:

1. ADI_DEV_CMD_SET_DATAFLOW_METHOD. Для драйверов устройств такого рода важно установить метод потока ADI_DEV_MODE_CHAINED (драйвер FAT FSD не поддерживает другие методы потока данных).

2. ADI_DEV_CMD_TABLE. Здесь передается адрес таблицы конфигурации, определенной пользователем, и этот адрес присваивается полю pConfigTable структуры ADI_FSS_DEVICE_DEF, переданной драйверу FAT FSD для конфигурирования.

3. ADI_FSD_CMD_SET_PID_HANDLE. Хендл устройства (Device Handle) низкоуровневого драйвера PID передается драйверу FAT FSD, чтобы позволить ему делать вызовы драйвера устройства PID.

4. ADI_FSD_CMD_MOUNT_VOLUME. В завершение адрес структуры ADI_VOLUME_DEF передается драйверу FAT FSD вместе со всей требуемой информацией для монтирования подходящей файловой системы на носителе данных (media).

Настройки по умолчанию. Драйвер FAT FSD подразумевает следующую настройку кучи для кэша:

Элемент Значение по умолчанию Command ID
Идентификатор кучи кэша (Cache Heap ID) -1 ADI_FSS_CMD_SET_CACHE_HEAP_ID

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

Элемент Возможные значения Command ID
Метод потока данных Поддерживается только метод ADI_DEV_MODE_CHAINED (см. выше секцию "Методы потока данных"). ADI_DEV_CMD_SET_DATAFLOW_METHOD

Замечания, касающиеся аппаратуры. Для драйвера FAT FSD нет специальных замечаний, связанных с аппаратной конфигурацией. Однако нижележащий драйвер физического интерфейса (Physical interface driver, PID) имеет определенные требования к аппаратуре. За подробностями обращайтесь к конфигурации на соответствующий драйвер PID.

[Ссылки]

1. ADI FAT FILE SYSTEM DRIVER site:analog.com.
2Драйвер файловой системы (FSD) для службы файловой системы (FSS).
3Служба файловой системы Blackfin.
4. VDK: драйверы устройств и системные службы процессоров Blackfin.
5VDK: менеджер драйверов устройств.
6Драйвер интерфейса (PID) для службы файловой системы (FSS).
7. VisualDSP: работа с динамически выделяемой памятью.