Raccoon Flash Explorer | 9 месяцев спустя…
Доброго всем времени ночи:)
9 месяцев назад я выпустил программатор BIOS-ов для компов и запилил о нём статью.
Тогда на момент выпуска статьи он был довольно сырым, и до законченного продукта по части реализации всего заявленного функционала добрался чуть менее месяца назад.
Здесь же я хочу рассказать как всё это происходило, какие были трудности, и всякое прочее)
В целом было очень много всякого, что по разным причинам не вошло в данную статью, но некоторые моменты постараюсь описать здесь.
В первую очередь скажу что примерно осенью, в один из самых сложных моментов, когда я не имел понятия как решать одну из сложных задач по коду и хотел забросить это дело — судьба свела с одним замечательным человеком @15432, и он на своём примере показал что и намного более сложные технические задачи вполне решаемы, главное иметь желание и верить в себя.
Естественно всё это было случайно, и в первую же минуту знакомства мы с ним качественно поругались как и положено, но чуть более ознакомившись с подробностями он высоко оценил мою работу и ознакомил со своими. Это было довольно неожиданно, примерно как в общественном эмм. лесу познакомиться с высокоразвитыми пришельцами, которые не ставят на вас опыты, а общаются как с хорошими друзьями xD, и после этого я начал ещё с большим усердием работать над проектом.
В целом проект хорошо оценили только жители хабра, и небольшая группа ремонтников. Многие из них заказали просто поиграться, ведь мы любим всякое коллекционировать, приборов много не бывает : D, а к своей оценке пришли уже после того как вживую опробовали проект в своих задачах.
Основное же отношение у целевой аудитории, которая о проекте только слышала в ютубе или читала на форумах сложилось примерно такое:
-О, так это обычный юсб диск на ардуине, фигня, несите следующего.
-Так это же клон chxxx, нафиг никому не надо.
-Автор понакупил в китае программаторов и толкает со своим названием.
-Автор спёр прошивку и железо у старого xxx проекта.
-Автор не представляет что такое программаторы и никогда ими не пользовался.
К сожалению целевая аудитория в своей основной массе оказалась не готовой к подобным нововведениям.
Окончательное мнение формируется ещё на словах «юсб диск», и дальше никто не вникает ни в технические характеристики, ни в предоставляемые возможности.
Это был наш большой просчёт, как и то, что мы вовремя не уделили должного внимания на необходимость качественных обзоров от авторитетных в ремонтной сфере людей.
Но не всё прям совсем печально. Вчера тему с описанием девайса добавили в список закреплённых важных тем на ведущем ремонтном форуме по ноутбукам vlab.su, и я по этому поводу написал там обращение ко всем мастерам, и к злостным хейтерам в частности.
Может быть это поможет изменить отношение людей к проекту и дела пойдут вверх, а может и не поможет и всё закончится в скором времени. «Будем посмотреть…»
Здесь ничего технического изначально не планировалось, а статья шла из разряда «Как мы проспали свой стартап». Но как известно — планы всегда меняются. Поэтому сделал для вас небольшое описание различных технических проблем и их решений, насколько для этого хватило моей одной извилины. Надеюсь вам оно понравится :)
Сразу скажу что я совсем не технический писатель, не имею профильного высшего образования, ооочень начинающий программист, и излагать мысли в понятном виде не умею. Изложу как получится.
Тапки хорошие себе осталю, плохого качества буду кидать обратно)))
За основу был взят пример от STC 65-USB-MSC_Mass Storage Class и значительно переделан. Ссылка находится внизу.
Проц — 8051 STC8H8K64U.
Я даже Usb vid/pid купил. Официально купить один код нельзя, но одна из древних фирм продаёт свой запас. USB IF с этим вендором не дружит, но запретить и заблокировать не может.
На момент начала работы кодить я умел примерно как «аааа памагитя лед блиньк не блинькает».
Но было достаточно опыта в электронике, желания получить девайс, и понимание каким он должен быть.
Железо должно быть надёжным. Но и должно быть простым и дешёвым. А значит нужна защита от перегрузок. Но каким образом её лучше всего построить?
Уже имелся ключ подачи питания на сокет (Q2), и в проце был довольно быстрый компаратор с временем переключения менее 100нс.
Получилось вот так. Применил ещё одну особенность строения компаратора (загадка), и схема научилась не просто следить за перегрузом, но и сравнивать параметры с графиком из нескольких точек.
Компаратор может отслеживать направление перекоса и время нарастания. Подглядывает он настолько хорошо, что в импульсном режиме может унюхать потребляемый одной только spi-флешкой ток. Из-за этого софтово чуть подрезал ему нюх. Вся защита срабатывает за 2 мкс, и что-либо спалить нереально.Нужно чтобы сразу поддерживались два питания, 1,8 и 3,3в. Легко.
Проц питается от 3,3в, его все лапы тоже. Но все лапы могут быть с открытым стоком.
Потому просто вешаем массив внешних подтяжек между сигнальными лапами сокета и переключаемым питанием, на всякий случай через отдельные ключи. Тут был в разводке косяк: один ключ из 8-ми стоит просто для симметрии, и замкнут дорожками. Менять разводку поздно, а не впаивать — некрасиво на вид. Так он и остался)))Нет никаких органов управления и индикации. А они нужны. Что делать?
Вот не предусмотрено ничего на плате. Вешать сопли — фу таким быть.
Плата делалась в спешке, схемы перед этим не было вообще.
Был только макет с процом, 3,3в стабилизатором, и сокетом, и больше ничего.
За несколько часов придумал навскидку всю схему прогера, по ней нарисовал печатку, и отправил на производство срочным заказом.При этом даже отладить нарисованные в схеме участки до приезда плат нельзя было.
На макетке собирать было проблемно, да и детали в пути были.
А если бы эти участки все переделывать пришлось? Но нет, так ведь не интересно))При разводке в первую очередь руководствовался внешним видом и размером платы, ведь корпуса не планировались, а железка должна ко всему ещё и выглядеть красиво.
Оптимальный размер платы нужен был для оптимизации цены плат, тк делают на заводе не одну, а целый лист.
Монтаж бескорпусного девайса надо было делать односторонним, для минимизации сбитых деталей снизу. Ещё и удобным для ручной пайки желательно.
Дольше всего при разработке платы я просидел в онлайн калькуляторе на сайте производителя плат.
Естественно никаких управлений, защит, переключаемых подтяжек и прочего на тот момент в макете и его софте не было. А плата уже нужна была вчера.Был примитивный детект флешек на уровне проверки JEDEC ID, но он ни о чём толком не говорит. Многие флешки корректно отзываются и при неправильном питании. Параметров много, далеко не все можно из SFDP взять. Огромная база флешек просто бы не влезла в 64 кб памяти кода проца. Как быть?
И начал полосатый копаться в мусорке и искать зависимости поведения флешек от питания. Искал долго. И нашёл. Причём сразу клад.
Рассказать подробно не могу, но скажу что нашёл около пяти особенностей поведения, по которым можно с высокой точностью определить нужное флешке напряжение.
146% точности не дают, но достаточно и того, что каждый последующий тест на 90% устраняет ошибку предыдущего.
Применил сразу всё. И проверку ID, и зависимости, и обмазал контекстным поиском записей о питании в SFPD. Дело в том, что в каком месте будет указано питание, и будет ли оно указано вообще — решает конкретный производитель, а не JEDEC.
Но записи эти имеют строго соблюдаемый формат.
Этого всего стало достаточно, чтобы определять питание лучше любого пользователя с ручным выбором или баз данных.Нужна повыше скорость, долго ждать никто не хочет.
Изначально я не планировал никаких повышений никаких скоростей, всё спокойно себе пыхтело со скоростью ~150 кб/сек как в вендорском примере. И понимания как это улучшить, как и навыков кодинга, не было вообще.А потом я дорвался до ассемблера. Немного изучил регистры, как происходит взаимодействие с юсб, и начал придумывать свои варианты.
Вариантов было много, с каждым месяцем всё это переделывалось, когда приходило больше понимания как вообще писать программы.
В какой-то момент улучшать стало некуда, тк уже добрался до потолка в 750 кб/сек для этого проца. Быстрее он не может из-за отсутствия двойной буферизации юсб, дма, и косвенной адресации каждого чиха в юсб. Но хотелось быстрее .
SPI работает на частоте до 22 мгц, но из-за тормозов юсб просто прогуливает свою производительность. Но нужна ещё и верификация. Всё это время её нужно было делать ручным сравнением, или терять время на автоматическую поблочную.Ещё очень напрягали огромные паузы в 350ns и выше между каждым байтом в spi. И эти паузы были даже при работе DMA SPI-XRAM. Настройка приоритетов тоже не помогла, ограничение железное. Попытался запустить с внешним тактированием и получил кучу ошибок данных. DMA не может без пауз работать с XRAM.
Длительность байта при этом 690ns и паузы эти были бревном в глазу. От DMA пришлось полностью отказаться.Немного поколупал в проце тайминги работы модуля spi и изучил длительности и зависимости исполнения различных его команд (в даташите ничего подобного нету), накидал nop-ов для точной синхронизации программы с состоянием сдвигового регистра spi после прыжков программы, и получил на выходе вот такие красивые тайминги.
Значительный выигрыш в скорости позволил два раза читать 64-байтный блок из флешки за то время, пока по юсб летит другой 64-байтный блок.
Таким образом скорость в 8 мб/~11сек влезла в эти ~750 кб/сек вместе с верификацией,
и верификация перестала влиять на время чтения. Время записи — совсем другой разговор, и там от таймингов каждой конкретной флешки никуда не убежать.Если кто скажет что верификации на стороне компа нету — он не совсем прав. Верификация есть — аппаратная проверка crc-16. Это часть usb bulk.
Текстовые файлы с всякой подноготиной о воткнутой флешке.
Просто дамп читать-писать недостаточно, надо ещё и видеть некоторые параметры.
Все данные по флешке, включая просмотр содержимого регистров и их изменение, ошибки, состояние контактов — выводятся в текстовый файл.
Файл генерируется на ходу. Иначе никак.
Сначала он состоял из кучи if (a) strcpy («AAA»); else strcpy («BBB);, открывался заметно медленно и жрал много памяти.Первую проблему решил обычным бустом частоты с 24 до 44 мгц, и тормоза вроде бы ушли. Но вторая проблема осталась, и её надо было решать. Кроме того было сложно добавлять новые сообщения, они занимали много места в памяти и строк кода.
Первые месяцев 4 я не знал как решать эту проблему, не хватало опыта. Но потом придумал.Проц имеет двойной реверсивный автоуказатель на XRAM (Dual DPTR), тоесть указатель может хранить два адреса, может сам после обращения прибавляться, убавляться, и переключаться с одного на другой. Смотря как настроишь.
Настройки у них почти независимые.
Но ни один компилятор ими нормально пользоваться не умеет, и работает по старинке с одним основным через INC DPTR.
Свои асм-вариации strcpy и memcpy я делать не стал, и вместо этого сделал кое-что другое. (Точнее memcpy сделал потом, но специфическую и для других задач.)Сделал формат хранения всех текстовых сообщений вот таким
Названия параметров лежат блоком.
5 — Длина блока в секциях, включая новую строку.
9 — Длина названия параметра в символах, и после него идёт название параметра.
39 — Длина свободной строки для значения параметра, после которой начинается новая строка.
Нужный блок параметров копируется в озу быстрой ассемблерной функцией, которая первым параметром видит длину каждого копируемого элемента.
Доступ к адресам в пзу и озу происходит последовательно, за каждую память отвечает свой указатель, никаких прыжков туда-сюда нет, и копируется максимально быстро.
Затем на него накладывается маска-указатель на структуру, и по ней в озу уже копируются значения параметров из любого удобного нам места в коде.Значения выглядят вот так.
Ничего особенного. Тоже первым идёт количество символов, и дальше массив символов.Суть такого строения текста и отдельных копирующих функций в том, что мы распихиваем в самом начале количество символов/блоков по регистрам Rx, а дальше просто крутим короткий цикл.
Двойные указатели инкрементируются/декрементируются и между собой переключаются сами, после каждого обращения к ним. Их поведение настраивается как угодно. Но компиляторы с этим не дружат (((Это же решение даёт возможность легко и даже на ходу менять локализацию.
Такой функции пока нету, но может появиться. Достаточно будет закинуть файл такого же строения, но со своей локализацией на диск, и с файла значения запишутся в память.25Q64.
Все spi-флешки изначально не планировалось называть своими именами.
Вполне устраивало что они называются просто 25Qxx. Но потом стало скучно.
Начал придумывать как не забивая всю память базами данных определять наиболее достоверное название, ну и заодно объём памяти. Сразу скажу что я не математик ни в одном глазу и таблицу умножения не знаю даже с калькулятором, потмоу log-шототам как зашифрован размер в последнем байте id так и не вкурил.
Ну и пофиг. Быстро делал свою реализацию на сдвигах.Втуда же пошла и генерация последних цифр маркировки, которые значат размер.
Названия вендоров оставил в таблице, она малюсенькая, а вот с более точным определением средней и последней букв пришлось попотеть.
Дело в том, что далеко не у всех флешек можно по id определить буквы, и значение этих букв везде разное.
Штош… Часть букв определяется по определённому ранее рабочему напряжению, другая часть по отсутствию/присутствию режимов QPI/QUAD, и возможностью включения/выключения этих режимов. Иногда режим включен принудительно и выключить его нельзя.
У разных флешек совсем разные зависимости, потому для каждой описать нельзя.
На 146% достоверно определить буквы тоже нельзя, только примерно.
Но это и не требуется, это только косметика)
Если же название не удалось определить — вместо него будет выведен JEDEC ID, и всё-равно можно полноценно работать. А что если id нестандартный? Нуу. Тут всё плохо, но не очень.
Для древних флешек есть таблица переназначения id, но такие флешки и девайсы с ними мохнатая редкость.
А у выпущенных с 2011 года всегда есть SFDP, в котором обязательно присутствует размер.Прищепка.
Проверка ошибок и подбор частоты для внутрисхемной работы.
Внутрисхемка изначально была заявлена, и нельзя было упасть в грязь мохнатой мордой. Потому после решения всех вопросов выше занялся прищепкой.Проблем тут сразу несколько:
1 — Большой потребляемый ток платой.
2 — Помехи со стороны платы, когда она тоже хочет потрогать флешку.
3 — Провода и скорость. Нужна максимально доступная скорость.
4 — Автодетект флешек и питаний. Как не подать 3,3в вместо 1,8в.Проблемы 1 и 4 решились сами собой за счёт дикой защиты от перегрузок в автоматическом режиме для неопытных, и добавлением опции отключения защит и ручной фиксации питания для опытных пользователей.
Проблема 2 решилась тоже практически сама собой. Естественно насколько это было возможно без увеличения числа деталей.
У проца довольно мощные и неубиваемые выходы. Ещё эти выходы у семейства С51 очень интересно устроены, и могут как кратковременно так и долговременно переходить в пуш-пул.
Усиленные выходы он включает только в ручном режиме, и бывает даже перетягивает помеху на плате. Для 1,8в в основном усиления не требуется.
В авторежиме просто стоят довольно низкоомные подтяжки. что тоже помогает при работе.
Если же проц попытался перетянуть помеху и не смог — рвать лапы он не будет, и скажет в лог, мол вот, не могу по этой вот причине, выпаивай.Проблема 3 была самой интересной. Работал над ней долго, добавил множество верификаций и повторных вычитываний всего что можно вычитать на разных частотах.
В конце концов это заработало на 95% точно. Но хотелось 995%.Уже когда почти перестал что-либо делать — сидел читал доку по вендорам флешек, соответствие кодов первого байта id вендорам.
И нашёл там такую тему, что коды эти совсем не рандомные, а с проверкой чётности.
старший бит кода является флагом четности младших 7-ми бит. Чуть поколупав в носу добавил эту проверку чётности, и получил свои, хоть и не 995, но 146% точности.Кактотак))Вроде бы всё что можно было рассказал, но если вспомню то дополню.
Ещё давно планировалось выпустить демо-версию софта. Вот она.
Надеюсь к этому моменту вы уже прочитали внимательно всю статью, и с учётом описанных в ней смягчающих факторов не будете кидаться в меня старыми ботинками за ужасный код (((
Хотя сейчас я бы и сам в себя пару ботинков за такое кинул.
Если бы я с нуля начал проект сейчас, то смог оформить бы намного лучше.
Но есть то, что есть. Оно достаточно хорошо работает, и тратить на это время было нельзя. Были более важные задачи.
Самое важное в демке удалено полностью и заменено заглушками. Местами вообще новые реализации сделал, например чтение и запись spi. В полной версии совсем другой код. Насколько эта прошивка отличается от того примера, поверх которого сделана — так же демо от основной отличается.
Ко времени релиза я не успел полностью весь проект привести в красивый вид, и по коду можно заметить как менялся со временем опыт.
Некоторые самые критичные части были в крайней обнове переписаны полностью, а другие (хорошо работающие) наоборот остались старыми или были минимально изменены для совместимости с новыми.
Так надо было делать для того, чтобы как можно быстрее вышла стабильная версия, и всё подкапотное допиливалось бы потом. Ибо пользователи ждут, и им без разницы как там внутри. Главное чтобы снаружи хорошо работало.
Самое сложное было не сделать диск и кинуть флешку как файл на нём. Диск был готовый.
Сложно было как раз сделать так, чтобы оно было быстрым, надёжным, и по максимуму автоматизированным.
Демо-версия прошивки с исходниками открытой части проекта
Это моё обращение к тем кто хейтит проект.
Оно адресовано совсем не жителям хабра, и вы можете его не читать. Но если совсем скучно — тогда можно)
Оно планировалось быть здесь основным текстом, но меня уговорили убрать его, и заменить техническими подробностями. Вышло даже лучше чем было:)
Там очень много букв и нытья, лучше не открывайте:)
Ссылка.

Habrahabr.ru прочитано 11476 раз