Создайте целевой канал связи для симуляции процессора в цикле (PIL)

Реализуйте канал связи для симуляции процессора в цикле (PIL).

Канал связи позволяет обмениваться данными между различными процессами. Канал связи поддерживает возможности, которые требуют обмена данными между программным окружением Simulink ®, которая работает на вашем компьютере разработчика (хосте) и развернутым кодом, который запускается на целевом компьютере. Для примера, PIL симуляция.

Вы узнаете об интерфейсе rtiostream и о том, как он обеспечивает типовой канал связи, который можно реализовать в форме целевых драйверов связи для различных типов соединений. В этом примере описывается использование реализации TCP/IP по умолчанию.

Две сущности, станция A и станция B, используют интерфейс rtiostream для настройки канала связи и обмена данными. В данном примере терминал A и терминал B конфигурируются в рамках одного и того же процесса на вашем рабочем компьютере.

Целевые драйверы подключения поддерживают PIL симуляцию на целевом уровне. В симуляции станция A и станция B представляют цель и хосты-компьютеры, которые обмениваются данными через канал связи. На стороне хоста целевой драйвер подключения реализован как общая библиотека, которая загружается и вызывается из продукта MATLAB ®. На целевой стороне драйвером является исходный код или библиотека, которая связана с приложением, работающим в целевой системе.

Кроме того, вы можете:

  • Сконфигурируйте собственный драйвер на целевой стороне для работы TCP/IP с драйвером TCP/IP по умолчанию.

  • Сконфигурируйте поставляемый драйвер на стороне хоста для последовательной связи.

  • Реализуйте пользовательские целевые драйверы подключения, например, с помощью CAN или USB для хоста и целевой стороны канала связи.

Смотрите также Test Generated Code with SIL and PIL симуляции и Configure Processor-In-The-Loop (PIL) для пользовательского целевого устройства.

Просмотр исходного кода для реализации TCP/IP по умолчанию

Файловая rtiostream_tcpip.c реализует коммуникацию TCP/IP на стороне клиента и сервера. Параметр запуска конфигурирует драйвер для работы в клиентском или серверном режиме. Можно использовать этот исходный файл в качестве начальной точки для пользовательской реализации. Каждая сторона канала связи требует только одной или другой реализации сервера или клиента. Если драйверы клиента и сервера работают на различных архитектурах, рассмотрите размещение кода драйвера для каждой архитектуры в отдельном исходном файле.

Заголовочный файл rtiostream.h содержит прототипы для функций rtIOStreamOpen/Send/Recv/Close. Включите его (используя # include) для пользовательских реализаций.

Извлечение местоположения исходного кода драйвера TCP/IP.

rtiostreamtcpip_dir=fullfile(matlabroot,'toolbox','coder','rtiostream','src',...
                              'rtiostreamtcpip');

Просмотрите rtiostream_tcpip.c.

edit(fullfile(rtiostreamtcpip_dir,'rtiostream_tcpip.c'));

Просмотр rtiostream.h.

edit(fullfile(matlabroot,'rtw','c','src','rtiostream.h'));

Расположение общих библиотечных файлов

Чтобы получить доступ к целевым драйверам подключения из продукта MATLAB, необходимо скомпилировать их в общую библиотеку. Общая библиотека должна располагаться в системном пути. Общая библиотека для драйверов TCP/IP по умолчанию находится в matlabroot/bin/$ ARCH ($ ARCH - ваша системная архитектура, например, win64).

Расширение и расположение имени файла общей библиотеки зависят от операционной системы.

[~, ~, sharedLibExt] = coder.BuildConfig.getStdLibInfo;

Идентифицируйте общую библиотеку для пикетов A и B.

libTcpip = ['libmwrtiostreamtcpip' sharedLibExt];
disp(libTcpip)
libmwrtiostreamtcpip.dll

Тестируйте целевые драйверы подключения

Если вы реализуете пользовательский целевой драйвер подключения, рекомендуется протестировать его из продукта MATLAB. В следующем примере показано, как загрузить целевые драйверы соединения TCP/IP по умолчанию и использовать их для обмена данными между станцией A и станцией B.

Для доступа к драйверам можно использовать rtiostream_wrapper файла MEX. С помощью этого файла MEX можно загрузить общую библиотеку и получить доступ к функциям rtiostream, чтобы открыть и закрыть канал rtiostream, а также отправить и получить данные.

Станции A и B запуска на хост-компьютер. Станция A сконфигурирована как сервер TCP/IP, а станция B как клиент TCP/IP. Для подключения хоста к целевому узлу обычно конфигурируется хост как клиент TCP/IP, а конечный - как сервер TCP/IP.

Выберите номер порта для TCP.

if usejava('jvm')
    % Find a free port
    tempSocket = java.net.ServerSocket(0);
    port = num2str(tempSocket.getLocalPort);
    tempSocket.close;
else
    % Use a hard-coded port
    port = '14646';
end

Откройте Station A rtiostream как сервер TCP/IP.

stationA = rtiostream_wrapper(libTcpip,'open',...
                                 '-client', '0',...
                                 '-blocking', '0',...
                                 '-port',port);

Если канал связи открывается, значение возврата является указателем на соединение. Значение возврата -1 указывает на ошибку.

Проверьте значение возврата.

assert(stationA~=(-1))

Откройте Station B rtiostream как клиент TCP/IP.

stationB = rtiostream_wrapper(libTcpip,'open',...
                                 '-client','1',...
                                 '-blocking', '0',...
                                 '-port',port,...
                                 '-hostname','localhost');

Если канал связи открывается, значение возврата является указателем на соединение. Значение возврата -1 указывает на ошибку.

Проверьте значение возврата.

assert(stationB~=(-1))

Отправка данных со станции B на станцию A

Целевые драйверы подключения отправляют поток данных в 8-битных байтах. Для процессоров, которые не являются адресуемыми по байтам, данные отправляются с наименьшим размером адресуемого слова.

Отправка данных сообщений от станции B на станцию A.

msgOut = uint8('Station A, this is Station B. Are you there? OVER');

[retVal, sizeSent] = rtiostream_wrapper(libTcpip,...
                                       'send',...
                                       stationB,...
                                       msgOut,...
                                       length(msgOut));

Возврат значение нуля указывает на успех.

assert(retVal==0);

Убедитесь, что байты в сообщении были отправлены.

assert(sizeSent==length(msgOut));

Оставьте время для завершения передачи данных.

pause(0.2)

Прием данных на станции А.

[retVal, msgRecvd, sizeRecvd] = rtiostream_wrapper(libTcpip,...
                                                 'recv',...
                                                 stationA,...
                                                 100);

Возврат значение нуля указывает на успех.

assert(retVal==0);

Убедитесь, что получены байты в сообщении.

assert(sizeRecvd==sizeSent);

Отображение полученных данных.

disp(char(msgRecvd))
Station A, this is Station B. Are you there? OVER                                                   

Отправка ответа от станции A на станцию B

Отправка ответных данных от станции A на станцию B.

msgOut = uint8('Station B, this is Station A. Yes, I''m here! OVER.');
[~, sizeSent] = rtiostream_wrapper(libTcpip,... %#ok
                                       'send',...
                                       stationA,...
                                       msgOut,...
                                       length(msgOut));

Оставьте время для завершения передачи данных.

pause(0.2)

Прием данных в терминале B.

[~, msgRecvd, sizeRecvd] = rtiostream_wrapper(libTcpip,... %#ok
                                                 'recv',...
                                                 stationB,...
                                                 100);

Отображение полученных данных.

disp(char(msgRecvd))
Station B, this is Station A. Yes, I'm here! OVER.                                                  

Закройте соединение и выгрузите общие библиотеки

Закройте rtiostream на станции B.

retVal = rtiostream_wrapper(libTcpip,'close',stationB);

Возврат значение нуля указывает на успех.

assert(retVal==0);

Закройте rtiostream на станции А.

retVal = rtiostream_wrapper(libTcpip,'close',stationA);

Возврат значение нуля указывает на успех.

assert(retVal==0)

Выгрузите общую библиотеку.

rtiostream_wrapper(libTcpip, 'unloadlibrary');

Драйвер на стороне хоста для последовательной связи

В качестве альтернативы драйверам TCP/IP можно использовать драйвер, поставляемый на стороне хоста для последовательной связи. Конфигурирование последовательного драйвера смотрите в разделе rtiostream_wrapper в справочной документации по Embedded Coder ®.

Сконфигурируйте свой собственный целевой драйвер

Если у вашего целевого компьютера есть подключение Ethernet, и у вас есть доступный стек TCP/IP, выполните следующие действия:

  1. Напишите оболочку для стека TCP/IP, которая делает его доступным через интерфейс rtiostream, определенный в rtiostream.h.

  2. Напишите тестовое приложение для вашего целевого устройства, которое отправляет и получает некоторые данные.

  3. Используйте rtiostream_wrapper файл MEX и драйвер TCP/IP на стороне хоста, чтобы протестировать программное обеспечение драйвера, работающее на целевом компьютере.

  4. Когда у вас будет рабочий целевой драйвер, включите исходные файлы драйвера в сборку для вашего автоматически сгенерированного кода.

Можно настроить драйвер на целевой стороне для работы только с сервером TCP/IP, поскольку драйвер PIL по умолчанию настроен как клиент TCP/IP.

Если необходимо использовать коммуникационный канал, который еще не поддерживается на стороне хоста, запишите драйверы для хоста и целевого устройства. В этом случае для проверки драйверов rtiostream все еще можно использовать rtiostream_wrapper файл MEX.

Сконфигурируйте собственный драйвер на стороне хоста

Можно реализовать целевые драйверы подключения с помощью различных каналов связи. Для примера можно реализовать коммуникации хост-цель через специальное последовательное соединение, которое требует, чтобы вы предоставляли драйверы для хоста и цели.

На стороне хоста можно протестировать драйверы с помощью rtiostream_wrapper файла MEX. Если драйвер включает выход диагностики из выражений printf и rtiostream_wrapper загружает общую библиотеку, необходимо заменить операторы printf на операторы mexPrintf.

Когда у вас есть работающий драйвер устройства на стороне хоста, вы должны сделать его доступным в программном окружении Simulink. Для PIL симуляции зарегистрируйте общую библиотеку на стороне хоста через sl_customization.

Похожие темы