Реализация канала связи для моделирования процессора в контуре (PIL).
Канал связи обеспечивает обмен данными между различными процессами. Канал связи поддерживает возможности, требующие обмена данными между программной средой Simulink ®, работающей на компьютере разработки (хосте), и развернутым кодом, работающим на целевом оборудовании. Например, моделирование PIL.
Вы узнаете об интерфейсе rtiostream и о том, как он обеспечивает общий канал связи, который можно реализовать в виде целевых драйверов подключения для различных типов соединений. В этом примере описывается использование реализации TCP/IP по умолчанию.
Два объекта, станция A и станция B, используют интерфейс rtiostream для настройки канала связи и обмена данными. В этом примере станция A и станция B настраиваются в одном и том же процессе на настольном компьютере.
Целевые драйверы подключения поддерживают моделирование PIL на цели. При моделировании станция A и станция B представляют целевой и хост-компьютеры, которые обмениваются данными через канал связи. На стороне хоста целевой драйвер подключения реализован как общая библиотека, которая загружается и вызывается из продукта MATLAB ®. На стороне назначения драйвер представляет собой исходный код или библиотеку, связанную с приложением, которое выполняется на цели.
Кроме того, можно:
Настройте собственный драйвер на стороне назначения для TCP/IP для работы с драйвером TCP/IP на стороне хоста по умолчанию.
Настройте предоставленный драйвер на стороне хоста для последовательной связи.
Реализуйте пользовательские драйверы целевого подключения, например, используя CAN или USB для главной и целевой сторон канала связи.
См. также раздел Тестирование сгенерированного кода с моделированием SIL и PIL и конфигурирование процессора в цикле (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
Откройте rtiostream Station A в качестве сервера TCP/IP.
stationA = rtiostream_wrapper(libTcpip,'open',... '-client', '0',... '-blocking', '0',... '-port',port);
Если канал связи открывается, то возвращаемое значение является дескриптором соединения. Возвращаемое значение -1 указывает на ошибку.
Проверьте возвращаемое значение.
assert(stationA~=(-1))
Откройте rtiostream Station B в качестве клиента 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)
Прием данных на станции A.
[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.
Закрыть ртиострим на станции B.
retVal = rtiostream_wrapper(libTcpip,'close',stationB);Возвращаемое значение, равное нулю, указывает на успех.
assert(retVal==0);
Закрыть ртиострим на станции А.
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_wrapper MEX для тестирования драйверов rtiostream.
Целевые драйверы подключения можно реализовать с помощью различных каналов связи. Например, можно реализовать связь между хостом и целью через специальное последовательное соединение, которое требует предоставления драйверов для хоста и цели.
На стороне хоста можно протестировать драйверы с помощью файла rtiostream_wrapper MEX. Если драйвер включает диагностические выходные данные операторов printf и rtiostream_wrapper загружает общую библиотеку, необходимо заменить операторы printf операторами mexPrintf.
При наличии работающего драйвера устройства на стороне хоста его необходимо сделать доступным в программной среде Simulink. Для моделирования PIL зарегистрируйте общую библиотеку на стороне хоста через sl_customization.