Многие привыкли легко и просто программировать микроконтроллеры на платформе Arduino или nanoFramework (используется C#). Но как обстоит с разработкой IoT приложений на C# .NET для одноплатных компьютеров под Linux? В ответ услышите что нужно все устанавливать из командной строки, да и еще хорошо разбираться в Linux, там не так просто как с Arduino. Для настройки удаленной отладки необходимо выполнить множество различных действий, вручную настроить конфигурацию запуска, генерировать ключи доступа для пользователя, от имени которого будет запускать отладка, и т. д. Но теперь, благодаря расширению .NET FastIoT для Visual Studio Code, это не требуется делать. Черновую работу по установке необходимых пакетов и конфигурированию проекта для удаленной отладки сделает за вас расширение. Теперь вы можете полностью сфокусироваться на своем коде, не отвлекаясь на лишние задачи.
Предыстория
Для начала рассмотрим, как ведется разработка и удаленная отладка .NET приложений в Linux без нового расширения. Обратимся к руководству Debug .NET apps on Raspberry Pi от Microsoft.
Первое, открываем проект в Visual Studio Code под Windows, далее компилируем проект под архитектуру ARM, и вручную переносим полученные бинарные файлы (сборки, ресурсы) на одноплатный компьютер. На одноплатном компьютере Raspberry/Banana/Orange/Rock/Nano Pi предварительно должен быть установлен Remote Debugger и .NET Runtime (в случае запуска приложения в формате Framework-dependent). Помимо этого, для каждого проекта вручную настраиваются параметры запуска в файле launch.json. И это мы не говорим про настройку прав доступа к файл-устройствам, если хотим работать с линиями GPIO, PWM, шиной I2C и т. д. не от имени пользователя root.
Пример файла launch.json для запуска .NET приложения как Framework-dependent:
"configurations": [
{
"name": ".NET Remote Launch - Framework-dependent",
"type": "coreclr",
"request": "launch",
"program": "~/dotnet/dotnet",
"args": ["~/sample/sample.dll"],
"cwd": "~/sample",
"stopAtEntry": false,
"console": "internalConsole",
"pipeTransport": {
"pipeCwd": "${workspaceRoot}",
"pipeProgram": "C:\\Program Files\\PuTTY\\PLINK.EXE",
"pipeArgs": [
"-pw", "raspberry",
"pi@raspberrypi"
],
"debuggerPath": "~/vsdbg/vsdbg"
}
},
Помимо Visual Studio Code в Windows, для отладки требуется еще терминал PuTTY, с помощью него создается SSH-туннель для связи с отладчиком, кратко про про SSH-туннели в блоге Timeweb Cloud.
Обратите внимание, в файле launch.json содержится пароль пользователя в открытом виде, что не очень хорошо с точки зрения безопасности. Эту проблему решает вариант использование ключей для доступа по SSH-протоколу взамен пароля. Для этого придется генерировать пару ключей, публичный и приватный. Публичный ключ потребуется скопировать на одноплатный компьютер, затем внести его в конфигурационный файл ~/.ssh/authorized_keys. Более подробно об этом не быстром процессе — Удаленная отладка приложения на .NET 5.0 в Visual Studio Code для ARM. Как заметили, процесс организации удаленной отладки на Linux не такой простой как для Arduino.
Для комплексного решения задачи удаленной отладки появилась идея разработать расширение для Visual Studio Code. Расширение должно автоматизировать процесс разработки IoT приложений для одноплатных компьютеров и сделать процесс разработки таким же простым и понятным, как и для платформ Arduino и nanoFramework. Подобную задачу решает расширение Torizon от компании Toradex, но это расширение работает только с железом собственного производства и отладка выполняется в Docker-контейнерах.
Рассмотрим расширение .NET FastIoT, возможности и решаемые задачи.
.NET FastIoT VS Code Extension
Расширение настраивает встраиваемое устройство на архитектуре ARMv7 или ARMv8, работающее под Linux, для запуска .NET приложений, и конфигурирует проекты *.csproj для удаленной отладки по ssh-туннелю. Работает только на Windows (64 бит).
Интерфейс расширения .NET FastIoT
Описание:
- Активация. Для активации расширения перейдите на кнопку расширения в главной панели;
- Список устройств. Содержит профили устройств. Можно добавлять, удалять устройства, а также экспортировать и импортировать из файла в формате json;
- Окно выбора источника событий. Из списка необходимо выбрать .NET FastIoT;
- Журналирование событий. Все события связанные с расширением отображаются в этом окне, в том числе ошибки с подробным отчетом.
Возможности расширения
- Простая установка .NET SDK, .NET Runtimes, .NET Debugger (vsdbg), Libgpiod, Docker для Linux;
- Настройка проектов .NET для удаленной отладки, добавление переменных окружения (метод Environment.GetEnvironmentVariable);
- Управление файлами наложения устройств (Device Tree overlays). Требуется для включения/выключения таких устройства как I2C, SPI, PWM, и т. д. Доступна удаленная загрузка файлов *.DTS и включение/выключение «слоев». Более подробно в публикации Работа с GPIO. Часть 2. Device Tree overlays. Поддерживается только дистрибутив Armbian. Для поддержки других дистрибутивов необходима реализация адаптера по интерфейсу IDtoAdapter.ts. Пример реализации для Armbian — IoTDTOArmbianAdapter.ts;
- Управление контактами GPIO (пока полностью не реализовано). Обнаружение доступных Gpiochip
и линий. Подача «0/1» на контакт, считывание состояния контакта. Формирование C# кода под выбранный контакт для переноса в проект один-к-одному.
Системные требования
- Версия ОС. Windows 7-10 (x64). Версия для Linux появится позже;
- Visual Studio Code. версия не ниже 1.63;
- .NET. Для компиляции проекта на C# требуется .NET SDK в зависимости от используемой версии вашего проекта (для работы самого расширения не требуется);
Дополнительные расширения необходимые для разработки .NET приложений:
- C# for Visual Studio Code (powered by OmniSharp) — поддержка разработки на C#;
- NuGet Package Manager — добавление Nuget-пакетов (позже менеджер Nuget-пакетов будет встроен в расширение);
- DeviceTree (опционально) — поддержка синтаксиса для файлов дерева устройств (Device Tree, DT). Используется для редактирования файлов *.dts. Например, потребуется если возникнет необходимость адаптации дисплея SPI LCD ILI9341 для вашего одноплатного компьютера.
Сторонние приложения:
- cwRsync. Из пакета используются утилиты rsync и ssh. Входит в состав расширения и копируется в папку по умолчанию C:\RemoteCode\cwrsync\ (расположение изменяется в настройках). По желанию можете заменить пакет, загрузив с официального сайта по ссылке. Терминал PuTTY не используется.
Сторонние bash-скрипты для установки пакетов/библиотек:
- .NET SDK, .NET Runtimes, .NET Debugger (vsdbg), Libgpiod, Docker, загружаются с официальных сайтов разработчиков пакетов, за исключением библиотеки Libgpiod. Скрипт для установки данной библиотеки загружается с ресурса GitHub — devdotnetorg/docker-libgpiod. Далее, загруженный скрипт скачивает исходный текст библиотеки с официального репозитория Libgpiod и выполняется компиляция библиотеки.
Как работает расширение
Принцип работы расширения достаточно прост. Пользователь в интерактивном режиме указывает необходимые опции. Далее, в зависимости от задачи, соответствующий bash-скрипт копируется на одноплатный компьютер. Затем этот скрипт выполняется с параметрами, которые задал пользователь. Потом на устройстве происходит какая-то «магия». А после всей «магии», для удаленного запуска проекта конфигурируются файлы launch.json и tasks.json.
Быстрый старт
Шаг 1 — Подготовка устройства
Одноплатный компьютер должен работать под управлением дистрибутива Debian или Ubuntu, Linux. Для удаленного доступа необходимо установить ssh-сервер и задать определенные настройки. В качестве терминала для удаленного доступа можно использовать MobaXterm (существенно удобнее по сравнению с PuTTY терминалом). Если пакет sudo не установлен, то установите данный пакет от имени пользователя root, с помощью команд:
apt-get update
apt-get install -y sudo
ля установки ssh-сервера и настройки доступа выполните следующие команды на одноплатном компьютере:
sudo apt-get update
sudo apt-get install -y openssh-server mc
sudo systemctl reload ssh
sudo mcedit /etc/ssh/sshd_config
В открывшемся редакторе задайте следующие параметры. Если данные параметры отсутствуют, то просто вставьте строку (обычно отсутствует параметр AuthenticationMethods):
PermitRootLogin yes
PasswordAuthentication yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey keyboard-interactive password
Затем сохраните изменения <F2> и выйдите из редактора <F10>.
Перезапустите ssh-сервер для применения новых настроек:
sudo systemctl reload ssh
sudo systemctl status ssh
Последняя команда выводит текущий статус службы.
Видео-инструкция настройки ssh-сервера для подключения расширения
Шаг 2 — Добавление устройства
При первом подключение создается пара ключей доступа, приватный и публичный. Приватный ключ копируется в папку C:\RemoteCode\keys\ (расположение изменяется в настройках). Данный ключ используется для конфигурирования устройства и запуска удаленной отладки.
Важный момент заключается в выборе учетной записи для создания на устройстве. Первый вариант это учетная запись debugvscode (название можно изменить в настройках), второй вариант это root:
Выбор учетной записи для создания на устройстве
При выборе варианта debugvscode создаетcя файл настройки прав доступа 20-gpio-fastiot.rules к устройствам используя подсистему udev. Создается группа с названием iot, и выдаются права на устройства, такие как: gpiochip, I2C, SPI, PWM, и т. д. Затем в эту группу добавляется пользователь debugvscode. В связи с тем, что тестирование выполнялось только на Armbian, возможно не все права доступа были добавлены. Поэтому, если возникнут проблемы с правами доступа к устройствам, то выбирайте — root.
Добавление нового устройства (YouTube):
Шаг 3 — Установка пакетов
Минимально требуется установить два пакета:
- .NET Runtime — фреймворк для запуска NET приложений;
- .NET Debugger — отладчик для удаленной отладки.
Libgpiod — потребуется для доступа к контактам GPIO.
Docker — на будущее, для запуска отладки в контейнерах.
Установка пакетов (YouTube):
Device Tree Overlays
Управление файлами наложения для дерева устройств используется для выключения/выключения устройств. Данные файлы загружаются в формате *.dts (исходный файл для дерева устройств). Если для работы с GPIO у вас нет в наличие светодиодов, но есть светодиоды на самом одноплатном компьютере, то доступные светодиоды можно исключить из конфигурации дерева устройств, а затем управлять ими из .NET кода. Как это сделать в публикации .NET IoT. Часть 2. Мигаем светодиодом (LED) используя библиотеку Libgpiod.
Шаг 4 — Создание конфигурации для удаленной отладки
После добавления устройства и установки пакетов, откройте проект формата *.csproj.
Обратите внимание, если после открытия проекта в папке /.vscode появились файлы launch.json и tasks.json, то удалите эти файлы, иначе конфигурация не будет создана. Проблема связанна с добавлением VSCode комментариев "//" в файл *.json, в результате при разборе возникает исключение. В следующей версии расширения будет добавлено игнорирование комментариев.
Нажимаем кнопку Add Configuration, выбираем проект и конфигурация создана. Для запуска проекта остается перейти в раздел Run and Debug и выбрать новую конфигурацию.
Выбор конфигурации для запуска проекта
Запуск тестового примера dotnet-iot-samples/dotnet-iot-fastiot-test:
Удаленная отладка консольного приложения .NET (YouTube):
В связи с тем, что в настройках launch.json и tasks.json прописываются абсолютные пути для задач и запуска проекта, требуется выполнить команду Rebuild в случаях изменения местоположения папки с утилитами cwRsync и самого проекта (изменение пути, включая переименование).
Перестройка конфигурации удаленной отладки
В файле launch.json создается корневая конфигурация, затем создаются задачи в файле tasks.json:
- Компиляция .NET проекта под архитектуру устройства;
- Создание папки в домашней директории на устройстве для копирования бинарных файлов;
- Копирование бинарных файлов, используя утилиту rsync.
Пример файла launch.json с конфигурацией для удаленной отладки
Пример файла tasks.json с конфигурацией для удаленной отладки
Пример использование библиотеки Libgpiod
А как насчет удаленной отладки на VPS сервере?
Расширение работает и с x86 серверами на Ubuntu, Debian. Казалось бы, зачем необходима удаленная отладка на сервере. На сервере помимо CPU, RAM и NVMe, может быть установлен GPU, модуль FPGA, NPU. А вам необходима отладка с использованием вычислений на графическом ускорителе или нейросетевом процессоре. Вот тут и пригодится расширение вместе с VSCode. Для теста выберем сервер на Debian 11:
<a href=«habrastorage.org/webt/ih/gh/no/ihghnoibrko60w_dfokj_gyy6hk.png>
Выбор VPS с Debian 11
Подключимся к серверу, установим все необходимые пакеты, и запустим тестовый пример:
Запуск тестового примера dotnet-iot-samples/dotnet-iot-fastiot-test на x86 сервере Timeweb Cloud
Дальнейший план разработки
Помимо оптимизации кода и доработки заявленных функций, планируется следующее:
- Добавление метода аутентификации keyboard-interactive. В текущей реализации необходимо изменять настройки ssh-сервера и включать доступ по паролю. После добавления метода keyboard-interactive, лишний раз не придется изменять настройки ssh-сервера;
- Адаптация работы в Linux. Для работы в Linux окружении требуется переписать код связанный с формирование путей к файлам;
- Добавление отладки в Docker контейнерах. В случае отсутствия возможности запустить Docker на устройстве требуется нативно устанавливать все библиотеки. Но если устройство поддерживает запуск Docker-контейнеров, то проще загрузить уже готовый контейнер с необходимыми библиотеками, и в нем выполнять отладку приложения;
- Добавление отладки графических приложений на Avalonia и Uno Platform. Поддержка отладки в Docker-контейнерах позволит подготавливать различные конфигурации, в том числе и с поддержкой графических подсистем;
- Добавление формата описания DTS файлов. Из названия файла не всегда достаточно понятно, какие устройства конфигурирует файл DTS;
- Добавление менеджера Nuget-пакетов. Интеграция более удобного менеджера пакетов, например как в Visual Studio.
- По возможности вынесение параметров в настройки. Пакеты для Linux устанавливаются по пути /usr/share/*, что не всегда может быть удобно. Поэтому подобные параметры будут вынесены в настройки расширения.
Итог
Первоначальная идея только конфигурирования файлов .NET проекта превратилась в полноценный инструмент для работы с IoT проектами. На данный момент не все функции реализованы. Скорость выполнения кода и скриптов далека от желаемой, в связи с отсутствием оптимизации. Первоначальная задача разработки расширения заключалась в предоставление рабочего варианта, и получение обратной связи. Пишите в комментариях, что вам понравилось, что не понравилось, свои предложения по улучшению. В связи с реализованной частью создания профиля устройств, возможно, добавить поддержку проектов для Python. Инструкция от Microsoft для Python debugging in VS Code тоже не маленькая. Пишите в комментарии, что вы об этом думаете?
Благодарю всех, кто принимал участие и помогал в создании и улучшении постов. Подписывайтесь на блог Timeweb Cloud, заказывайте VPS сервера и изучайте Docker, в следующем году плотно займемся построением облачной инфраструктуры для IoT решений. К облаку подключим устройства .NET IoT Linux, микроконтроллеры с nanoFramework и обычные бытовые сетевые фильтры/розетки/кофеварки и т. д. В блог добавятся темы связанные с разработкой для RISC-V процессоров, научимся собирать свой дистрибутив и создавать на IoT решения. Благодарю за уделенное время, всех поздравляю с Новым Годом, впереди нас ждет только лучшее!
Ресурсы
- Расширение .NET FastIoT в Marketplace Visual Studio Code
- GitHub — devdotnetorg/vscode-extension-dotnet-fastiot
- Тестовый пример на C# для удаленной отладки GitHub — dotnet-iot-samples/dotnet-iot-fastiot-test
- Пример Blink на C# с использованием GPIO (библиотека Libgpiod) GitHub — dotnet-iot-samples/dotnet-iot-blink