Настройте ведомое программное обеспечение XCP

Протокол связи 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

Уровень абстракции режима external mode

Чтобы связаться с 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.

Это представляет в виде таблицы, перечисляет функции, которые ваше целевое приложение должно вызвать на каждом этапе.

ЭтапФункцияЦель

INITIALIZE

extmodeParseArgs

Извлеките параметры командной строки режима external mode.

modelName_initialize

Инициализируйте сгенерировал типовой кодекс Simulink.

extmodeInit

Инициализируйте целевую возможность соединения режима external mode.

HOST START REQUEST

extmodeWaitForHostRequest

Ожидайте запроса запуска от компьютера разработчика, который создается, когда вы щелкаете по кнопке Run.

RUN

modelNameшаг

Запустите один шаг сгенерированного типового кодекса Simulink.

extmodeEvent

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

extmodeBackgroundRun

Передайте и получите пакет от физического коммуникационного интерфейса и пакетного содержимого процесса в соответствии с выбранным протоколом связи.

HOST STOP REQUEST OR SIMULATION COMPLETE

extmodeStopRequested

Проверяйте, получена ли просьба остановить симуляцию режима external mode от модели на компьютере разработчика. Запрос создается, когда вы нажимаете кнопку Stop.

extmodeSimulationComplete

Проверяйте, завершено ли выполнение сгенерированного типового кодекса.
RESET

modelName_terminate

Оконечный сгенерированный типовой кодекс Simulink.

extmodeReset

Сбросьте целевую возможность соединения режима 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 интерпретирует команды XCP и данные по данным Ассоциации для Стандартизации Автоматизации и Измеряющихся Систем (ASAM) стандарт, ASAM MCD-1 XCP.

Папка исходного кода:

matlabroot\toolbox\coder\xcp\src\target\slave\protocol\src
В симуляции режима external mode процесс сборки автоматически добавляет необходимые файлы в информационный объект сборки (Simulink Coder).

Ведомый транспортный уровень XCP

Ведомый транспортный уровень XCP передает и получает сообщения от коммуникационного носителя согласно техническим требованиям ASAM.

Исходная папка:

matlabroot\toolbox\coder\xcp\src\target\slave\transport\src
В симуляции режима external mode процесс сборки автоматически добавляет необходимые файлы в информационный объект сборки (Simulink Coder).

Уровень абстракции платформы XCP

Уровень абстракции платформы 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 файлы к информационному объекту сборки (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_PRINTF макрос препроцессора, реализация по умолчанию пуста.

Обратитесь к преобразованию

Стандарт XCP выражает адрес переменной в памяти как 32-битный адрес с 8-битным расширением.

Ведущее устройство XCP извлекает адреса сигналов и параметры модели путем парсинга отладочной информации, которую создает процесс сборки. Отладочная информация находится в DWARF или формате PDB.

Ведущее устройство XCP запрашивает доступ к параметрам и сигналам путем отправки команды XCP, которая содержит аргументы addressExtension и address.

Когда addressExtension и address информация получена целевым компьютером, Ведомое устройство XCP должно преобразовать адрес в местоположение переменной в памяти целевого компьютера. Переменное местоположение присвоено загрузчиком и целевое.

Используйте XCP_ADDRESS_GET() макрос, чтобы задать логику преобразования. Реализация по умолчанию для Linux и систем Windows:

#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
В настоящее время только 32-битные аппаратные архитектуры поддерживаются, таким образом, addressExtension 0.

Установите и скопируйте память

Можно задать оптимизированную версию памяти копии и работы памяти аппарата.

Если вы не задаете XCP_MEMCPY и XCP_MEMSET макросы препроцессора, реализация по умолчанию задает стандарт C функции, memcpy и memset.

#ifndef XCP_MEMCPY
#define XCP_MEMCPY memcpy
#endif

#ifndef XCP_MEMSET
#define XCP_MEMSET memset
#endif

Парсинг параметров командной строки

Если ваш целевой компьютер не поддерживает парсинг параметров командной строки, задайте макрос препроцессора EXTMODE_DISABLE_ARGS_PROCESSING.

Заменять -w опция, можно использовать эту команду, чтобы указать, что целевое приложение входит и остается в состоянии ожидания, пока это не получает сообщение Подключения от Simulink:

set_param(modelName, 'OnTargetWaitForStart', 'on');
Процесс сборки предоставляет необходимую возможность (-DON_TARGET_WAIT_FOR_START=1) к компилятору.

Создайте пользовательский уровень абстракции

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

  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
    

  2. Задайте команду генерации почтового индекса.

    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

Смотрите также

| | | | | | | | |

Похожие темы

Внешние веб-сайты