Portfolio Обо мне Блог

Для одного из моих проектов у меня оказалась отладочная плата LDM-HELPER-K1921BK01T-FULL, как очевидно из названия платы и статьи на контроллере K1921VK01T. Вместе с ней шол дополнительный модуль LDM-HELPER-MB501-FULL. По сути все что нужно знать про эти 2 платы это их 2 шиматика раз и два, дабы вы могли сопоставить мои примеры со схемой вашей отладочной платы. По ходу статьи мы настроем среду для работы с данным контроллером в среде VSCode, и напишем простенькую программу.

Вообще производитель предлагает использовать следующие IDE:

  • CodeMaster++[арм] (вроде как его не существует)
  • Keil (без комментариев)
  • IAR (без комментариев)
  • Vector IDE (для венды наверное лучший вариант)
  • Qt Creator (вроде как можно настроить).
  • MexBIOS Development студио (вроде как программирование с помощью блоков)
  • Любые IDE и редакторы, поддерживающие GNU ARM Embedded Toolchain и openocd/SEGGER J-Link.

К сожалению, из этого всего на линуксе работает только Qt Creator, но он мне не нравится, так что выберем последний вариант и настроим все своими руками.

Для венды крайне советую Vector IDE, работает из коробки с stlink, а вот с jlink какие-то проблемы и нужно ставить сторонние драйвера, что не позволит использовать этот программатор с другими контроллерами до отката дров. Также в комплекте не плохие примеры с русскими комментарии, но к сожалению эти ребята отрицают библиотеки и пишут все на CMSIS.

Toolchain

  1. Компилятор

Для начала я предлагаю разобраться со сборкой кода и заливкой прошивки. Первым делом решим проблему с компилятором. Тут есть 2 пути, первый:

sudo apt install -y gcc-arm-none-eabi

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

Скачаем компилятор с официального сайта. Тут есть важный нюанс, если у вас в системе уже стоит какой-то компилятор gcc-arm-none-eabi*, то удалите его, для избегания конфликтов, если у вас стоит какая-то IDE вроде CubeIDE, то это не важно т.к. они держат свои версии компиляторов внутри себя. Как только удалили из системы прошлую версию компилятора если она была, качаем последнюю версию для Linux x86_64 Tarball. Для того чтобы установить gcc-arm-none-eabi, необходимо сделать следующее:

tar xvjf ~/Downloads/gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2
mkdir ~/toolchains
cp -R gcc-arm-none-eabi-10-2020-q4-major ~/toolchains
echo "export PATH=\"$PATH:~/toolchains/gcc-arm-none-eabi-10-2020-q4-major/bin\"" >> ~/.bashrc
rm -r gcc-arm-none-eabi-10-2020-q4-major

Далее можно проверить что все работает и доступно из консоли:

arm-none-eabi-gcc --version

Должен появится тот номер версии которую вы ставили.

arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  1. Debugger.

Производитель обещает, что работают любые программаторы "подходящие для Cortex-M микронтроллеров (ST-Link, JLink и др.)", однако у меня нормально заработало только с ST-Link'ом, поэтому будем использовать его. В качестве сервера будем использовать OpenOCD. Как ни странно, но разработчики OpenOCD приняли коммит от НИИЭТа и теперь дебаг сервер официально поддерживает работу с данным контроллером.

Если версия в репозитории поддерживает нужный контроллер, то:

sudo apt install openocd

Если нет, то вам необходима более свежая версия ее можно собрать из исходников, процесс достаточно простой и описан в ReadMe.

  1. Остальное

Также для работы потребуется дополнительные пакеты - Cmake и git:

sudo apt install git cmake

API

  1. SDK

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

mkdir k1921vk01t_test
cd k1921vk01t_test
git clone https://bitbucket.org/niietcm4/k1921vkx_sdk.git
cd k1921vkx_sdk/projects/niietcm4_pd/gpio/run_led/GCC
./build_debug.sh
rm -r build-Debug

Если в процессе сборки не возникло ошибок значит все хорошо и у нас установленны все необходимые пакеты, для сборки.

Я специально создал папку k1921vk01t_test Таким образом мы можем обновлять (либо менять версию) sdk без вмешательства в наш проект.

TODO: Здесь тоже лучше прям консольными командами расписать

Далее добавим "Шаблон проекта для К1921ВК01T с использованием библиотеки NIIETCM4 PD" из k1921vkx_sdk/templates/k1921vk01t-niietcm4pd в нашу папку, а именно:

  • переместим папку app в корень нашего проекта.
  • из папки GCC перетащим CMakeLists.txt и gcc_cm4f.cmake

и изменим некоторые параметры в CMakeLists.txt:

  • APP_PATH с ../app --> app
  • PLATFORM_PATH с ../platform --> k1921vkx_sdk/platform
  • PROJECT с template --> k1921vk01t_test

Последний параметр повлияет на название конечного бинаря, что в свою очередь повлияет на то, сможет ли найти его дебагeр. Так что там необходимо прописать актуальное имя проекта.

Тут есть альтернативный вариант, когда мы создаем k1921vkx_workspace и храним SDK в корне этого воркспейса и тогда все проекты которые будут созданы будут ссылаться на одну копию SDK, что позволит сэкономить место на диске. Для того чтобы воспользоваться этим вариантом, необходимо будет поменять путь PLATFORM_PATH на ../k1921vkx_sdk/platform и возможно еще что-то. Я решил не использовать этот вариант. 200Mb не так уж и много + если я вдруг что-то изменю в SDK (лучше так не делать), то это не сломает остальные проекты.

  1. Тестовая программа

Также я предлагаю добавить в код часть с миганием диодом, чтобы легко убедится в его работоспособности. Для этого необходимо в main.c добавить код для инициализации gpio:

#define LED7_PORT NT_GPIOE
#define LED7_PIN_MASK (1 << 3)

void GPIOInit()
{
    GPIO_Init_TypeDef GPIOInit;
    GPIO_StructInit(&GPIOInit);
    GPIOInit.GPIO_Dir = GPIO_Dir_Out;
    GPIOInit.GPIO_Out = GPIO_Out_En;

    /* GPIOE */
    GPIOInit.GPIO_Pin = LED7_PIN_MASK;
    GPIO_Init(NT_GPIOE, &GPIOInit);
}

Далее в функцию periph_init() необходимо добавить вызов функции описанной выше:

    GPIOInit();

И менять состояние пина в прерывании:

void SysTick_Handler()
{
    GPIO_ToggleBits(NT_GPIOE, LED7_PIN_MASK);
}

Чтобы убедится в том, что мы все правильно сделали попробуем собрать проект:

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
  1. Тестируем.

Для начала проверим работу OpenOCD. Для этого открываем второй терминал и в нем запускаем openocd server.

TODO: Проверить тему с конфигами stlink

openocd -f interface/stlink.cfg -f target/k1921vk01t.cfg

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

telnet localhost 4444
> program /home/zen/Desktop/K1921VK01T_test/build/template.hex verify reset 0x00000000

После чего плата должна удачно прошиться и диод должен начать мигать. Однако это не является 100% гарантией нормальной работы. Тестовая программа по Завершению инициализации должна напечатать строку и частоте SystemCoreClock, со скоростью 115200. Подключившись USB->UART преобразователем к плате и Увидя не битое сообщения мы убедимся в том что система тактирования настроена правильно. А значит все работает. В случае если вместо осмысленного сообщения приходит мусор, поставьте в CMakeLists.txt частоту соответствующую кварцу подключенному к контроллеру:

SET(OSECLK_VAL      16000000)       # OSECLK value in Hz (0 if disconnected)

VSCODE

  1. Cmake

Dсе работает, теперь осталось дело за малым - настроить VScode так, чтобы он мог заливть и собирать код для нашего контроллера, для этого в нем должны быть установленны следующие расширения:

  • C/C++ (ms-vscode.cpptools) - продвинутый линтер.
  • Cortex-Debug (marus25.cortex-debug) - дебагер для cortex контроллеров.
  • CMake Tools (ms-vscode.cmake-tools) - расширение которое позволяет работать с cmake как с проектом.
  • CMake (twxs.cmake) - подсветка синтаксиса cmake.

Расширение CMake Tools добавляет полезные кнопки внизу такие как:

cmake

  1. Выбор конфига для сборки (в теории можно указать несколько в launch.json).

  2. Выбор варианта текущей сборки (то что прописанно в cmake).

  3. Выбор компилятора (нужно выбрать то что установили вначале).

  4. Кнопка для сборки кода.

  5. Дебагер

Для заливки прошивки в плату и последующей отладки, нам необхедимо cоздать папку с файлом .vscode/launch.json в корне проекта, и записать туда следующий конфиг:

TODO: "cortex-debug.armToolchainPath": "/home/tuo/toolchains/gcc-arm-none-eabi-10-2020-q4-major/bin"

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Cortex Debug",
            "cwd": "${workspaceRoot}",
            "executable": "build/${workspaceFolderBasename}.elf",
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "openocd",

            "device": "K1921VK01T",
            "svdFile": "K1921VK01T.svd",
            "runToMain": true,
            "configFiles": [
                "interface/stlink.cfg",
                "target/k1921vk01t.cfg"                
            ]
        }
    ]
}

Иногда дебаг может стартовать не с первой команды, а непонятно откуда, и не работать. Чтобы решить эту проблему нужно сделать cmake clean project:

fix

Также для работы с регитрами перефирии нужен SWD файл. К сожалению файл k1921vkx_sdk/tools/svd/K1921VK01T.svd не заработал, выдавая ошибку:

Unable to parse SVD file: TypeError: Cannot read property 'map' of undefined

Поэтому я попросил свою коллегу создать issue на гите расширения Cortex Debug. Все оказалось очень просто, парсер расширения не может работать с пустыми полями. Поэтому копируем SVD из SDK себе в корень проекта, и удаляем 2 строки:

10823   <fields>
10824   </fields>

После чего регистры перефирии будут распозноватся правильно.

  1. Линтер

UDP: Для Cmake можно использовать расширение от Microsoft ms-vscode.cmake-tools и оно автоматически настроет линтер, пример использования можно глянуть тут.

Для работы линтера необходимо добавить файл .vscode/c_cpp_properties.json в проект.

{
    "configurations": [
        {
            "name": "K1921VK01T",
            "compilerPath": "arm-none-eabi-gcc",
            "includePath": [
                "${workspaceRoot}/**"
            ],
            "defines": [
                "MCUNAME=K1921VK01T"
            ],
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-arm"
        }
    ],
    "version": 4
}

Тут необходимо указать название нашего конроллера в defines, для того чтобы линтер знал библиотеку для какого контроллера необходимо выбрать при авто подстановке и переходам по коду.

Вот собственно и все, мы получили гибкую и современную IDE для работы с отечественным контроллером. А все благодаря тому что niiet использует стандартное ARM ядро, под которое существует много инструментов для работы.

Интересные ссылки

В данной статье я менее подробно описывал процесс настройки vscode потому что более подробное описание было сделано в статье про настройку среды для stm32.

  • Datasheet на контроллер К1921VK01T1.
  • Errata на контроллер К1921VK01T1/
  • GIT c K1921VKx_SDK.
  • Страница с контроллером от производителя.
  • FAQ от производителя по данному контроллеру.
  • Руководство пользователя по VectorIDE.
  • Описание отладочной платы VectorCARD K1921BK01T (NT32M4F1).
  • Курс проектирование цифровых систем управления на базе отечественного микроконтроллера НИИЭТ К1921ВК01Т.
  • Страница с отладочной платой.
  • Статья про создание данного контроллера на хабр (самая годнота комментарии).
  • API для взаимодействия с контроллером на RUST.