Цель статьи – рассказать о нашем самом первом пользовательском опыте 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 Собираю проект из “Быстрого старта”! Именно для отладочной платы ревизии 2.3 или 2.5 входной аргумент BOARD=[тип платы] в текущей версии SDK можно не указывать, но лучше указать явно, для будущей совместимости. Доступные варианты можно посмотреть в Tools\build\Makefile_template.

cd C:\habr\mcu-sdk-windows_2.3.0_20260703\Projects\HAL_examples\UART\UART_printf
C:\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.elf
Memory 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_LEDBlink
C:\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.elf
Memory 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/bin
openocd -f C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/OpenOCD/share/openocd/scripts/board/baikal/EVU_BA_2_3.cfg
Open On-Chip Debugger 0.12.0+dev-g87e4b69bb (2025-10-26-13:11)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Error: libusb_open() failed with LIBUSB_ERROR_NOT_FOUND
Error: unable to open ftdi device with description '*', serial '*' at bus location '*'
Error: [CORE_0] Unsupported DTM version: -1
Error: [CORE_0] Could not identify target type.
Error: [CORE_1] Unsupported DTM version: -1
Error: [CORE_1] Could not identify target type.
Error: [CORE_2] Unsupported DTM version: -1
Error: [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/bin
openocd -f C:/habr/mcu-sdk-windows_2.3.0_20260703/Tools/OpenOCD/share/openocd/scripts/board/baikal/EVU_BA_2_3.cfg
Open On-Chip Debugger 0.12.0+dev-g87e4b69bb (2025-10-26-13:11)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : clock speed 500 kHz
Info : 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=16
Info : [CORE_0] Disabling abstract command reads from CSRs.
Info : [CORE_0] Disabling abstract command writes to CSRs.
Info : [CORE_0] Examined RISC-V core
Info : [CORE_0]  XLEN=32, misa=0x40903127
[CORE_0] Target successfully examined.
Info : [CORE_0] Examination succeed
Info : [CORE_0] starting gdb server on 3336
Info : Listening on port 3336 for gdb connections
Info : [CORE_1] starting gdb server on 3337
Info : Listening on port 3337 for gdb connections
Info : [CORE_2] starting gdb server on 3338
Info : Listening on port 3338 for gdb connections
CORE_0 halted due to debug-request.
Info : Listening on port 6667 for tcl connections
Info : Listening on port 4445 for telnet connections
Info : [CORE_1] datacount=2 progbufsize=16
Info : [CORE_1] Disabling abstract command reads from CSRs.
Info : [CORE_1] Disabling abstract command writes to CSRs.
Info : [CORE_1] Examined RISC-V core
Info : [CORE_1]  XLEN=32, misa=0x4010b127
[CORE_1] Target successfully examined.
Info : [CORE_1] Examination succeed
Info : [CORE_2] datacount=2 progbufsize=16
Info : [CORE_2] Disabling abstract command reads from CSRs.
Info : [CORE_2] Disabling abstract command writes to CSRs.
Info : [CORE_2] Examined RISC-V core
Info : [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.gdb
GNU gdb (crosstool-NG Baikal rv32) 16.3
Copyright (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 support
determining 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, обязательно посмотрим ?.

Комментарии (7)


  1. Kudriavyi
    26.10.2026 13:28

    Встроенное указание cortex-debug на “оpenocd” “из коробки” не заработало.

    В файле target/baikal/common/server.cfg гвоздями прибит gdb port 3336, а cortex-debug передает в аргументах запуска 50000 и к нему же и пытается подключиться.

    Интересно посмотреть, как отладка трех ядер запускается.


    1. MViktorE Автор
      26.10.2026 13:28

      Действительно интересный вопрос. Поэкспериментируем и, если будет интересный результат напишу здесь.


  1. Gudin
    26.10.2026 13:28

    …Baikal-U - это … 2х16 МБ (XIP режим).

    Это некорректно. В микроконтроллере нет такой памяти. По интерфейсу QSPI к микроконтроллеру можно подключить память любого объема, и затем работать в командном режиме. А в режиме XIP (eXute In Place) адресуетс 16 МБ.

    BOARD=[тип платы] можно не указывать.

    Можно. Но тогда может не заработать. Если работаете с конкретной отладочной платой, то желательно указывать ее модель (либо через аргумент make, либо в файле Makefile). По умолчанию будет использоваться та отладочная плата, которая была актуальна на момент выхода SDK.

    Забегая вперед, чтобы работали точки останова (breakpoints), нужно в EVU_BA_2_3.cfg добавить строчку gdb breakpoint_override hard.

    Это, думаю, делать необязательно. Для отладки из региона eFlash автоматически должны использовать hardware breakpoint. Их количество задано в файле Tools/scripts/bmcu.gdb

    2.4 Теперь настрою отладку через VS Code…

    Стоит попробовать использовать существующий шаблон для VS Code, который входит в состав SDK (Tools/IDE/VSCode/.vscode). Должно быть значительно проще.
    Тут есть видеоролик по теме: https://mcu.baikalelectronics.ru/storage/videos/be-u1000_vs_code_webinar.mp4


    1. MViktorE Автор
      26.10.2026 13:28

      • Про 2x16 Мб XIP. Информация взята с https://www.baikalelectronics.ru/products/baikal-u/. Посмотрел по datasheet и по коду SDK. Вижу что есть 2 QSPI (QSPI0 и QSPI1) к которым теоретически можно подключить 2 внешние flash по 16 Мбайт.

      В Tools\build\platform\BE_U1000\mem_map.mk

      QSPI0_ORIGIN      := 0x80000000
      QSPI0_SIZE        := 16M
      
      QSPI1_ORIGIN      := 0x90000000
      QSPI1_SIZE        := 16M
      

      и в Drivers\BASIS\Device\BMCU\Include\be_u1000.h

      #define XIP0_BASE    0x80000000UL    /*!< XIP0 base address */
      #define XIP1_BASE    0x90000000UL    /*!< XIP1 base address */
      

      Но при этом в “datasheet” версии 1.6.1 от февраля вижу “Максимальный объем прямо адресуемой внешней FLASH памяти – 16 МБ (в XIP режиме)”

      У меня не было необходимости проверять сразу 2 QSPI в режиме XIP. Увы, нет под рукой платы где бы эти оба QSPI удобно распаяны, чтобы попробовать. Вопрос пока открыт.

      • Про BOARD= согласен. Это в будущем может вызвать проблему. Добавил рекомендацию в статью.

      • Про breakpoint_override. Без этой строчки точки останова не работали.

      • Про существующий шаблон для VS Code, пока делали пусконаладку и готовили материал увидели это в новом SDK. Уже добавил в UPD. Спасибо.


  1. NutsUnderline
    26.10.2026 13:28

    для физ. лиц на маркетах продается. только цена от недешевой (по акции) до неразумной.


    1. VO_Obsidian
      26.10.2026 13:28

      Да по ценам уровень тех же Nucleo, даже разумнее чем отладки НИИЭТовских контроллеров. Проблема в том что сам МК стоит ~1500 в розницу.


      1. MViktorE Автор
        26.10.2026 13:28

        Действительно, появились на маректплейсах. Изменил статью. Спасибо.