Реализуйте канал связи для симуляции процессора в цикле (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) для пользовательского целевого устройства.
Файловая 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))
Целевые драйверы подключения отправляют поток данных в 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.
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, выполните следующие действия:
Напишите оболочку для стека TCP/IP, которая делает его доступным через интерфейс rtiostream, определенный в rtiostream.h.
Напишите тестовое приложение для вашего целевого устройства, которое отправляет и получает некоторые данные.
Используйте rtiostream_wrapper файл MEX и драйвер TCP/IP на стороне хоста, чтобы протестировать программное обеспечение драйвера, работающее на целевом компьютере.
Когда у вас будет рабочий целевой драйвер, включите исходные файлы драйвера в сборку для вашего автоматически сгенерированного кода.
Можно настроить драйвер на целевой стороне для работы только с сервером TCP/IP, поскольку драйвер PIL по умолчанию настроен как клиент TCP/IP.
Если необходимо использовать коммуникационный канал, который еще не поддерживается на стороне хоста, запишите драйверы для хоста и целевого устройства. В этом случае для проверки драйверов rtiostream все еще можно использовать rtiostream_wrapper файл MEX.
Можно реализовать целевые драйверы подключения с помощью различных каналов связи. Для примера можно реализовать коммуникации хост-цель через специальное последовательное соединение, которое требует, чтобы вы предоставляли драйверы для хоста и цели.
На стороне хоста можно протестировать драйверы с помощью rtiostream_wrapper файла MEX. Если драйвер включает выход диагностики из выражений printf и rtiostream_wrapper загружает общую библиотеку, необходимо заменить операторы printf на операторы mexPrintf.
Когда у вас есть работающий драйвер устройства на стороне хоста, вы должны сделать его доступным в программном окружении Simulink. Для PIL симуляции зарегистрируйте общую библиотеку на стороне хоста через sl_customization.