Интеграция Библиотеки Fatfs Для Организации Чтения Дисковых Устройств На Ios



Введение Статья посвящена реализации на iOS библиотеки с открытым исходным кодом для чтения/записи данных из МФО дисковое устройство на базе FAT12/FAT16/FAT32/Exfat. Представлен метод построения архитектуры приложения, основанный на ТЭФФ библиотеки, а также методы отладки и тестирования проводных МФО -устройства.

Статья практически не содержит кода из-за соответствия Соглашение о неразглашении .



Постановка задачи

Основной целью было создание своего рода универсального SDK (.

framework), способного работать с производителями различных устройств доступа к дискам по протоколу MFI, используя единый стандарт API.

Интеграция библиотеки FATFS для организации чтения дисковых устройств на iOS

На рисунке показана обобщенная блок-схема такого каркаса.

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

В зависимости от того, какая файловая система (ФС) используется на диске, выбирается соответствующий алгоритм работы с диском: FAT/exFat/Другая ФС.

При этом несколько приложений (использующих этот SDK), находящихся в памяти устройства, могут иметь доступ к устройству; однако одновременно писать/читать может только один человек.

Этот SDK подразумевает его использование в многопоточном приложении с одновременными задачами чтения и записи.



Поиск решения

Первоначально реализация FAT32 от Apple была выбрана в качестве базовой библиотеки для реализации FS FAT32. Однако сложность интеграции стандартного API устройства доступа из-за привязки к конкретной платформе заставила нас искать готовое решение с отдельным абстрактным API для физического уровня доступа к устройству MFI через библиотеку производителя.

Также были рассмотрены ЕФСЛ И ТЭФФ реализация FAT32 с открытым исходным кодом.

FATFS была выбрана по нескольким причинам: • постоянная поддержка библиотеки • независимость от платформы и простота портирования • широкий выбор вариантов конфигурации • поддержка exFAT • абстрактный уровень доступа для медиадрайверов Из-за проблем с получением логов приложения, учитывая, что физический разъем был занят и не было возможности подключиться к XCode, библиотека была подключена НСлоггер , что позволяет передавать логи по Wi-Fi практически в реальном времени.

Однако при отладке такой библиотеки возникла проблема.

Было решено разработать симулятор устройства MFI, который обращался бы к определенной области на диске устройства iOS/MAC и эмулировал чтение/запись с использованием того же API, что и реальное устройство.



Проблемы интеграции



Портирование на Obj-C

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



Поддержка Юникод

Вариант Юникод адекватно работал только с параметром кодировки Obj-C NSUTF16LittleEndianStringEncoding , несмотря на то, что согласно заявленным требованиям дополнительно поддерживались UTF-16BE и UTF-8. Все методы, работающие с именами файлов, необходимо было сделать потокобезопасными для корректной работы FAT32.

Потокобезопасный

Опция безопасности потоков, активируемая параметрами ФС_РЕЕНТРАНТ и реализуется через функции ff_req_grant, ff_rel_grant, ff_del_syncobj требовалась дополнительная реализация через POSIX. Без включенной опции потокобезопасности наблюдалось повреждение таблицы файловой системы и, как следствие, потеря данных.

Дескриптор файла pthread_t не сразу удалось правильно реализовать из-за того, что ff_ функции для синхронизации потоков данные передавались по значению, а не по ссылке.

После замены на эталонные значения проблем с потокобезопасностью операций не возникло.



Кэширование

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

Учитывая, что дисковое пространство могло составлять более 16 ГБ, некоторые базовые типы переменных пришлось изменить на «длинный журнал».

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

В результате функции чтения/записи выполнялись одним кластером дискретно в единицу времени, что существенно меньше, чем непрерывное чтение/запись.

Аналогичная проблема возникла при чтении структуры каталогов, когда в каталоге было более 100 файлов.

Производительность чтения/записи одного файла увеличивалась линейно с увеличением количества файлов, как показано на рисунке.

По оси «х» указано количество файлов в каталоге, а по оси «у» — время чтения в секундах.

Виды кривых на графике для: V2 Sim Fat – симулятор дискового устройства, V1 Fat FAT32 файловая система, для которой данной проблемы не существует (не FATFS), V2 Fat64/128 FATFS с размером диска 64 и 128 ГБ соответственно.



Интеграция библиотеки FATFS для организации чтения дисковых устройств на iOS

Блок-схема работы кэша в таком SDK показана на рисунке ниже.

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



Интеграция библиотеки FATFS для организации чтения дисковых устройств на iOS



Уникальный доступ приложения к устройству

Приложения со встроенным SDK не должны одновременно обращаться к внешнему дисковому устройству.

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



Интеграция библиотеки FATFS для организации чтения дисковых устройств на iOS

Для установления правил доступа к устройству реализован механизм на основе Центр уведомлений Дарвина позволяя с помощью уведомлений разрешить или заблокировать работу приложения с устройством, когда на устройстве работает другое приложение с этим SDK. Когда вы впервые запускаете приложение, всем приложениям, которые подписались, отправляется запрос на получение определенных уведомлений.

Каждое приложение публикует свое состояние другим приложениям, чтобы новое приложение могло перейти в адекватное состояние.

Если устройство свободно, приложение переходит в состояние USING. Состояние ОЖИДАНИЕ является промежуточным между ЗАНЯТО и ОЖИДАНИЕ в случае, если устройство недоступно или занято.

В случае сбоя связи используется состояние INVALID. По окончании использования устройства приложение переходит в состояние НЕАКТИВНО.



Тестирование платформы

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

Изначально все тесты проводились на симуляторе дисковых устройств.

Однако симулятор и библиотеку низкоуровневого доступа к диску писали разные люди, не имевшие возможности взаимодействия, и поэтому поведение симулятора не всегда совпадало с поведением драйвера устройства.

Для этого была разработана схема тестирования на реальном устройстве, представленная ниже.

Тестируемый фреймворк был интегрирован в приложение, написанное с использованием Private API, а установка осуществлялась через Установка сервера Xcode по беспроводной сети .

Private API позволил вывести приложение из Фонового состояния приложения через Push Notification и запустить необходимые тесты.

Результаты тестирования отправлялись по протоколу REST на сервер статистики, где впоследствии представлялись в виде графиков и таблиц.

В состав библиотеки также входят Отслеживание активности функции для получения более подробного журнала сбоев.



Интеграция библиотеки FATFS для организации чтения дисковых устройств на iOS



Заключение

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

При корректной модификации библиотеки с подключением дополнительных функций кэширования и чтения/записи буфера функции копирования и чтения файлов FAT32 API всего на 10-15% ниже скорости копирования LBA-блоков медиадрайвера производителя оборудования.

Для новичков в разработке и интеграции файловых систем FATFS может быть достойным выбором.



Полезные ссылки

FatFs — универсальный модуль файловой системы FAT Спецификация файловой системы Microsoft EFI FAT32 Концепции уведомлений Дарвина О непрерывной интеграции в Xcode Теги: #FatFs #iOS #разработка iOS
Вместе с данным постом часто просматривают: