Almaz1988 4 15 марта, 2018 Опубликовано 15 марта, 2018 · Жалоба Добрый день! Имеется печатная плата, на которой расположена ПЛИС как основное устройство и микроконтроллер STM32, как вспомогательное устройство для загрузки конфигурационного файла в ПЛИС. Замысел следующий - STM32 реализует USB Mass storage, в результате, пользоваттель, при подключении по USB видит подключенную к компу флешку, загружает на эту флешку bit-файл, которым инициализируется ПЛИС. Реализовал данное устройство с памятью во внутренней памяти микроконтроллера, но проблема в том, что она меньше размеров загрузочного файла. Сам файл мне сохранять в памяти не нужно, - требуется лишь дергая ножками STM32 загрузить его в ПЛИС, соответственно нужно эмулировать для компа память большего размера, а для этого, необходимо парсить usb-запросы от компа на запись и считывание. Сама реализация USB mass storage устройства в STM32 - проще некуда, достаточно реализовать лишь две функции STORAGE_Write_FS и STORAGE_Read_FS См. файл по ссылке: https://cloud.mail.ru/public/ALsV/UTQGUYgwo Мне нужно модифицировать их так, чтобы понимать, что в данный момент времени пришел запрос на загрузку файла, вычитать его данные, делая вид, что сохраняю его во флеш, а на самом деле передать его в ПЛИС, а в ответ на запрос на считывание его просто вернуть набор нулей. Кто-нибудь сталкивался с подобной задачей? Поделитесь мануалами, примерами кода, описанием протокола usb-команд к usb mass storage. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_4afc_ 25 15 марта, 2018 Опубликовано 15 марта, 2018 · Жалоба Замысел следующий - STM32 реализует USB Mass storage, в результате, пользоваттель, при подключении по USB видит подключенную к компу флешку, загружает на эту флешку bit-файл, которым инициализируется ПЛИС. Реализовал данное устройство с памятью во внутренней памяти микроконтроллера, но проблема в том, что она меньше размеров загрузочного файла... Кто-нибудь сталкивался с подобной задачей? Делали - двумя способами: 1. Запись файла с определённым именем: нужна поддержка файловой системы типа Х внутри МК и отслеживания появления файла. Мы проверяли наличие файла при подаче питания на карте памяти. После прошивки его удаляли и перезагружались. В вашем случае не подойдёт - памяти мало. Можно конечно парсить на лету диск, чтоб понять, что запись сектора - это создание файла... это будет увлекательно, но примеры врятли есть - надо писать самому. 2. Запись в определённые сектора. Делается виртуальный диск любого размера. Записываете файл через любую утилиту типа HxD. Можно и своё приложение написать, только для работы с секторами под виндой - потребуются права администратора... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Almaz1988 4 16 марта, 2018 Опубликовано 16 марта, 2018 · Жалоба Можно конечно парсить на лету диск, чтоб понять, что запись сектора - это создание файла... это будет увлекательно, но примеры врятли есть - надо писать самому. Видимо, это единственный возможный вариант. Попытался прикрутить библиотеку FatFS от Chan - не хватает памяти. Пока удалось следующее: Во флеш-память usb mass storage устройства загрузил файл с наименованием "00000.txt" и содержимым "77777", т.е. обычный текстовый файл размером 5 байт. После этого считал память МК. USB mass storage устройство имеет размер 43 блока по 512 байт. 20 КБ из них занято файловой системой FatFS, т.е. устройство после подключения к ПК по USB имеет размер 1.5 КБ: 43 * 512 = 0x5600 Глянул содержимое памяти HEX-редактором и действительно, флеш-память МК начиная с адреса 0x08010000 по которому хранится содержимое usb mass устройства по адрес 0x08015600 Содержит осмысленные данные. Вся остальная память после 0x08015600 заполнена FF. Вырезал данный кусок памяти 0x08010000 - 0x08015600в отдельный файл (он в приложении). Ищу кодовую последовательность 30 30 30 30 30 ( "00000" в ASCII кодах, т.е. наименование файла) - вижу ее по адресу 0x1060: Кодовая последовательность 37 37 37 37 37 ( "77777" в ASCII кодах, т.е. содержимое файла) расположена по адресу 0x5400: Адрес 0x5400 соответствует началу последнего сектора (размер сектора 512 байт = 0x200). Интуиция подсказывает, что рядом с названием файла должен располагаться указатель на адрес, по которому расположено содержимое файла и его размер. Видимо предстоит раскуривать какую-либо библиотеку, реализующую FatFS, например, того же самого Chan'а в поисках нужного куска кода, который откроет свет на взаимосвязь между названием файла и его расположением. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 16 марта, 2018 Опубликовано 16 марта, 2018 · Жалоба Реализовал данное устройство с памятью во внутренней памяти микроконтроллера, но проблема в том, что она меньше размеров загрузочного файла. Сам файл мне сохранять в памяти не нужно, - требуется лишь дергая ножками STM32 загрузить его в ПЛИС, соответственно нужно эмулировать для компа память большего размера, О каком размере файла хоть речь-то? Вообще в любом STM32 есть довольно большой объём памяти - flash-памяти программ. Почему не использовать её раз уж так хочется mass storage? Но я бы не заморачивался: раз USB, значит - реализовать DFU. DFU именно для того и предназначен (обновления прошивки). Вместо странного использования mass storage. Ну или хоть сделать CDC и передать туда файл прошивки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andreas1 1 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Mass Storage - просто считывание/запись сектора и ФС вы уже сами должны изображать. По минимуму в флеше STM32 должно хранится содержимое 4 секторов по 512 байт: mbr, boot, fat, root с прописанными туда данными вашего файла. При этом отдавать в зависимости от номера запрошенного сектора или эти предопределенные сектора, или выкачанную по SPI вашу прошивку. Записывать можно примерно также, но желательно размер носителя сделать равным размеру прошивки+служебная область файловой системы. При этом новая прошивка будет перезаписывать старую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Almaz1988 4 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба О каком размере файла хоть речь-то? Вообще в любом STM32 есть довольно большой объём памяти - flash-памяти программ. Почему не использовать её раз уж так хочется mass storage? Но я бы не заморачивался: раз USB, значит - реализовать DFU. DFU именно для того и предназначен (обновления прошивки). Вместо странного использования mass storage. Ну или хоть сделать CDC и передать туда файл прошивки. Размер файла от 1-го МБ/ USB Mass storage - требование заказчика. Ему хочется, чтобы обновление прошивки ПЛИС выглядело простой записью файла на флешку, подключенную к ПК по USB. И роль этой флешки должна играть STM32 с размером флеш-памяти 128 КБ. Mass Storage - просто считывание/запись сектора и ФС вы уже сами должны изображать. По минимуму в флеше STM32 должно хранится содержимое 4 секторов по 512 байт: mbr, boot, fat, root с прописанными туда данными вашего файла. При этом отдавать в зависимости от номера запрошенного сектора или эти предопределенные сектора, или выкачанную по SPI вашу прошивку. Записывать можно примерно также, но желательно размер носителя сделать равным размеру прошивки+служебная область файловой системы. При этом новая прошивка будет перезаписывать старую. Удалось впихнуть FatFS от Chan'а в 64 КБ флеш-памяти МК, оставив другие 64 КБ под память программы. Выяснилось, что при перезаписи файла с ПК файл остается в прежнем секторе, не меняя своего положения. На первый взгляд это очень упрощает задачу в том случае, если файл прошивки ПЛИС будет иметь одно и то же название - тогда достаточно будет отслеживать запись в один и тот же сектор памяти. Но прежде этого нужно научиться симулировать для ПК флешку размером несколько мегабайт имея всего лишь 64 КБ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 191 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Выяснилось, что при перезаписи файла с ПК файл остается в прежнем секторе, не меняя своего положения. На первый взгляд это очень упрощает задачу в том случае, если файл прошивки ПЛИС будет иметь одно и то же название - тогда достаточно будет отслеживать запись в один и тот же сектор памяти. Но прежде этого нужно научиться симулировать для ПК флешку размером несколько мегабайт имея всего лишь 64 КБ. Ну да - а теперь попробуйте туда записать ещё файлы, потом дописать предыдущий файл и т.п. - нет никакой гарантии по расположению файла по секторам, это всё на откупе драйвера ФС ПК. Будет очень ненадёжно. Что делать если ФС ПК обратится к тем секторам, которые вы уже вытеснили за пределы своих 64кБ? Вернуть мусор? Впрочем - если есть доступ к прошивке ПЛИС не только по записи, но и по чтению, то можно эти сектора читать оттуда: если файл прошивки при записи в ПЛИС никак не преобразуется, пишется "как есть", байт-в-байт, то можно считать первые 512 байт прошивки - первым сектором файла, вторые - вторым и т.д. Хранить в памяти МК только таблицу FAT, по ней определять когда доступ (по чтению или записи) идёт к сектору относящемуся к файлу прошивки - читать или писать его из/в память ПЛИС по соответствующему смещению, равному номеру сектора в цепочке секторов файла. Правда нужно будет пресекать все попытки выполнить операции записи каких-то ещё файлов кроме прошивки в такой mass storage. Да и вообще - придётся ещё и в FatFS порыться: если вы даёте ей команду "запись данных в такой-то файл с такого то смещения", то как будете определять в какой именно сектор она данные этого смещения запишет? Она может их записать в каком угодно порядке, а не обязательно в цепочку возрастающих по номеру секторов. Поэтому такой метод является крайне ненадёжным. И Вам бы лучше следовало объяснить заказчику какие потенциальные грабли он закладывает в свои будущие обновления прошивок, гонясь за кажущейся простотой, кажущейся ему, потому что он не понимает механизмов работы всего этого. Ну или можно написать свой драйвер ФС (а не использовать FatFS) чтобы быть уверенным в соответствии секторов смещениям файла... B) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andreas1 1 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Удалось впихнуть FatFS от Chan'а в 64 КБ флеш-памяти МК, оставив другие 64 КБ под память программы. Выяснилось, что при перезаписи файла с ПК файл остается в прежнем секторе, не меняя своего положения. На первый взгляд это очень упрощает задачу в том случае, если файл прошивки ПЛИС будет иметь одно и то же название - тогда достаточно будет отслеживать запись в один и тот же сектор памяти. Но прежде этого нужно научиться симулировать для ПК флешку размером несколько мегабайт имея всего лишь 64 КБ. Вам надо просто хранить во флеше 4 правильно сформированных сектора и фсе. Если идет запрос к ФС (запрашиваемый сектор меньше первого сектора файла прошивы) - отдаем эти сектора или нули, если к файлу прошивки - читаем. пишем из плис. Если размер носителя в настройках массстораджа будет размер ФС+размер прошивки и правильно сформировать 4 служебных сектора, то запись файла размером с прошивку будет всегда идти одинаково. Только надо учитывать, что если общее число кластеров ФС меньше 4096, то комп считает, что это FAT12, несмотря на то, что в буте прописана фат16. Возможно это можно побороть, но мне проще оказалось фат12 эмулировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Almaz1988 4 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Мне пока удалось съэмулировать лишь 110КБ памяти. Для этого в запросах от ПК на считывание оказалось достаточно подменять: 1) значение байта по адресу 0x1D0 (сектор 0), который содержит размер раздела (partition): 2) значение байта по адресу 0x7E13 (сектор 63), который содержит, видимо, размер раздела (пока не уверен): Если меняю значение байтов, выделенных на скриншотах синим цветом на 255 (0xff), то получаю размер флеш накопителя ( 255 + 63 ) * 512 = 159 КБ. Как только пытаюсь задать количество секторов, превышающее 0xff, т.е. перезаписать больше одного байта, то все рушится. Видимо чего-то не учел. Нет ли у кого-нибудь бинарного "скана" (image) файловой системы на несколько мегабайт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
controller_m30 1 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Вот содержимое MBR и BS секторов для 16 Мбайт "флешки". Скрины из WinHex. Если что неясно спрашивайте. Вот в текстовом виде Для MBR. Фрагмент располагается с адреса 1BEh (на 1-й картинке - начало выделенной области). 0x00,0x03,0x02,0x00,0x06,0x07,0xE0,0xC9,0x61,0x00,0x00,0x00,0xff,0x7f,0x00,0x00 Для BootSector 0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x04,0x04,0x00 0x02,0x00,0x02,0xff,0x7f,0xF8,0xF2,0x00,0x3F,0x00,0xFF,0x00,0x61,0x00,0x00,0x00 0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x0C,0x72,0xFA,0xB0,0x4E,0x4F,0x20,0x4E,0x41 0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20 Для MBR и BS достаточно хранить в памяти контроллера только эти фрагменты, а остальное легко сформировать программно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Almaz1988 4 17 марта, 2018 Опубликовано 17 марта, 2018 · Жалоба Вот содержимое MBR и BS секторов для 16 Мбайт "флешки". Скрины из WinHex. Если что неясно спрашивайте. Вот в текстовом виде Для MBR. Фрагмент располагается с адреса 1BEh (на 1-й картинке - начало выделенной области). 0x00,0x03,0x02,0x00,0x06,0x07,0xE0,0xC9,0x61,0x00,0x00,0x00,0xff,0x7f,0x00,0x00 Для BootSector 0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x04,0x04,0x00 0x02,0x00,0x02,0xff,0x7f,0xF8,0xF2,0x00,0x3F,0x00,0xFF,0x00,0x61,0x00,0x00,0x00 0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x0C,0x72,0xFA,0xB0,0x4E,0x4F,0x20,0x4E,0x41 0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x31,0x36,0x20,0x20,0x20 Для MBR и BS достаточно хранить в памяти контроллера только эти фрагменты, а остальное легко сформировать программно. Спасибо! Очень помогло! Методом тыка добился эмуляции 678 КБ памяти: uint8_t mbr[16] = { 0x00, // not bootable 0x01, // head number of partition start sector in CHS form. ?? 0x01,0x00, // cylinder number ?? 0x01, // FAT12 (CHS/LBA, <65536 sectors) 0x07, // header number of partition end sector in CHS form. ?? 0xE0,0xC9, // cylinder number and sector number in the cylinder... ?? 0x3F,0x00,0x00,0x00, // partition start sector in LBA (0x3F = 63) 0xFF,0x7F,0x00,0x00 // partition size in unit of sector (0x7FFF = 32767) }; uint8_t br[62] = { 0xEB,0x3C,0x90, // Jump to bootstrap 0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,// "MSDOS5.0" 0x00,0x02, // 512 bytes per sector 0x04, // 1 sector per cluster 0x01, 0x00, // number of reserved sectors 0x01, // number of FAT copies 0x00, 0x02, // number of root directory entries 0xF0,0x07, // Total number of sectors in the filesystem 0xF8, // descriptor type - hard disk 0x01,0x00, // Number of sectors per FAT 0x3F,0x00, // Number of sector per track 0xFF,0x00, // number of heads 0x3F,0x00, // Number of hidden sectors 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x4E,0x4F, 0x20,0x4E,0x41, 0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x20,0x20,0x20,0x20,0x20 }; Но изменение параметров совершенно рандомно влияет на объем памяти, которое "видит" Винда на ПК. Например, если в br поменяю поле "Total number of sectors in the filesystem" c 0x07F0 на 0x7FFF, т.е. увеличу значение поля, то Винда обнаружит меньше памяти - порядка 500 КБ. Описание, которое нашел на просторах интернета - весьма скромное: https://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html http://elm-chan.org/docs/fat_e.html#partition и не дает понимания на что влияет каждый параметр. Магическое "CHS form" гуглу вообще неизвестно) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
controller_m30 1 18 марта, 2018 Опубликовано 18 марта, 2018 · Жалоба Магическое "CHS form" гуглу вообще неизвестно) Это альтернативный способ адресации сектора, привязанный к физическим параметрам носителя. Head - магнитная головка дисковода, которая в данный момент читает-пишет данные. Например у Floppy-диска доступно две стороны и соответственно используется две Head, у жестких дисков этих Head-ов ещё больше (4,6,8 и т.д.). Cylinder - дорожка на выбранной стороне диска. Sector - сектор на дорожке (на цилиндре). Вместо неудобной CHS-адресации позже придумали более универсальную LBA - с линейным адресным пространством. Но для совместимости сохраняется и CHS. Возможно параметры CHS и LBA должны как-то соотноситься между собой, но точно не знаю, т.к. с этим не экспериментировал. Я брал готовые образцы: MicroSD карту на 128Мб (FAT16), и виртуальную флешку 32Мб (FAT16) с платы "STM32VLDiscovery". И по ним делал собственный вариант, который привёл выше. На моей "флешке" реальный объём данных около 1Мб, а виртуальных 16Мб было объявлено для того, чтоб не сильно отклоняться от образца "STM32VLDiscovery", и не искать подводные камни. Но изменение параметров совершенно рандомно влияет на объем памяти, которое "видит" Винда на ПК. Например, если в br поменяю поле "Total number of sectors in the filesystem" c 0x07F0 на 0x7FFF, т.е. увеличу значение поля, то Винда обнаружит меньше памяти - порядка 500 КБ. В таблице данных BS, как мне кажется, есть ошибка: размер таблицы FAT = 1 сектор. Может этот размер должен быть равным количеству объявленных секторов (или хотя бы не менее)? Попробуйте его изменить. Есть ещё такой нюанс. Флешка должна сообщить компу в SCSI-дескрипторах тот-же размер физического диска, что записан в MBR-секторе. Если они отличаются, то комп или ругается, или показывает неправильные цифры. Может и в этом дело. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 36 18 марта, 2018 Опубликовано 18 марта, 2018 · Жалоба Mass Storage - просто считывание/запись сектора и ФС вы уже сами должны изображать. По минимуму в флеше STM32 должно хранится содержимое 4 секторов по 512 байт: mbr, boot, fat, root с прописанными туда данными вашего файла. При этом отдавать в зависимости от номера запрошенного сектора или эти предопределенные сектора, или выкачанную по SPI вашу прошивку. Записывать можно примерно также, но желательно размер носителя сделать равным размеру прошивки+служебная область файловой системы. При этом новая прошивка будет перезаписывать старую. Чет непонятно, там что, куча файлов должна быть и в разных каталогах??? По моему, достаточно файла прошивки в корневом каталоге, нафига тут "толстая" ФС?? Ну и под буфер для размещения прошивки целиком можно использовать какую-нить внешнюю флешку, FRAM, например... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Almaz1988 4 31 марта, 2018 Опубликовано 31 марта, 2018 · Жалоба Добрый день. Приключения не закончились. Методом перебора подобрал следующие параметры для эмуляции накопителя объемом 6МБ: uint8_t mbr[16] = { 0x00, // not bootable 0x01, // head number of partition start sector in CHS form. ?? 0x01,0x00, // cylinder number ?? 0x01, // FAT12 (CHS/LBA, <65536 sectors) 0x07, // header number of partition end sector in CHS form. ?? 0xE0,0xC9, // cylinder number and sector number in the cylinder... ?? 0x3F,0x00,0x00,0x00, // partition start sector in LBA (0x3F = 63) 0xFF,0x7F,0x00,0x00 // partition size in unit of sector (0x7FFF = 32767) }; uint8_t br[62] = { 0xEB,0xFE,0x90, // Jump to bootstrap 0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,// "MSDOS5.0" 0x00,0x02, // 512 bytes per sector 0x20, // 1 sector per cluster 0x01, 0x00, // number of reserved sectors 0x01, // number of FAT copies 0x00, 0x02, // number of root directory entries 0xF0,0x40, // Total number of sectors in the filesystem 0xF8, // descriptor type - hard disk 0x01,0x00, // Number of sectors per FAT 0x3F,0x00, // Number of sector per track 0xFF,0x00, // number of heads 0x3F,0x00, // Number of hidden sectors 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x4E,0x4F, 0x20,0x4E,0x41, 0x4D,0x45,0x20,0x20,0x20,0x20,0x46,0x41,0x54,0x20,0x20,0x20,0x20,0x20 }; Теперь накопитель отображается в ОС windows следующим образом: Для того, чтобы переваривать файлы размером Мегабайты функцию STORAGE_Write_FS модифицировал следующим образом: /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { /* USER CODE BEGIN 7 */ if(blk_addr <= 97) { flash_write(lun, buf, blk_addr, blk_len); } else { printf("!W blk %d, cnt %d\r\n", blk_addr, blk_len); } if(blk_addr == 97) { printf("W blk %d, cnt %d\r\n", blk_addr, blk_len); printf("%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\r\n", *(buf+0x00), *(buf+0x01), *(buf+0x02), *(buf+0x03), *(buf+0x04), *(buf+0x05), *(buf+0x06), *(buf+0x07), *(buf+0x08), *(buf+0x09), *(buf+0x0A), *(buf+0x0B), *(buf+0x0C), *(buf+0x0D), *(buf+0x0E), *(buf+0x0F) ); } return USBD_OK; /* USER CODE END 7 */ } Где блок 97 - это область памяти, в котором FatFs создает реально существующий файл объемом 5 байт - этот блок записывается во флеш память МК по-настоящему, а все последующие нет. При попытке записать файл размером 16КБ и выше получаю следующую ошибку: В чем может быть проблема? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Almaz1988 4 31 марта, 2018 Опубликовано 31 марта, 2018 · Жалоба И в окне форматирования отображается 32.5 КБ вместо 6 МБ: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться