Visual Studio Code — написание и отладка прошивок для RISC-V

Это будет в некотором роде продолжение статьи IAR RISC-V GD32V Evaluation Board, только теперь с примером проекта на бесплатном ПО, исправлением косяков отладочной платы IAR и просто бомблением на тему, как же так плохо можно было сделать отладочную плату.

Реклама

Фиксим отладочную плату от IAR

В качестве примера проекта я захотел сделать что-то посерьезнее мигания светодиодом, задействовав сразу АЦП, SPI, GPIO, таймер и немного математики.

В процессе изучения SDK и примеров производителя я столкнулся с тем, что с канала АЦП, на который заведён микрофон, читается постоянно значение «4095» (для 12 бит это аккурат напряжение питания). Странно. Смотрю осциллографом, что на выходе первого ОУ после микрофона (точка 1):

Всё в норме, половина питания (Vref задаётся резисторами R31, R32) и усиленный переменный сигнал с микрофона. Смотрю выход второго ОУ (точка 2) и там… напряжение питания. Гхм. Может быть, я ошибся, настроил пин как выход — перепроверяю всё, в прошивке всё отлично. Смотрю на схему ещё раз, и меня осенило — R52. Вот это реально могёт в схемотехнику тот, кто проектировал эту плату…

Не, ну правда, чётко. Задать усиление ОУ как по переменному, так и по постоянному напряжению и потом подать полное напряжение Vref на положительный вход (и ОУ попытается усилить Vref по постоянному напряжение в Ку раз, войдя в насыщение). С этим связан ещё один прикол, заходим в официальный репозиторий примеров этой отладочной платы:

Видите тут примеры с АЦП? Нет. Правильно, ведь без доработки платы поиграться с микрофоном не получится (хотя есть ещё другие каналы, с подстроечным резистором и датчиком освещения, там проблем нет, вроде). :) Благо с ЦАП особо не накосячили, просто повесили буферный ОУ.

Я даже набросал эту схему в симуляторе (почти аналог по номиналам и типу ОУ):

И всё ожидаемо (не) работает:

Зелёный луч — Vref, красный луч — выход первого ОУ, синий луч — выход второго ОУ.

Исправляем схему:

И всё работает в симуляции корректно теперь:

Красный луч — выход первого ОУ, зелёный луч — выход второго ОУ.

Итак, вносим правки в схему отладочной платы теперь, чтобы она работала корректно и микрофон имел хорошую чувствительность:

  • Выпаять R52 — это основная проблема;
  • Последовательно с C18 необходимо впаять резистор R? номиналом 1 кОм;
  • Поменять номиналы резисторов R33, R51 на 100 кОм — эта и предыдущая доработки увеличат усиление и чувствительность микрофона соответственно;
  • Поменять номинал C20 на 100 пФ — чуть лучше фильтровать ВЧ будет, но особой роли НЕ сыграет, можно не менять или даже выпаять (а игрался я с этим номиналом и R?, а также параллельно самому микрофону ставил конденсатор по другой причине, о которой ниже).

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

И это я уже забил на то, что после R60 и других аналогичных резисторов на входах ОУ требуется буферный конденсатор на общий, чтобы минимизировать результаты процессов переключения входов АПЦ, а точнее взаимного влияния их друг на друга и ошибки квантования входного сигнала. Очень хорошая статья на эту тему — Демоны в АЦП STM32.

Проверяю я работу схемы после доработок и замечаю такое дело:

Периодические иголки в сигнале, они зависят от режима работы внешнего SPI дисплея. Не, ну я, конечно, соглашусь, дома у меня осциллограф старый Owon ещё тот, но не настолько… Проверяю опять всю схему аналоговую, может, чего подвозбуждается или ещё что-то, и нахожу, что, как минимум, если взять GND с J4 и посмотреть, что происходит на GND J1, то можно увидеть следующую картину (на самом деле там пачками помехи идут, как раз на обновление ЖКИ, но осциллограф сохраняет сигнал как ему больше нравится):

Окей, аналогичная картина и на пинах питания ОУ, а это значит, что у нас КРИВАЯ разводка питания платы. Стоило ожидать… после перлов, найденных при первом знакомстве с отладочным комплектом. Ну что ж, максимум, что я могу сделать, это:

Да, просто накинул поверх провода от LDO и конденсатора рядом, стало лучше, но полностью наводки не ушли:

Примечание: также закоротил J6, который, по задумке разработчика, давал возможность запитать +3.3 В от USB или от внешнего разъёма J6, а вот +3.3 В при таком раскладе на внешнюю плату было брать неоткуда, что довольно бредово, если хочется подключить внешние модули с питанием +3.3 В, но это не последнее такое решение в отношении внешних разъёмов, есть ещё приколы…

В процессе изучения схемы отладочной платы, помимо того что я постоянно плевался на её «стиль» (сами взгляните в pdf), я для удобства расписал все разъёмы IO (странно, что производитель такого не сделал, файл Board IO.xlsx на гите):

Практически НИ ОДИН GPIO не выведен просто так на разъёмы, он так или иначе подключен к периферии, что установлена на плате, тогда как у МК есть свободные пины, и их просто не задействовали… также зачем-то профукали кучу интерфейсов МК (таких как USB, SPI, I2S, I2C), не подключив или только частично выведя IO этих интерфейсов на внешние разъёмы. Это фиаско. Настолько откровенно ужасно спроектированной платы я давно не видел, да многие noname платы с Али продуманы и разведены лучше, чем эта. И да, это уже 3-я ревизия (!!!), страшно представить, что было в первой:

И после увиденного я уже вообще не удивляюсь подобному (и теперь понимаю, откуда появились перемычки на светодиодах и горка mosfet-ов):

Нормальный человек как считает? 1, 2, 3, 4, 5… а разработчик данной отладки считает более изощрённо.

Ну да ладно, подгорели и теперь готовы к дальнейшему созданию проекта.

Реклама

Подготовка Visual Studio Code

Всё аналогично, как и в предыдущей статье для ARM МК, поэтому повторяться я не буду. Если вы уже работаете с ARM-ми, то вам и настраивать ничего не потребуется, а если вы впервые работаете с Visual Studio Code, то тогда стоит прочесть первую статью — Visual Studio Code — написание и отладка прошивок для ARM Cortex-M.

Установка тулчейна, драйверов отладчика

Всё аналогично. Кроме момента с тулчейном, для сборки прошивок под архитектуру RISC-V потребуется GCC версия для RISC-V архитектуры — xPack GNU RISC-V Embedded GCC, пути прописываются в Path аналогичным образом. В качестве инструментов для сборки можно использовать как GNU MCU Eclipse Windows Build Tools, так и xPack Windows Build Tools.

Тестовый проект и компиляция

Базовая структура, описывающая проект:

Да, это суперпростой осциллограф\анализатор спектра, переключаемый кнопками. По сути, у нас есть таймер, который пинает АЦП, с которого замеры читаются по DMA в память (массив), а после заполнения массива вызывается обработка накопленных данных (получая на выходе спектр Фурье или просто масштабированный сигнал), после обработки данные пишутся уже в большой массив, отображающий один кадр ЖКИ (с упрощённым форматом R2G3B3, чтобы минимизировать потребление памяти), а после чего, на лету переводя из R2G3B3 в R5G6B5, кадр пишется в ЖКИ по SPI. ЖКИ я использовал на контроллере ST7735S с разрешением 80*160 точек. Вот такой:

Итак, сам проект можно скачать с гитхаба, и открывается он аналогично в Visual Studio Code как Folder:

Основные моменты, когда будете менять его под свои нужды:

  • файл .vscode\c_cpp_properties.json — все локальные пути в проекте, дефайны и путь к тулчейну в «RISCV_GCC_TOOLCHAIN«, чтобы среда могла корректно проверять на лету на ошибки, подсвечивать их и работали переходы по коду;
  • файл .vscode\launch.json — настройки отладки, тут, в целом, ничего особо нового не появилось, основное отличие от ARM версии — интерфейс подключения JTAG;
  • файл .vscode\settings.json — дополнительные настройки отладки, и тут есть одно важное отличие — параметр «cortex-debug.armToolchainPrefix«, благодаря которому расширение Cortex-Debug стартует отладку RISC-V :) ;
  • файл .vscode\tasks.json — немного поменялся формат команд, как и сами скрипты для J-Link, но, в целом, ничего примечательного.

Далее файл сборки проекта — Makefile, он очень похож на STM32 версию, добавились только отдельные секции для пользовательских исходников, include папок, поменялись настройки компилятора и линковщика, но всё в целом наглядно и понятно расположено.

Папка Drivers — сюда я положил исходный код SDK (папка Firmware) из файла GD32VF103_Firmware_Library_V1.0.2.rar (уже доступна GD32VF103_Firmware_Library_V1.1.0.rar версия, но я не стал обновлять).

Папка DriversExt — различные драйверы внешней периферии, добавляемые пользователем.

Файлы startup, lds (start.S, entry.S, GD32VF103xB.lds) также взяты из GD32VF103_Firmware_Library_V1.0.2.rar, лежат в папке примера под Eclipse Firmware\Drivers\RISCV\env_Eclipse.

Папка Drivers\NMSIS — сюда я положил порт CMSIS DSP из гитхаба NMSIS (вложения папки NMSIS без документации и примеров).

Файл Inc\window_table.h сгенерирован самописной утилитой на C#, тут хранятся коэффициенты окна для сигнала, который будет обработан быстрым преобразованием Фурье.

На этом, собственно, и всё, основной код можно посмотреть в main.c, хоть и без комментариев, но всё довольно наглядно и адекватно проименовано.

После стиля именования HAL или LL на STM32 функции с именами типа gpio_init или spi_i2s_data_transmit прям дико навевают забытый уже SPL, но потом быстро привыкаешь и уже не обращаешь внимания.

Реклама

Прошивка и тестирование работы

Основное, с чего стоит начать — это версия J-Link, согласно официальному обзору различий версий Software and Hardware Features Overview, минимальная версия J-Link для работы с RISC-V – v10.1, а лучше v11. Подойдёт даже EDU версия, с демократичным ценником и минимальным функционалом, но не ограниченным числом точек останова в отладке (правда, отладчик Ozone будет работать неполноценно). Единственный косяк для меня заключается в большом размере самого отладчика и неудобном, огромном разъёме IDC-20, поэтому я сваял на скорую руку такой переходник для удобства использования:

В остальном же прошивка ничем не отличается от прошивки STM32, различия только в интерфейсе — JTAG и прописывании адреса флешки в скрипте JLink\FlashMCU.jlink.

Итак, прошиваем скомпилированную прошивку, и можно играться:

Отладка

Всё абсолютно аналогично примеру на ARM, запускаем отладку так же и можем ставить точки останова когда захотим (не как в IAR EB, только в паузе) и смотреть переменные налету:

Примечание: единственное, что неадекватно работает — это автоопределение Global, Local, Static переменных, что и можно наблюдать на гифке выше. Возможно, я накосячил с флагами компилятора… или таки не получилось Cortex-Debug натянуть на RISC-V без проблем. :)

Если же добавить переменные вручную в Watch, то они прекрасно читаются (тут видно, как они меняются, когда я нажимаю на кнопки на плате):

Ну и последнее, добавив SVD файл, можно смотреть регистры МК (аналогично смотрю на PA10, который меняется в зависимости от нажатия на кнопку):

На этом всё. :) Спасибо, что прочитали!

Реклама

Ссылки

Добавить комментарий

Please log in using one of these methods to post your comment:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google photo

Для комментария используется ваша учётная запись Google. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s