Микроконтроллер Baikal-U: «Привет мир» и отладка в VS Code

—

от автора

Цель статьи – рассказать о нашем самом первом пользовательском опыте Baikal-U, обменяться опытом с другими пользователями этого чипа и, возможно, привлечь внимание сообщества к новому МК, т. к. один из факторов, влияющих на его массовость и счастливую долгую жизнь, это спрос рынка. В рамках статьи и обсуждений “пробежимся” по “быстрому старту”, настроим отладку через связку OpenOCD + GDB + VS Code, помигаем светодиодом, оно же “Hello world” на микроконтроллерном 😉 и наметим планы на будущее. План выглядит небольшим “вошли и вышли, приключение на 20 минут”, но обо всём по порядку. Большая часть информации будет пересекаться с официальной документацией на сайте BE, но постарался из всего многообразия сделать “выжимку” и описать, как обойти “подводные камни”.

Настроим отладку BE U-1000 за 20 минут!

Настроим отладку BE U-1000 за 20 минут!

Почему именно Baikal-U? Мы как разработчики телекоммуникационного оборудования, сторонники локального развития в целом всей “пищевой цепочки” от компонентов до готовых систем связи, поэтому проводим тесты подходящих по параметрам отечественных компонентов и постепенно внедряем их в наше оборудование. Недавно мы, в Т8, для ряда новых устройств начали использовать отечественный микроконтроллер (МК) Baikal-U (BE U-1000). Выбрать подходящий микроконтроллер — только начало. Дальше предстоит пройти весь инженерный путь: от изучения документации и разработки аппаратной платформы до запуска периферии, написания ПО, интеграции и комплексного тестирования. Каждый этап приносит свои задачи, особенности и, порой, неожиданные проблемы. Поэтому начнем с первого запуска Baikal-U и нашего опыта работы с ним.

Отдельная благодарность коллегам @retrodolivo и @georgyru за помощь в настройке отладки!

0. Технический задел

Экспериментировать буду на отладочной плате “EVU-BA-2.3” с Baikal-U на борту. Если кратко, то Baikal-U — это универсальный микроконтроллер на открытой архитектуре RISC-V с тремя ядрами. Два CloudBEAR BR-350 и один CloudBEAR BM-310, 192 КБ SRAM (в т. ч. 160 КБ TCM), 256 КБ eFLASH и 2х16 МБ (XIP режим).

Отладочная плата с BE U-1000 EVU-BA-2.3.

Отладочная плата с BE U-1000 EVU-BA-2.3.

Техническое описание отладочных плат можно почитать тут. Новая ревизия платы доступна здесь (там для юр. лиц, надеюсь, что в ближайшее время и для физ. лиц будут готовы продать 😉). Сам микроконтроллер доступен тут и тут. Тестировать буду на ОС Windows 10 (сборка 19044.1526).

1. Быстрый старт

Воспользуюсь быстрым стартом на сайте “Байкала”. Там в самой инструкции всё неплохо расписано, поэтому я остановлюсь только на моментах, которые вызвали сложности. Основные сложности были связаны с DFU и, забегая в следующую главу, драйверами USB и настройкой точек останова. В общем, я прошёл по граблям за вас.

1.1 Скачиваю комплект для разработки программного обеспечения (SDK). Использовать буду версию 2.3.0 от 3 июля 2026.

1.2 Распаковываю, путь будет такой: C:\habr\mcu-sdk-windows_2.3.0_20260703

1.3 В инструментах есть bat-файл, прописывающий инструменты для сборки в Path. Запустим C:\habr\mcu-sdk-windows_2.3.0_20260703\Tools\toolchain\xpack-windows-build-tools\add_to_path.bat. Вывод cmd “Успех. Указанное значение сохранено.”, но новый путь в Path не нашел. Прописал C:\habr\mcu-sdk-windows_2.3.0_20260703\Tools\toolchain\xpack-windows-build-tools\bin вручно.

ВНИМАНИЕ, если в вашей системе уже есть утилита make, то могут возникнуть конфликты при попытке сборки проектов.

1.4 Собираю проект из “Быстрого старта”! Для отладочной платы входной аргумент BOARD=[тип платы] можно не указывать.

cd C:\habr\mcu-sdk-windows_2.3.0_20260703\Projects\HAL_examples\UART\UART_printfC:\habr\mcu-sdk-windows_2.3.0_20260703\Projects\HAL_examples\UART\UART_printf>make[CC ] bmcu_cru.c           -> bmcu_cru.o[CC ] bmcu_uart.c          -> bmcu_uart.o[CC ] bmcu_gpio.c          -> bmcu_gpio.o[CC ] bmcu_i2c.c           -> bmcu_i2c.o[CC ] button.c             -> button.o[CC ] led.c                -> led.o[CC ] serial.c             -> serial.o[CC ] i2c2.c               -> i2c2.o[CC ] tusb320.c            -> tusb320.o[CC ] main.c               -> main.o[CC ] syscalls.c           -> syscalls.o[AS ] startup_c0_c1.S      -> startup_c0_c1.o[LD ] generated.ld          : UART_printf.elfMemory region         Used Size  Region Size  %age Used             ROM:       11920 B       256 KB      4.55%             RAM:         424 B        32 KB      1.29%Size of C:/habr/mcu-sdk-windows_2.3.0_20260703/Projects/HAL_examples/UART/UART_printf/output/debug/UART_printf.elf:   text    data     bss     dec     hex filename  11826      92     332   12250    2fda C:/habr/mcu-sdk-windows_2.3.0_20260703/Projects/HAL_examples/UART/UART_printf/output/debug/UART_printf.elf    Build ID: 9ce9048e790de1d07c86a96d9deff96c28fb7bf8[BIN] UART_printf.elf      -> UART_printf.bin[HEX] UART_printf.elf      -> UART_printf.hex[DIS] UART_printf.elf      -> UART_printf.disasm[LSS] UART_printf.elf      -> UART_printf.lss[SYM] UART_printf.elf      -> UART_printf.sym

Забегая вперед, соберу проект GPIO_LEDBlink, который будем использовать при настройке отладки (в следующем разделе).

Скрытый текст. Сборка проекта GPIO_LEDBlink
cd C:\habr\mcu-sdk-windows_2.3.0_20260703\Projects\HAL_examples\GPIO\GPIO_LEDBlinkC:\habr\mcu-sdk-windows_2.3.0_20260703\Projects\HAL_examples\GPIO\GPIO_LEDBlink>make[CC ] bmcu_cru.c           -> bmcu_cru.o[CC ] bmcu_gpio.c          -> bmcu_gpio.o[CC ] bmcu_i2c.c           -> bmcu_i2c.o[CC ] bmcu_uart.c          -> bmcu_uart.o[CC ] button.c             -> button.o[CC ] led.c                -> led.o[CC ] serial.c             -> serial.o[CC ] i2c2.c               -> i2c2.o[CC ] tusb320.c            -> tusb320.o[CC ] main.c               -> main.o[CC ] syscalls.c           -> syscalls.o[AS ] startup_c0_c1.S      -> startup_c0_c1.o[LD ] generated.ld          : GPIO_LEDBlink.elfMemory region         Used Size  Region Size  %age Used             ROM:        8476 B       256 KB      3.23%             RAM:         424 B        32 KB      1.29%Size of C:/habr/mcu-sdk-windows_2.3.0_20260703/Projects/HAL_examples/GPIO/GPIO_LEDBlink/output/debug/GPIO_LEDBlink.elf:   text    data     bss     dec     hex filename   8382      92     332    8806    2266 C:/habr/mcu-sdk-windows_2.3.0_20260703/Projects/HAL_examples/GPIO/GPIO_LEDBlink/output/debug/GPIO_LEDBlink.elf    Build ID: ad133b112d005d73cb38681b19205bd23b394ff0[BIN] GPIO_LEDBlink.elf    -> GPIO_LEDBlink.bin[HEX] GPIO_LEDBlink.elf    -> GPIO_LEDBlink.hex[DIS] GPIO_LEDBlink.elf    -> GPIO_LEDBlink.disasm[LSS] GPIO_LEDBlink.elf    -> GPIO_LEDBlink.lss[SYM] GPIO_LEDBlink.elf    -> GPIO_LEDBlink.sym

1.5 Попробую загрузить и исполнить собранные образы ВПО. Через DFU загрузить у меня не получилось. Ошибка была следующая: Cannot open DFU device cafe:2303. Долго разбираться не стал, сразу перешел на “Запись и исполнение программы через UART”. Скачал ExtraPuTTy. Не буду тут дублировать инструкцию. В результате файл через XMODEM загрузился, в PuTTy пришла заветная отладочная строка “UART printf example”:

Загрузка bin файла через XMODEM.

Загрузка bin файла через XMODEM.
Данные, полученные в терминале от Baikal U-1000.

Данные, полученные в терминале от Baikal U-1000.

В итоге “Быстрого старта” проверил, что основной функционал “EVU-BA-2.3” с Baikal-U на борту работает, теперь перейду к самому интересному и более близкому к реальному процессу разработки.

2. Настройка отладки через OpenOCD + GDB + VS Code

Положение перемычек для XP1 и XP11 на EVU-BA-2.3 для отладки.

Положение перемычек для XP1 и XP11 на EVU-BA-2.3 для отладки.

2.1 Для того чтобы корректно подключиться, установлю перемычки на XP1 на M2 и XP11 на USB (см. фотографию). Тут можно посмотреть детальную схемотехнику и понять, на что влияют перемычки. А мы пока приступаем к запуску отладочных инструментов, включая USB-кабель между ПК и разъемом XS2 отладочной платы.

2.2 Запускаю OpenOCD, который уже есть в инструментах SDK и конфигурацию EVU_BA_2_3.cfg, после чего можем увидеть следующую ошибку:

cd C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/OpenOCD/binopenocd -f C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/OpenOCD/share/openocd/scripts/board/baikal/EVU_BA_2_3.cfgOpen On-Chip Debugger 0.12.0+dev-g87e4b69bb (2025-10-26-13:11)Licensed under GNU GPL v2For bug reports, read        http://openocd.org/doc/doxygen/bugs.htmlError: libusb_open() failed with LIBUSB_ERROR_NOT_FOUNDError: unable to open ftdi device with description '*', serial '*' at bus location '*'Error: [CORE_0] Unsupported DTM version: -1Error: [CORE_0] Could not identify target type.Error: [CORE_1] Unsupported DTM version: -1Error: [CORE_1] Could not identify target type.Error: [CORE_2] Unsupported DTM version: -1Error: [CORE_2] Could not identify target type.

Чтобы исправить ошибку, изменим драйвера. Для этого воспользуюсь утилитой Zadig, которую разработчики SDK заботливо положили в архив: C:\habr\mcu-sdk-windows_2.3.0_20260703\Tools\zadig-2.9.exe

Нажимаем “Options” и “List All Devices”. В появившемся списке ниже выбираем Dual RS232-HS (Interface 0) и ставим “libusb-win32 (v1.4.0.0)” или “libusbK (v.3.1.0.0)” (у меня заработало с libusbK, у коллеги с libusb-win32). Нажимаем “Install Driver” или “Replace Driver”. Повторяем для Dual RS232-HS (Interface 1).

В утилите Zadig выбираем libusb-win32 или libusbK.

В утилите Zadig выбираем libusb-win32 или libusbK.

ВАЖНО! Забегая вперед, чтобы работали точки останова (breakpoints), нужно в EVU_BA_2_3.cfg добавить строчку gdb breakpoint_override hard. Эта команда принудительно заменяет все обычные программные точки останова, запрашиваемые отладчиком GDB, на аппаратные точки останова (hardware breakpoints).

Добавление замены точки останова на аппаратные.

Добавление замены точки останова на аппаратные.

Снова пробую запустить OpenOCD в отдельном окне терминала, теперь вывод в консоль такой:

cd C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/OpenOCD/binopenocd -f C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/OpenOCD/share/openocd/scripts/board/baikal/EVU_BA_2_3.cfgOpen On-Chip Debugger 0.12.0+dev-g87e4b69bb (2025-10-26-13:11)Licensed under GNU GPL v2For bug reports, read        http://openocd.org/doc/doxygen/bugs.htmlInfo : clock speed 500 kHzInfo : JTAG tap: riscv.cpu2 tap/device found: 0x1bafa001 (mfg: 0x000 (<invalid>), part: 0xbafa, ver: 0x1)Info : JTAG tap: riscv.cpu1 tap/device found: 0x1bafa001 (mfg: 0x000 (<invalid>), part: 0xbafa, ver: 0x1)Info : JTAG tap: riscv.cpu0 tap/device found: 0x1bafa001 (mfg: 0x000 (<invalid>), part: 0xbafa, ver: 0x1)Info : [CORE_0] datacount=2 progbufsize=16Info : [CORE_0] Disabling abstract command reads from CSRs.Info : [CORE_0] Disabling abstract command writes to CSRs.Info : [CORE_0] Examined RISC-V coreInfo : [CORE_0]  XLEN=32, misa=0x40903127[CORE_0] Target successfully examined.Info : [CORE_0] Examination succeedInfo : [CORE_0] starting gdb server on 3336Info : Listening on port 3336 for gdb connectionsInfo : [CORE_1] starting gdb server on 3337Info : Listening on port 3337 for gdb connectionsInfo : [CORE_2] starting gdb server on 3338Info : Listening on port 3338 for gdb connectionsCORE_0 halted due to debug-request.Info : Listening on port 6667 for tcl connectionsInfo : Listening on port 4445 for telnet connectionsInfo : [CORE_1] datacount=2 progbufsize=16Info : [CORE_1] Disabling abstract command reads from CSRs.Info : [CORE_1] Disabling abstract command writes to CSRs.Info : [CORE_1] Examined RISC-V coreInfo : [CORE_1]  XLEN=32, misa=0x4010b127[CORE_1] Target successfully examined.Info : [CORE_1] Examination succeedInfo : [CORE_2] datacount=2 progbufsize=16Info : [CORE_2] Disabling abstract command reads from CSRs.Info : [CORE_2] Disabling abstract command writes to CSRs.Info : [CORE_2] Examined RISC-V coreInfo : [CORE_2]  XLEN=32, misa=0x40101106[CORE_2] Target successfully examined.Info : [CORE_2] Examination succeed

Не закрываем это окно.

2.3 Теперь запущу GDB. Можно для проверки, что GDB отвечает корректно, запустить в окне cmd с конфигурацией C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/scripts/bmcu.gdb:

cd C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/toolchain/riscv32-none-elf/bin/riscv32-none-elf-gdb.exe -x C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/scripts/bmcu.gdbGNU gdb (crosstool-NG Baikal rv32) 16.3Copyright (C) 2024 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.Type "show copying" and "show warranty" for details.This GDB was configured as "--host=x86_64-host_w64-mingw32 --target=riscv32-none-elf".Type "show configuration" for configuration details.For bug reporting instructions, please see:<https://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:    <http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word".warning: No executable has been specified and target does not supportdetermining executable automatically.  Try using the "file" command.0x4000124c in ?? ()(gdb)

Если вывод в cmd такой, то всё работает корректно. Можем пока закрыть cmd с GDB.

2.4 Теперь настрою отладку через VS Code. Устанавливаем VS Code если его у вас нет 😀. Для отладки будем использовать расширение “cortex-debug” (использовал версию 1.12.1).

Расширение cortex-debug

Расширение cortex-debug

Устанавливаем. Для настройки создадим в примере проекта C:\habr\mcu-sdk-windows_2.3.0_20260703\Projects\HAL_examples\GPIO\GPIO_LEDBlink (да-да, именно тот, который мы собирали в п.1.4) папку “.vscode” и там создаем «launch.json» со следующим наполнением:

{  "version": "0.2.0",  "configurations": [    {      "name": "beu1000_debug",      "cwd": "${workspaceFolder}",      "executable": "C:/habr/mcu-sdk-windows_2.3.0_20260703/Projects/HAL_examples/GPIO/GPIO_LEDBlink/output/debug/GPIO_LEDBlink.elf",      "request": "launch",      "type": "cortex-debug",      "servertype": "external",      "gdbTarget": "localhost:3336",      "gdbPath": "C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/toolchain/riscv32-none-elf/bin/riscv32-none-elf-gdb.exe",      "svdFile": "C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/svd/be_u1000.svd",      "showDevDebugOutput": "raw",      "preLaunchCommands": [        "source C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/scripts/bmcu.gdb"      ],      "overrideLaunchCommands": [        //< Erase eFlash        "bmcu eFlash erase",        "bmcu reset",        //< Load eFlash        "file C:/habr/mcu-sdk-windows_2.3.0_20260703/Projects/HAL_examples/GPIO/GPIO_LEDBlink/output/debug/GPIO_LEDBlink.elf",        "load",        //< Run        "break main"      ]    },  ]}

Пути указал абсолютные, чтобы было более явно видно, что имею ввиду.

“servertype”: “external” — подразумевается, что будет использоваться OpenOCD, который был запущен в п.2.2. Встроенное указание cortex-debug на “оpenocd” “из коробки” не заработало.

“preLaunchCommands” как раз та команда, которую мы проверяли в п.2.3.

“overrideLaunchCommands” взято минимальное количество команд, которые в том числе описаны в “bmcu.gdb”.

Не забываем проверить, что в фоне работает OpenOCD.

2.5 Запускаю отладку из VS Code (нажимаю F5):

Начало отладки в VS Code.

Начало отладки в VS Code.

Шагаю (F10) и даже видим, что значения регистров меняется (не зря подключили be_u1000.svd), а светодиод на плате тоже то включается, то выключается:

Отладка в VS Code.

Отладка в VS Code.
Ура! Пользовательский диод LD1 засветился :)

Ура! Пользовательский диод LD1 засветился 🙂

Заключение

Хотел бы отметить, что в рамках данной статьи реализован демонстрационный вариант. Безусловно, это не самые оптимальные конфигурации launch.json. Сюда можно добавить tasks.json c задачами сборки проекта, включения/выключения OpenOCD, и работу с точками останова, и отладку с помощью J-Link, а не FTDI и т. д., но это, если интересно, то в следующий раз.

UPD: Разработчики SDK подготовили настройки для VS Code в C:\habr\mcu-sdk-windows_2.3.0_20260703\Tools\IDE\VSCode, обязательно посмотрим 😊.

ссылка на оригинал статьи https://habr.com/ru/articles/1099562/