Введение Статья посвящена реализации на iOS библиотеки с открытым исходным кодом для чтения/записи данных из МФО дисковое устройство на базе FAT12/FAT16/FAT32/Exfat. Представлен метод построения архитектуры приложения, основанный на ТЭФФ библиотеки, а также методы отладки и тестирования проводных МФО -устройства.
Статья практически не содержит кода из-за соответствия Соглашение о неразглашении .
Постановка задачи
Основной целью было создание своего рода универсального SDK (.
framework), способного работать с производителями различных устройств доступа к дискам по протоколу MFI, используя единый стандарт API.
На рисунке показана обобщенная блок-схема такого каркаса.
В зависимости от протокола устройства выбирается та или иная библиотека для взаимодействия с устройством.
В зависимости от того, какая файловая система (ФС) используется на диске, выбирается соответствующий алгоритм работы с диском: 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 ГБ соответственно.
Блок-схема работы кэша в таком SDK показана на рисунке ниже.
Таким образом, кэшировалась не только файловая структура, но и сектора для низкоуровневых функций чтения/записи медиаустройства из-за отсутствия аппаратного кэша.
Уникальный доступ приложения к устройству
Приложения со встроенным SDK не должны одновременно обращаться к внешнему дисковому устройству.Правила, которым должно подчиняться приложение, использующее SDK, должны выглядеть так, как показано на диаграмме состояний ниже.
Для установления правил доступа к устройству реализован механизм на основе Центр уведомлений Дарвина позволяя с помощью уведомлений разрешить или заблокировать работу приложения с устройством, когда на устройстве работает другое приложение с этим SDK. Когда вы впервые запускаете приложение, всем приложениям, которые подписались, отправляется запрос на получение определенных уведомлений.
Каждое приложение публикует свое состояние другим приложениям, чтобы новое приложение могло перейти в адекватное состояние.
Если устройство свободно, приложение переходит в состояние USING. Состояние ОЖИДАНИЕ является промежуточным между ЗАНЯТО и ОЖИДАНИЕ в случае, если устройство недоступно или занято.
В случае сбоя связи используется состояние INVALID. По окончании использования устройства приложение переходит в состояние НЕАКТИВНО.
Тестирование платформы
Написание модульных тестов для всех функций библиотеки было критически важным из-за строгих детерминированных требований к поведению API для конечных пользователей.Изначально все тесты проводились на симуляторе дисковых устройств.
Однако симулятор и библиотеку низкоуровневого доступа к диску писали разные люди, не имевшие возможности взаимодействия, и поэтому поведение симулятора не всегда совпадало с поведением драйвера устройства.
Для этого была разработана схема тестирования на реальном устройстве, представленная ниже.
Тестируемый фреймворк был интегрирован в приложение, написанное с использованием Private API, а установка осуществлялась через Установка сервера Xcode по беспроводной сети .
Private API позволил вывести приложение из Фонового состояния приложения через Push Notification и запустить необходимые тесты.
Результаты тестирования отправлялись по протоколу REST на сервер статистики, где впоследствии представлялись в виде графиков и таблиц.
В состав библиотеки также входят Отслеживание активности функции для получения более подробного журнала сбоев.
Заключение
Несмотря на серьезные недостатки открытой библиотеки FATFS, требующие доработки, другой альтернативы с возможностью использования Fat32 и ExFat, а также с абстрактным уровнем поддержки медиадрайверов найти не удалось.При корректной модификации библиотеки с подключением дополнительных функций кэширования и чтения/записи буфера функции копирования и чтения файлов FAT32 API всего на 10-15% ниже скорости копирования LBA-блоков медиадрайвера производителя оборудования.
Для новичков в разработке и интеграции файловых систем FATFS может быть достойным выбором.
Полезные ссылки
→ FatFs — универсальный модуль файловой системы FAT → Спецификация файловой системы Microsoft EFI FAT32 → Концепции уведомлений Дарвина → О непрерывной интеграции в Xcode Теги: #FatFs #iOS #разработка iOS-
Вы Можете Избежать Синусита!
19 Oct, 24 -
Phdays 9: Анализ Задач Ai Ctf
19 Oct, 24 -
Восемь Способов Демотивировать Сотрудников
19 Oct, 24 -
Исследование Кортежей В C# 7
19 Oct, 24 -
Еще Одно Сопоставление С Образцом В C#
19 Oct, 24