Usb storage stick что это
USB Mass Storage Device — что это?
USB Mass Storage Device — устройство, которое чаще всего является флешкой. Быстрый запуск диспетчера устройств: зажмите Win + R, введите команду devmgmt.msc, нажмите ОК.
Данное устройство вы можете увидеть в диспетчере задач, может быть например в разделе Universal Serial Bus controllers:
Если напротив нет восклицательного знака, значит винда флешку нормально увидела и проблем нет. Однако бывает что проблем нет, винда определила.. но неправильно.. в таком случае нужно шаманить с драйверами..
Хм, есть мысль, что если устройство неправильно обнаружено или если оно с воскликом — тогда может попробовать прогу по автоматической установки драйверов? Нет, я не рекламирую и не предлагаю какую-то ерундовину. Я лично пользовался DevID Agent, мне понравилось — вроде нет рекламы, все понятно, прога небольшая. Если будете ставить, то смотрите чтобы вместе с ней и Яндекс-софт не установился..
Нашел скриншот — получается USB Mass Storage Device может представлять из себя меню, раскрыв которое, вы увидите модель флешки:
Возможно что как раз в случае, когда такого меню нет и модели флешки не видно — тогда возможно проблемы с дровами. Правда можно попробовать их вручную установить.. Похожий пример:
Надеюсь кому-то инфа помогла. Удачи и добра, до новых встреч господа!
Настройки связи через USB: что такое режим MSC?
Не знаете, когда использовать режим MSC?
Это метод связи (протокол), используемый для передачи файлов. MSC специально разработан для передачи данных через интерфейс USB. Обычно это используется между USB-устройством (например, MP3-плеером) и компьютером.
Просматривая настройки вашего портативного устройства, вы, возможно, уже видели эту опцию. Если ваш MP3-плеер/портативное устройство поддерживает его, вы обычно найдете его в меню настроек USB. Не все устройства, которые вы подключаете к USB-портам вашего компьютера, будут поддерживать MSC. Вы можете обнаружить, что вместо этого используется какой-то другой протокол, например, MTP.
Несмотря на то, что стандарт MSC более старый и менее функциональный, чем более интуитивный протокол MTP, на рынке все еще есть множество потребительских электронных устройств, которые его поддерживают.
Этот режим передачи через USB иногда называют UMS (сокращение от USB Mass Storage ), что может сбивать с толку. Но это одно и то же.
Какие типы оборудования могут поддерживать режим MSC?
Примерами типов потребительских электронных устройств, которые обычно поддерживают MSC, являются:
Другие потребительские электронные устройства, которые могут поддерживать режим MSC, включают в себя:
Когда вы подключаете USB-устройство к вашему компьютеру, который находится в режиме MSC, оно будет отображаться как простое устройство хранения, которое, скорее всего, будет отображаться только с назначенной ему буквой диска. Это отличается от режима MTP, когда аппаратное устройство контролирует соединение и отображает удобное для пользователя имя, такое как: Sansa Clip +, 8Gb iPod Touch и т. Д.
Недостатки режима MSC для цифровой музыки
Как упоминалось ранее, устройство, находящееся в режиме передачи MSC, будет рассматриваться как обычное запоминающее устройство, например флэш-накопитель. Если вы хотите синхронизировать цифровую музыку, тогда это не лучший режим USB для использования.
Вместо этого более новый протокол MTP является предпочтительным режимом для синхронизации аудио, видео и других типов мультимедийных файлов. Это потому, что MTP может сделать гораздо больше, чем просто передача файлов. Например, это облегчает передачу связанной информации, такой как обложка альбома, рейтинги песен, списки воспроизведения и другие типы метаданных, которые MSC не может сделать.
Еще одним недостатком MSC является то, что он не поддерживает защиту от копирования DRM. Для воспроизведения песен с защитой от копирования DRM, которые вы загрузили из онлайновой службы подписки на музыку, вам нужно будет использовать режим MTP на портативном медиаплеере, а не на MSC.
Это связано с тем, что метаданные по лицензированию музыки необходимо будет синхронизировать с портативным компьютером, чтобы воспроизводить песни по подписке, аудиокниги и т. Д. Без этого файлы не будут воспроизводиться.
Преимущества использования MSC
Есть моменты, когда вы захотите использовать устройство в режиме MSC, а не более полнофункциональный протокол MTP. Например, если вы случайно удалили некоторые из своих файлов песен, вам понадобится программа для восстановления файлов, чтобы восстановить ваши MP3. Однако устройство, находящееся в режиме MTP, будет контролировать соединение, а не операционную систему вашего компьютера. Это не будет выглядеть как обычное устройство хранения данных, поэтому ваша программа восстановления, вероятно, не будет работать.
MSC имеет преимущество в этом сценарии, потому что его файловая система будет доступна так же, как обычный съемный диск.
Другое преимущество использования режима MSC состоит в том, что он более универсально поддерживается различными операционными системами, такими как Mac и Linux. Для использования более продвинутого протокола MTP на компьютере, отличном от Windows, может потребоваться установка стороннего программного обеспечения. Использование режима MSC устраняет необходимость в этом.
USB stick
Содержание
Описание [ | ]
Основное назначение USB-накопителей — хранение, перенос и обмен данными, резервное копирование, загрузка операционных систем (Live USB) и др.
Основные компоненты флешки:
На большинстве флешек повсеместно используются файловые системы семейства FAT. В зависимости от размера накопителя применяются FAT16, FAT32 или exFAT. Для флешек размером 64 ГБ и более используются NTFS или exFAT.
Дизайн [ | ]
Некоторые варианты дизайна USB-флеш-накопителей:
Простая форма, фиксированный USB-разъём
Простая форма, выдвигающийся USB-разъём
Декоративный внешний вид корпуса (имитация суши)
Инкрустированная бриллиантами флешка Uniq
С USB-разъёмом типа А и microUSB-разъёмом типа B (для подключения к смартфонам, планшетам и т. д.)
Миниатюрных размеров с цельнозалитым корпусом и без металлической рамки USB-разъёма типа А
Накопители с комбинированными интерфейсами USB-флеш и Secure Digital
История [ | ]
[3] Первые USB-флеш-накопители появились в 2000 году. С 1998 по 2000 годы многие компании и отдельные лица заявляли о своём первенстве в их изобретении.
Одновременно с этим сингапурская компания Trek Technology представила свою разработку, повторяющую патент от M-Systems. Своё детище ThumbDrive объёмом 8 Мб они презентовали в феврале 2000 года на выставке CeBIT в Германии. Trek Technology смогла доказать своё первенство в Сингапуре, но проиграла иски, поданные в других странах.
Китайская компания Netac Technology также претендует на первенство в изобретении USB-флеш-накопителя.
Преимущества и недостатки [ | ]
Безопасность [ | ]
Флеш-накопитель — это один из самых распространённых носителей данных на сегодня. Вследствие включённой по умолчанию возможности одной из наиболее распространённых операционных систем — Windows (начиная с Windows 95 [9] ) — позволять автозапуск со сменных носителей, флеш-накопители способствуют распространению вирусов в среде Windows при обмене информацией.
Передача данных в портативных мультимедиа-плеерах: Mass Storage
В предыдущей статье мы попытались описать тот хаос, который творился в 1998-2003 гг. в области протоколов сопряжения плееров с ПК. Период 2003-2004 гг. стал для отрасли временем упорядочения. Множество ручейков проприетарных протоколов сменилось тремя стройными потоками. Точнее, двумя с половиной, т.к. два из этих потоков представляли собой вариации одного и того же протокола.
Чистый Mass Storage использовался наибольшим количеством производителей, особенно компаниями небольшого калибра из Кореи или Китая. В России он стал наиболее популярным протоколом. О нем наш сегодняшний рассказ.
Для обозначения Mass Storage «в быту» используются две аббревиатуры – MSC и UMS. MSC (Mass Storage Class) является официальной, а UMS (возможны варианты расшифровки: USB/Universal Mass Storage) – «народной». Друг другу они не противоречат, а скорее дополняют.
MSC сообщает о том, что протокол входит в число утвержденных стандартных «классов устройств» в рамках спецификации USB и тем самым является индустриальным стандартом де-юре. UMS говорит об универсальности протокола, который на сегодня поддерживается большинством операционных систем и бесчисленным множеством конечных устройств, что делает его стандартом и де-факто. Вариант расшифровки UMS как USB Mass Storage дополняет эту информацию, уточняя, что в качестве физической линии используется интерфейс USB. Буквы MS (Mass Storage), общие для всех аббревиатур, показывают, что перед нами протокол, предназначенный для работы с устройствами хранения больших объемов данных. Именно для них и был разработан данный стандарт – для «флэшек», карт-ридеров, мобильных HDD-накопителей. Как он попал в портативные плееры?
Протокол Mass Storage задумывался в первую очередь для подобных устройств. Его появление в MP3-плеерах было вынужденным шагом
В прошлых материалах мы неоднократно говорили о том, как стихийно, неожиданно появились и начали развиваться портативные аудиоплееры. Индустрия просто не хотела их замечать, сначала в силу их маргинальности, позже – из-за надуманной связи этих устройств с цифровым пиратством. Это имело много последствий, и одним из них было то, что плееры «обошли» при раздаче классов устройств USB.
Взглянем на список этих классов: тут есть и внешние звуковые карты, и коммуникационные устройства, и отдельный класс для периферии типа мышей и клавиатур, есть свои классы для принтеров, USB-хабов, вэб-камер, адаптеров беспроводной связи. Свой класс есть и для цифровых камер. И только аудио- и мультимедиа-плееры остались в категории «прочие».
Среди стандартных классов USB нашлось место для самых разных устройств. Но только не для мультимедиа плееров
Добрых лет пять никто не задумывался о разработке отдельного класса для них. Производителям оставалось выбирать из того, что есть.
На этом фоне MSC/UMS был единственным универсальным решением. Если ограничивать задачи исключительно «тупой» загрузкой контента в плеер, то ничего больше и не нужно. К тому же, протокол позволял превратить плеер в мобильный накопитель. Простые продавцы и покупатели и сейчас описывают плееры с данным протоколом как «работающие как флешка», «подключающиеся как флеш-накопитель» «программы ставить никакие не надо», «можно файлы хранить» и т.д. и т.п.
Простенький плейдрайв – «MP3-Stick» и Mass Storage протокол – созданы друг для друга
Эта дополнительная возможность хорошо вписывалась в подход «много-в-одном», выбранный азиатскими производителями MP3-плееров. Именно они стали пионерами в адаптации MSC/UMS в аудиоплееры. Они и компания Sigmatel, чья платформа STMP3400 в начале 2003 года начала поддерживать этот протокол.
Январь 2003 года – Sigmatel объявляет о поддержке Mass Storage в своих платформах D-Major
Достоинства протокола. Главное – простота: все операции осуществляются через стандартные файловые оболочки, в т.ч. Windows Explorer (Проводник), никакие дополнительные знания или обучение для работы с ним не требуются.
Распространенность – уже Windows Me и 2000 имели базовую поддержку протокола, Windows XP поддерживал его полностью. Множество других ОС – MacOS, Linux и т.п. – совместимы с Mass Storage.
ОС, в том или ином виде поддерживающие Mass Storage протокол
Сегодня сложнее найти ПК, не поддерживающий этот протокол. Поддержка в данном случае означает наличие драйверов протокола в составе операционной системы.
Mass Storage плеер на 1.8” жестком диске Toshiba подключен к ПК. Как MSC-устройство он использует стандартный драйвер USBSTOR.SYS, входящий в состав ОС. Как накопитель он также использует стандартные драйверы Windows. Установка дополнительных драйверов не требуется.
Так как вся работа с контентом также ведется стандартными средствами, через Windows Explorer (Проводник), у пользователя вообще не возникает необходимости в установке чего бы то ни было: вся поддержка протокола уже встроена в ОС.
Плеер виден в Проводнике Windows как еще один жесткий диск. Вся работа с контентом ведется в Проводнике или любом файловом менеджере на выбор пользователя. Установка дополнительного программного обеспечения не требуется
Получается настоящий Plug-and-Play: вынул из коробки, подключил и пользуйся. По таким параметрам, как прозрачность, невидимость для пользователя этот протокол просто не имеет равных.
С точки зрения совместимости с портативными устройствами у нас тоже все хорошо: протокол не зависит от файловых систем и может работать с любой из них, если она поддерживается ОС.
Немаловажным является существование спецификации USB host (on the go), позволяющей подключать Mass Storage устройства к другим портативным (и не портативным) аппаратам. Сегодня MSC-совместимый плеер можно подключить к обширному перечню устройств, будь то игровая приставка, стереосистема, автомагнитола, FM-трансмиттер, другой плеер.
Набирают популярность автомобильные FM-трансмиттеры, позволяющие подключать к себе любой Mass Storage плеер
Недостатки протокола являются продолжением его достоинств. Его функциональность является базовой, примитивной. Фактически он не способен ни на что, кроме копирования данных взад-вперед.
Но данные, с которыми имеет дело плеер, являются больше чем просто набором двоичных символов, это контент. У каждой единицы контента, будь то песня или файл, есть целый ряд свойств, таких, как название, формат, автор, продолжительность и т.п. Отдельные единицы могут быть частью более сложных совокупностей, таких, как альбом, плей-лист.
Ни о чем подобном Mass Storage знать не знает, что возлагает все заботы о менеджменте контента либо на пользователя, либо на встроенное ПО плеера. Последнее же чаще всего не способно эффективно справляться с задачей управления большим количеством контента. Как следствие, большинство MSC/UMS-плееров имеют крайне бедный механизм навигации – по папкам, аналогично навигации в Windows Explorer. При этом не используется значительный объем информации, содержащийся в метаданных, тэгах, который удобен для классификации контента.
Информация, которая может содержаться в тэгах (на примере программы MP3tag). Мало что из этого используется в Mass Storage плеерах
Пользователь вынужден организовывать свой контент самостоятельно, с помощью системы вложенных папок. При этом, избрав, к примеру, систему классификации «песня-альбом-автор», он не сможет быстро и безболезненно перейти к системе «песня-жанр» или «песня-год записи», ему придется перетряхивать всю библиотеку.
Очень слаба по своим возможностям организация таких плеерах плей-листов. Плей-лист обычно возможен только один. Работа с плей-листами возложена исключительно на само устройство, и если через ПК в режиме MSC/UMS был удален один из файлов, входящих в плей-лист, это может нарушить работу всего листа в целом. Такая премиум-возможность, как отображение обложки альбома (Album Art или Jacket), «чистым» MSC/UMS-плеерам недоступна в принципе. Теоретически ее можно реализовать загрузкой графического файла из папки, но на практике никто этого пока не сделал. А если сделает, пользователю придется вручную рассовывать во все папки соответствующие картинки. Некоторые плееры имеют возможность отображения слов песни (Lyrics), но берутся эти слова не из метаданных: пользователю приходится самостоятельно подготавливать их с помощью специальной программы.
Во всем этом главная проблема Mass Storage. Плеер – это больше, чем просто мобильный накопитель, для эффективной работы он должен иметь глубокое понимание того, что, собственно, хранится в его памяти. Будучи современным мультимедийным устройством, рассчитанным на самый широкий круг пользователей, он не может просто пробубнить подряд все, что на него записано. Он должен уметь рассказать о том, что мы смотрим или слушаем, причем кратко, исчерпывающе и ненавязчиво, как высококлассный конферансье. Он, словно опытный библиотекарь, должен помочь нам быстро найти среди тысяч песен именно то, что нам нужно, даже если мы подзабыли название. Во всем этом предельно ограниченный в своих возможностях протокол MSC/UMS ему не помощник. И свежий зажигательный шлягер, и кандидатская диссертация, и своп-файл Windows для него являются лишь безликими массивами данных. Это превращает протокол в своего рода обезличивающее «бутылочное горлышко» между двумя мощными мультимедиа-системами – плеером и ПК. На плечи последних падает вся тяжесть преобразования безликого потока информации в удобную для пользователя форму.
На ПК все зависит от самого пользователя: проявит он усидчивость и изобретательность – организует музыкальную библиотеку на зависть всем. А может и просто сваливать все в одну папку, пока там не станет совершенно невозможно что-то найти.
На плеере же все зависит от разработчика, а они вовсе не горят желанием прилагать большие усилия для разработки мощной программной начинки. В результате конферансье из таких плееров так себе – монотонным голосом он прочитает название песни, автора, в лучшем случае – альбома. А может и вовсе только имя файла.
Интерфейс iPod по сравнению с интерфейсом Mass Storage плеера iriver h300 выглядит более спартанским, но при этом отображает значительно больше информации о проигрываемом треке. При этом плеер от iriver – это еще относительно удачный пример Mass Storage плеера
И библиотекарь он никудышный – так, рукой направление укажет, где искать, но не более.
Пользователь Mass Storage плеера (Cowon X5 в данном случае, слева) при поиске интересующей композиции может руководствоваться только логикой папок и файлов, созданной им самим. В случае применения иных решений (как в Creative Zen Touch, справа) у них есть возможность свободного поиска по параметрам
Есть отдельные исключения (например, плееры от Archos), но их не много.
Эта ситуация имеет очень простое следствие. Пользователи, которые с компьютером «на ты», привыкшие к концепции файлов и папок, не сильно требовательные к внешним эффектам и быстро приспосабливающиеся к новому, стоят горой за чистый Mass Storage. Прозрачность, открытость и распространенность протокола для них преимущества, рядом с которыми меркнут все минусы.
Компании iriver и Cowon своей популярностью среди определенных слоев покупателей обязаны не в последнюю очередь поддержке «свободного» Mass Storage
А вот пресловутые «обычные» пользователи не очень довольны. Для них плеер – это все-таки не флэшка, не хранилище для файлов, а плеер. Аккуратно сооружать пирамиду файлов и папок музыкальной библиотеки у них нет никакого желания, бродить в недрах этой пирамиды на экране плеера, ориентируясь лишь на названия папок, – тоже. Навигация по метаданным, проигрывание с красивым Album Art, автоматическая загрузка на плеер новых песен – все это им гораздо ближе. Значительное количество возвращенных в магазин и обменянных на iPod-ы MSC/UMS-плееров в тех же Соединенных Штатах – тому подтверждение.
И все же тон в отрасли задают производители, не использующие чистый Mass Storage
Есть и еще одна категория недовольных протоколом. Это студии звукозаписи и киностудии. Безразличный ко всему, Mass Storage уж точно никак не сможет отличить «пиратский» трек от честно приобретенного. Производитель, плееры которого поддерживают загрузку контента через «чистый» Mass Storage, вряд ли могут рассчитывать на плодотворное сотрудничество с крупными лейблами. Конечно, небольшим компаниям оно не очень-то и нужно. Но крупные корпорации, желающие дать пользователям вертикальное решение, включая приобретение контента, вынуждены принимать этот фактор во внимание.
В результате производитель, желающий создать плеер, который:
– вынужден искать решения за рубежами возможностей «чистого» Mass Storage.
USB на регистрах: bulk endpoint на примере Mass Storage
В прошлый раз мы познакомились с общими принципами организации USB и собрали простое устройство, иллюстрирующее работу конечной точки типа Control. Пришло время изучать следующий тип — Bulk. Конечные точки такого типа предназначены для обмена большими объемами информации, причем чувствительной к надежности, но не скорости обмена.
Классические примеры — запоминающие устройства и переходники вроде USB-COM. Но переходники требуют еще наличия конечной точки типа Interrupt, которую мы пока «не проходили», так что остановимся на эмуляции флешки. Точнее, двух флешек одновременно.
Рекомендую параллельно сравнивать написанное с исходным кодом.
Дескриптор
Здесь мы видим сначала заголовок дескриптора с полной длиной и другими неинтересными параметрами. Потом идет описание единственного интерфейса запоминающего устройства, в котором важно правильно указать поля Class, Subclass и Protocol — именно они отвечают за правильную идентификацию устройства в системе. Также важное поле bNumEndpoints, которое показывает сколько конечных точек нашему интерфейсу принадлежит. В нашем случае их две: на чтение и на запись. И тут же идут их описания, в которых внимание нужно уделить номеру (в номере конечной точки типа IN также выставлен 7-й бит, что прописано в дескрипторе как OR с 0x80) и размеру. Организация конечных точек в STM32 позволяет один номер точки использовать как на передачу, так и на прием. Существует еще альтернативный режим, в котором направление у точки одно, а буфер «комплементарной» точки используется для двойной буферизации. По идее, это может повысить скорость, но мы так делать пока не будем и воспользуемся более простым способом — приемник и передатчик, 0x01 и 0x81. А вот поле частоты опроса роли не играет вообще: пока данные для передачи есть, хост будет нашу точку дергать так часто, как только сможет, а когда данные закончатся — оставит в покое.
Еще пару слов надо сказать про размер конечных точек. Согласно стандарту [1], он должен быть равен 8, 16, 32 или 64 байта. Правда, покупные флешки как-то умудряются использовать и 512-байтные… В любом случае, делать полноценную флешку на контроллере общего назначения не самая удачная идея, так что оставим 64 байта. Да и места под буферы у нас немного.
Приведенные в этом примере константы для Class / Subclass / Protocol не являются единственно возможными. Скажем, можно попытаться эмулировать флоппик (Subclass = 0x04 вместо нашего 0x06). И оно при подключении даже показывает красивую иконку дисекты. Правда, не в винде — очевидно, она использует какие-то специфичные запросы и не верит, что бывают флоппики, их не поддерживающие. Но до специфичных запросов мы еще доберемся. Еще, если поменять Protocol, можно воспользоваться для обмена не только Bulk-точками, но и Interrupt. Но опять же, Interrupt мы не проходили, да и реальные флешки таким тоже не пользуются.
Помните, у нас в DeviceDescriptor (который почти ни за что не отвечает, поэтому не меняется и поэтому же здесь не приведен) есть поле iSerialNumber? Так вот, на этом поле растут грабли! Стандарт предписывает последние 12 символов использовать для идентификации экземпляра устройства. Соответственно, «хвост» этой строки должен представлять собой последовательность шестнадцатеричных цифр (‘0’-‘9’, ‘A’-‘F’), закодированных в 16-битной кодировке. Есть подозрение, что перед ними можно оставить осмысленный текст. А практика показала, что и количество «цифр» может быть меньше 12-и.
Скажем, в моем примере вся строка состоит из единственного символа u»1» и, кажется, работает. Но вот подставлять туда не-шестнадцатеричные символы все же не стоит: некоторые версии Windows такого пугаются и не хотят с устройством работать.
SETUP запросы
Несмотря на то, что обмен данными идет только через Bulk-точки, кое-какая информация передается и через ep0 по соответствующим запросам. Нам понадобится всего два таких запроса — USBCLASS_MSC_RESET и USBCLASS_MSC_GET_MAX_LUN, причем первый (ресет) мы пока проигнорируем. А вот второй стоит рассмотреть подробнее. Дело в том, что запоминающее устройство по логике авторов стандарта состоит из независимых логических блоков (адресуемых по logical unit number, LUN), с каждым из которых можно общаться независимо. Дальше мы увидим, что в протокол обмена всегда входит поле bLUN, именно за это отвечающее. Всего в одном устройстве их может быть до 15 штук. Правда, никто не запрещает сделать составное устройство, где по 15 «носителей» будет в каждом. В общем, важная это штука, обрабатываем обязательно. Тем более что в качестве ответа на этот запрос достаточно вернуть всего один байт с номером последнего unit’а. Важно! Не количество, а именно номер. То есть если устройство у нас всего одно с lun=0, то и вернуть надо 0, а не 1.
Принцип обмена bbb
BBB (bulk/bulk/bulk) или, что тоже самое, BOT (bulk only transport) — протокол обмена [1], при котором используется единственный тип конечной точки. Через нее передаются команды, через нее же передаются данные и через нее же успешность команд контролируется. Собственно всю логику обмена я сейчас и описал. Перейдем к подробностям:
Передача команд осуществляется всегда от хоста к устройству, то есть через конечную точку типа OUT, и представляет собой структуру следующего вида:
поле dSignature — волшебное чиселко, равное 0x43425355 (или же 4 символа »USBC»), передающееся хостом для синхронизации. Благодаря им устройство могло более-менее достоверно отличить начало команды от простого потока данных. Дальше идет dTag — порядковый номер команды чтобы если хост не дождался завершения команды и послал другую, смог отличить ответы. Это число надо будет куда-нибудь сохранить, а потом хосту вернуть.
Следующее поле, dDataLength, ограничивает количество байтов ответа. То есть наша посылка не может быть больше, чем dDataLength байт. Поле bmFlags для нас бесполезно, оно по большей части состоит из устаревших настроек. А вот bLUN это то, о чем я говорил раньше — номер «носителя», с которым хочет пообщаться хост. Если носитель у вас единственный, оно всегда будет равно нулю. Но в данном примере мы сделаем их два, так что этот самый LUN придется активно читать. bCBLength — снова бесполезное поле, которое показывает размер дополнительных данных… как будто мы его и так не знаем. И наконец, CB[] — данные, специфичные для конкретного запроса. Их мы будем рассматривать только применительно собственно к запросам. Хотя нет, не совсем так. Поле CB[0] собственно за запрос отвечает, поэтому его мы будем читать и по нему же определять как на данный запрос реагировать.
А реакция может заключаться либо в чтении данных размером dDataLength от хоста, либо запись данных того же объема. Формат этих данных зависит от принятой команды, так что пока не будем углубляться.
И наконец идет подтверждение — специальная структура следующего вида:
Поле dSignature, как и в случае запроса, является магическим чиселком, но другим: 0x53425355 (оно же строка u»USBS»). А вот поле dTag должно в точности совпадать с полученным нами при начале обмена. Смысл следующего поля, dDataResidue, я не слишком понял. Вроде бы оно содержит количество данных, которое мы хотели передать хосту, но в dDataLength не влезло, но не похоже чтобы значение там на что-то влияло. Пожалуй, самое важное поле здесь — bStatus. Если что-то пошло не так, по нему хост может увидеть, что команда завершилась ошибкой и надо что-то делать.
В результате первая посылка всегда идет от хоста, вторая либо от хоста, либо от нас, и третья — всегда от нас.
Реализация этого алгоритма может показаться неочевидной, поэтому рассмотрю ее подробнее:
Как уже было сказано, обмен начинается с того, что в конечную точку OUT приходит посылка от хоста. Проблема в том, что размер посылки составляет 31 байт, а размер конечной точки может быть и 8 байт, так что стоит предусмотреть прием по частям. К счастью, пока мы не ответим на один запрос, другого нам слать не будут (если не вылетим по таймауту, конечно), поэтому для хранения запроса и ответа заведем глобальные переменные
И до тех пор пока количество принятых байтов не сравняется с размером запроса, читать будем именно туда. Если последний байт принят «в нашу смену», то не спешим выходить, а сразу запускаем обработчик команд scsi_command() и даже пересылку ответа (мы ведь помним, что для начала IN транзакции первый пакет надо передать вручную). Но вот запросы на чтение обрабатывать сразу не выйдет, ведь в буфере приема у нас «хвост» команды, а вовсе не данные.
Поэтому scsi_command() только выставляет количество данных (bytestoread). В частности, может выставить в 0 чтобы показать что чтение не нужно. Таким образом дальнейший прием будет повторяться пока количество реально принятых байтов bytescount не достигнет желаемого. После чего все равно произойдет ручной вызов обработчика конечной точки IN, которая пошлет если не данные, то хотя бы отчет об успешности.
Собственно, устройство точки IN не слишком отличается от OUT. Основная разница, что она сначала пытается передать bytestowrite байтов и только потом структуру msc_csw с использованием ее персонального счетчика msc_csw_count.
Организация памяти и прочие извращения
Раз уж решили реализовать несколько LUN’ов, имеет смысл и внутреннюю организацию им сделать максимально различной (впрочем, максимальной она не получилась, чуть позже объясню почему). Причем желательно обойтись без возни с подключением к контроллеру периферии Допустим, LUN=0 будет отображением части флешки контроллера (а поскольку возиться с записью на нее данных опять же лень, сделаем ее read-only), а LUN=1 — оперативки.
Объем флешки у L151 целых 256 кБ, но ведь нам его еще программировать, а это долго.
Ограничимся объемом 100 кБ: на таком объеме уже можно создать файловую систему FAT и даже место для файлов останется. Оперативки у нас поменьше, всего 32 кБ, от которых мы откусим 29 кБ и заполним первый «сектор» копией из образа флешки. Пусть тоже будет считаться FAT’ом, хотя и корявым. Впрочем, если будете экспериментировать с моим кодом, рекомендую взять образ флешки поменьше, чтобы не ждать минуту пока оно прошьется.
Собственно, от его (своего) имени и кидаем туда файлы. Из хулиганских соображений я предпочел записать туда исходники прошивки. Только надо учитывать, что винда не поймет обычный конец строки ‘\n’, ей надо ‘\r\n’. То есть открываем каждый скопированный файл и меняем ему формат конца строки. Возможно, это как-то делается и из консоли, но я не искал.
Наконец снова заходим в рута дабы отмонтировать образ umount /mnt
Сразу предупреждаю: я не знаю как подобное делается в Windows. Не исключено, что по-человечески оно там вообще не делается, придется искать и скачивать какие-то сторонние программы. Ну или пользоваться для тестов каким-то из моих образов.
Обязательные команды
Все команды, с которыми мы будем иметь дело, относятся к семейству SCSI (Small Computer System Interface) — интерфейсу обмена данными с носителями информации и много чем еще. Причем не только по USB.
Обязательными для реализации являются следующие (достаточно подробно описаны тут):
Также еще несколько запросов, которые формально не обязательны, но лучше бы их реализовать
Первым делом хост запрашивает у носителей данных подробности их внутреннего устройства, посылая для этого запрос SCSI_INQUIRY. В ответ он ожидает очередную волшебную структуру, подробно рассматривать которую я не хочу. Для нашего случая достаточно скопировать готовую и немного поиграться с константами. Скажем, поменять строку вендора. Или, например, нулевой байт изменить с 0x00 на 0x05 чтобы данный LUN считался не просто носителем, а CD/DVD диском. Правда, одного этого недостаточно: необходимо дописать поддержку каких-то специфичных запросы. Поэтому уж настолько извращаться не будем… а жаль
Далее идет запрос емкости (SCSI_READ_CAPACITY), на который надо ответить двумя 32-битными числами (суммарно 8 байт, очевидно): 0-3 байты это номер последнего блока, а 4-7 это размер одного блока. Дело в том, что носители данных не обеспечивают доступ к отдельному байту — только к блоку размером обычно 512 байт. На такие же блоки устройство поделим и мы.
Обратите внимание, что передается не количество блоков, а, как и в случае LUN, номер последнего. То есть uint32_t last_lba = capacity / 512 — 1;
Внимание, грабли! Винда почему-то не полагается на запрос SCSI_READ_CAPACITY, а отправляет SCSI_MMC_READ_FORMAT_CAPACITY с немного другим форматом. И ее не волнует что этот запрос не обязателен для реализации, так что после получения ошибки «запрос не поддерживается» она еще долго отключает-подключает устройство в надежде что то образумится. Если не хотите полчаса ждать пока винда таки смирится что неподдерживаемый запрос не поддерживается, лучше этот запрос реализовать. Как несложно догадаться, линукс ведет себя адекватно и понимает с первого раза.
Еще один запрос, который имеет смысл обработать — SCSI_MODE_SENSE_6. Точнее, опять забить вместо ответа чей-то готовый кусок. 1-й байт в нем отвечает за размер посылки и будет равен 3, второй байт описывает тип носителя (что-то вендор-специфичное, оставим ноль).
Третий байт самый для нас интересный. Его 7-й бит означает защиту от записи, его мы и взведем для 0-го LUN чтобы хост даже не пытался писать в нашу флеш-память. Вот в LUN=1 (оперативка) — другое дело, там этот бит будет нулевым и пусть пишет на здоровье.
Потом хост проверяет готов ли вообще носитель с нужным номером к обмену (SCSI_TEST_UNIT_READY), причем пакет данных ему для ответа не нужен — достаточно кода ошибки: готов — не готов.
Далее по хронологии должен идти рассказ про чтение и запись, но их мы оставим на конец.
Хост может попытаться управлять подключением носителей данных при помощи команд SCSI_MMC_START_STOP_UNIT и SCSI_MMC_PREVENT_ALLOW_REMOVAL, причем если они не поддерживаются, ругается что не может отмонтировать устройство. Впрочем, заглушки, возвращающей «все хорошо» ему достаточно, так что глубже я и не копал. В реальном применении покопать все же придется, поскольку некоторой периферии нужно больше нуля секунд для корректного завершения работы. А пока она медленно отключается, надо попросить хоста чтобы подождал.
Если что-то пошло не так (на этапе подтверждения устройство вернуло ошибку), хост запрашивает по этой ошибке подробности (SCSI_REQUEST_SENSE) — массив из трех байтов, кратко поясняющих что же именно случилось. Чаще всего у нас будет случаться SBC_SENSE_KEY_ILLEGAL_REQUEST (неподдерживаемый запрос), но в принципе таким же способом сообщают о неготовности носителя данных и многом другом. Кстати, раз запрос подробностей ошибки — отдельный запрос, то и хранить результат предыдущего надо в отдельной переменной, msc_sense.
READ / WRITE
Ну и наконец самое интересное — чтение и запись данных. На самом деле это не один запрос, а целое семейство, отличающихся размером. Скажем, бывают READ(6), READ(10), READ(12), даже READ(16), которые занимают в msc_cbw.CB соответственно 6, 10, 12 и 16 байтов. Мы будем пользоваться READ(10). И WRITE(10), естественно. Формат у них одинаковый, отличается только направление передачи: от хоста к устройству или от устройства к хосту. Структура запроса такова:
Из нее нас интересуют только поля block_address и length — номер первого блока, который предстоит прочитать и количество этих блоков. Напоминаю, что размер блока мы сообщили хосту раньше, по запросу SCSI_READ_CAPACITY и что составляет он у нас 512 байт.
Следовательно, адрес первого байта, с которого начнем чтение, равен block_address * 512, а их суммарное количество length * 512.
Из соображений простоты демонстрационного кода (ну и из лени, конечно) посекторной работы с внешней памятью вы здесь не увидите. В самом деле, что к оперативке, что к флешке контроллера доступ побайтный. Но вот при взаимодействии с более сложной периферией вроде SD-карточек уже придется лавировать между прерываниями USB и этой периферии. Возможно, кстати, работу с USB будет проще осуществлять опросом, чем прерываниями. По той же причине выбор нужного буфера на чтение или запись остался в обработчике IN и OUT, а не в scsi_command.
Заключение
Вот мы и познакомились в общих чертах с принципом передачи данных в запоминающих устройствах и даже заставили макетную плату прикидываться одновременно read-only флешкой, накоторую записаны ее же исходники, и энерго-зависимой флешкой, которая информацию не сохраняет при отключении. Заодно протестировали работу конечной точки типа Bulk и обнаружили что ее использование не особо отличается от других.
Хотелось бы, конечно, еще сэмулировать флоппик и оптический дисковод, но там используются какие-то свои, специфичные команды. В рамках данной статьи это было бы неуместно.
Если кто-то захочет повторить данную конструкцию, исходный код как обычно в репозитоии, туда же я добавил найденную литературу, поскольку это уже какая-то нездоровая традиция создавать на ровном месте проблемы со скачиванием официальной документации.
[1] Universal Serial Bus Mass Storage Class Bulk-Only Transport копия
[2] Universal Serial Bus Mass Storage Class Specification Overview копия
[3] SCSI Multimedia Commands – 2 (MMC-2) копия
[4] SCSI Primary Commands-3 (SPC-3) копия
[5] SCSI Commands Reference Manual (от Seagate) копия