Программирование Файловые системы Secure Digital Host PID для службы файловой системы FSS Wed, March 29 2017  

Поделиться

нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Secure Digital Host PID для службы файловой системы FSS Печать
Добавил(а) microsin   

В этом документе описывается функционал драйвера хоста для карт SD (Secure Digital Host Physical Interface Driver, сокращенно SDH PID), который следует стандартной модели драйверов для файловой системы компании Analog Devices (File System Service, ADI FSS). Аппаратура SDH доступна на семействе моделей процессоров серий ADSP-BF54x (и также на процессорах ADSP-BF51x, ADSP-BF60x, где она почему-то называется в документации Removable Storage Interface, RSI). Драйвер SDH поддерживает доступ к данным Secure Digital (SD) карт памяти Version 1.X и Version 2.0 стандартной емкости, повышенной емкости (Higher Capacity Secure Digital, SDHC) и картам памяти Secure Digital IO (карты SDIO, SDIO-Combo). Поддержка карт мультимедиа (Multimedia card, MMC) и функций ввода/вывода карт SDIO и SDIO-combo запланирована для реализации в будущем (здесь приведен перевод документации [1], входящей в комплект поставки среды разработки VisualDSP++ 5.0).

[Файлы драйвера SDH PID]

Подключаемые файлы. Исходный код драйвера использует следующие подключаемые файлы (все эти файлы размещены в подкаталогах системы программирования VisualDSP++ 5.0):

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

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

< services/fss/adi_fss.h >. Этот файл содержит все определения, прототипы функций и т. п. для файловой системы ADI (File System Service, FSS).

< drivers/pid/sdh/adi_sdh.h >. Этот файл содержит все определения, прототипы функций и т. п. для драйвера SDH PID.

< drivers/pid/adi_ata.h >. Этот файл содержит определения структуры таблицы диска ATA (ATA Partition Table Structure) и перечисляет идентификаторы поддерживаемых типов разделов диска (Partition type ID).

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

Файлы исходного кода. Исходный код драйвера находится в следующих файлах, размещенных в подкаталоге Blackfin/lib/src/drivers/pid/ каталога установки VisualDSP++ 5.0:

< sdh/adi_sdh.c >. Этот файл содержит исходный код драйвера устройства SDH PID. Весь код написан на языке C, никакие низкоуровневые функции на языке ассемблера не используются.

< sdh/adi_sdh_reg.h >. Этот файл содержит определения всех адресов MMR и макросы доступа к битовым полям регистров аппаратуры SDH.

Документация находится в файле Blackfin\docs\drivers\pid\sdh\adi_sdh.pdf.

Драйвер SDH PID не использует внутри себя никаких дополнительных низкоуровневых драйверов.

[Ресурсы, требуемые для драйвера SDH PID]

Драйверы устройств обычно потребляют некоторое количество системных ресурсов. В этом разделе описаны ресурсы, требуемые для драйвера устройства SDH PID.

Если специально не указано нечто иное в секциях ниже, то SDH PID использует системные службы (System Services, SSL) для доступа и управления требуемой аппаратурой. Информация в этой секции может помочь в определении ресурсов, необходимых для работы драйвера SDH PID, таких как количество обработчиков прерывания или количество каналов DMA и т. п., требуемых от System Services.

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

Службой File System Service поддерживается 2 типа куч, это куча для кеша (cache heap), предназначенная для буферов данных наподобие памяти источника и назначения передач DMA, и общая куча (general heap), где содержатся такие данные, как экземпляры объектов библиотек и драйвера SDH PID. Драйвер SDH PID использует general heap, определенную в FSS. Приложение может установить индекс используемой SDH кучи для кеша (cache heap) с использованием соответствующей пары команда-значение, которая может быть отправлена как часть таблицы конфигурации SDH по умолчанию из структуры определения SDH PID.

{ ADI_FSS_CMD_SET_CACHE_HEAP_ID, (void*)CacheHeapIndex }

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

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

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

Прерывания. SDH PID требует памяти для трех обработчиков прерывания (ISR) – обработчик прерывания данных DMA SDH, обработчик прерывания ошибки DMA SDH и обработчик прерывания статуса SDH. Каждый из этих ISR требует памяти размером в ADI_INT_SECONDARY_MEMORY.

DMA. Драйвер SDH PID поддерживает только SD-протокол (в режиме полудуплекса) и требует/использует один канал DMA для перемещения данных между процессором и подключенным устройством памяти (карта памяти SD, SDHC и т. п.). Приложение во время процесса инициализации должно выделить память для одного канала SDH DMA размером ADI_DMA_CHANNEL_MEMORY.

Таймеры. Драйвер SDH PID не требует использования службы таймеров.

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

Часы реального времени, RTC. Драйвер SDH PID не требует службы RTC (Real-Time Clock, часы для отсчета реального времени).

Программируемые флаги. Драйвер SDH PID не требует использования программируемых флагов.

Выводы процессора. SDH требует как минимум 3 выводов для подключения сигналов Command, Clock и Data слота карт SD. Приложение может выбрать работу SDH в режиме широкой шины (wide-bus mode), который расширяет шину данных SDH до 4 бит, тогда это потребует дополнительных 3 выводов процессора. На моделях процессоров Blackfin, где используется мультиплексирование выводов с другими функциями, в зависимости от значений регистра SDH, драйвер SDH PID автоматически переконфигурирует выводы программируемых флагов (programmable flag, PF), чтобы разрешить требуемые выводы для использования в интерфейсе карты SD. Разработчик должен с внимательно распределить выводы процессора таким образом, чтобы SDH не использовал программируемые флаги, которые используют другие устройства ввода/вывода общего назначения, и наоборот.

[Функции, поддерживаемые драйвером SDH PID]

Направление. Драйвер поддерживает типы направлений потоков данных, перечисленные в следующей таблице.

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

ADI_DEV_DIRECTION Описание
ADI_DEV_DIRECTION_INBOUND Поддерживается прием данных в драйвер устройства (чтение носителя данных).
ADI_DEV_DIRECTION_OUTBOUND Поддерживается передача данных из драйвера устройства (запись носителя данных).
ADI_DEV_DIRECTION_BIDIRECTIONAL Поддерживается и прием данных, и передача данных (чтение и запись носителя).

Методы потока данных. Драйвер SDH PID может поддерживать только метод потока цепочек буферов, ADI_DEV_MODE_CHAINED. Когда драйвер используется совместно с FSS, это конфигурируется автоматически внутри службы FSS. Если драйвер работает отдельно, без FSS, то тогда важно при конфигурировании драйвера SDH PID послать ему команду, устанавливающую метод потока:

{ ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void*)ADI_DEV_MODE_CHAINED },

Типы буферов. Драйвер поддерживает только один тип буферов, линейный одномерный буфер ADI_DEV_1D_BUFFER. Этот буфер встраивается внутрь структуры супербуфера службы FSS (подробнее см. документацию FSS [2], где описывается структура супербуфера). Поля с буфере ADI_DEV_1D_BUFFER используются следующим образом:

CallbackParameter. Здесь всегда содержится адрес структуры супербуфера файловой системы (FSS Super Buffer), и это поле не должно оставаться не измененным.
ProcessedFlag. Это поле не используется драйвером SDH PID.
pAdditionalInfo. Это поле не используется драйвером SDH PID.

Идентификаторы команд. В этой секции перечислены команды, которые поддерживаются/требуется драйвером SDH PID. Эти команды поделены на 3 секции. Первая врезка описывает команды, которые поддерживаются напрямую Менеджером Устройств (Device Manager). Вторая врезка описывает общие команды драйвера устройства, которые поддерживает SDH PID. Эти команды поддерживают все драйверы PID. Следующая, третья врезка описывает поддерживаемые команды PID. И последняя, четвертая врезка описывает команды, специфичные именно для драйвера SDH PID.

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

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

Во врезках ниже перечислены идентификаторы команд, поддерживаемые драйвером, и описание соответствующих значений Value для каждого идентификатора команды CommandID.

Команды, перечисленные ниже, поддерживаются и обрабатываются напрямую Менеджером Устройств (Device Manager). Здесь описаны только те команды, которые имеют отношение к SDH PID.

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

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

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

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

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

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

ADI_DEV_CMD_SET_INBOUND_DMA_CHANNEL_ID. Установит значение DMA channel ID для входящего канала DMA драйвера устройства SDH PID. Value – ADI_DMA_CHANNEL_ID (DMA channel ID).

ADI_DEV_CMD_SET_OUTBOUND_DMA_CHANNEL_ID. Установит значение DMA channel ID для исходящего канала DMA драйвера устройства SDH PID. Value – ADI_DMA_CHANNEL_ID (DMA channel ID).

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

Команды, перечисленные ниже, являются общими для большинства драйверов PID. Здесь перечислены команды, которые будут поддержаны и обработаны SDH PID.

ADI_DEV_CMD_SET_DATAFLOW. Разрешает/запрещает поток данных через устройство. Value – TRUE/FALSE.

ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT. Позволяет определить, поддерживает ли драйвер устройства периферийный DMA. Value типа u32 * (ячейка, где будет сохранено значение TRUE или FALSE). SDH является полудуплексным устройством, отображенным на один канал DMA. Чтобы улучшить управление потоком данных DMA, SDH DMA и буферы обрабатываются внутри самого драйвера, а не в Device Manager. Поэтому драйвер в ответ на эту команду вернет FALSE.

ADI_DEV_CMD_FREQUENCY_CHANGE_PROLOG. Оповещает драйвер устройства непосредственно перед изменением частоты ядра/шины (CCLK/SCLK) процессора. Если частота SCLK увеличивается, то параметры времени SDH PID подстраиваются до изменения частоты. Value – ADI_DEV_FREQUENCIES * (новые частоты).

ADI_DEV_CMD_FREQUENCY_CHANGE_EPILOG. Оповещает драйвер устройства непосредственно за изменением частоты ядра/шины (CCLK/SCLK) процессора. Если частота SCLK уменьшается, то параметры времени SDH PID подстраиваются в после изменения частоты. Value – ADI_DEV_FREQUENCIES * (новые частоты).

Команды, перечисленные ниже, будут поддержаны и обработаны SDH PID. Идентификаторы этих команд уникальны для FSS.

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

ADI_FSS_CMD_GET_DATA_ELEMENT_WIDTH. Запрашивает SDH PID вернуть ширину (в байтах) для каждого элемента данных. Value – место в памяти, предоставленное клиентом, чтобы команда возвратила туда результат. DMA SDH поддерживает только 32-битные передачи, поэтому всегда будет возвращено значение 4.

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

ADI_FSS_CMD_RELEASE_LOCK_SEMAPHORE. Запрашивает SDH PID освободить семафор блокировки (Lock Semaphore), предоставленный в ответ на команду ADI_FSS_CMD_ACQUIRE_LOCK_SEMAPHORE. Value – NULL.

ADI_FSS_CMD_SET_CACHE_HEAP_ID. Инструктирует экземпляр SDH PID использовать указанный индекс кучи для динамического выделения буферов данных. Value – индекс требуемой кучи.

ADI_PID_CMD_GET_FIXED. Запрашивает SDH PID возвратить TRUE или FALSE в зависимости от того, может ли считаться устройство фиксированным, или же оно извлекаемое. Value – место в памяти, предоставленное клиентом, чтобы команда возвратила туда результат. SDH PID поддерживает только извлекаемые устройства памяти, поэтому он вернет TRUE.

ADI_PID_CMD_MEDIA_ACTIVATE. Активирует SDH PID, конфигурируя его для использования. Value – TRUE для активации, FALSE для деактивации.

ADI_PID_CMD_POLL_MEDIA_CHANGE. Инструктирует SDH PID проверить состояние устройства на предмет извлечения или установки носителя данных. Если драйвер детектировал, что носитель был установлен, то он выполнит процесс идентификации карты, и выдаст callback-событие ADI_FSS_EVENT_MEDIA_INSERTED, чтобы оповестить FSS об установке нового носителя. Value – NULL.

ADI_PID_CMD_DETECT_VOLUMES. Инструктирует SDH PID распознать тома/разделы на носителе данных. Для каждого детектированного тома SDH PID выдает событие ADI_FSS_EVENT_VOLUME_DETECTED, передавая указатель на относящуюся к тому информацию в качестве третьего аргумента. Value – NULL.

ADI_PID_CMD_SEND_LBA_REQUEST. Запрашивает SDH PID подать команду устройству, чтобы прочитать/записать некоторое количество секторов из устройства/в устройство по указанному начальному сектору LBA (LBA start sector). Value – адрес структуры ADI_FSS_LBA_REQUEST, содержащей вышеперечисленную информацию.

ADI_PID_CMD_ENABLE_DATAFLOW. Инструктирует SDH PID предпринять необходимые шаги для начала/остановки потока данных. Value - TRUE/FALSE.

ADI_PID_CMD_SET_DIRECT_CALLBACK. Предоставляет адрес callback-функции, чтобы она вызывалась напрямую (без откладывания на уровень кода вне прерываний, т. е. без использования Менеджера DCB) при событиях установки/извлечения носителя и событиях детектирования тома. Value – адрес callback-функции.

ADI_PID_CMD_GET_GLOBAL_MEDIA_DEF. Запрашивает SDH PID для возврата информации, относящейся к общей геометрии установленного устройства памяти. Value – адрес структуры ADI_FSS_VOLUME_DEF для сохранения всей информации об устройстве. Ниже перечислены поля этой структуры ADI_FSS_VOLUME_DEF:

FileSystemType. Не используется.
StartAddress. Сектор (значение LBA) первого сектора на носителе, который можно использовать.
VolumeSize. Общее количество секторов на устройстве.
SectorSize. Размер в байтах каждого сектора.

ADI_SDH_CMD_SET_SUPPORTED_CARD_OPERATING_CONDITION. Устанавливает диапазон рабочих условий карты (напряжение питания карты) поддерживаемых аппаратно. Value – u32. Установки по умолчанию для драйвера – условия работы, поддерживаемые оценочной платой разработчика ADSP–BF548 Ez-Kit rev 1.1.

В следующей таблице перечислены диапазоны рабочих напряжений, поддерживаемые картами SD Version 1.X / Version 2.0 стандартной емкости, повышенной емкости (Higher Capacity SD, SDHC) и картами SDIO. Разработчик должен просмотреть эту таблицу на предмет соответствия окну рабочих напряжений, поддерживаемого аппаратурой, и передать значение типа u32, где будут установлены биты в соответствии с поддерживаемыми диапазонами напряжений.

Таблица 3. Условия работы карты.

Позиции бит в u32 Окно рабочих напряжений, V
0..3 Зарезервировано, должно быть установлено в 0.
4 1.6 .. 1.7
5 1.7 .. 1.8
6 1.8 .. 1.9
7 1.9 .. 2.0
8 2.0 .. 2.1
9 2.1 .. 2.2
10 2.2 .. 2.3
11 2.3 .. 2.4
12 2.4 .. 2.5
13 2.5 .. 2.6
13 2.6 .. 2.7
15 2.7 .. 2.8
16 2.8 .. 2.9
17 2.9 .. 3.0
18 3.0 .. 3.1
19 3.1 .. 3.2
20 3.2 .. 3.3
21 3.3 .. 3.4
22 3.4 .. 3.5
23 3.5 .. 3.6
24 .. 31 Зарезервировано, должно быть установлено в 0.

ADI_SDH_CMD_SET_CARD_LOCK_ENABLED. Разработчик должен использовать эту команду для передачи драйверу SDH PID состояния блокировки карты (card lock, механический контакт) установленного носителя (карты). Положение этих контактов неизвестно для внутренних узлов установленного носителя данных, и следовательно драйвер SDH PID не может обнаружить это автоматически. Разработчик должен в программе приложения реализовать опрос этих контактов, используя вывод порта (флаг порта), и информировать об его состоянии драйвер SDH PID. Когда контакты в состоянии блокировки карты, драйвер SDH защищает носитель карты от записи, так что все операции записи не будут выполнены. Value – TRUE/FALSE. (TRUE when the card is locked). Установка драйвера по умолчанию – подразумевается, что карта не заблокирована на запись.

ADI_SDH_CMD_ENABLE_WIDEBUS. Разрешает/запрещает режим широкой шины (wide-bus mode). SDH может быть сконфигурирован для использования 1-битной ("узкая" шина) или 4-битной ("широкая" шина) шины данных для обмена данными между процессором и установленным носителем данных (карта SD). 4-битная шина данных значительно уменьшает время доступа, и рекомендуется использовать этот режим всякий раз, когда он поддерживается. Некоторые типы карт (наподобие карт Multimedia, MMC и низкоскоростные карты SDIO) поддерживают только 1-битную шину данных и SDH PID должен пропустить установку широкой шины для такого носителя. Обратите внимание, что режим широкой шины увеличивает количество используемых выводов процессора для SDH с 3 до 6 (без учета выводов портов, используемых для детектирования заполнения слота и контакта блокировки записи). Value – TRUE/FALSE (TRUE для разрешения wide-bus mode, FALSE для его запрета). Установки по умолчанию для драйвера разрешают режим широкой шины.

Команды, специфичные для SD I/O, команды для установки/очистки пароля карты SD и т. п., запланированы для реализации в будущем.

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

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

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

if (adi_dev_Xxxx(...) == ADI_DEV_RESULT_SUCCESS)
{
   // Нормальная обработка, ошибки нет:
   ...
}
else
{
   // Обработка ошибки:
   ...
}

Коды возврата, описанные в этой врезке, являются общими для многих драйверов устройств. Этот список перечисляет все общие коды, которые поддерживаются драйвером SDH PID.

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.

Следующие коды возврата определены в заголовочном файле < services/fss/adi_fss.h >. Они используются драйвером SDS PID:

ADI_FSS_RESULT_NO_MEDIA. Не был детектирован носитель, либо неудачно выполнилась команда идентификации карты.

ADI_FSS_RESULT_NO_MEMORY. Недостаточно памяти для выполнения запроса. Обычно происходит в результате неудачного вызова _adi_fss_malloc().

ADI_FSS_RESULT_MEDIA_CHANGED. Поменялся носитель данных.

ADI_FSS_RESULT_FAILED. Общая ошибка.

ADI_FSS_RESULT_DEVICE_IS_LOCKED. Драйвер устройства был заблокирован, когда осуществлялся процесс перемещения данных.

ADI_FSS_RESULT_NOT_SUPPORTED. Запрошенная операция не поддерживается SDH PID.

ADI_FSS_RESULT_SUCCESS. Общий код успешного завершения.

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

ADI_DEV_PDD_ENTRY_POINT. Это так называемая структура точек входа в драйвер (Device Driver Entry Points). Эта структура используется в общем для всех драйверов, удовлетворяющих модели драйверов устройств Analog Devices (ADI Device Driver model), и она содержит адреса стандартного набора функций драйвера устройства. Эта структура определена в модуле исходного кода SDH PID, файл adi_sdh.c, и декларирована как переменная extern в заголовочном файле SDH PID, adi_sdh.h:

extern ADI_DEV_PDD_ENTRY_POINT ADI_SDH_EntryPoint;

ADI_DEV_CMD_VALUE_PAIR. Это структура для определения пары команда-значение, используемая всеми драйверами устройств, удовлетворяющих модели драйверов устройств Analog Devices (ADI Device Driver model). Структура используется в основном для начальной конфигурации драйвера. Драйвер SDH PID должен поддерживать все 3 метода передачи пар команда-значение:

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

ADI_FSS_DEVICE_DEF. Это структура определения устройства, используемая для инструктирования FSS, как открыть и сконфигурировать SDH PID. Содержимое этой структуры в основном это набор параметров, переданных как аргументы в вызов adi_dev_Open(). Структура определена в заголовочном файле службы файловой системы 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(). Для драйвера SDH PID это значение будет 0.
pEntryPoint Это указатель на точку входа в драйвер устройств (массив указателей на стандартные функции драйвера ADI). Передается как аргумент pEntryPoint, требуемый для вызова adi_dev_Open(). Для SDH PID это значение назначается в &ADI_SDH_EntryPoint.
pConfigTable Это указатель на таблицу пар команда-значение, чтобы конфигурировать драйвер SDH PID. Если таблица команд не используется (подразумевается, что конфигурирование будет выполнено позже вызовами adi_dev_Control), то здесь передается NULL.
pCriticalRegionData Это указатель на аргумент, который должен быть передан в функцию adi_int_EnterCriticalRegion() библиотеки системных служб (SSL). В настоящее время эта возможность не используется, и здесь должен быть NULL.
Direction Это аргумент Direction (направление передачи данных), требуемый для вызова функции adi_dev_Open(). Возможные для драйвера SDH PID значения направлений перечислены в таблице 2.
DeviceHandle Это указатель на место в памяти, используемой внутри драйвера. Здесь сохраняется хендл драйвера устройства - набор данных, полученный при возврате из вызова функции adi_dev_Open(). Перед инициализацией должно быть установлено в NULL.
DefaultMountPoint Это буква по умолчания, используемая для обслуживания диска под управлением SDH PID. Установка этого поля гарантирует, что будет использоваться каждый раз одна и та же буква диска, когда монтируется SD-диск.

Экземпляр по умолчанию этой структуры определена в заголовочном файле SDH PID, adi_sdh.h, защищена от повторного подключения в исходном модуле PID, и будет доступна в модуле приложения только если разработчик определит в нем макрос _ADI_SDH_DEFAULT_DEF_:

#if defined(_ADI_SDH_DEFAULT_DEF_)
static ADI_FSS_DEVICE_DEF ADI_SDH_Def = { ... };
...
#endif

ADI_FSS_VOLUME_DEF. Это структура определения тома, используемая в SDH PID для обмена с FSS. В ней представлено описание тома, который можно использовать. Адрес глобального экземпляра этой структуры будет возвращен как третий аргумент callback-функции, посланный к FSS вместе с событием ADI_FSS_EVENT_VOLUME_DETECTED. Структура определена в заголовочном файле службы файловой системе adi_fss.h следующим образом:

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

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

FileSystemType Это уникальный идентификатор, определяющий тип файловой системы. Допустимые типы декларируются в анонимном перечислении заголовочного файла FSS. Для SDH PID это значение всегда ADI_FSS_FSD_TYPE_FAT.
StartAddress Начальный сектор тома/раздела в формате LBA.
VolumeSize Количество секторов, содержащихся в томе/разделе.
SectorSize Количество байт на сектор, используемое в томе/разделе.
DeviceNumber Это используется для индикации номера устройства в цепочке устройств. Для SDH PID всегда устанавливается в 0.

Служба файловой системы (FSS) рассматривает эту структуру как volatile, и будет делать копию ее содержимого.

Это структура супербуфера FSS. Супербуфер используется как обертка над структурой буфера ADI_DEV_1D_BUFFER. По этой причине в структуре ADI_FSS_SUPER_BUFFER в качестве первого поля находится структура ADI_DEV_1D_BUFFER, так что эти две структуры имеют общий адрес. Это используется следующим образом:

• Адрес супербуфера может использоваться в вызовах adi_dev_Read/adi_dev_Write, и
• В коде этих функция может быть разименован указатель на супербуфер, и может быть получен доступ к его содержимому.

На каждой стадии процесса обработки, от файлового кеша FSD до PID, супербуфер получает на всем пути уместную информацию. Эти поля определенны в следующей таблице, и цветами помечены их разновидности. Красным помечены поля, относящиеся к файловому кешу, зеленым поля, устанавливаемые драйвером FSD, и синим поля, устанавливаемые драйвером PID. Запрос LBA устанавливается драйвером FSD для запросов, исходящих и от кеша, и от FSD, или в PID для его собственных внутренних запросов.

Имейте в виду, что для использования вне контекста службы файловой системы (FSS) все вызовы adi_dev_Read() или adi_dev_Write() с хендлом устройства SDH PID должны использовать адрес допустимой структуры супербуфера ADI_FSS_SUPER_BUFFER.

Владелец супербуфера установит в 0 те его поля, которые не уместны. Определение структуры супербуфера следующее:

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, требуемая для перемещения данных. Обратите внимание, что это не поле указателя. Это поле должно быть установлено драйвером PID только в том случае, когда он выдает запрос на передачу данных.
SemaphoreHandle Хендл семафора для публикации после завершения перемещения данных. Это должно быть установлено драйвером PID только в том случае, когда он выдает запрос передачи данных, и тогда сюда должно быть записано значение хендла семафора, сохранное в данных экземпляра драйвера PID. См. секции ниже для описания использования семафоров.
LBARequest Структура ADI_FSS_LBA_REQUEST для связанного буфера. Подробнее см. ниже описание этой структуры.
pBlock Используется в файловом кеше FSS. Это значение не должно изменяться драйвером PID. Для внутренних передач драйвера PID это должно быть установлено в NULL.
LastinProcessFlag
pFileDesc
FSDCallbackFunction Это поле зарезервировано для использования драйверами FSD. Для внутренних передач данных PID должно быть установлено в NULL.
FSDCallbackHandle
PIDCallbackFunction Драйвер PID назначает адрес callback-функции, которая запускается при событиях завершения перемещения данных.
PIDCallbackHandle
Драйвер PID назначает адрес подходящей структуры для передачи как первый аргумент в вызов функции, определенной полем PIDCallbackFunction.

ADI_FSS_LBA_REQUEST. Эта структура используется для передачи запроса на количество секторов для чтения с установленного носителя данных (представляет запрос LBA). Адрес экземпляра этой структуры должен быть послан драйверу SDH PID командой ADI_PID_CMD_SEND_LBA_REQUEST. Структура ADI_FSS_LBA_REQUEST определена в заголовочном файле 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 Номер устройства в цепочке устройств. Драйвер SDH PID игнорирует это значение.
ReadFlag Флаг, показывающий, является ли перемещение данных операцией чтения. Если это так, то здесь должно быть значение 1. Операция записи требует значения 0.
pBuffer Адрес, связанный с подбуфером ADI_FSS_SUPER_BUFFER.

Использование драйвером структуры ADI_DEV_1D_BUFFER. Драйвером SDH PID может использоваться только структура буфера типа ADI_DEV_1D_BUFFER. Подробное описание определения этой структуры см. в руководстве по системным службам (библиотека System Services, SSL) и драйверу устройства (библиотека Device Driver, DDL).

Data Адрес буфера для заполнения (при чтении)/опустошения (при записи). Подразумевается, что объем буфера ElementCount*ElementWidth.
ElementCount Количество слов данных для передачи.
ElementWidth Размер в байтах каждого слова данных. Это значение должно быть то же самое, что и значение в ответе на команду ADI_FSS_CMD_GET_DATA_ELEMENT_WIDTH.
CallbackParameter Адрес внешней структуры ADI_DEV_1D_BUFFER. Он должен быть передан как третий аргумент в вызове callback-функции Device Manager при завершении передачи данных.
pAdditionalInfo Не используется.
ProcessedElementCount Это поле будет заполнено количеством элементов, которое было передано из устройства SDH / в устройство SDH. Если передача данных ненормально оборвалась, то обработчик прерывания SDH PID оповестит приложение об ошибке установкой этого поля в 0.
ProcessedFlag Не используется.

Использование структуры ADI_FSS_SUPER_BUFFER. Хотя вызовы adi_dev_Read/adi_dev_Write передают адрес структуры ADI_DEV_BUFFER, в пределах фреймворка FSS этот адрес в действительности указывает сразу и на адрес структуры ADI_DEV_BUFFER, и на адрес структуры ADI_FSS_SUPER_BUFFER одновременно. Так происходит потому, что в структуру ADI_FSS_SUPER_BUFFER как первое поле входит структура ADI_DEV_BUFFER, и в структуре супербуфера ADI_FSS_SUPER_BUFFER содержится другая важная информация, требуемая для обмена с другими компонентами фреймворка FSS. Структура супербуфера содержит следующие поля данных:

Buffer Структура ADI_DEV_BUFFER, требуемая для передачи. Обратите внимание, что это не поле указателя, и SDH PID поддерживает буферы только типа ADI_DEV_1D_BUFFER.
pBlock Используется в файловом кеше FSS.
LastinProcessFlag Используется в файловом кеше FSS.
LBARequest Структура ADI_FSS_LBA_REQUEST для связанного буфера. Если буфер формирует часть цепочки, и значение SectorCount равно 0, то запрос LBA предыдущего подбуфера также относится к данным и этого буфера.
SemaphoreHandle Хендл семафора, который должен быть опубликован (освобожден) при завершении передачи данных.
pFileDesc Используется в файловом кеше FSS.
FSDCallbackFunction Устанавливаются драйвером FSD.
FSDCallbackHandle Устанавливаются драйвером FSD.
PIDCallbackFunction Адрес функции типа ADI_DCB_CALLBACK_FN, которая должна быть вызвана FSS при получении событий ADI_DEV_EVENT_BUFFER_PROCESSED и ADI_PID_EVENT_DEVICE_INTERRUPT.
PIDCallbackHandle Адрес экземпляра драйвера устройства SDH PID.

[Инициализация]

Работа драйвера совместно с FSS. Служба файловой системы File System Service (FSS) автоматически откроет и сконфигурирует драйвер SDH PID вызовом его функций adi_dev_Open() и adi_dev_Control() в соответствии с записью в связанном списке устройств (Devices Linked list, одна из особенностей библиотек ADI).

Чтобы использовать SDH PID совместно с FSS, определите структуру ADI_FSS_DEVICE_DEF (как было описано выше в разделе "Структуры данных"). Обратите внимание, что может использоваться структура по умолчанию, которая будет определена, если будет определен макрос _ADI_SDH_DEFAULT_DEF_ перед подключением заголовочного файла драйвера, в этом случае структура ADI_FSS_DEVICE_DEF получит имя ADI_SDH_Def.

Имейте в виду, что FSS попытается применить букву по умолчанию точки монтирования для этого устройства, и сохранять её при смене носителей данных. Если буква диска по умолчанию не требуется, то это значение может быть установлено в NULL. Если запрошенная буква недоступна на любой стадии функционирования, то FSS назначит следующую доступную букву диска, начиная с буквы "C". В определении по умолчанию ADI_SDH_Def не указана буква диска по умолчанию.

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

{ ADI_FSS_CMD_ADD_DRIVER, (void*)&ADI_SDH_Def },

Как только SDH PID был открыт и сконфигурирован, запрашивает активацию носителя данных следующей парой команда-значение:

{ ADI_PID_CMD_MEDIA_ACTIVATE, (void *)TRUE },

При получении этой команды SDH PID инициализирует регистры SDH и вернет ADI_FSS_RESULT_SUCCESS, если инициализация была успешна, или в противном случае вернет ADI_FSS_RESULT_FAILED. На этой стадии SDH PID автоматически инициализирует поток данных с менеджером устройств (Device Manager) через следующую пару команда-значение:

{ ADI_DEV_CMD_SET_DATAFLOW, (void*)TRUE },

Начиная с этого момента контроллер DMA будет отвечать на запросы от устройства хранения данных (mass storage device), когда это необходимо. Как только SDH PID был активизирован, он будет опрошен на предмет определения наличия носителя данных в слоте карты SD. Перед тем, как сделать это, FSS передает адрес своей callback-функции в драйвер SDH PID следующей парой команда-значение:

{ ADI_PID_CMD_SET_DIRECT_CALLBACK, (void *)< callback-функция FSS > },

Эта callback-функция будет вызвана при детектировании установки носителя данных / его извлечения, и также при детектировании подходящих разделов или томов на носителе.

Чтобы опросить наличие носителя данных FSS посылает следующую пару команда-значение драйверу SDH PID:

{ ADI_PID_CMD_POLL_MEDIA_CHANGE, (void*)NULL },

Если был детектирован допустимый носитель данных, то драйвер SDH PID выдаст событие в callback-функцию FSS, которая была определена, как описано выше. Это немедленный вызов (live callback), и он выполняется со следующими аргументами:

1. Аргумент с адресом DeviceHandle, который был предоставлен как третий аргумент в вызове функции adi_pdd_Open() драйвера SDH PID.
2. Событие ADI_FSS_EVENT_MEDIA_INSERTED.
3. Адрес переменной типа u32. SDH PID устанавливает значение переменной в 0 (индицируя Device Number). При возврате из этого callback указанная переменная будет установлена в подходящий код результата: либо ADI_FSS_RESULT_FAILED, либо ADI_FSS_RESULT_SUCCESS. Последнее значение показывает, что FSS корректно поддерживает детектированный носитель данных.

Если драйвер SDH PID детектирует извлечение носителя, то он выдает событие ADI_FSS_EVENT_MEDIA_REMOVED в callback-функцию DMcallback (это callback Менеджера Устройств). Аргументы вызова следующие:

1. Аргумент с адресом DeviceHandle, который был предоставлен как третий аргумент в вызове функции adi_pdd_Open() драйвера SDH PID.
2. Событие ADI_FSS_EVENT_MEDIA_REMOVED.
3. Адрес переменной типа u32. Драйвер SDH PID устанавливает эту переменную в 0 (индицируя Device Number).

В ответ на установку носителя FSS будет инструктировать PID детектировать рабочие тома/разделы следующей парой команда-значение:

{ ADI_PID_CMD_DETECT_VOLUMES, (void*)< device-number > },

SDH PID не принимает во внимание переданный device-number, и подразумевает здесь 0.

При детектировании допустимого тома PID выдает другое событие ADI_FSS_EVENT_VOLUME_DETECTED в callback-функцию FSS. Аргументы вызова следующие:

1. Аргумент с адресом DeviceHandle, который был предоставлен как третий аргумент в вызове функции adi_pdd_Open() драйвера SDH PID.
2. Событие ADI_FSS_EVENT_VOLUME_DETECTED.
3. Адрес структуры ADI_FSS_VOLUME_DEF, определяющей том. Подробнее об этой структуре см. описание в разделе "Структуры данных".

Самостоятельная работа драйвера. В тех случаях, когда SDH PID используется напрямую (без FSS), например когда требуется создать на носителе разделы, или в случаях, когда встраиваемое приложение это периферийное устройство USB флешки (здесь поддержка файловой системы предоставляется хостом PC), может потребоваться инициализировать PID отдельно от контекста FSS. В этой секции как раз описывается, что для этого нужно.

Структура определения драйвера ADI_SDH_Def предоставляет основные требуемые данных для вызова adi_dev_Open(), чтобы открыть драйвер устройства SDH PID:

Result = adi_dev_Open (< DeviceManagerHandle >,
                       ADI_SDH_Def.pEntryPoint,
                       ADI_SDH_Def.DeviceNumber,
                       &ADI_SDH_Def.DeviceHandle,
                       &ADI_SDH_Def.DeviceHandle,
                       ADI_SDH_Def.Direction,
                       < DMAManagerHandle >,
                       < DCBQueueHandle >,
                       < Callback-function >);

В этом вызове нужно предоставить и другие аргументы. Аргументы < DeviceManagerHandle > и < DMAManagerHandle > обычно бывают получены при инициализации системных служб и Менеджера Устройств [4]. Аргумент < DCBQueueHandle > это хендл к очереди DCB (так называемый Менеджер DCB [5]), callback-вызовы < Callback-function > из драйвера SDH PID должны быть отложены в контекст основного выполнения кода (callback не будет вызываться немедленно в прерывании).

Далее PID нужно сконфигурировать требуемыми настройками (см. ниже "Дополнительные необходимые настройки конфигурации"), или например могут быть изменены настройки по умолчанию (см. ниже "Настройки по умолчанию").

< Callback-function > передается в вызов adi_dev_Open() не из PDD-секции драйвера устройства, и из часть менеджера устройств драйвера устройства. Если используется очередь откладывания вызовов callback-функций и был указан хендл Менеджера DCB < DCBQueueHandle >, то этот вызов будет осуществляться с откладыванием запуска (запуск не в прерывании). Однако процедура детектирования носителя требует немедленного вызова (live-callback) либо в ту же самую callback-функцию (как в случае, когда инициализация осуществлялась во фреймворке FSS), либо в отдельную функцию. В любом случае callback-функция должна быть зарегистрирована с драйвером SDH PID командой ADI_PID_CMD_SET_DIRECT_CALLBACK, как это было показано выше.

Callback-функция (или функции) должна обрабатывать следующие события. Во всех этих событиях первым аргументом в вызове callback-функции будет адрес места размещения хендла устройства драйвера SDH PID (т. е. DeviceHandle), у которого будет то же значение, которое было получено при вызове adi_dev_Open(), по имени это будет &ADH_SDH_Def.DeviceHandle; аргумент Event будет одним из следующих значений, и третий аргумент будет интерпретирован соответствующим образом, как это описано ниже.

ADI_FSS_EVENT_MEDIA_INSERTED. Третий аргумент это адрес ячейки (тип u32*), содержащего номер того устройства (device number), на котором был детектирован носитель. При возврате эта ячейка должна содержать код возврата, показывающий успешность вызова callback.

ADI_FSS_EVENT_MEDIA_REMOVED. Для этого события третий аргумент не имеет значения. Ответное действие в callback-функции будет зависеть от назначения приложения.

ADI_FSS_EVENT_VOLUME_DETECTED. Третий аргумент это адрес структуры ADI_FSS_VOLUME_DEF, определяющей детектированный том. Определение этой структуры и назначение её полей см. в разделе "Структуры данных". Ответное действие в callback-функции будет зависеть от назначения приложения.

ADI_DEV_EVENT_BUFFER_PROCESSED. Это событие завершения перемещения данных в контексте периферийного DMA. Третий аргумент pArg в этом случае содержит поле CallbackParameter структуры ADI_DEV_1D_BUFFER, переданной в соответствующий вызов adi_dev_Read() или adi_dev_Write(). Это значение должно быть адресом внешней структуры ADI_FSS_SUPER_BUFFER. В этом событии callback-функция должна вызвать SDH PID через его callback-функцию, идентифицированную полем PIDCallbackFunction структуры ADI_FSS_SUPER_BUFFER. Первый аргумент в этом вызове должен быть установлен в поле PIDCallbackHandle структуры ADI_FSS_SUPER_BUFFER, аргументы Event и pArg должны быть просто переданы как есть:

(pSuperBuffer->PIDCallbackFunction) (pSuperBuffer->PIDCallbackHandle,
                                     Event,
                                     pArg);

Дальнейшее действие может потребоваться в зависимости от приложения. Например, поле pNext буфера не равно 0, и значение SectorCount запроса LBA следующего супербуфера не 0, тогда могут потребоваться действия для постановки в очередь следующего запроса LBA с драйвером PID, как это происходит в случае работы драйвера в фреймворке FSS. Подробнее см. раздел "Передача данных".

ADI_PID_EVENT_DEVICE_INTERRUPT. Это событие завершения данных в контексте самого устройства. Оно обрабатывается идентично обработке события ADI_DEV_EVENT_BUFFER_PROCESSED.

Настройки по умолчанию. Таблица 4 описывает конфигурационные настройки по умолчанию для драйвера SDH PID. Если настройки по умолчанию не подходят для имеющейся системы, то приложение должно поменять их командами, либо перечисленными в таблице, либо выдаваемыми по отдельности, через вызов функции adi_dev_Control, чтобы настроить драйвер соответствующим образом. Любые настройки, не перечисленные в таблице 4, не определены.

Таблица 4. Настройки SDH PID по умолчанию.

Настройка Значение по умолчанию Возможные значения Command ID
Индекс кучи для кеша -1 0, 1, 2, ... (индекс кучи, которая будет использоваться для выделения памяти под буферы передач данных). ADI_FSS_CMD_SET_CACHE_HEAP_ID
Поддерживаемые рабочие условия (питание карты SD) 0x00FF8000 Зависят от используемой аппаратуры. ADI_SDH_CMD_SET_SUPPORTED_CARD_OPERATING_CONDITION
Состояние механических контактов блокировки карты FALSE (карта не защищена от записи) TRUE/FALSE ADI_SDH_CMD_SET_CARD_LOCK_ENABLED
Разрешить режим широкой шины (4 бита) TRUE TRUE/FALSE ADI_SDH_CMD_ENABLE_WIDEBUS

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

Таблица 5. Дополнительные требуемые настройки.

Настройка Возможные значения Command ID
Метод потока данных Только ADI_DEV_MODE_CHAINED. ADI_DEV_CMD_SET_DATAFLOW_METHOD
FSS Callback Адрес callback-функции FSS. ADI_PID_CMD_SET_DIRECT_CALLBACK
Ширина элемента данных См. врезку "Общие команды для драйверов PID". ADI_FSS_CMD_GET_DATA_ELEMENT_WIDTH
Поддержка фоновой передачи данных. См. врезку "Общие команды для драйверов PID". ADI_FSS_CMD_GET_BACKGRND_XFER_SUPPORT

[Передача данных]

В описываемой процедуре перемещения данных важно отличать друг от друга события устройства (инициированные физическим mass storage device) и события хоста (инициированным программно). В контексте SDH передача данных активна от получения команды запроса для перемещения нужного количества секторов до завершения этого перемещения. Мы будем называть это как блок DRQ. Другими словами, хост считает событием завершения передачи данных момент, когда он примет вызов callback по завершению обработки каждого буфера ADI_DEV_1D_BUFFER.

Когда цепочка таких буферов определит непрерывную порцию данных на носителе, и один запрос LBA был отправлен к драйверу SDH PID, чтобы покрыть цепочку или часть её будет осуществлено несколько событий завершения передач хоста на одно событие завершения передачи устройства, или блок DRQ. Необходимо для драйвера SDH PID заблокировать к себе доступ на время выполнения этого блока DRQ. Это достигается путем поддерживающего семафора блокировки (Lock Semaphore), который является двоичным, с начальным значением 1, и который используется с помощью функций службы семафоров(Semaphore Service).

Освобождение этого семафора будет ожидаться при получении команды ADI_FSS_CMD_ACQUIRE_LOCK_SEMAPHORE:

adi_sem_Pend ( pDevice->LockSemaphoreHandle, ADI_SEM_TIMEOUT_FOREVER);

и освобождаться этот семафор будет при получении команды ADI_FSS_CMD_RELEASE_LOCK_SEMAPHORE:

adi_sem_Post (pDevice->LockSemaphoreHandle);

Процесс выдачи этого запроса (что обычно осуществляется драйвером файловой системы FSD [6]) выполняется следующим образом:

1. Lock Semaphore захватывается в SDH PID выдачей ему пары команда-значение:

{ ADI_FSS_CMD_ACQUIRE_LOCK_SEMAPHORE, NULL },

2. Для драйвера SDH PID предоставляется запрос LBA для первого буфера в цепочке выдачей пары команда-значение, например:

{ ADI_PID_CMD_SEND_LBA_REQUEST, (void*)&pSuperBuffer->LBARequest },

Драйвер SDH PID назначает поля PIDCallbackFunction и PIDCallbackHandle структуры супербуфера ADI_FSS_SUPER_BUFFER, на которую указывает поле pBuffer структуры запроса LBA, и сохраняет копию структуры запроса LBA в данных своего экземпляра.

3. Затем FSD предоставляет цепочку буферов для SDH PID вызовом adi_dev_Read() или adi_dev_Write(), например:

adi_dev_Read{ ..., ADI_DEV_1D, (ADI_DEV_BUFFER*)pSuperBuffer },

4. Поток данных разрешается отправкой следующей командой драйверу SDH PID:

{ ADI_PID_CMD_ENABLE_DATAFLOW, (void*)TRUE},

Lock Semaphore, захваченный на шаге 1, будет освобожден драйвером FSD либо по завершению блока DRQ для одного буфера (если нет цепочки буферов), или по завершению блока DRQ на последнем подбуфере цепочки.

На событии завершения передачи хоста для драйвера SDH PID будет выдано событие ADI_DEV_EVENT_BUFFER_PROCESSED через часть Менеджера Устройств драйвера. По завершении каждого юнита DRQ драйвер SDH PID выдает событие ADI_PID_EVENT_DEVICE_INTERRUPT. Эти вызовы callback-функций должны быть сделаны через Device Manger со следующими аргументами:

1. Аргумент DeviceHandle, предоставленный как третий аргумент, переданный в adi_pdd_Open() драйвера SDH PID.
2. Соответствующий код события.
3. Адрес pBuffer в структуре запроса LBA, который был сохранен на шаге 2 вышеописанного процесса.

В ответ на эти события FSS сделает вызов в драйвер SDH PID, используя поля PIDCallbackFunction и PIDCallbackHandle структуры ADI_FSS_SUPER_BUFFER:

(pSuperBuffer->PIDCallbackFunction) (pSuperBuffer->PIDCallbackHandle,
                                     Event,
                                     pArg);

В этой функции SDH PID проверит статус завершения передачи. Если передача данных для блока DRQ была неудачной, то ProcessedElementCount буфера, соответствующего блоку DRQ, будет установлен в 0. Кроме того, в ответе на событие ADI_PID_EVENT_DEVICE_INTERRUPT драйвер SDH PID освободит свой Lock Semaphore, и опубликует его только если SemaphoreHandle в ADI_FSS_SUPER_BUFFER равен хендлу семафора SDH PID.

[Ссылки]

1. adi_sdh.pdf - SECURE DIGITAL HOST (ADI_SDH) PHYSICAL INTERFACE DRIVER site:analog.com.
2. Служба файловой системы Blackfin.
3. VisualDSP: работа с динамически выделяемой памятью.
4. VDK: менеджер драйверов устройств.
5. VDK: менеджер отложенных функций обратного вызова.
6. Драйвер FSD для FAT от компании Analog Devices.
7. Драйвер интерфейса (PID) для службы файловой системы (FSS).

 

Добавить комментарий


Защитный код
Обновить

Top of Page