Протокол связи XCP для симуляций режима external mode Simulink® является протоколом связи "главный-подчиненный". По умолчанию программное обеспечение поддерживает симуляции режима 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 с набором System target file к ert.tlc
. Затем от папки генерации кода откройте ert_main.c
.
Ведомый слой протокола XCP интерпретирует команды XCP и данные по данным Ассоциации для Стандартизации Автоматизации и Измеряющихся Систем (ASAM) стандарт, ASAM MCD-1 XCP.
Папка исходного кода:
matlabroot\toolbox\coder\xcp\src\target\slave\protocol\src
Ведомый транспортный уровень XCP передает и получает сообщения от коммуникационного носителя согласно техническим требованиям ASAM.
Исходная папка:
matlabroot\toolbox\coder\xcp\src\target\slave\transport\src
Уровень абстракции платформы XCP обеспечивает:
Драйвер XCP для отправки и получения необработанных данных через физический коммуникационный интерфейс.
Реализация средства выделения статического ЗУ.
Другая специфичная для целевого компьютера функциональность (Simulink Coder).
Для примера индивидуальной настройки смотрите, Создают Пользовательский Уровень абстракции.
Драйвер 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
файлы к информационному объекту сборки (Simulink Coder). Для примера смотрите, Создают Пользовательский Уровень абстракции.
Ведомое программное обеспечение XCP требует, чтобы динамическое выделение переменного размера, непрерывные блоки памяти содержало внутренние структуры данных.
В симуляции режима external mode процесс сборки автоматически добавляет файлы средства выделения памяти в информационный объект сборки.
xcpMemBlockSizes
и xcpMemBlockCounts
макросы препроцессора задают выделение памяти.
Средство выделения памяти по умолчанию может выделить и освободить до 16 различных наборов блоков памяти. Для каждого набора можно заменить выделения по умолчанию во время компиляции. Можно задать:
Размер блока через XCP_MEM_BLOCK_
макрос препроцессора.N
размер
Количество блоков в каждом наборе через XCP_MEM_BLOCK_
макрос препроцессора.N
_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_
<N
размерXCP_MEM_BLOCK_
N
+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
, процесс сборки использует файлы по умолчанию, которые поддерживают системы Windows® и Linux®.Эта таблица описывает функциональность, что необходимо предусмотреть ведомое программное обеспечение 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