October 21, 2019

Linux + TwinCAT 3 + .Net Core 3 + ADS 5

Система реального времени по прежнему работает под Windows, но реализовать клиентскую сторону, визуализацию или массивную обработку данных (дата саенс, ага) под Linux уже можно.

Не то чтобы раньше нельзя было. Например, родные Бекхоффские реализации протокола ADS на C++, с неродным интерфейсом на QT. Python+Ads для обработки данных, например в блокнотах Jupiter и AdsClient (.NET Standart) для C# под гуем из WPF. Протокол открытый, почему бы и нет?

Теперь же Бекхофф выкатил в публичное превью библиотеки для работы с ADS под .NET Core 3. В первую очередь это означает кросс-платформенность для приложений на C# под Linux, Windows, Mac. О последнем я говорить не хочу, а для первых двух вырисовывается полный стек интересных технологий (или интересный стек полных технологий):
  • .NET Core 3.0
  • AvaloniaUI
  • Beckhoff.TwinCAT.Ads 5

Я еще раз подчеркну, сразу для двух операционных систем: Windows - Linux. Одно и то же приложение. Возможно необходимо пересобрать, тыкнув мышой в выбор операционки, но переписывать код уже не нужно. Выглядеть интерфейс будет одинаково на обеих операционках. Это благодаря Avalonia, которая почти как WPF.


TwinCAT.Ads 5.0.0-preview1


Итак, не далее как неделю назад, Бекхофф выложила превью библиотек. Нас ждут интриги, расследования и гонки на багги. "This is a prerelease version of Beckhoff.TwinCAT.Ads", — говорят нам RaHe, sveno, MichaelKn и Beckhoff со страниц NuGet. Далее идут инструкции как со всем этим жить, но это не точно. Потому что инструкции не работают. Как "нада жить" будет позже, а сейчас про состав выложенного:
  • TwinCAT.Ads 5.0.0-preview1
    Сборка для доступа к данным ПЛК через ADS. Совместима с предыдущими версиями библиотеки. Состав прежний: Client, Session, Read-Write Any Symbol, и тому подобное. Появились асинхронные операции. TcAdsClient переименован в AdsClient; AdsStream заменен на модные и современные Span+Memory.
  • Ads.AdsRouterConsole
    Под Linux нет рантайма и ADS-роутера соответственно. Поэтому Бекхофф предлагает нам нечто вроде выполняющее функции роутера. Запускается как консоль отдельно и самостоятельно, в том числе и под Linux.
  • Ads.TcpRouter
    А это уже не самостоятельная штука, зато можно засунуть себе в программу. Это как бы переносной роутер, который будет внутри вашей программы. Вокруг этой же штуки построена консоль AdsRouterConsole.
  • Ads.Reactive
    Тоже сборка для доступа к данным, но доступ "реактивным" способом.
  • AdsServerAbstractions
    Сервер и всё что сборки делят между собой. Про сервер как-нибудь в другой раз: где еще делать сервер как не под Linux?


Запускаем AdsRouterConsole


Сборка консоли роутера будет лежать в 
%USERPROFILE%\.nuget\packages\beckhoff.twincat.ads.adsrouterconsole\5.0.0-preview1\lib\netcoreapp3.0\TwinCAT.Ads.AdsRouterConsole.dll

...но(!) в инструкции, которая лежит в разделе Documentation NuGet, есть опечатка. На самом деле запускать нужно так:
dotnet TwinCAT.Ads.AdsRouterConsole.dll

...но(!) опять-таки  не запустится, так как этой сборке для запуска не хватает других сборок. Поэтому мы установим сборку TwinCAT.Ads.AdsRouterConsole в свой проект, и тогда .dll файл сборки будет лежать в папке /bin/Debug/netcoreapp3/, а в ней уже автоматом будут все необходимые для запуска консоли роутера сборки.

...но(!) при запуске мы получим следующую ошибку:
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in '...\bin\Debug\netcoreapp3\'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the ...\TwinCAT.Ads.AdsRouterConsole.runtimeconfig.json file specifying the appropriate framework.
Это связано с безопасностью в системе, поэтому возвращаемся к
%USERPROFILE%\.nuget\packages\beckhoff.twincat.ads.adsrouterconsole\5.0.0-preview1\lib\netcoreapp3.0
(да-да, именно для этого он нам и нужен был) и кладем файл TwinCAT.Ads.AdsRouterConsole.runtimeconfig.json рядом со сборкой консоли роутера, то есть в каталог /bin/Debug/netcoreapp3/ или /bin/Release/netcoreapp3/ проекта. Выбор конечного пути зависит от этапа разработки и конфигурации проекта.

Файл можно создать самостоятельно, вот его содержимое:

{
    "runtimeOptions": {
        "tfm": "netcoreapp3.0",
        "framework": {
            "name": "Microsoft.NETCore.App",
            "version": "3.0.0"
        }
    }
}

После этого, может запуститься, а может не запуститься и вылететь с ошибкой:
Error: An attempt was made to access a socket in a way forbidden by its access permissions.
...и это всё потому, что у вас уже запущен роутер. Приложение кросплатформенное, можно запускать как под Linux так и под Windows. Прибить работающий роутер можно остановив сервис TcSysSrv из командной строки PowerShell от имени Администратора или через Computer Management.


Таблица роутинга


На самом деле и сейчас не запустится: любому роутеру нужны настройки роутинга. Со стороны ПЛК придется настроить самостоятельно и вручную, а со стороны ПК сформировать XML файл StaticRoutes.xml, расположив его рядом со сборкой консоли роутера:

<?xml version="1.0" encoding="utf-8"?>
<TcConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\TwinCAT3\Config\TcConfig.xsd">
  <Local>
      <Name>RALFH03</Name>
      <NetId>172.17.60.215.1.1</NetId>
  </Local>
  <RemoteConnections>
    <Route>
      <Name>CX-1CD661</Name>
      <Address>169.254.116.30</Address>
      <NetId>5.28.214.97.1.1</NetId>
      <Type>TCP_IP</Type>
    </Route>
  </RemoteConnections>
</TcConfig>

Секция Local — это имя и локальный Ams NetId адрес ПК. Выбираются произвольно, но в роутерах с обеих сторон, в записях касающихся ПК, этот адрес должен совпадать с обеих сторон, то есть во всех роутерах сразу. RemoteConnections — это про удаленную сторону, то есть о ПЛК. Сравним с настройками роутера на ПЛК.

Зайдем на ПЛК через web-конфигуратор: http://169.254.112.234/Config. Далее: TwinCAT → Connectivity → Add TwinCAT Route. Внизу списка жмем кнопки [+] и создаем запись роутинг для удаленного ПК (или ноутбука разработчика), удаленного теперь уже относительно ПЛК:

Route Name: RALFH03
AMS Net ID: 172.17.60.215.1.1
Transport Type: TCP/IP
Address: 169.254.7.118
Connection Timeout (ms): 3000

Сравните "тут" и "там" и станет немного понятнее.


Virtual Box


Я тестировал под виртуальной машиной на x64 Ubuntu 19.04. Для Virtual Box необходимо... краткое объяснение на пальцах — обязательно выставить все три сетевые параметра сетевого коннекта Убунты: IP адрес, маску и обязательно gateway (гейтвей можно произвольный, я выставлял 192.168.0.1). Не забыть установить исполняемому файлу атрибут исполняемого фалйа: chmod +x имя-исп-файла. Установить в системе dotnet core 3 (читайте справку Майкрософта).

И наконец прибить роутер TwinCAT в операционной системе хосте (Windows), иначе будут заняты сетевые порты. Переключения в режим конфигурации (синий) недостаточно, нужен серый значок полного аута.


Багги


А дальше начинаются скачки по дюнам и прочим неровностям превью бета версии библиотек. На любых функциях типа client.ReadSymbol("MAIN.Counter") я получал ошибку:
Stack overflow.
Aborted (core dumped)
...и приложение падает. Интересно, что точно такую же ошибку я получал когда пытался использовать независимую сборку независимого разработчика AdsClient. Видимо, корень проблемы одинаковый.

В то же время можно создать хэндл client.CreateVarHandle("MAIN.Counter"), а затем нормально работать на функциях чтения-записи через хэндлы. Также нормально работает чтение по имени переменной через реактивную подписку, которая к тому же неплохо ложится на реактивность Avalonia:

var valueObserver = Observer.Create(val => {
    Dispatcher.UIThread.InvokeAsync(() => {
        var mwvm = (MainWindowViewModel)DataContext;
        mwvm.Counter = val.ToString();
    });
});

IDisposable subscription =
    session.Connection
        .WhenNotification("MAIN.Counter", NotificationSettings.Default)
        .Subscribe(valueObserver);


То есть как-то работать уже можно и что-то рабочее уже вырисовывается:



Среда разработки


Теперь попробуем поработать под Linux — посмотрим в сторону среды разработки.

Как таковой среды еще нет, зато есть кроссплатформенный редактор Visual Studio Code, а к нему расширение vscode-st за авторством Сергея Романова. Расширение помогает работать с кодом на ST. Проект открытый, исходный код есть на GitHub. Самое главное, что проект не заброшен и развивается: я добавил туда пару новых штук, и внезапно разработчик принял пул-реквест, и так же мгновенно пересобрал расширение.


Подсветка синтаксиса, подсказка по переменным и ФБ, снипеты и прочие плюшки. Еще раз: это не отладчик и не среда разработки, а редактор кода, но это уже что-то. Остается дождаться чего-нибудь подобного TcXaeMgmt, ведь PowerShell Core уже работает под Linux, а роутероподобное ПО мы только что потрогали палочкой. Да что там, TcXaeMgmt уже можно установить, но работать командлеты не будут: отсутствует TwinCAT Automation Interface который построен на COM объектах.

Поэтому — ждем. Редактор файлов уже есть, остается прослойка для работы с загрузкой-выгрузкой файлов-проектов и пуск-стопом рантаймов, а там и до дебага недалеко (на самом деле, далеко).

No comments

Post a Comment

Note: Only a member of this blog may post a comment.