Протокол связи XCP для Simulink® симуляции режима external mode являются протоколом связи ведущий-ведомый. По умолчанию программное обеспечение поддерживает симуляции режима external mode XCP:
На вашем компьютере разработчика для кода, который генерируется при помощи ERT (ert.tlc
) и GRT (grt.tlc
) системные целевые файлы.
Если целевой системный файл для пользовательского целевого компьютера получен из целевых файлов ERT или GRT, можно использовать поставляемые API для обеспечения возможности подключения к целевому XCP. Применяются ограничения режима external mode XCP.
Целевое программное обеспечение подключения к режиму external mode содержит:
Слой абстракции режима external mode
Ведомый протокол XCP слоя
Ведомый транспортный слой XCP
Слой абстракции XCP-платформы
Чтобы связаться с Simulink во время симуляции режима external mode, ваше целевое приложение должно вызвать функции из слоя абстракции режима external mode.
Родительская папка для файлов исходного кода:
matlabroot\toolbox\coder\xcp\src\target\ext_mode
API слоя объявлены в include\ext_mode.h
и реализованы в src\xcp_ext_mode.c
.
Чтобы связаться с Simulink, целевое приложение использует службы, открытые слоем абстракции режима external mode. Этот график потока показывает необходимые шаги целевого приложения для установления связи с Simulink.
В этих таблицах перечислены функции, которые должно вызывать целевое приложение на каждом этапе.
Стадия | Функция | Цель |
---|---|---|
| Извлечение аргументов командной строки режима external mode. | |
| Инициализируйте сгенерированный код модели Simulink. | |
Инициализируйте целевое соединение режима external mode. | ||
| Дождитесь запроса запуска от компьютера разработчика, который создается при нажатии кнопки Run. | |
|
| Запустите один шаг сгенерированного кода модели Simulink. |
Для шага расчета ID модели, выборочные сигналы, сгенерированные функцией шага модели, и передают содержимое пакета на транспортный слой протокола связи для передачи на компьютер разработчика. | ||
Передача и прием пакета от физического интерфейса связи и обработка содержимого пакета в соответствии с выбранным протоколом связи. | ||
HOST STOP REQUEST OR SIMULATION COMPLETE | Проверьте, получен ли запрос на остановку симуляции режима external mode от модели на компьютере разработчика. Запрос создается при нажатии кнопки Stop. | |
Проверьте, завершено ли выполнение сгенерированного кода модели. | ||
RESET |
| Завершает сгенерированный код модели Simulink. |
Отключите соединение целевого устройства режима external mode в начальное состояние. |
Этот пример псевдокода показывает, как можно реализовать различные этапы блок-схемы в целевом приложении. Во время RUN
этап, окружение выполнения режима external mode требует, по меньшей мере, двух потоков:
Периодический поток, который отвечает за выполнение сгенерированного кода модели.
Фоновый поток, который отвечает за выполнение стека связи во режиме external mode и передачу и прием пакетов.
Псевдокод моделирует многопоточность при запуске periodicThread
и extmodeBackgroundRun
последовательно в пределах одного и того же while()
цикл.
/*------------- Pseudo-Code Example -------------*/ /* Define periodic thread */ void periodicThread(void) { /* Run model step function */ modelName_step(); /* Notify external mode abstraction layer about periodic event */ extmodeEvent(PERIODIC_EVENT_ID, currentSimulationTime); } /* Main function for target application */ main(int argc, char *argv[]) { /*------------- INITIALIZE -------------*/ /* Parse external mode command line arguments */ extmodeParseArgs(argc, argv); /* Initialize model */ modelName_initialize(); /* Initialize external mode target connectivity */ extmodeInit(extModeInfo, finalSimulationTime); /*------------- HOST START REQUEST -------------*/ /* Wait until a start request is received from development computer */ extmodeWaitForHostRequest(EXTMODE_WAIT_FOREVER); /*------- HOST STOP REQUEST OR SIMULATION COMPLETE -------*/ /* While simulation is not complete and stop request is not received */ while (!extmodeSimulationComplete() && !extmodeStopRequested()) { /*------------- RUN -------------*/ periodicThread(); extmodeBackgroundRun(); } /*------------- RESET -------------*/ /* Terminate model */ modelName_terminate(); /* Reset external mode target connectivity */ extmodeReset(); return 0; }
Чтобы увидеть код, который вызывает функции, завершите пример в Симуляции Режима external mode, Используя XCP Communication с System target file установленным на ert.tlc
. Затем из папки генерации кода откройте ert_main.c
.
Ведомый протокол XCP слоя интерпретирует команды и данные XCP согласно стандарту ASAM MCD-1 XCP Ассоциации систем автоматизации и измерения (ASAM).
Папка исходного кода:
matlabroot\toolbox\coder\xcp\src\target\slave\protocol\src
Ведомый транспортный слой XCP передает и принимает сообщения от носителя связи в соответствии со спецификациями ASAM.
Исходная папка:
matlabroot\toolbox\coder\xcp\src\target\slave\transport\src
Слой абстракции XCP-платформы обеспечивает:
Драйвер XCP для отправки и приема необработанных данных через интерфейс физической связи.
Реализация статического выделителя памяти.
Другие функциональные возможности целевого оборудования.
Пример индивидуальной настройки см. в разделе «Создание пользовательского слоя абстракции».
Драйвер XCP отправляет и получает сообщения XCP через канал связи. В симуляции режима external mode процесс сборки автоматически добавляет файлы драйвера к объекту информации о сборке.
Драйвер XCP основан на rtiostream
API. Для примера симуляции режима external mode на основе хоста используют эти rtiostream
файлы:
matlabroot
\ toolbox\coder\rtiostream\src\rtiostreamtcpip.c
matlabroot
\ toolbox\coder\rtiostream\src\rtiostream _ serial.c
Для получения дополнительной информации о реализации и проверке rtiostream
канал связи, см.:
Для пользовательского слоя абстракции платформы необходимо добавить rtiostream
файлы к информационному объекту сборки. Для получения примера см. раздел «Создание пользовательского слоя абстракции».
Ведомое программное обеспечение XCP требует динамического распределения смежных блоков памяти переменного размера для хранения внутренних структур данных.
В симуляции режима external mode процесс сборки автоматически добавляет файлы выделителя памяти к объекту информации о сборке.
The xcpMemBlockSizes
и xcpMemBlockCounts
макросы препроцессора определяют выделение памяти.
Выделитель памяти по умолчанию может выделять и освобождать до 16 различных наборов блоков памяти. Для каждого набора можно переопределить назначения по умолчанию во время компиляции. Можно задать:
Размер блока через
макрос препроцессора.XCP_MEM_BLOCK_<reservedrangesplaceholder0 >
_SIZE
Количество блоков в каждом наборе через
макрос препроцессора.XCP_MEM_BLOCK_<reservedrangesplaceholder0 >
_NUMBER
Для примера эти макросы препроцессора создают четыре блока по 64 байта и восемь блоков по 256 байтов.
#define XCP_MEM_BLOCK_1_SIZE 64 #define XCP_MEM_BLOCK_1_NUMBER 4 #define XCP_MEM_BLOCK_2_SIZE 256 #define XCP_MEM_BLOCK_2_NUMBER 8
Сконфигурируйте размеры блоков различных наборов в порядке возрастания:
< XCP_MEM_BLOCK_<reservedrangesplaceholder0 >
_SIZEXCP_MEM_BLOCK_<reservedrangesplaceholder0 >
+ 1 _ SIZE
Наименьший размер блока, XCP_MEM_BLOCK_1_SIZE
, должно быть достаточно большим, чтобы удерживать указатель.
Сконфигурируйте выравнивание для выделителя памяти через XCP_MEM_ALIGNMENT
макрос препроцессора. Для примера:
#define XCP_MEM_ALIGNMENT 8
Этот файл определяет интерфейс слоя абстракции платформы:
matlabroot\toolbox\coder\xcp\src\target\slave\platform\include\xcp_platform.h
XCP_CUSTOM_PLATFORM
макрос препроцессора к информационному объекту сборки. Обеспечивает реализацию пользовательских функций в файле с именем xcp_platform_custom.h
. Если вы не задаете XCP_CUSTOM_PLATFORM
, процесс сборки использует файлы по умолчанию, которые поддержка Linux® и Windows® систем.В этой таблице описываются функциональные возможности, которые необходимо обеспечить для ведомого программного обеспечения XCP, развертываемого на целевом компьютере.
Функциональность | Подробнее |
---|---|
Взаимное исключение | Для доступа к системным структурам данных с поддержкой взаимного исключения драйвер XCP зависит от основных API для определения, инициализации, блокировки и разблокировки. Чтобы поддержать взаимное исключение для целевого компьютера, предоставьте пользовательскую реализацию. Реализация по умолчанию для Linux и Windows поддерживает взаимное исключение. #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) ... #define XCP_MUTEX_DEFINE(lock) HANDLE lock #define XCP_MUTEX_INIT(lock) lock = CreateMutex(0, FALSE, 0) #define XCP_MUTEX_LOCK(lock) WaitForSingleObject((lock), INFINITE) #define XCP_MUTEX_UNLOCK(lock) ReleaseMutex(lock) #else ... #include <pthread.h> #define XCP_MUTEX_DEFINE(lock) pthread_mutex_t lock #define XCP_MUTEX_INIT(lock) pthread_mutex_init(&(lock), NULL) #define XCP_MUTEX_LOCK(lock) pthread_mutex_lock(&(lock)) #define XCP_MUTEX_UNLOCK(lock) pthread_mutex_unlock(&(lock)) ... #endif |
Сон | Обеспечьте API-интерфейс ожидания, который делает вызывающий поток неактивным до истечения заданного времени. Реализацией по умолчанию для систем Linux и Windows является: #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) ... #define XCP_SLEEP(seconds,microseconds) Sleep((seconds) * 1000 \ + (((microseconds) + 1000 - 1) / 1000)) #else ... #if _POSIX_C_SOURCE >= 199309L #define XCP_SLEEP(seconds,microseconds) do {struct timespec t;\ t.tv_sec = seconds; t.tv_nsec = microseconds * 1000; nanosleep(&t, NULL);} while(0) #else /* nanosleep is not available. Use select instead. */ #define XCP_SLEEP(seconds,microseconds) do {struct timeval t; t.tv_sec = seconds;\ t.tv_usec = microseconds; select(0, NULL, NULL, NULL, &t);} while(0) #endif /* _POSIX_C_SOURCE >= 199309L */ ... #endif |
Логгирование | Для генерации диагностических сообщений ведомому программному обеспечению XCP требуется пользовательский API печати, который поддерживает логгирование услуги, предоставляемые целевому компьютеру. Если вы не задаете |
Преобразование адреса | Стандарт XCP выражает адрес переменной в памяти как 32-битный адрес с 8-битным расширением. Мастер XCP извлекает адреса сигналов и параметров модели, анализируя информацию отладки, которую создает процесс сборки. Отладочная информация находится в формате DWARF или PDB. Мастер XCP запрашивает доступ к параметрам и сигналам путем отправки команды XCP, которая содержит аргументы Когда Используйте #if defined(__MINGW32__) || defined(__MINGW64__) #define XCP_ADDRESS_GET(addressExtension, address) \ (uint8_T*) ((uintptr_t) address) #else #define XCP_ADDRESS_GET(addressExtension, address) \ (uint8_T*) ((address) + (uint8_T*)&__ImageBase) #endif addressExtension равен 0. |
Установите и скопируйте память | Можно задать оптимизированную версию памяти копирования и задать операции памяти. Если вы не задаете #ifndef XCP_MEMCPY #define XCP_MEMCPY memcpy #endif #ifndef XCP_MEMSET #define XCP_MEMSET memset #endif |
Синтаксический анализ аргументов в командной строке | Если ваш целевой компьютер не поддерживает синтаксический анализ аргументов в командной строке, задайте макрос препроцессора Чтобы заменить set_param(modelName, 'OnTargetWaitForStart', 'on'); -DON_TARGET_WAIT_FOR_START=1 ) компилятору. |
Для процесса сборки можно задать команду генерации посткода, которая создает пользовательский слой абстракции платформы.
Укажите заголовочный файл xcp_platform_custom.h
. Этот пример Linux определяет необходимые функции.
#ifndef XCP_PLATFORM_CUSTOM_H #define XCP_PLATFORM_CUSTOM_H /* XCP_ADDRESS_GET */ #include <stdint.h> #define XCP_ADDRESS_GET(addressExtension, address) (uint8_T*) ((uintptr_t) address) /* XCP_MUTEX */ #include <pthread.h> #define XCP_MUTEX_DEFINE(lock) pthread_mutex_t lock #define XCP_MUTEX_INIT(lock) pthread_mutex_init(&(lock), NULL) #define XCP_MUTEX_LOCK(lock) pthread_mutex_lock(&(lock)) #define XCP_MUTEX_UNLOCK(lock) pthread_mutex_unlock(&(lock)) /* XCP_SLEEP */ #include <sys/time.h> /* gettimeofday */ #if _POSIX_C_SOURCE >= 199309L #include <time.h> /* for nanosleep */ #else #include <stddef.h> #include <sys/select.h> /* for select */ #endif /* _POSIX_C_SOURCE >= 199309L */ #if _POSIX_C_SOURCE >= 199309L #define XCP_SLEEP(seconds,microseconds) do {struct timespec t;\ t.tv_sec = seconds; t.tv_nsec = microseconds * 1000; nanosleep(&t, NULL);} while(0) #else /* nanosleep is not available. Use select instead. */ #define XCP_SLEEP(seconds,microseconds) do {struct timeval t; t.tv_sec = seconds;\ t.tv_usec = microseconds; select(0, NULL, NULL, NULL, &t);} while(0) #endif /* _POSIX_C_SOURCE >= 199309L */ #endif
Определите команду генерации пост-кода.
function myXCPTargetPostCodeGenCommand(buildInfo) buildInfo.addDefines('-DXCP_CUSTOM_PLATFORM', 'OPTS'); % Configure the default memory allocator buildInfo.addDefines('-DXCP_MEM_BLOCK_1_SIZE=64', 'OPTS'); buildInfo.addDefines('-DXCP_MEM_BLOCK_1_NUMBER=46', 'OPTS'); buildInfo.addDefines('-DXCP_MEM_BLOCK_2_SIZE=256', 'OPTS'); buildInfo.addDefines('-DXCP_MEM_BLOCK_2_NUMBER=10', 'OPTS'); % Add my rtiostream buildInfo.addSourceFiles(customRtIOStreamFileName, ... customRtIOStreamSrcPath); % If the target hardware does not support parsing of command % line arguments buildInfo.addDefines('-DEXTMODE_DISABLE_ARGS_PROCESSING', 'OPTS'); end
extmodeBackgroundRun
| extmodeEvent
| extmodeGetFinalSimulationTime
| extmodeInit
| extmodeParseArgs
| extmodeReset
| extmodeSetFinalSimulationTime
| extmodeSimulationComplete
| extmodeStopRequested
| extmodeWaitForHostRequest