Служба файловой системы Blackfin Печать
Добавил(а) microsin   

В этой статье приведен перевод документации по службе файловой системы (file system service, FSS) библиотек Analog Devices для процессора Blackfin [1].

FSS предоставляет доступ к устройствам хранения данных. При этом обеспечивается портируемость и возможность расширения при переходе от одной системе к другой, и при смене модели процессора Blackfin. FSS разработана таким образом, чтобы максимально облегчить поддержку файловых систем, таких как FAT (обычно FAT используется на извлекаемых носителях данных наподобие карт SD и флешек USB) и физических интерфейсов (таких как ATA/ATAPI на семействе процессоров ADSP-BF54x), так что эти возможности добавляются к приложениями с минимальными усилиями. Вместе с VisualDSP++ 5.0 предоставляется поддержка платы разработчика ADSP-BF548 EZ-KIT Lite для файловых систем FAT на хост-интерфейсах secure digital, чтобы можно было подключить жесткий диск, карту SD и флешку USB. Ниже показана общая архитектура библиотек Analog Devices (ADI), обеспечивающих работу службы файловой системы.

ADI FSS architecture

Примечание: на картинке выглядит все хорошо, однако внутри все устроено далеко не так красиво и просто. Разработчики библиотек ADI постарались сделать их универсальными (т. е. чтобы они работали на всех процессорах Analog Devices), поэтому пришлось широко использовать библиотеку так называемых стандартных служб (Analog Devices System Services Library, ADI SSL), подсистему динамического выделения памяти и т. д. В результате система получилась весьма требовательной к размеру кода и к размеру потребляемой памяти, поэтому на младших моделях процессоров и без подключения SDRAM использовать ADI FSS будет затруднительным. Стоит добавить, что примеров кода для библиотеки FSS очень мало, список готовых модулей для разных поддерживаемых носителей беден, и в Интернете Вы найдете мало примеров использования библиотеки FSS. Поэтому многие разработчики предпочитают более простые и облегченные решения для доступа к файловой системе - старые добрые EFSL и FatFS.

Приложение взаимодействует с этими драйверами через фреймворк и API службы файловой системы, известной как file system service (FSS). Когда служба FSS инициализирована, приложение может делать прямые вызовы функций API службы FSS (см. раздел "Справочник по API-функциям службы FSS"), или если такая возможность зарегистрирована, можно использовать расширенный стандартный интерфейс ввода/вывода языка C (extensible standard C I/O interface), предоставленный в библиотеке ввода/вывода (I/O library) системы разработки VisualDSP++ 5.0. Когда I/O library зарегистрирована, вызовы fopen(), fread(), и так далее перенаправляются к FSS для прямого обращения к файлам на хранилище данных. С таким методом приложения используют стандартный интерфейс ввода/вывода языка C, что облегчает портирование готового кода при использовании службы файловой системы. В дополнение к этим функциям, предоставляется поддержка для определенных функций POSIX, таких как opendir(), rename(), remove(), и так далее. Описание этих функций доступно в разделе "Дополнительные функции POSIX, поддерживаемые FSS".

Хотя FSS API предоставляет поддержку для расширения декларации имен файлов и директорий для использования спецификации Unicode UTF-8 (кодировка 16 бит), текущая реализация FSS обслуживается только имена файлов ASCII (кодировка 8 бит).

Доступ к каждому из типу носителя данных в приложении предоставляется регистрацией для FSS драйвера устройства, так называемого драйвера физического интерфейса (physical interface driver, PID). Каждый носитель форматируется для определенной файловой системы (например, файловая система Microsoft® FAT), и интерпретация этих файловых систем осуществляется регистрацией драйвера устройства другого типа, так называемого драйвера файловой системы (file system driver, FSD) [10, 11].

Пользователи, которые хотели бы предоставить дополнительные FSD и PID, или их замену для поддержки какой-то определенной файловой системы или физического интерфейса, могут это осуществить, просто следуя правилам дизайна соответствующего класса драйвера устройства, и регистрацией этого драйвера для FSS в момент инициализации приложения. Подробнее см. раздел "Расширяемость".

FSS разработана с учетом применения как в обычном приложении, так и в рабочем окружении RTOS. Вместе с VisualDSP++ 5.0 предоставляется несколько примеров конфигурирования и использования FSS. В одном из примеров (shell browser) реализована многопоточная среда выполнения с простым командным интерфейсом через эмулятор терминала, подключенный к интерфейсу UART платы разработчика ADSP-BF548 EZ-KIT Lite. Подробности см. в описании примеров, раздел "Примеры".

[FSS: быстрый старт]

В этой секции приведены базовые принципы инициализации и использования в приложении службы файловой системы. Подразумевается, что уже были инициализированы Системные Службы (system services) [2] и Менеджер Устройств (device manager) [3]. Зависимости от ресурсов системных служб подробно описаны в разделе "Требования к системным службам". Здесь описано общее функционирование FSS, более подробно см. описание функций интерфейса программирования (API) в последних разделах статьи.

Инициализация. FSS создана на основе модели Драйвера Устройств (device driver), поэтому требует использования как Менеджера Устройств, так и Системных Служб [2, 3]. Таким образом, для приложения необходимо сконфигурировать Системные Службы и Менеджер Устройств перед инициализацией FSS. Разработчик приложения может обратиться к соответствующей документации для каждого из необходимых драйверов FSD (драйвер файловой системы) и PID (драйвер физического интерфейса), чтобы определить, какие дополнительные ресурсы и службы могут потребоваться.

FSS конфигурируется для использования путем регистрации требуемых драйверов FSD и PID, вместе с предоставлением указателей (handle) на Менеджер Устройств и Менеджер DMA [4], и предоставлением указателя на очередь отложенных функций обратного вызова (deferred callback queue). Это реализовано передачей в API-функцию инициализации adi_fss_Init() специальной таблицы пар команда-значение. Вот пример такой простейшей таблицы:

ADI_FSS_CMD_VALUE_PAIR adi_fss_Config[] =
{
   /* Регистрация драйвера интерфейса ATA/ATAPI */
   { ADI_FSS_CMD_ADD_DRIVER, (void*)&ADI_ATAPI_Def },
   /* Регистрация драйвера FSD для файловой системы FAT */
   { ADI_FSS_CMD_ADD_DRIVER, (void*)&ADI_FAT_Def },
   /* Предоставление DMA Manager Handle */
   { ADI_FSS_CMD_SET_DMA_MGR_HANDLE, (void*)adi_dma_ManagerHandle },
   /* Предоставление Device Manager Handle */
   { ADI_FSS_CMD_SET_DEV_MGR_HANDLE, (void*)adi_dev_ManagerHandle },
   /* Предоставление DCB Queue Handle */
   { ADI_FSS_CMD_SET_DCB_MGR_HANDLE, (void*)adi_dcb_QueueHandle },
   /* Маркер конца таблицы команд */
   { ADI_FSS_CMD_END, (void*)NULL }
};

Адрес этой таблицы просто передается API-функции adi_fss_Init() следующим образом:

Result = adi_fss_Init( adi_fss_Config );

В приведенной выше таблице команда-значение задана конфигурация для доступа FSS к жесткому диску, подключенному к интерфейсу ATA/ATAPI процессора ADSP-BF54x. Определение структур ADI_ATAPI_Def и ADI_FAT_Def могут быть приведены либо в самом приложении, либо взяты из заголовочных файлов драйвера устройства. Чтобы использовать последнее, перед оператором #include должен быть определен макрос. Ниже показан самый быстрый способ применить таблицу команда-значение:

/* FSD-драйвер FAT12/16/32 */
#define _ADI_FAT_DEFAULT_DEF_
#include < drivers/fsd/fat/adi_fat.h >
 
/* Интерфейс ATAPI */
#define _ADI_ATAPI_DEFAULT_DEF_
#include < drivers/pid/atapi/adi_atapi.h >

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

   { ADI_FSS_CMD_ADD_DRIVER, (void*)&< Device-Def-Structure > },

Обратите внимание, что если приложение одновременно использует два или большее количество медиа-носителей данных, который используют один и тот же драйвер FSD, то в таблице команд конфигурации FSS должна быть только одна запись ADI_FSS_CMD_ADD_DRIVER для соответствующего драйвера FSD. Например, ADSP-BF548 EZ-KIT Lite поддерживает носители данных на жестком диске, карте SD и флешке USB, и все они могут использовать один и тот же драйвер FSD для файловой системы FAT.

Полный набор команд, который можно использовать для инициализации FSS можно найти во врезке с описанием функции adi_fss_Init.

Теперь служба FSS готова для использования через свои прямые вызовы API. Однако для достижения максимального удобства и портируемости приложений и библиотек лучше использовать FSS косвенно, через стандартный интерфейс ввода/вывода языка C. VisualDSP++ 5.0 предоставляет возможность расширить поддержку файлового ввода вывода по умолчанию (PRIMIO). Это достигается простым подключением хедера FSS:

#include < services/fss/adi_fss.h >

и регистрации требуемой структуры точки входа (тип DevEntry) с библиотекой ввода/вывода:

add_devtab_entry( &adi_fss_entry );

Определение структуры DevEntry можно найти в части 3 документации "VisualDSP++ 5.0 C/C++ Compiler and Library Manual for Blackfin Processors". Декларацию adi_fss_entry можно найти в файле adi_fss_deventry.c папки Blackfin\lib\src\services\fss каталога установки VisualDSP++ 5.0.

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

[Требования к системным службам]

Как было отмечено в разделе "FSS: быстрый старт", служба файловой системы зависит от соответствующей конфигурации Системных Служб и Менеджера Устройств. Для быстрого старта рекомендуется сделать копию файлов adi_ssl_init.c и adi_ssl_init.h, которые можно найти в примерах FSS, и использовать их как базовый код в Вашем собственном приложении. Например, просмотрите файлы примера в папке: Blackfin \ Examples \ ADSP-BF548 EZ-KIT Lite \ Services \ File System \ HardDisk \ HardDiskAccess.

Файл adi_ssl_init.c дает базовую последовательность вызовов инициализации каждой из Системных Служб и Менеджера Устройств, с предоставлением каждой службе необходимой памяти. Файл adi_ssl_init.h содержит определения для констант, относящихся к реализации FSS, и только в этом из этих двух файлов требуется сделать модификацию в зависимости от требований приложения. Вот эти настроечные макросы:

#define ADI_SSL_INT_NUM_SECONDARY_HANDLERS (2)
#define ADI_SSL_DCB_NUM_SERVERS            (1)
#define ADI_SSL_DMA_NUM_CHANNELS           (2)
#define ADI_SSL_FLAG_NUM_CALLBACKS         (0)
#define ADI_SSL_SEM_NUM_SEMAPHORES         (10)
#define ADI_SSL_DEV_NUM_DEVICES            (2)

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

Служба Менеджера Прерываний [5]. Менеджер Прерываний это один из модулей базовых служб, который поддерживает реализацию драйверов устройств, при этом физические драйверы интерфейса (PID) не являются исключением. С каждым PID связано определенное количество прерываний периферийного устройства. Например, драйвер ATAPI имеет 3 прерывания DMA и одно прерывание устройства. В зависимости от того, выбрали ли Вы уровни IVG по умолчанию для соответствующих прерываний, или назначили свои уровни, зависит, как много вторичных прерываний потребуется приложению. Все драйверы устройств подцепляют обработчики прерываний к уровню IVG, как это идентифицировано в регистрах SIC_IARx. Вы можете счесть полезным явно установить требуемые приоритеты серией вызовов API-функции adi_int_SICSetIVG() для всех периферийных устройств в Вашем приложении. Например, чтобы установить приоритеты ATAPI, Вы должны сделать следующее:

adi_int_SICSetIVG(ADI_INT_DMA10_ATAPI_RX, 10);
adi_int_SICSetIVG(ADI_INT_DMA11_ATAPI_TX, 11);
adi_int_SICSetIVG(ADI_INT_ATAPI_ERROR, 7);
adi_int_SICSetIVG(ADI_INT_DMA_ERROR, 7);

С таким методом настройки Вы сможете ясно увидеть, какие уровни IVG используются несколькими периферийными устройствами. Тогда Вы можете определить количество используемых вторичных обработчиков (ADI_SSL_INT_NUM_SECONDARY_HANDLERS).

См. документацию для драйвера устройства по каждому PID, требуемому для приложения, чтобы узнать подробности по соответствующим требуемым прерываниям. Эта документация находится в папке Blackfin\Docs\drivers\pid каталога установки VisualDSP++ 5.0.

Служба отложенных функций обратного вызова (Deferred Callback Service) [6]. Служба FSS лучше всего работает с использованием отложенных вызовов функций событий (deferred callbacks). Для работы в приложении VDK особенно важно использовать отложенные вызовы callback. Хотя в приложении можно использовать несколько серверов отложенных callback, рекомендуется использовать один сервер, и сконфигурировать его на уровень IVG 14. Фактически для использования в среде приложения VDK разрешено использовать только один сервер, и этот сервер использует очередь отложенных процедур (Deferred Procedure Queue) VDK, которая выполняется на уровне ядра (IVG 14).

Таким образом, рекомендуется установить макрос ADI_SSL_DCB_NUM_SERVERS в значение 1.

В дополнение к коду файла adi_ssl_init.c нужен следующий код для открытия сервера очереди:

adi_dcb_Open (14, DCBMgrQueue1, SIZE_DCB_QUEUE, &ResponseCount, &adi_dcb_QueueHandle);

Здесь DCBMgrQueue1 это адрес блока памяти размером как минимум SIZE_DCB_QUEUE. Этот код взят из файла InitServices.c примера HardDiskAccess. Размер очереди зависит от Ваших требований, но хорошей стартовой точкой будет использование 4 записей в очереди:

#define SIZE_DCB_QUEUE ((ADI_DCB_ENTRY_SIZE)*4)

Служба DMA [4]. Менеджер DMA используется службой FSS для передачи данных между приложением и физическим носителем данных, где это необходимо, как это определено внутренним устройством каждого PID в приложении. Использование DMA и его задействованных каналов подробно описано в соответствующей документации на драйвер устройства PID. Значение, которое дается ADI_SSL_DMA_NUM_CHANNELS, должно быть инкрементировано на количество каналов, требуемое для каждого PID.

Требования к DMA для каждого физического драйвера устройства подробно описаны в документации на соответствующий драйвер. Например, драйвер ATAPI требует, чтобы Менеджер DMA был инициализирован с двумя каналами; SD PID требует один канал; и драйвер хоста USB не требует каналов DMA.

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

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

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

Значение, заданное в макросе ADI_SSL_SEM_NUM_SEMAPHORES, должно быть инкрементировано на количество семафоров, требуемое для заданной конфигурации FSS.

Когда FSS используется в среде приложения VDK, это значение игнорируется службой семафоров; однако Вам нужно назначить подходящее значение для максимального количества активных семафоров на закладке Kernel настроек приложения VDK.

Служба часов реального времени. Имеется зависимость от службы часов (real-time clock, RTC) в том случае, если драйвер FSD, подключенный в приложении, использует RTC для предоставления данных времени и даты, когда они используются для создания новых файловых объектов или при модификации файлов. Это случай использования драйвера FSD для файловой системы FAT, который поставляется вместе с VisualDSP++5.0.

Инициализация службы реального времени, и как установить текущую дату и время, подробно описано в части 11 "Real-Time Clock Service" руководства [1].

Менеджер Устройств (Device Manager). Каждый PID и FSD, зарегистрированный в приложении, представляет как минимум один драйвер устройства; некоторые драйверы PID, такие как USB mass storage class driver, могут потребовать двух или большего количества драйверов. Дополнительно используются несколько экземпляров FSD, представляющих отдельные драйверы устройств.

Значение, предоставленное в макросе ADI_SSL_DEV_NUM_DEVICES, должно быть инкрементировано на количество экземпляров PID и FSD для требуемой конфигурации FSS. Подробнее см. соответствующую документацию драйвера устройства в папках Blackfin \ Docs \ drivers \ fsd и Blackfin \ Docs \ drivers \ pid.

[Расширенная конфигурация]

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

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

Структуры определения устройства имеют тип ADI_FSS_DEVICE_DEF, который описан далее в разделе "Типы данных и перечисления для API службы FSS". Эта структура определена в хедере FSS <services/fss/adi_fss.h >.

Таблица команд это массив пар команда-значение (тип ADI_DEV_CMD_VALUE_PAIR), которые полезны для драйверов устройств, удовлетворяющих модели драйвера устройства Системных Служб.

Допустимые команды для таблицы конфигурации драйвера представлены в отдельных файлах документации драйвера, находящихся в соответствующем подкаталоге папок Blackfin \ Docs \ drivers \ fsd или Blackfin \Docs \ drivers \pid каталога установки VisualDSP++ 5.0. Например, так должен быть назначен индекс кучи для выделения буферов DMA (см. "Динамическое использование памяти"):

ADI_DEV_CMD_VALUE_PAIR ADI_FAT_ConfigTable [] =
{
   { ADI_FSS_CMD_SET_CACHE_HEAP_ID, (void*)2 },
   { ADI_DEV_CMD_END, NULL },
};

В дополнение к возможности настроить определение PID, можно зарегистрировать PID, который уже открыт и зарегистрирован. Эта возможность предоставлена главным образом для того, чтобы разрешить смену медиа-носителя данных между FSS и другими элементами приложения. Например, встроенную память NAND flash, жесткий диск или карту SD можно переставить между FSS и классом драйвера USB mass storage (device), чтобы разрешить доступ к встроенному носителю данных из компьютера PC или Mac.

Перед тем, как зарегистрировать PID, должно быть сделано следующее:

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

adi_dev_Open (adi_dev_ManagerHandle,
              ADI_ATAPI_Def.pEntryPoint,
              ADI_ATAPI_Def.DeviceNumber,
              < хендл клиента >,
              &ADI_ATAPI_Def.DeviceHandle,
              ADI_ATAPI_Def.Direction,
              adi_dma_ManagerHandle,
              adi_dcb_QueueHandle,
              < callback-функция клиента >);

Обратите внимание, что аргументы < хендл клиента > и < callback-функция клиента > имеют значение только перед регистрацией PID со службой FSS; эти элементы переназначаются внутри FSS. Если у них нет прямого отношения к самому приложению, то они могут быть присвоены в значения NULL и 1 соответственно.

• Назначен метод потока данных (Data Flow Method): метод потока данных PID должен быть установлен в ADI_DEV_MODE_CHAINED следующей парой команда-значение:

   { ADI_DEV_CMD_SET_DATAFLOW_METHOD, (void *)ADI_DEV_MODE_CHAINED }

• Конфигурирование: в дополнение к установке метода потока данных PID должен быть сконфигурирован как минимум командами, определенными в таблице команд, адрес которой задается полем pConfigTable соответствующей структуры определения устройства.

Регистрация PID может быть осуществлена либо передачей следующей пары команда значение в функцию adi_fss_Control:

   { ADI_FSS_CMD_REGISTER_DEVICE, (void *)&ADI_ATAPI_Def }

либо использованием функции adi_fss_RegisterDevice:

adi_fss_RegisterDevice(&ADI_ATAPI_Def,1);

Подробности см. во врезке с описанием этой функции, раздел "Справочник по API-функциям службы FSS".

[Динамическое использование памяти]

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

Однако, чтобы предоставить разработчику некоторое управление, все запросы на динамическое выделение памяти для FSS, компоненты файловой системы и физических драйверов устройств интерфейса выполняются через централизованные функции, которые затем делают вызовы библиотечных функций C, или могут быть направлены на вызов пользовательских функций с целью повышения эффективности или для мониторинга. Имеется 3 функции выделения из кучи для операций malloc, realloc и free, и все они должны быть заменены пользовательскими функциями, если заменяется любая из них. Для использования своих собственных функций убедитесь, что эти функции удовлетворяют следующим прототипам для каждой операции.

malloc:

void *< custom-heap_malloc-function > ( int, size_t );

realloc:

void *< custom-heap_realloc-function > ( int, void *, size_t );

free:

void < custom-heap_free-function > ( int, void * );

Они должны быть затем зарегистрированы для FSS использованием следующих пар команда-значение:

   { ADI_FSS_CMD_SET_MALLOC_FUNC, (void*)< custom-heap_malloc-function > },
   { ADI_FSS_CMD_SET_REALLOC_FUNC, (void*)< custom-heap_realloc-function > },
   { ADI_FSS_CMD_SET_FREE_FUNC, (void*)< custom-heap_free-function > },

Кроме того, выделение памяти делится на 2 категории по требованиям к памяти: общая память (GeneralHeapID) для структур данных, таких как данные экземпляра драйвера устройства и дескрипторы файлов и т. п., и память кэша (CacheHeapID), определенная как память, требуемая для буферов с типом кэша, таких как буферы передач DMA. Управление этими категориями памяти реализовано через использование дополнительных (или пользовательских) куч [7], доступных в VisualDSP++ 5.0. Каждый компонент фреймворка FSS выделяет общую память из единственной общей кучи, определенной в FSS. Для памяти кэша каждый компонент может назначить для использования отдельную кучу.

Определены 2 команды для назначения индексов общей кучи и куч кэша. Чтобы назначить индекс общей кучи, используйте следующую пару команда-значение в таблице команд конфигурации FSS, которая передается только функции adi_fss_Init():

   { ADI_FSS_CMD_SET_GENERAL_HEAP_ID, (void*)GeneralHeap },

Значение GeneralHeap это индекс массива в записи кучи в heap_table. Например, пример "Shell_Browser" назначает значение GeneralHeap в 1, что является индексом записи FSSGeneralHeap_space в следующей таблице. Обратите внимание, что это также значение userid в записи таблицы, которое совпадает с последовательностью имеющихся выше записей, автоматически сгенерированных мастером опций проекта. Это может быть не тот случай, когда кучи пользователя определяются через heap_install.

struct heap_table_t heap_table[4] =
{
   { &ldf_heap_space, (int) &ldf_heap_length, 0 },
   { &FSSGeneralHeap_space, (int) &FSSGeneralHeap_length, 1 },
   { &FSSCacheHeap_space, (int) &FSSCacheHeap_length, 2 },
   { 0, 0, 0 }
};

Этот индекс может быть также получен из вызова heap_lookup() для требуемого userid:

GeneralHeap = heap_lookup(1);

Чтобы назначить кучу кэша, используйте:

   { ADI_FSS_CMD_SET_CACHE_HEAP_ID, (void*)CacheHeap },

Эта пара команда-значение может быть добавлена в таблицу конфигурации каждого драйвера и функцию adi_fss_Init(). В последнем случае это используется для назначения индекса кучи для выделения буфера кэша для каждого файла. Подробнее см. раздел "Файловый кэш".

По умолчанию для всех куч кэша является по умолчанию общая куча, и общая куча по умолчанию привязана к системной куче. Это случай, показанный в разделе "FSS: быстрый старт". Имейте в виду, что в то время как совершенно допустимо использовать один и тот же индекс кучи кэша для каждого драйвера (FSD или PID), требуется зарегистрировать индекс кучи с каждым драйвером устройства через его таблицу конфигурации.

[Файловый кэш]

Служба FSS разработана с возможностью при необходимости использовать файловый кэш. Этот кэш, который был выделен из кучи кэша FSS (см. раздел "Динамическое использование памяти"), работает как кэш типа "read-ahead, write-behind", что повышает скорость передачи данных в обоих направлениях. Чтобы достичь самых высоких скоростей, блоки кэша передаются в носитель или из него в фоновом режиме, и его использование таким образом оптимально для тех драйверов физического интерфейса, которые имеют поддержку со стороны периферийного DMA. Решение использовать файловый кэш для файла принимается при открытии файла, когда соответствующий драйвер файловой системы и драйверы физического интерфейса опрашиваются, чтобы определить, может ли поддерживаться файловый кэш. Подробности см. в соответствующей документации на драйверы FSD и PID. Например, драйверы FAT и ATAPI для доступа к жесткому диску платы ADSP-BF548 EZ-KIT Lite поддерживают использование файлового кэша.

Каждый файловый кэш состоит из некоторого количества блоков, у каждого из которых размер равен самой маленькой адресуемой единице блока данных в пределах соответствующей файловой системы. Например, в файловой системе FAT самый малый размер блока равен размеру кластера. Размер кластера зависит от размера и формата (FAT12, FAT16 или FAT32) носителя данных. FSS запрашивает размер блока от соответствующего FSD при открытии файла. Количество блоков кэша для использования по умолчанию 4, но это можно переназначить при инициализации FSS с помощью добавления в таблицу конфигурации команды:

   { ADI_FSS_CMD_SET_NUMBER_CACHE_BLOCKS, (void*)< number-cache-blocks > },

Когда файл открывается, динамически выделяется файловый кэш из кучи кэша FSS; когда файл закрывается, эта память освобождается.

Обратите внимание, что формат по умолчанию для жесткого диска ADSP-BF548 EZ-KIT Lite подразумевает размер кластера - и соответственно каждого блока кэша - равным 16 килобайт.

[Справочник по API-функциям службы FSS]

В этом разделе подробно описаны структуры данных и API-функции FSS.

Чтобы избежать конфликтов с другими библиотеками, предоставленными компанией Analog Devices или другими источниками, служба FSS использует однозначную систему именования для значений перечисления (enum) и операторов определения типа (typedef) с префиксом ADI_FSS_. Соответственно функции и глобальные переменные получают аналогичный префикс в нижнем регистре: adi_fss_.

Каждая функция в API файловой системы возвращает код типа ADI_FSS_RESULT. Как и у других системных служб нулевой код возврата (ADI_FSS_RESULT_SUCCESS) показывает отсутствие ошибки при вызове функции. Любое не нулевое значение показывает определенный тип ошибки, которая произошла при вызове функции. Коды ошибки для FSS уникальны среди других системных служб, и определены в заголовке adi_fss.h, и описаны в разделе "Типы данных и перечисления для API службы FSS". Причину ошибки можно определить, найдя в описание ошибки по её коду.

u32 adi_fss_Init (ADI_FSS_CMD_VALUE_PAIR *pTable);

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

ADI_FSS_CMD_ADD_DRIVER (0xB0005) Указывает место размещения структуры ADI_FSS_DEVICE_DEF, определяющей либо драйвер файловой системы (file system driver, FSD), либо драйвер физического интерфейса (physical interface driver, PID). Эта команда обязательна только для драйверов FSD.
ADI_FSS_CMD_SET_DEV_MGR_HANDLE (0xB000E) Устанавливает хендл Менеджера Устройств.

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

ADI_FSS_CMD_SET_DMA_MGR_HANDLE (0xB000D) Устанавливает хендл Менеджера DMA. Это требуется только в том случае, если PID использует периферийный DMA.
ADI_FSS_CMD_SET_DCB_MGR_HANDLE (0xB000F) Устанавливает хендл Менеджера DCB (обслуживает очереди отложенных функций обратного вызова). Настоятельно рекомендуется использовать отложенные вызовы callback-ов в обычном приложении, и обязательно в VDK-приложении.
ADI_FSS_CMD_SET_CACHE_HEAP_ID (0xB0011) ID кучи для блоков кэша.
ADI_FSS_CMD_SET_GENERAL_HEAP_ID (0xB0014) ID кучи для дескрипторов файлов.
ADI_FSS_CMD_SET_NUMBER_CACHE_BLOCKS (0xB0012) Количество блоков кэша для использования (минимум 2).
ADI_FSS_CMD_SET_NUMBER_CACHE_SUB_BLOCKS (0xB0013) Количество субблоков кэша для использования (минимум 1). Настоятельно рекомендуется не менять это значение.
ADI_FSS_CMD_SET_MALLOC_FUNC (0xB0006) Устанавливает клиентскую функцию malloc.
ADI_FSS_CMD_SET_REALLOC_FUNC (0xB0007) Устанавливает клиентскую функцию realloc.
ADI_FSS_CMD_SET_FREE_FUNC (0xB0008) Устанавливает клиентскую функцию free.
ADI_FSS_CMD_SET_VOLUME_SEPARATOR (0xB0009) Устанавливает символ разделителя для тома файловых путей (volume separator).
ADI_FSS_CMD_SET_DIRECTORY_SEPARATOR (0xB000A) Устанавливает символ разделителя для директорий (directory separator).
ADI_FSS_CMD_SET_MEDIA_CHANGE_CALLBACK (0xB001B) Устанавливает callback-функцию ADI_DCB_CALLBACK_FN, которая вызывается, когда меняется носитель данных (media); например, когда флешка USB или карта SD устанавливается или извлекается.
ADI_FSS_CMD_SET_MEDIA_CHANGE_HANDLE (0xB001C) Устанавливает хендл, который отправляется как первый аргумент callback-функции, когда меняется носитель данных (media change).
ADI_FSS_CMD_SET_DATA_SEMAPHORE_TIMEOUT (0xB001D) Устанавливает аргумент таймаута для всех ожиданий на семафоре в контексте FSS. Это значение должно быть результатом логического ИЛИ в тиках значения таймаута и подходящего значения, чтобы предотвратить событие ошибки RTOS по таймауту.
ADI_FSS_CMD_SET_TRANSFER_RETRY_COUNT (0xB001E) Устанавливает количество раз повтора передачи после истечения таймаута. Это значение включает начальную попытку, так что значение 1 означает отсутствие повторных попыток после истечения таймаута. Это значение установлено по умолчанию.
ADI_FSS_CMD_REGISTER_DEVICE (0xB0019) Регистрирует драйвер физического интерфейса (PID) путем указания места нахождения соответствующей структуры ADI_FSS_DEVICE_DEF. Перед использованием этой команды должен быть сконфигурирован и открыт подходящий драйвер устройства.

Аргумент:

pTable Указатель на таблицу пар команда-значение, которые используются для инициализации модуля службы FSS.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_Terminate (void);

Функция adi_fss_Terminate() завершает работу службы файловой системы.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_Control (u32 CommandID, void *Value);

Функция adi_fss_Control() вызывается для отправки определенных команд модулю службы FSS, чтобы управлять её функционированием. Список допустимых кодов команд:

ADI_FSS_CMD_END (0xB0002) Конец таблицы пар команда-значение.
ADI_FSS_CMD_PAIR (0xB0003) Значение в команде это указатель на пару команды управления.
ADI_FSS_CMD_TABLE (0xB0004) Значение в команде это указатель на таблицу пар команд управления.
ADI_FSS_CMD_GET_NUMBER_VOLUMES (0xB000B) Получает количество доступных разделов (partition) диска.
ADI_FSS_CMD_GET_VOLUME_INFO (0xB000C) Получает информацию, относящуюся к доступным разделам диска.
ADI_FSS_CMD_FORMAT_VOLUME (0xB4017) Форматирует том (volume) диска.
ADI_FSS_CMD_REGISTER_DEVICE (0xB0019) Регистрирует драйвер физического интерфейса (PID) путем указания места расположения соответствующей структуры ADI_FSS_DEVICE_DEF. Перед использованием этой команды должен быть сконфигурирован и открыт соответствующий драйвер устройства.
ADI_FSS_CMD_DEREGISTER_DEVICE (0xB001A) Отменяет регистрацию хендла драйвера устройства физического интерфейса (PID).
ADI_FSS_CMD_SET_MEDIA_CHANGE_CALLBACK (0xB001B) Устанавливает callback-функцию ADI_DCB_CALLBACK_FN, которая будет вызвана при изменении состояния носителя данных (media change); например, когда флешка USB или карта SD устанавливается или извлекается.
ADI_FSS_CMD_SET_MEDIA_CHANGE_HANDLE (0xB001C) Устанавливает хендл, который отправляется как первый аргумент callback-функции при изменении состояния носителя данных (media change).
ADI_FSS_CMD_SET_DATA_SEMAPHORE_TIMEOUT (0xB001D) Устанавливает аргумент таймаута для всех ожиданий на семафоре в контексте FSS. Это значение должно быть результатом логического ИЛИ в тиках значения таймаута и подходящего значения, чтобы предотвратить событие ошибки RTOS по таймауту.
ADI_FSS_CMD_SET_TRANSFER_RETRY_COUNT (0xB001E) Устанавливает количество раз повтора передачи после истечения таймаута. Это значение включает начальную попытку, так что значение 1 означает отсутствие повторных попыток после истечения таймаута. Это значение установлено по умолчанию. После того, как все повторы потерпели неудачу, FSS сообщает приложению об ошибке.

Аргументы:

CommandID Идентификатор команды.
Value Указатель на значение, смысл которого зависит от идентификатора команды.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_RegisterDevice (ADI_FSS_DEVICE_DEF *pDeviceDef, u32 PollForMedia);

Функция adi_fss_RegisterDevice() вызывается для регистрации в службе FSS драйвера физического интерфейса (physical interface driver, PID). При регистрации PID активируется. Детектирование состояния носителя (media detection) может быть также выполнено в зависимости от значения аргумента PollForMedia.

Аргументы:

pDeviceDef Место расположения структуры определения устройства для требуемого драйвера физического интерфейса.
PollForMedia Флаг, который определяет, нужно ли опросить наличие носителя данных (media) после активации. Установка 1 означает опросить, иначе 0. Если опрос не выбран, то приложение должно явно опросить состояние носителя.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DeRegisterDevice (ADI_DEV_DEVICE_HANDLE DeviceHandle);

Функция adi_fss_DeRegisterDevice() вызывается для отмены регистрации драйвера физического интерфейса (physical interface driver, PID) в службе FSS. Все связанные тома демонтируются, и устройство деактивируется.

Аргумент:

DeviceHandle Хендл устройства драйвера физического интерфейса, у которого должна быть отменена регистрация для службы FSS.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_PollMediaOnDevice (ADI_DEV_DEVICE_HANDLE DeviceHandle);

Функция adi_fss_PollMediaOnDevice() вызывается для опроса состояния носителя данных (media), связанного с указанным хендлом устройства PID.

Аргумент:

DeviceHandle Хендл устройства требуемого драйвера физического интерфейса.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_PollMedia (void);

Функция adi_fss_PollMedia() вызывается для опроса устройств физического интерфейса (physical interface devices, PID) на предмет изменения состояния носителя данных (media change). Функция не принимает аргументов (влияет на все зарегистрированные интерфейсы).

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_Stat (ADI_FSS_WCHAR *name,
                  u32 namelen,
                  struct stat *pStat);

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

Аргументы:

name Массив, в котором сохранено имя файла или директории в кодировке Unicode UTF-8.
namelen Размер массива name.
pStat Указатель на структуру, в которой будет возвращена информация.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_UnMountDevice (ADI_DEV_DEVICE_HANDLE DeviceHandle);

Функция adi_fss_UnMountDevice() вызывается для размонтирования всех томов на носителе данных, связанном с указанным хендлом устройства PID. Устройство остается зарегистрированным для FSS.

Аргумент:

DeviceHandle Хендл устройства требуемого драйвера физического интерфейса.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileOpen (ADI_FSS_WCHAR *name,
                      u32 namelen,
                      u32 mode,
                      ADI_FSS_FILE_HANDLE *FileHandle );

Функция adi_fss_FileOpen() открывает поток файла для чтения или записи. Аргумент name может быть указан как абсолютный путь до файла, или как относительный путь от текущей директории. Допустимые значения для параметра mode (режим открытия файла) приведены в следующей таблице. Могут потребоваться комбинации по ИЛИ значений режима. Например, для открытия файла с возможностью добавления данных в его конец требуется указать mode как ADI_FSS_MODE_WRITE | ADI_FSS_MODE_APPEND.

ADI_FSS_MODE_READ Доступ к файлу только на чтение (read-only).
ADI_FSS_MODE_WRITE Доступ к файлу только на запись (write-only).
ADI_FSS_MODE_READ_WRITE Доступ и на чтение, и на запись.
ADI_FSS_MODE_APPEND Режим добавления данных в конец файла.
ADI_FSS_MODE_CREATE Если файл с указанным именем не найден, то он будет создан.
ADI_FSS_MODE_TRUNCATE Обрезать файл, если существующий файл открыт для записи.

Аргументы:

name Массив, в котором сохранено имя файла или директории в кодировке Unicode UTF-8.
namelen Размер массива name.
mode Режим доступа к открываемому файлу.
FileHandle Место в памяти, куда будет сохранен хендл, идентифицирующий файловый поток.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileClose (ADI_FSS_FILE_HANDLE FileHandle);

Функция adi_fss_FileClose() закрывает файловый поток, идентифицированный по параметру FileHandle.

Аргумент:

FileHandle Хендл, идентифицирующий файловый поток.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileWrite (ADI_FSS_FILE_HANDLE FileHandle,
                       u8 *buf,
                       u32 size,
                       u32 *BytesWritten);

Функция adi_fss_FileWrite() записывает size байт данных из буфера buf в файловый поток, идентифицированный по FileHandle, и возвращает количество записанных байт в ячейке памяти, на которую указывает BytesWritten.

Аргументы:

FileHandle Хендл, идентифицирующий файловый поток.
buf Начальный адрес буфера, данные из которого должны быть записаны в файл.
size Количество записываемых байт.
BytesWritten Место в памяти, куда будет сохранено реальное количество записанных байт.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileRead (ADI_FSS_FILE_HANDLE FileHandle,
                      u8 *buf,
                      u32 size,
                      u32 *BytesRead);

Функция adi_fss_FileRead читает данные из файлового потока, идентифицированного по FileHandle, и помещает прочитанные данные в буфер buf. Количество байт для чтения задается параметром size. Функция возвратит реальное количество прочитанных байт в ячейке памяти, на которую указывает BytesRead.

Аргументы:

FileHandle Хендл, идентифицирующий файловый поток.
buf Начальный адрес буфера, куда будут прочитаны данные из файла.
size Количество байт, которое должно быть прочитано.
BytesRead Место в памяти, куда будет сохранено реальное количество прочитанных байт.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileSeek (ADI_FSS_FILE_HANDLE FileHandle,
                      s32 Offset,
                      u32 Origin,
                      u32 *tellpos);

Функция adi_fss_FileSeek перемещает текущую позицию в файле в место, которое указано аргументами Offset и Origin.

Значение Origin должно быть одним из следующих значений (определены в файле stdio.h):

SEEK_SET Позиционирование относительно начала файла.
SEEK_CUR Отсчет от текущей позиции в файле.
SEEK_END Позиционирование относительно конца файла.

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

Аргументы:

FileHandle Хендл, идентифицирующий файловый поток.
Offset Смещение (в байтах) относительно положения Origin.
Origin Точка отсчета, от которой осуществляется позиционирование.
tellpos Место в памяти, куда будет сохранена текущая позиция в файле после позиционирования.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileTell (ADI_FSS_FILE_HANDLE FileHandle, u32 *tellpos);

Функция adi_fss_FileTell возвратит текущую позицию в файле.

Аргументы:

FileHandle Хендл, идентифицирующий файловый поток.
tellpos Место в памяти, куда будет сохранена текущая позиция в файле.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_IsEOF (ADI_FSS_FILE_HANDLE FileHandle);

Функция adi_fss_IsEOF() определяет, достиг ли поток конца файла.

Аргумент:

FileHandle Хендл, идентифицирующий файловый поток.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
ADI_FSS_RESULT_EOF Был достигнут конец файла.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileRemove (ADI_FSS_WCHAR *name, u32 namelen);

Функция adi_fss_FileRemove() удаляет указанный файл. Аргумент name может быть указан либо как абсолютный, либо как относительный путь.

Аргументы:

name Строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая удаляемый файл.
namelen Длина строки имени, исключая завершающий нулевой символ; например, эту длину строки возвратит вызов strlen(name).

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_FileRename (ADI_FSS_WCHAR *old_path,
                        u32 oldlen,
                        ADI_FSS_WCHAR *new_path,
                        u32 newlen);

Функция adi_fss_FileRename() переименовывает файл из пути old_path в новый путь new_path. Оба аргумента можно указать как абсолютный, либо как относительный путь.

Аргументы:

old_path Строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая переименовываемый файл.
oldlen Длина строки old_path, исключая завершающий нулевой символ; например, эту длину строки возвратит вызов strlen(old_path).
new_path Строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая новое имя файла.
newlen Длина строки new_path, исключая завершающий нулевой символ; например, эту длину строки возвратит вызов strlen(new_path).

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirOpen (ADI_FSS_WCHAR *name,
                     u32 namelen,
                     ADI_FSS_DIR_HANDLE *DirHandle);

Функция adi_fss_DirOpen() открывает поток указанной директории. Аргумент name может быть указан как абсолютный, либо как относительный путь.

Аргументы:

name Строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая удаляемый открываемую директорию.
namelen Длина строки имени, исключая завершающий нулевой символ; например, эту длину строки возвратит вызов strlen(name).
DirHandle Место в памяти, куда будет сохранен хендл, идентифицирующий поток директории.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirClose (ADI_FSS_DIR_HANDLE DirHandle);

Функция adi_fss_DirClose() закрывает указанный поток директории.

Аргумент:

DirHandle Хендл, идентифицирующий поток директории.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirRead (ADI_FSS_DIR_HANDLE DirHandle,
                     ADI_FSS_DIR_ENTRY **pDirEntry);

Функция adi_fss_DirRead() возвратит указатель на следующую запись в директории, взятую из потока директории.

Аргументы:

DirHandle Хендл, идентифицирующий поток директории.
pDirEntry Место в памяти, куда будет сохранен указатель на структуру записи директории.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirSeek (ADI_FSS_DIR_HANDLE DirHandle, u32 Seekpos);

Функция adi_fss_DirSeek() перемещает позицию в потоке директории, который задан параметром DirHandle. Аргумент Seekpos должен быть получен предыдущим вызовом adi_fss_DirTell().

Аргументы:

DirHandle Хендл, идентифицирующий поток директории.
Seekpos Позиция (в байтах), указывающая на место позиционирования в потоке директории.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirTell (ADI_FSS_DIR_HANDLE DirHandle, u32 *tellpos); 

Функция adi_fss_DirTell() сообщает текущую позицию (в байтах) в указанном потоке директории.

Аргументы:

DirHandle Хендл, идентифицирующий поток директории.
tellpos Место в памяти, куда будет сохранена текущая позиция.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirRewind (ADI_FSS_DIR_HANDLE DirHandle);

Функция adi_fss_DirRewind() отматывает указанный поток директории в начальную позицию.

Аргумент:

DirHandle Хендл, идентифицирующий поток директории.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirChange (ADI_FSS_WCHAR *name, u32 namelen);

Функция adi_fss_DirChange() меняет текущую рабочую директорию, от которой отсчитываются относительные пути. Значение name может быть указано либо как абсолютный, либо как относительный путь.

Аргументы:

name Строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая новую текущую рабочую директорию.
namelen Длина строки имени, исключая завершающий нулевой символ; например, эту длину строки возвратит вызов strlen(name).

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_GetCurrentDir (ADI_FSS_WCHAR *name, u32 *namelen);

Функция adi_fss_GetCurrentDir() возвратит имя текущей рабочей директории.

Аргументы:

name Массив, куда будет сохранена строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая текущую рабочую директорию.
namelen Место в памяти, куда будет сохранена длина массива имени.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirCreate (ADI_FSS_WCHAR *name,
                       u32 namelen,
                       u32 mode);

Функция adi_fss_DirCreate() создает указанную директорию (каталог на диске). Аргумент name может быть указан как абсолютный или как относительный, при условии, что существуют все промежуточные директории.

Аргументы:

name Строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая имя создаваемой директории.
namelen Длина строки имени name, не включая завершающий ноль; значение этой длины, например, может быть получено вызовом strlen(name).
mode Режим для новой создаваемой директории. В настоящий момент этот аргумент игнорируется и зарезервирован для возможного использования в будущем.

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

u32 adi_fss_DirRemove (ADI_FSS_WCHAR *name, u32 namelen);

Функция adi_fss_DirRemove() удаляет указанную директорию. Аргумент name может быть задан как абсолютный или относительный путь.

Аргументы:

name Строка, заканчивающаяся нулем (ASCIIZ, или null-terminated строка), идентифицирующая имя директории для удалений.
namelen Длина строки имени name, не включая завершающий ноль; значение этой длины, например, может быть получено вызовом strlen(name).

Возвращаемое значение:

ADI_FSS_RESULT_SUCCESS Не было ошибок при вызове функции.
Любое другое значение При вызове функции произошла ошибка. Список кодов возврата и описание соответствующих ошибок см. в таблице 12-1.

[Типы данных и перечисления для API службы FSS]

В этой секции описаны типы данных, используемые FSS API и перечислении кодов возврата.

Тип данных ADI_FSS_WCHAR используется в FSS API для всех имен файлов и директорий. Как уже упоминалось в начале этого руководства, текущая реализация FSS обслуживает только имена файлов в кодировке ASCII (8 бит). Этот тип данных определен следующим образом:

typedef char ADI_FSS_WCHAR;

Тип данных ADI_FSS_VOLUME_IDENT используется для идентификаторов всех смонтированных томов. Этот тип данных определен следующим образом:

typedef char ADI_FSS_VOLUME_IDENT;

Тип данных ADI_FSS_FILE_HANDLE непрозрачный, используемый для уникальной идентификации файловых потоков, которыми манипулирует программа. Этот тип данных определен следующим образом:

typedef void *ADI_FSS_FILE_HANDLE;

Тип данных ADI_FSS_DIR_HANDLE непрозрачный, используемый для уникальной идентификации потоков директорий, которыми манипулирует программа. Этот тип данных определен следующим образом:

typedef void *ADI_FSS_DIR_HANDLE;

Тип данных ADI_FSS_CMD_VALUE_PAIR это структура, содержащая код команды и связанное с ней значение. Эти пары команда-значение используются в таблице конфигурации FSS и в вызове функции adi_fss_Control(). Список допустимых команд приведен во врезках с описанием функций adi_fss_Init и adi_fss_Control. Структура типа определена следующим образом:

typedef struct
{
   u32 CommandID;
   void *Value;
} ADI_FSS_CMD_VALUE_PAIR;

Назначение поля структуры показаны в таблице ниже:

CommandID Идентификатор выполняемой команды.
namelen Значение, смысл которого зависит от выполняемой команды.

Тип данных ADI_FSS_DIR_ENTRY это структура, которая содержит информацию записи директории. Эта структура идентична структуре dirent стандарта POSIX:

typedef struct dirent ADI_FSS_DIR_ENTRY;

Структура dirent описана в документации POSIX (см. раздел "Дополнительные функции POSIX, поддерживаемые FSS", и определена в заголовочном файле FSS < services/fss/adi_fss.h >.

Тип данных ADI_FSS_DEVICE_DEF задает структуру, содержащую информацию, требуемую для открытия и конфигурирования драйвера FSD или PID. Структура определена следующим образом:

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(). Допустимые значения параметра см. в документации на соответствующий драйвер.
pEntryPoint Это указатель на точку входа драйвера устройства (device driver entry point), и он передается как аргумент pEntryPoint в вызов функции adi_dev_Open(). См. соответствующий файл заголовка драйвера и документацию по его декларации точки входа.
pConfigTable Это указатель на таблицу пар команда-значение, которая задает конфигурацию драйвера. Если никаких команд не требуется, то в этом поле должно быть значение NULL.
pCriticalRegionData Это указатель на аргумент, который должен быть передан в функцию системных служб adi_int_EnterCriticalRegion(). В настоящий момент эта фича нигде не используется, и это поле должно быть установлено в NULL.
Direction This is the Direction argument required for a call to adi_dev_Open(). See the appropriate driver documentation for valid values.
DeviceHandle This is the location used internally to store the device driver handle on return from a call to adi_dev_Open(). It should be set to NULL prior to initialization.
DefaultMountPoint This is the default drive letter used for volumes managed by the driver. This is especially useful for removable media types such as USB memory sticks, SD cards, and optical media. This can be left as NULL if no preference is desired.

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

Каждая из функций FSS API возвратит код, который может быть интерпретирован по описанию из заголовочного файла службы adi_fss.h. Коды возврата сведены в таблицу 12-1.

Таблица 12-1. Коды возврата функций FSS.

ADI_FSS_RESULT_SUCCESS (0) Обычное нормальное, безошибочное завершение функции.
ADI_FSS_RESULT_FAILED (1) Обычное завершение с ошибкой (без описания типа ошибки).
ADI_FSS_RESULT_OPEN_FAILED (0xB0001) Ошибка открытия файла/директории (возможно сбой носителя данных).
ADI_FSS_RESULT_NOT_FOUND (0xB0002) Файл/директория не найдены.
ADI_FSS_RESULT_CLOSE_FAILED (0xB0003) Ошибка закрытия файла/директории (сбой носителя данных).
ADI_FSS_RESULT_NO_MEDIA (0xB0004) Не обнаружен носитель данных (media).
ADI_FSS_RESULT_MEDIA_CHANGED (0xB0005) Носитель данных был заменен от последней его проверки.
ADI_FSS_RESULT_MEDIA_FULL (0xB0006) Нет свободного места на носителе данных.
ADI_FSS_RESULT_NO_MEMORY (0xB0007) Недостаточно памяти для выполнения запроса.
ADI_FSS_RESULT_INVALID_DEVICE (0xB0008) Не получается инициализировать драйвер устройства.
ADI_FSS_RESULT_BAD_FILE_HANDLE (0xB0009) Недопустимый дескриптор файла по предоставленному адресу.
ADI_FSS_RESULT_BAD_NAME (0xB000A) Указано недопустимое имя для файла/директории.
ADI_FSS_RESULT_EOF (0xB000B) Достигнут конец файла.
ADI_FSS_RESULT_EOD (0xB000C) Достигнут конец директории.
ADI_FSS_RESULT_BAD_VOLUME (0xB000D) Указан недопустимый раздел диска (partition).
ADI_FSS_RESULT_NOT_SUPPORTED (0xB000E) Код команды не поддерживается.
ADI_FSS_RESULT_TIMEOUT (0xB0010) Истек таймаут операции.
ADI_FSS_RESULT_BAD_CACHE_HANDLE (0xB0011) Недопустимый хендл кэша.
ADI_FSS_RESULT_CANT_CREATE_SEMAPHORE (0xB0012) Не получилось создать семафор в файловом кэше.

[Функции интерфейса стандартного ввода/вывода C]

В этом разделе приведено краткое описание стандартного API ввода/вывода языка C. Путем регистрации FSS совместно с библиотекой ввода/вывода C, как это подробно описано в части 3 руководства "C and C++ Compiler and Linker Manual for Blackfin Processors", и упомянуто в секции "FSS: быстрый старт", вызовы функций из этой секции перенаправляются службе FSS после обработки их библиотекой ввода/вывода. Все функции следуют системе именования POSIX для аргумента и кодов возврата. Подробное описание функций см. в подходящем руководстве по C.

Этот список детализирует большинство доступных функций, но любая функция, определенная в < stdio.h > для доступа к файлу приводит к вызову соответствующему вызову FSS API.

FILE* fopen (const char *name, const char *mode);

Функция fopen() открывает файл по пути name в соответствии с указанными флагами режима доступа mode. В случае успеха функция вернет хендл потока файла, иначе вернет NULL.

int fclose (FILE *stream);

Функция fclose() закроет указанный поток файла.

int fwrite (void *buffer, size_t size, size_t num, FILE *stream);

Функция fwrite() записывает num элементов данных, каждый из которых имеет размер size байт, в файловый поток stream.

int fread (void *buffer, size_t size, size_t num, FILE *stream);

Функция fread() читает num элементов данных, каждый из которых имеет размер size байт из файлового потока stream.

int fprintf (FILE *stream, const char *fmt, ...);

Функция fprintf() записывает в файл, идентифицированный параметром stream, строку текста в соответствии с форматом fmt. Библиотека ввода/вывода VisualDSP++ 5.0 выполняет всю требуемую обработку формата.

int fscanf (FILE *stream, const char *fmt, ...);

Функция fscanf() осуществляет чтение из файла, идентифицированного параметром stream, данных по формату, определенному строкой fmt. Библиотека ввода/вывода VisualDSP++ 5.0 выполняет всю требуемую обработку формата.

int fgetc (FILE *stream);

Функция fgetc() читает следующий символ из файла, идентифицированного параметром stream.

char* fgets (char *buf, int n, FILE *stream);

Функция fgets() читает следующие n байт из файла, идентифицированного параметром stream, в буфер символов buf.

int fputc (int ci, FILE *stream);

Функция fputc() записывает байт ci в файл, идентифицированный параметром stream.

int fputs (const char *s, FILE *stream);

Функция fputs() записывает строку текста s в файл, идентифицированный параметром stream.

int fseek (FILE *stream, long offset, int origin);

Функция fseek() перемещает текущую позицию в файле.

long ftell (FILE *stream);

Функция ftell() возвратит текущую позицию в файле.

int feof (FILE *stream);

Функция feof() позволяет проверить, достигла ли текущая позиция конца файла (end-of-file, EOF).

[Дополнительные функции POSIX, поддерживаемые FSS]

В этом разделе предоставлен обзорный список дополнительных функций POSIX и структур, поддерживаемых службой FSS. Более подробное описание подпрограмм можно найти в Интернет при поиске по имени функции, или в на странице документации "The Single UNIX® Specification, Version 2, System Interface & Headers Reference Pages" [8].

Перечисленные в этом разделе функции не имеют реализации в библиотеке ввода/вывода VisualDSP++ 5.0, кроме rename() и remove(). Эти две функции также имеются в библиотеке ввода/вывода VisualDSP++ 5.0, но их использование ограничено доступом PRIMIO для файловой системы хоста PC.

Для использования всех функций в этой секции Вам нужно подключить к исходному коду приложения заголовочный файл FSS < services/fss/adi_fss.h >. После этого все ссылки обращения к функциям rename и remove в исходном коде приложения будут разрешаться к FSS-вариантам этих функций.

DIR* opendir (const char *dirname);

Функция opendir() откроет указанную директорию для последующей работы с ней через функции readdir, readdir_r, telldir, seekdir, rewinddir и closedir.

int closedir (DIR *dirp);

Функция closedir() закрывает доступ к структуре директории, на которую указывает аргумент dirp.

struct dirent* readdir (DIR *dirp);

Функция readdir() вернет указатель на структуру dirent, представляющую следующую запись в директории, на которую указывает параметр потока директории dirp. Функция вернет NULL, если был достигнут конец списка записей директории, или если произошла ошибка. Имена файлов и директорий в записях, которые будет возвращать функция, будут появляться в том порядке, как они создавались в файловой системе.

int readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result);

Поведение функции readdir_r() подобно функции readdir, но отличие в том, что функция readdir_r инициализирует структуру, на которую указывает параметр entry, параметрами, представленными в текущей позиции потока директории dirp, и сохранит указатель на эту структуру в ячейку памяти, которая задана в параметре result. В эту ячейку будет записано значение NULL, если достигнут конец потока директории. Как и у функции readdir, после возврата из функции readdir_r текущая позиция в потоке директории будет перемещена на следующую запись.

void rewinddir (DIR *dirp);

Функция rewinddir() отматывает (переводит текущую позицию в начало) указанный поток директории.

void seekdir (DIR *dirp, long loc);

Функция seekdir() устанавливает позицию следующей операции readdir() в потоке директории dirp по индексу, заданному параметром loc.

long telldir (DIR *dirp);

Функция telldir() позволяет получить текущую позицию (индекс) в директории, на которую указывает связанный поток директории dirp.

int mkdir (const char *path, mode_t mode);

Функция mkdir() создает указанную директорию. Служба FSS игнорирует аргумент mode.

int rmdir (const char *path);

Утилита rmdir() удаляет указанную директорию.

int rename (const char *_oldnm, const char *_newnm);

Функция rename() переименовывает файл: старое имя _oldnm меняется на имя _newnm.

int remove (const char *_filename);

Функция remove() удаляет указанный файл.

[Расширяемость]

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

Новые драйверы устройств для вставки в FSS должны удовлетворять документации разработки FSD или PID, которая поставляется вместе с VisualDSP++ 5.0:

Blackfin\docs\drivers\fsd\Generic_FSD_Design_Document.pdf
Blackfin\docs\drivers\pid\Generic_PID_Design_Document.pdf

В этих документах подробно описан интерфейс драйверов с другими компонентами фреймворка службы FSS.

Когда драйвер создан, он напрямую доступен для использования вместе с FSS. Все, что требуется, это декларировать структуру ADI_FSS_DEVICE_DEF (и сопутствующую конфигурационную таблицу, если это нужно), и зарегистрировать её для FSS командой ADI_FSS_CMD_ADD_DRIVER:

{ ADI_FSS_CMD_ADD_DRIVER, (void*)&< Device-Def-Structure > },

Описание структуры ADI_FSS_DEVICE_DEF см. в разделе "Типы данных и перечисления для API службы FSS".

[Примеры]

Вместе с VisualDSP++ 5.0 поставляются несколько примеров для демонстрации, как конфигурируется FSS, и как её можно использовать. Для упрощения код примеров был намеренно ограничен, поэтому используйте эти примеры с осторожностью для Ваших собственных приложений. Все примеры, описанные в этом разделе, относятся к специфике платы разработчика ADSP-BF548 EZ-KIT Lite. Подобные примеры могут существовать для платы разработки ADSP-BF527 EZ-KIT Lite, но они будут использовать только интерфейс хоста USB для доступа к носителям данных на флешках USB.

Ниже описаны 3 примера. Первый (HardDiskAccess) показывает, как начать работу со службой файловой системы. Второй пример (HardDiskFormat) сложнее, он демонстрирует, как использовать драйверы помимо FSS, чтобы отформатировать жесткий диск, специально для случаев, когда он ранее не форматировался. Последний пример (Shell_Browser) основан на приложении VDK, он демонстрирует использование службы файловой системы с многопоточной среде, когда применяется несколько периферийных устройств.

Это простая программа (Hello World для FSS), демонстрирующая базовую конфигурацию службы файловой системы и её использование.

Программа выполняет следующие операции:

1. Показывает характеристики раздела FAT (FAT partition).
2. Создает подкаталог (subdirectory) на жестком диске.
3. Переходит в этот подкаталог.
4. Создает файл в этой директории.
5. Выводит содержимое этой директории.
6. Выполняет операцию вычисления контрольной суммы для созданного файла и отображает результат.
7. Удаляет этот файл.
8. Переходит обратно в корневой каталог (root directory).
9. Удаляет подкаталог.
10. Выходит из программы.

Эта программа предполагает, что подключенный жесткий диск был ранее отформатирован как один раздел FAT (single FAT partition). Файл создается и заполняется известными данными, и операция вычисления контрольной суммы делает проверку содержимого файла по ранее вычисленной контрольной сумме, чтобы убедиться в целостности данных файла. Имейте в виду, что метки времени создаваемых файлов могут оказаться произвольными. Причина в том, что фактически служба реального времени (real-time clock, RTC) может быть еще не установлена. Подробнее см. пример Shell_Browser, где показана установка RTC.

[Конфигурация]

Пример HardDiskAccess инициализирует FSS для:

• Двух блоков кэша на файл
• Использования драйвера ATA/ATAPI
• Файловой системы FAT

Конфигурирование происходит в файле InitfileSystem.c вызовом adi_fss_Init() путем передачи адреса массива adi_fss_config. Затем система FSS добавляется в таблицу устройств библиотеки выполнения (C runtime library). Когда FSS сконфигурирована, она становится по умолчанию для доступа к файлам через стандартный интерфейс ввода/вывода.

Эта программа используется для форматирования подключенного жесткого диска как одиночного раздела FAT32 размером 32 гигабайта. Этот пример относится только к плате разработчика ADSP-BF548 EZ-KIT Lite.

Приложение инициализирует SSL (библиотека системных служб), загружает ATAPI PID, подключается к жесткому диску ATAPI, форматирует диск и затем выходит из программы.

[Конфигурация]

Это приложение только инициализирует FSS только до установки индекса общей кучи, чтобы можно было выделить память в коде драйверов. Иначе оба драйвера ATAPI PID и FAT FSD конфигурируются и к ним осуществляется доступ напрямую для форматирования раздела и создания главной загрузочной записи диска (master boot record, MBR).

Это приложение VDK демонстрирует простой командный интерфейс (shell через окно терминала), чтобы можно было делать навигацию по носителю данных и выполнять над ним определенные операции, такие как отображение слайд-шоу растровых картинок на подключенном экране LCD платы ADSP-BF548 EZ-KIT Lite.

Приложение использует 3 потока - поток коммуникации с консолью ввода/вывода, подключенной к интерфейсу UART, поток отображения картинки на панели LCD, и поток обработки команд для управления приложением и выполнения задач управления файлами, не связанных с показом картинок. Поток обмена собирает введенные символы из консоли ввода/вывода, и передает их в поток обработки команд. Поток отображения картинок берет файл изображения или список файлов картинок, и отображает картинки на панели LCD. Поток команд интерпретирует введенные команды и выполняет требуемые действия. Полный список поддерживаемых команд доступен, если ввести команду "help" или "?". Подобным образом синтаксис каждой отдельной команды может быть получен вводом команды, за которой следует -h. Например, ввод rmdir -h перечисли синтаксис и назначение этой команды.

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

[Конфигурация]

Shell_Browser настраивает FSS для:

• Двух блоков кэша на файл
• Драйвера ATA/ATAPI
• Драйвера карты SD
• Драйвера хоста USB для работы с извлекаемыми носителями
• Файловой системы FAT
• Драйвер устройства UART для приема команд и отображения сообщений

Когда пример работает, то происходит следующее:

• Регистрируется драйвер консоли UART для использования stdin и stdout
• Инициализируется просмотр изображений через драйвер LCD
• Запускается поток отображения картинок

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

Обратите внимание, что метки времени для любых создаваемых файлов могут оказаться произвольными. Причина в том, что фактически часы реального времени (real-time clock, RTC) могут быть пока не установлены. Установить часы можно командой date. Например, чтобы установить дату как "2:30 после полудня (PM), понедельник, 17 сентября 2007", введите следующую команду: date mon 091714302007. Для подсказки по полному синтаксису этой команды введите date -h.

[Ссылки]

1. VisualDSP++ 5.0 Device Drivers and System Services Manual for Blackfin® Processors site:analog.com.
2. VDK: драйверы устройств и системные службы процессоров Blackfin.
3. VDK: менеджер драйверов устройств.
4. VDK: менеджер DMA.
5. VDK: менеджер прерываний.
6. VDK: менеджер отложенных функций обратного вызова.
7. VisualDSP: работа с динамически выделяемой памятью.
8. System Interface & Headers Issue 5 Reference Pages site:pubs.opengroup.org.
9. Драйвер интерфейса (PID) для службы файловой системы (FSS).
10. Драйвер файловой системы (FSD) для службы файловой системы (FSS).
11. Драйвер FSD для FAT от компании Analog Devices.