Как стать автором
Обновить

Комментарии 36

Спасибо за идею! А то я в подобных случаях занимался сексом с USB-HID…
НЛО прилетело и опубликовало эту надпись здесь
Спасибо за библиотеку! Может и пригодиться.
Просто к слову: подобную идею эмуляции файловой системы реализуют микроконтроллеры NXP LPC134x для загрузки в них микропрограммы. Там при подключении в режиме USB-загрузчика появляется раздел с файлом firmware.bin, стерев который и записав новый образ (причем не обязательно с таким же именем), перепрошивается память микроконтроллера.
Да, читал про из бутлоадер. По-моему это даже лучше чем USB Device Firmware Upgrade, так как не требует на компьютере никаких утилит для обновления прошивки
Для использования в самоделках — может быть. Для прошивки больших партий — очень спорно, может вылезти куча других проблем.
Да, еще интересный факт: LPC13xx содержит ошибку в загрузчике, причем так и не исправленную. Проявляется задержкой подключения раздела в 20 секунд (в Windows точно, в Linux никогда не было надобности проверять).
Во внутрисхемном отладчике для stm32 st-link v2.1 (например, на платах stm32*-nucleo) присутствует аналогичный функционал. Кроме отладчика система видит ещё msd, который выглядит пустым, но скопированный туда файл с прошивкой заливается на контроллер.
Очень хорошая штука для различных самодельных самописцев. Быстро и кроссплатформенно.
А есть ли возможность при выдаче данных на ходу формировать, например, файл excel, данные для которого хранятся в компактном, сыром виде, а остальная структура формируется на лету?
Да, так можно и даже нужно делать!
Для этого нужно:
— при подключении USB рассчитать (и записать в таблицу) конечный размер файла, после чего вызвать init.
— в колбэке чтения формировать ту часть файла, которую запрашивает библиотека
Только нужно учесть, что целевые данные не должны меняться, когда МК находится в режиме Mass Storage.
Иначе хост прочитает часть «старых» и часть уже изменённых данных в одном файле.
Мысль нравится. А насколько сложно будет перенести на другие контроллеры? Хочу минимальный функционал, но для восьмибитного PIC'a.
Сам эмулятор, как и говорил, кроссплатформенный, сложностей возникнуть не должно. Однако драйвер USB-MSC придётся, само собой, запускать нативный для PIC-а. Если займётесь — будет интересно понаблюдать! Допускаю, что могут возникнуть проблемы в части директивы выравнивания или из-за другой специфики PIC компилятора.
В Microchip Solutions уже заглядывали? Там есть демки работы с USB MSD.
Потенциально весьма полезная штука.
А динамически изменять рапортуемый размер файла можно? Идея в том, чтоб некое приложение периодически тыркалось на «карту» посмотреть размер «файла» и если он не нулевой, считать из него новую порцию данных, после чего он снова станет нулевым до следующей порции.
А то на терминальных серверах зачастую USB только и умеет нормально пробрасывать мышь, клавиатуру и mass-storage. Прочие HID-девайсы и COM-порты — или совсем никак, или криво.
Увы, красивого способа это сделать нет. По причине кеширования ФС операционной системой. Даже если мы изменим ФС на устройстве, вряд ли есть способ сообщить об этом хосту. Повторное чтение файла с устройства с большой вероятностью будет происходить уже из кеша ФС, а не с нашего устройства.
Напрашивающийся выход — это, действительно, CDC интерфейс (COM-порт).
Если Вам понадобится стабильный CDC (или MSC+CDC) для stm32f4 — обращайтесь, было дело, переписывал stm-ый драйвер как раз по причине той самой кривости (отсутствие flow-контроля, гигантизм roll-back буффера, отсутствие обработки кратности bulk-пакета).
Но в API со стороны хоста же есть обычно команды сброса файлового кеша? А как файловые менеджеры в риалтайме(или почти) могут видеть изменения размеров файлов, например копируемых по сети? Или тут как раз вся фишка в наличии самой операции копирования(даже не важно, какой стороной инициированной), репорт о прогрессе которой разносится по событиям самим драйвером на стороне хоста?

В любом случае, COM-порт уже не интересует, спасибо. Мне проще решить проблему превращением устройства в независимое сетевое, что я и сделал )
Если вкратце, то нет пути засинхронизировать наше устройство с кешем ОС. Поэтому о динамике речи не идёт. Изменения ФС возможны только перед перед её монтированием.
Но в API со стороны хоста же есть обычно команды сброса файлового кеша?

Сброс файлового кеша (flush) заставит вылить на носитель отложенные для записи данные. Что нам не интересно.
Если же сбрасывать кеш всей файловой системы (если это возможно) — то это равносильно перемонтированию ФС или передёргиванию USB, что приведёт к гигантскому накладному расходу, т.к. драйвер ФС тот час же перечитает несколько кластеров (FAT таблица и корень). В этом случае — да, мы можем менять ФС на устройстве в динамике. Но это путь злодея.
как файловые менеджеры в риалтайме(или почти) могут видеть изменения размеров файлов

Двумя способами:
1. Специфическое API нотификации файловой системы.
2. Периодическое чтение файлового каталога с мониторингом изменений.
В обоих случаях работа программы происходит с драйвером ФС и его кешем, и лишь редкий вызов будет транслироваться в реальное чтение носителя.
решить проблему превращением устройства в независимое сетевое

А вот это красиво и современно )
Сброс файлового кеша (flush) заставит вылить на носитель отложенные для записи данные. Что нам не интересно.
Если же сбрасывать кеш всей файловой системы (если это возможно) — то это равносильно перемонтированию ФС или передёргиванию

Не, я не про это. Наверное неточно выразился. Я имел в виду что-то вроде виндовой опции FILE_FLAG_NO_BUFFERING при работе с файловой системой, или аналоги clearstatcache в PHP… В разных средах свои примочки, по разному действуют, где-то всему приложению буфферизацию отключает, где-то — на конкретный дескриптор файла, где-то вообще очень качественно не работает… Но не заставляет операционку вылить кеш всего и вся на диск.

Так же, как аналог F5 в проводнике или Ctrl+R в TotalCommander. Эти действия же не сбрасывают кеш всей системы ) Но перечитать текущий каталог соответствующий драйвер операционки, как правило, заставляют.

Собственно интерес к этому сугубо академический, т.к. превращением устройства в сетевое я решил кучу проблем, включая эту, а так же породил несколько новых )
Но вот такие вот извраты в копилку откладывать люблю, т.к. в определенных «специальных» случаях такие фишки могут здоровски выручить, да.
Возможно сделать потоковые данные например сделав файл в несколько гбайт, сколько там для фат максимум? 4? А потом переходить к следующему файлу или в следующую папку. У меня когда то была идея сэмулировать по SPI SD/MMC карту в фотике и сделать быстрое получение файлов из фотоаппарата или вообще вебкамеру, но забросил идею из за отсутствия знаний и лени.
Можно вообще организовать и прямой доступ к разделу (в Windows):
HANDLE hFile = CreateFileA("\\\\.\\F:",
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL, 
		OPEN_EXISTING,
		FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,
		NULL);
DeviceIoControl(hFile, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwLen, NULL);
SetFilePointer(hFile, dwOffset, &dwOffsetH, 0);
ReadFile(hFile, pbFileBuff, dwLen, &dwLenR, 0);

Запросы ReadFile/WriteFile при этом идут как непосредственные запросы SCSI_READ/WRITE в USB устройство, в обход кеша ОС. Адрес чтения соответсвует физ. адресу сектора.
И в обход драйвера ФС(FAT)?
Да, именно в обход драйвера файловой системы.
Это, действительно, может быть пригодно. Можно иметь специальный номер сектора для динамического обмена данными, хоть это всё и от нищеты.
Так же, как аналог F5 в проводнике или Ctrl+R в TotalCommander. Эти действия же не сбрасывают кеш всей системы ) Но перечитать текущий каталог соответствующий драйвер операционки, как правило, заставляют

Заставляют. Только перечитать не физически с диска, а из кеша ФС. Этот кеш содержит набор ранее прочитанных с устройства кластеров. Перечитывать эти кластеры с носителя повторно ОС объективно считает накладным.
Повторно она прочитает кластер с носителя, только если он был исключён из кеша в целях экономия памяти, а пользователю снова понадобятся эти данные. При чём, что интересно, на этом уровне ОС не делает различий между кластерами относящимися к файлу или же к структуре каталога.
Есть такое наблюдение: первое копирование достаточно большого файла/каталога с носителя происходит за минуту, повторное копирование — уже за еденицы секунд при отсутствии на устройстве запросов чтения. Секрет кроется в подсосе из кеша и хитром драйвере :)
Вообще, если получится ОС заставить перечитывать физически кластеры файла (и его содержащего каталога) каждый раз при обращении — это будет полезно для нас. Если у Вас получится — буду рад опыту ;)
Под какой лицензией вы опубликовали свой проект?
GNU GPLv3.
Собственно хорошо, что напомнили сей факт отметить в шапке исходников, было упущено из виду.
Даже не LGPL?
Здравствуйте. Раньше не задавался вопросом лицензий, т.к. ничего не публиковал.
Я так понял, что LGPL не заставляет открывать производные исходники? Если так, то это, действительно, больше подходит.
Публикация под LGPL не требует получения соответствующего разрешения?
LGPL здесь тоже не очень подходит, т. к. линкуется статически. Хотя она допускает такой вариант, это приведет к необходимости предоставить пользователю конечной программы, содержащей эту библиотеку, как минимум объектные файлы и скрипты сборки, чтобы пользователь имел возможность перекомпоновать с иной версией библиотеки.

Иногда встречается варианты GPL со static linkage exception и другими оговорками. См., например, вариант GPL with exceptions для FreeRTOS. Там довольно подробно описывается, какие файлы считаются частью производной работы, а какие — нет (в частности, использование макросов не делает файл частью производной работы).

В общем, если не хочется таких заморочек и вы пишите маленькую библиотеку, то удобнее использовать пермиссивные лицензии типа MIT/X11, Apache, 2-clause BSD и т. п.

Для общего представления рекомендую на choosealicense.com/. Там есть наглядные и краткие таблички по разным лицензиям.
Отлично. Товарищ мне также посоветовал остановиться на MIT.
Обновил шапку, большое спасибо за информацию!
Спасибо! Пермиссивные лицензии для небольших проектов — максимальное переиспользование кода другими людьми.
А что, если написать эмуляцию протокола MTP? Там ОС допускает изменение файла, пока устройство подключено.
Как же мне он не нравится, сколько я мучался с плеером и смартфоном, хотя протокол имеет место быть.
Да, смотрел с самого начала в сторону MTP. Увы, он очень накручен и позволяет работать только с медиа-файлами (картинки, аудио, видео). Бинарник гонять по USB уже нельзя. Хотя сам концепт файл-обмена с «интеллектуальным» устройством — это, казалось бы, то что нужно.
Весьма! Может пригодится, утянул в избранное.
А вы не должны теперь отчислить денежек Microsoft'у за использование их технологии FAT32?
Оно же не exFAT, там должно было уже всё протухнуть, не? exFAT же не спроста появился…
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории