Использование произвольных DataFlash 25-й серии вместо дорогих конфигураторов FPGA Altera без дополнительной аппаратуры

    Из любого описания на популярные FPGA известно, что для хранения их конфигураций используются специальные микросхемы – конфигураторы. В комментариях меня поправили, что потихоньку набирают популярность и FPGA, где это не требуется, но пока многие делают разработки именно на классике, где нужен конфигуратор, и с этим надо считаться. Например, для Altera Cyclone используются микросхемы EPCS. Ниже схема от типичной макетной платы с кристаллом семейства Cyclone IV. На ней мы видим конфигуратор EPCS16. Всё бы ничего, но традиционно эти конфигураторы достаточно дороги, поэтому хотелось бы использовать что-нибудь подешевле.

    Подробности в длиннющем тексте ниже. Если же очень интересно, но лень читать так много букв, то можно упростить задачу, посмотрев подробное 20-минутное видео.


    Итак, вернёмся к нашей проблеме.



    Если повертеть в руках ту самую макетную плату с кристаллом семейства Cyclone IV, то мы увидим очень удивительную вещь.

    Вот она, ПЛИСина, а вот конфигурационная ПЗУ:



    Как ни странно, это никакой не EPCS, а обычная 25-тая флешка. Такие флешки стоят дёшево и продаются достаточно много у кого.

    Но, как говорится, не все йогурты одинаково полезны. В частности, наши заказчики на радостях закупили подобные флешки, припаяли на плату и получили глобальную проблему. Заходим в программатор, грузим файл, подготовленный для прошивки, начинаем его прошивать и получаем ошибку:



    Вот сообщение об ошибке:



    Error (209025): Can't recognize silicon ID for device 1. A device's silicon ID is different from its JTAG ID. Verify that all cables are securely connected, select a different device, or check the power on the target system. Make sure the device pins are connected and configured correctly.

    Не опознан идентификатор устройства. То есть у флешки неизвестный идентификатор с точки зрения квартуса. Конкретно у наших заказчиков были закуплены кристаллы 25P32, которые вообще не поддерживаются в принципе, но в жизни может быть и более приземлённая ситуация. В частности, на фото выше припаяна флешка от ST, а определяется она как MICRON. Китайские продавцы и не такое могут намаркировать, а когда партия закуплена и не работает – что можно сделать?

    Я полез на форумы. Все русскоязычные, какие удалось осмотреть, пестрели обсуждениями, у каких поставщиков и что следует брать, чтобы не напороться на подобную проблему. Но в нашем случае никто покупать новую партию не хотел. В англоязычных источниках удалось найти лишь одну статью с решением, но в современной среде Quartus Prime данное решение «в лоб» не сработает. Поэтому мы взялись задокументировать данную проблему для современной среды, на русском языке и в видео формате.

    Итак, как вообще программируется ПЗУшина?

    В ПЛИС вливается специальная конфигурация, по которой становится возможно по JTAG достукиваться до флешки. И потом, пользуясь этой конфигурацией, мы заливаем данные. Оказывается, можно сделать подобную конфигурацию, которая даст нам доступ к флешке и даст прошить, невзирая на ID, причём при этом не придётся писать ни строчки собственного кода, да и утилиты все будут использоваться из поставки Quartus Prime (либо Qiartus II, кто пользуется старыми версиями среды разработки).

    То есть нам предстоит сделать 3 шага:

    1. Сделать конфигурацию, которая достукивается до флешки.
    2. Написать файл, в котором флешка описывается.
    3. Прошить.

    Давайте этим и займёмся. Начнём с разработки собственной «прошивки» (она же конфигурация), не написав при этом ни одной строчки своего кода.

    Заходим в Quartus:



    Создаём новый проект:



    Назовём его, скажем, flasher:



    Это имя следует запомнить – оно нам ещё понадобится.

    Создаём пустой проект, семейство у меня Cyclone IV E, используемый в проекте кристалл вот такой:



    Так. Заканчиваем создание проекта, нажимаем Finish. Проект создан. Как уже было сказано, мы не пишем ни одной строчки своего кода. Но заставить среду сделать что-то всё-таки нужно. Для этого идем в Tools – Platform Designer.

    Вот он загрузился. Конкретно у меня в этой плате кварц на 60 Гц, поэтому я подправлю установки частоты:



    То, что я делаю сейчас, мы делаем один раз для платформы. То есть если изготовлена какая-то плата, то вот этот загрузчик будет для нее для любого проекта работать.

    Я подготовил кварц – теперь мы ставим процессор. В библиотеке слева находим «Процессоры и Периферия», «Встроенные процессоры» и затем – Nios II Processor:



    Выбираем его и нажимаем «Добавить».

    В открывшемся окне, в свойствах, выбираем Nios II/e, потому что он абсолютно бесплатный и к нему не нужна никакая лицензия.



    Ошибки сообщают нам, что не настроены вектора. Мы не собираемся ничего программировать для этого процессора. Поэтому вектора мы просто направляем в первое попавшееся место из списка:



    Нам очень важно, чтобы у процессора работал модуль JTAG:



    После наших манипуляций ошибки ушли.



    С процессором закончено. Нажимаем Finish и двигаемся дальше.

    Теперь мы идём в основные функции. Здесь есть конфигураторы:



    Раскрываем список конфигураторов – ближе к концу находим EPCS-ки – наши конфигураторы:



    Всё оставляем по умолчанию:



    Теперь начинаем их связывать. Тактовые сигналы пропускаем на оба модуля, сигнал сброса пропускаем на оба модуля. Сигнал сброса, выходящий из аппаратуры JTAG, – debug_reset_request – мы также пропускаем на оба модуля. Дальше data_master пропускаем на оба модуля. Instruction_master пропускаем только на отладчик. И запрос на прерывания мы также пропускаем:



    Дальше мы переходим к внешним ножкам – external. Экспортируем их, для чего дважды щелкаем в поле Double-click to export:



    Для простоты назову epcs, чтобы меньше длина была:



    Теперь привычным движением руки назначаем базовые адреса:



    И назначаем прерывания:



    Автоматически назначенный адрес для нашего flash-контроллера – 0×800 – нам следует запомнить:



    Он нам еще пригодится. А всё остальное, в принципе, само сделалось и будет работать.

    Сейчас очень важно, так как мы не собираемся писать ни одной строчки своего кода, чтобы имя процессорной системы совпадало с именем проекта. Проект у нас был flasher.

    Сохраняем систему, называем flasher:



    Именно тогда у нас топ-модуль будет именно этот процессор, и поэтому нам не придется ничего делать.

    Следующий наш шаг:



    Все оставляем по умолчанию, потому что мы просто пользуемся тем, что уже готово:



    Завершаем:



    Появилось сообщение о том, что нам надо не забыть добавить файл в проект:



    Давайте добавим. Идём в Project – Add/Remove Files in Project:



    Находим наш файл на компьютере.



    Вот он, наш файл flasher с расширением qsys.



    Добавили его:



    Теперь делаем черновую компиляцию:



    Она завершилась успешно.



    Теперь, когда она прошла, мы можем назначить выводы. Идем в Pin Planner:



    JTAG-овские ножки нам назначать не надо – мы назначаем ножки флешки.



    Для каждой микросхемы, для каждого корпуса они свои. В принципе, можно смотреть документацию на микросхему или на свою плату. Например, вот у нас двенадцатая ножка DCLK:



    У меня список уже подготовлен – просто вобьём по нему.

    Так, epcs_data0, LOCATION: PIN13, epcs_dclk – PIN12, epcs_sce – PIN8, epcs_sdo – PIN6. И конкретно на плате наших заказчиков тактовая частота PIN24, reset_n – PIN88.



    Ножки назначили. Запускаем компиляцию. Выдаются ошибки:



    Все потому, что я сделал вид, что забыл произвести очень важную настройку. Мы сейчас подключили флешку к служебным линиям. И, по окончании конфигурирования, часть этих линий вообще не доступна, а часть – используется для служебных целей. Поэтому нам выдали сообщения, что у нас конфликт:



    Чтобы это устранить, идем в Assignments – Device:



    Device and Pin Options:



    Здесь выбираем Dual-Purpose Pins. И все эти линии по окончании программирования мы просим сделать обычными линиями ввода-вывода:



    Жмём OK, запускаем компилятор. И всё получилось.



    Итак, первый шаг завершен. У нас получилась конфигурация, через которую мы можем достукиваться до флешки.

    Теперь наша задача – сделать файл, с помощью которого система нашу флешку будет опознавать.

    Идём во все программы, Intel FPGA (для старых версий это будет Altera), Nios II Command Shell.



    Здесь мы идём в каталог, где мы только что все собрали. При этом не забываем, что слэши тут должны быть не обратные, а прямые, и что результирующий файл flasher.sof лежит в каталоге output_files:



    Теперь начинаем произносить волшебные заклинания. Итак, нам нужно влить только что сформированную конфигурацию. Для этого мы пишем:

    nios2-configure-sof flasher.sof

    и нажимаем Enter:



    Файл залился – теперь у нас есть доступ к флешке. Для того, чтобы определить все, что касается доступа к флешке, нам нужно запустить следующую программу:

    nios2-flash-programmer --epcs --base=0x800--debug.

    где 0x800 – это тот самый адрес, который автоматически назначился на блок epcs и который надо было не забыть.



    Нажимаем Enter:



    Что он нам сказал? Он попытался осмотреть ту область, которую мы назвали. И по смещению 0 по адресу 800 не нашёл ничего. По адресу с00 он нашёл то, что нам требуется:



    Теперь мы запоминаем не просто базовый адрес 800, а конкретный адрес с00 – в дальнейшем работа будет вестись с ним.

    Он нашел флешку, ее идентификатор 202016, но сказал, что понятия не имеет, что с ней делать, потому что её не знает.

    Вот документация на нашу флешку:





    Её полный идентификатор 202016 – именно его она возвращает в ответ на команду запроса своего кода.

    Так что всё правильно – флешка нашлась правильная.

    Он нам говорит, что должен быть файл с секцией EPCS-202016.

    Замечательно. Изменить – Пометить. Выделяем её имя и берём в буфер обмена.





    Создаём файл ovr.txt и секцию с именем, которое только что скопировали:



    В документации на нашу флешку, в разделе Memory Map, мы можем посмотреть, что она состоит из 64 секторов. Каждый сектор имеет размер 64 Кбайт, потому что от 0000 до FFFF.



    Поэтому файл с конфигурацией, который мы только что создали, должен выглядеть вот так:



    64 сектора размером по 64 Кбайта, или 65536 байта, каждый.
    Второй шаг готов. У нас имеются файлы flasher.sof и ovr.txt, который содержит конфигурацию флешки.

    Переходим к третьему шагу.

    Напомню, что рабочий проект был USB16_my. А файл для прошивания назывался Test1.sof. Мы копируем flasher.sof и ovr.txt к нему.

    Теперь мы закончили все подготовительные шаги – приступаем к непосредственным боевым действиям. Чтобы подчеркнуть отсутствие связи между подготовкой и работой, я войду в терминал ещё раз, как будто это происходит на следующий день, через неделю, через месяц или через любой срок после завершения подготовки.



    Первое, что нам нужно сделать, это сформировать выходной файл. Потому что файл sof не шьется в ПЗУ – шьется немного другой файл. Для того чтобы его сформировать, мы пишем:



    Получился файл Test1.flash:



    Теперь, чисто формально, пришёл черёд действий, которые должны делать сборщики плат. В первую очередь, они точно так же должны загрузить наш flasher, то есть:



    После чего они должны прошить ПЗУ:



    Собственно, на этом всё. Задача решена, флешка прошита – можно ее использовать, даже несмотря на то, что основной путь говорил про несовпадение ID-шников. И совершенно не требуется покупать дорогие конфигураторы или искать, у какого поставщика 25-е флешки имеют совместимые ID. Мы подготовили «прошивальщик» для нашей конкретной платы (и любых других, где стоит такой же кристалл и Reset с генератором подключены к тому же выводу), мы подготовили текстовый файл для конфигуратора, после чего влили «прошивку», пользуясь утилитами, идущими в комплекте поставки штатной среды Quartus Prime (они же шли и со средой Quartus II).
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 21
    • +3
      Хорошее дело. А FPGA сама идентификатор не проверяет при старте?
      И небольшой коммент: после создания системы в QSys лучше добавлять в проект не .qsys, а .qip (лежит в .\qsys_system\synthesis\qsys_system.qip). Первый вызывает полную перегенерацию qsys-подсистемы при перекомпиляции, а второй подключает уже имеющиеся результаты генерации системы.
      • 0
        Скорее всего, не проверяет, что логично, ведь в целом — нет жёсткого требования, какой ёмкости конфигуратор использовать для конкретного кристалла. Главное — чтобы этой ёмкости хватило. По крайней мере, всё работает именно с 32-й флэшкой, а EPCS — бывает 16, бывает 64 и далее — уже вверх. А 32 — не бывает. И всё работает. Проверено.

        За комментарий по подключаемым файлам — спасибо. Век живи — век учись. Буду пробовать.
      • +1
        Раз флэшки сами по себе совместимы и только альтеровскому программатору не нравится прочитанный ID (что есть свинство со стороны альтеры, можно же было сделать предупреждение «ID не совпали, продолжить на свой страх и риск?», но ведь кто тогда будет покупать их флэш втридорога), то тогда можно со спокойной совестью взять в руки ollydbg и просто объяснить программатору, что не надо ругаться на несовпадение ID, а лишь выполнить пару nopов вместо перехода на обработку ошибки и продолжить работать как ни в чём ни бывало.
        • 0
          Тоже вариант. Но, в целом, как видим, можно воспользоваться и фирменными Альтеровскими вещами, которые всё равно установились, просто их надо несколько извратно вызывать.

          Но на самом деле, готовим прошивальщик — один раз на жизнь схемы и ей подобных схем.

          Готовим файл под прошивку — единожды на версию, так как всё равно при отладке он льётся прямо в ПЛИС, на то она и отладка. Причём готовить — что этим способом, что мышкой давить — и там и тут надо кучку действий выполнить.

          Ну, и дальше — только кто платы прошивает, должен будет ввести заклинание один раз за смену против трёх движений мышкой. Потом — просто «Вверх, Enter» нажимать.

          Не так и сложно, как оказалось.
          • 0
            Кстати, на самом деле, они все совместимы на чтение. Задали адрес, дальше — нам идут данные, а адрес — автоинкрементируется. А вот на запись — у них действительно могут быть всякие несовместимости по размеру страницы и прочему. Не даром же приходится заполнять конфигурационный файл. Почему нельзя его заполнять для штатного GUI-программатора — вопрос открытый.
            • 0
              Например, по идентификатору оно может подгружать sector map. К тому же патчить компиляторы и прошивальщики — занятие сомнительное, и на практике порождает неуловимые баги.
              • 0
                Естественно, простой патч будет работать при условии что различие только в ID.

                habrahabr.ru/post/110395
                habrahabr.ru/post/302570
                а тут всего лишь размер сектора поправить если вдруг не совпадёт :)
                • 0
                  Если вы предлагаете заменить одни значения другими — то это действительно не должно повлечь последствий, однако тогда функционал больше не станет, в то время как в статье описано как не потеряв старый добиться нового (пусть и таким путем).
                  А серьезная модификация утилиты с изменением размеров внутренних таблиц может плохо кончится. Мне встречался компилятор, который во внутренней логике использовал собственную хеш-сумму (кажется, простым однобайтовое сложение), и при этом всегда выдавал валидный, но каждый раз работающий по разному бинарник.
                  К тому же, логика движка игры, как правило, не очень сложная. А логика компиляторов, синтезаторов и прошивальщиков на порядок сложнее, и цена ошибки на порядок выше.
                  • 0
                    Ну никакого нового функционала нет, только прошивка неродной конфигурационной памяти, штатным бластером.
                    Протокол общения с бластером впринципе известен, BSDL файлы для цыклона есть, команды для для работы с флешью — в её даташите, то есть если уж изобретать велосипеды, можно было и самому программатор соорудить который будет шить данный «нестандартный» флэш через усббластер как напрямую(такой велосипед я и сам делал, хотя и готовых наверняка хватает), так и через дрыгание ногами подопытной плис через jtag, что даже дополнительного коннектора к памяти не потребует.

                    Беглый осмотр даташитов M25P32 и EPCS показал что размеры секторов(65К) и страниц(256) абсолютно одинаковые, соответственно единственное различие, которое и не нравится программатору это прочитанный ID, что очень легко вылечить, убедив его, что он всегда читает правильный ID, не влезая при этом в сам процесс программирования и ничего там не модифицируя.
                    А вообще подход описанный автором конечно правильный. Ещё более правильный путь это, пожалуй, иметь возможность обновления флэша в самой боевой прошивке, и просто загружать её через jtag, а затем «обновляться» штатными средствами, но такой отдельный небольшой велосипедик тут тоже подходит.
            • 0
              Из любого описания на FPGA известно, что для хранения их конфигураций используются специальные микросхемы – конфигураторы.

              автор видимо не знаком с FPGA со встроенным флешем
              • 0
                Ой знаком. Наши Заказчики с целью защиты от клонирования в своей плате такую использовали однажды… Вернее, они использовали с однократкой без возможности перешивки. Воспоминания — только самые ужасные.

                Так или иначе, спасибо за замечание, добавил одно слово в текст. Теперь там говорится про описания на популярные FPGA.
                • 0
                  Пожалуйста, но из описания на популярные Lattice FPGA известно, что дополнительные микросхемы конфигураторы не нужны, так как для этого есть встроенная флеш память.
                  • 0
                    Посмотрел статистику продаж их и средств разработки на них и на Altera/Xilinx на Ali Express. Посмотрел предложения в отечественных конторах. Давайте сойдёмся на том, что они ещё не настолько популярны, как их загружаемые конкуренты. А статья — вообще про Альтеру. Которая на сегодняшний день в паре с Xilinx пока, вроде, популярней остальных. Усложнять фразу в основном тексте в сегодняшних реалиях — не вижу смысла. Особенно если учитывать, что дальше — даже Xilinx не рассматривается.
                    • 0
                      Вынес свои мысли в виде предложения в основной текст.
                      • 0
                        встроенный флэш там у мелких ICE и MachXO.
                        те что побольше, ECP, загружаются снаружи.
                  • 0
                    Кстати, по поводу назначения пинов для флешки — в моём случае не получается вообще никак, они заблокированы как «Dedicated Programming». Можно ли это обойти вообще?
                    • 0
                      К сожалению, сильно больше, чем показано в видео, рассуждать не могу. Я всегда опытным путём под конкретный случай пытаюсь подогнать, так что теоретизировать об общих вещах, без предварительных изучений конкретного случая — сложно.

                      Как показано в видео — точно работает. Там есть, как войти в настройку поведения этих ножек, на что переключить, кратко видно, какие ещё варианты имеются в списках. В тексте это сложно разъяснить, именно поэтому я считаю, что первично всё-таки видео (но без текста нельзя делать публикации, поэтому он тоже нужен). Возможно, из того, что там ещё попало в кадр, можно какие-то идеи вывести под те чипы, что у Вас (для четвёртого Циклона — просто следовать этой инструкции).

                      А дальше — если не получается какая-то конкретика, то нужно уже под конкретный случай занудно документацию смотреть, «что там можно, что нельзя».
                      • 0
                        В том-то и дело, что эти ноги недоступны для переключения.
                        У меня — 5-ый циклон, SoC. В настройках ног только это:
                        image
                        Я уже вручную в qsf-файле прописал эти ноги — ругается при сборке.
                        • 0
                          Всё, проблему решил.
                          В Qsys не надо было настраивать выходы программатора как EXTERNAL — оно автоматом подхватывает дефолтные ноги само, без лишних телодвижений:
                          image
                          В итоге флешку увидело, прочитало и прошило.
                          • 0
                            Век живи — век учись. Спасибо, что описали. Если возникнет подобное — будет уже готовое решение (с пятым SoC я пока не подружился, хотя уже несколько подходов сделал — пытаюсь понять, как там Bare Metal приложения делаются, но слишком много информации сразу — не хватает свободного времени, чтобы переварить).
                            • 0
                              Baremetal — легко, тут был мануал. Но что-либо сложное там геморрой делать. Для сети и проще проще линь поднять самый минимальный (с LFS, например).
                              Если что — могу помочь с этим делом, уже разбирался на своей этим зоопарком.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое