exponenta event banner

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

Протокол связи XCP для моделирования внешнего режима Simulink ® является протоколом связи ведущий-ведомый. По умолчанию программное обеспечение поддерживает моделирование внешнего режима XCP:

  • На компьютере-разработчике для кода, который генерируется с помощью ERT (ert.tlc) и GRT (grt.tlc) системные целевые файлы.

  • Для некоторых пакетов поддержки.

Если системный целевой файл для пользовательского целевого оборудования получен из системных целевых файлов ERT или GRT, можно использовать поставляемые API для обеспечения целевого подключения XCP. Применяются ограничения внешнего режима XCP.

Программное обеспечение целевого соединения внешнего режима содержит:

  • Уровень абстракции внешнего режима

  • Уровень подчиненного протокола XCP

  • Уровень ведомого транспорта XCP

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

Слой абстракции внешнего режима

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

Родительская папка для файлов исходного кода:

matlabroot\toolbox\coder\xcp\src\target\ext_mode

API-интерфейсы уровня объявлены в include\ext_mode.h и реализовано в src\xcp_ext_mode.c.

Для связи с Simulink целевое приложение использует службы, предоставляемые уровнем абстракции внешнего режима. Эта блок-схема показывает необходимые целевые шаги приложения для установления связи с Simulink.

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

СтадияФункцияЦель

INITIALIZE

extmodeParseArgs

Извлеките аргументы командной строки внешнего режима.

modelName_initialize

Инициализация созданного кода модели Simulink.

extmodeInit

Инициализация целевого подключения внешнего режима.

HOST START REQUEST

extmodeWaitForHostRequest

Дождитесь запроса на запуск с компьютера разработки, который будет создан при нажатии кнопки Выполнить.

RUN

modelName_step

Выполните один шаг созданного кода модели Simulink.

extmodeEvent

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

extmodeBackgroundRun

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

HOST STOP REQUEST OR SIMULATION COMPLETE

extmodeStopRequested

Проверьте, получен ли запрос на остановку моделирования внешнего режима от модели на компьютере разработчика. Запрос создается при нажатии кнопки «Остановить».

extmodeSimulationComplete

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

modelName_terminate

Завершить созданный код модели Simulink.

extmodeReset

Сброс целевого подключения внешнего режима в исходное состояние.

В этом примере псевдокода показано, как можно реализовать различные этапы блок-схемы в целевом приложении. Во время RUN среда выполнения внешнего режима требует, по меньшей мере, двух потоков:

  • Периодический поток, ответственный за выполнение созданного кода модели.

  • Фоновый поток, который отвечает за запуск стека связи внешнего режима и передачу и прием пакетов.

Псевдокод имитирует многопоточность, выполняя 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;
}

Для просмотра кода, вызывающего функции, выполните пример моделирования во внешнем режиме с помощью функции XCP Communication with System target file, для которой установлено значение ert.tlc. Затем из папки создания кода откройте ert_main.c.

Уровень подчиненного протокола XCP

Уровень подчиненного протокола XCP интерпретирует команды и данные XCP в соответствии со стандартом ASAM (ASAM) Ассоциации стандартизации систем автоматизации и измерений (Association for Standardization of Automation and Measuring Systems, ASAM MCD-1 XCP).

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

matlabroot\toolbox\coder\xcp\src\target\slave\protocol\src
При моделировании во внешнем режиме процесс построения автоматически добавляет требуемые файлы в информационный объект построения.

Уровень ведомого транспортного сервера XCP

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

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

matlabroot\toolbox\coder\xcp\src\target\slave\transport\src
При моделировании во внешнем режиме процесс построения автоматически добавляет требуемые файлы в информационный объект построения.

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

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

Пример адаптации см. в разделе Создание пользовательского слоя абстракции.

Драйвер XCP

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

Драйвер XCP основан на rtiostream API. Например, при моделировании внешнего режима на основе хоста используются следующие параметры: rtiostream файлы:

  • matlabroot\toolbox\coder\rtiostream\src\rtiostreamtcpip.c

  • matlabroot\toolbox\coder\rtiostream\src\rtiostream_serial.c

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

Для пользовательского уровня абстракции платформы необходимо добавить rtiostream файлы в информационный объект построения. Пример см. в разделе Создание пользовательского слоя абстракции.

Распределитель памяти

Подчиненное программное обеспечение XCP требует динамического выделения блоков памяти переменного размера для хранения внутренних структур данных.

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

xcpMemBlockSizes и xcpMemBlockCounts макросы препроцессора определяют распределение памяти.

Распределитель памяти по умолчанию может выделять и освобождать до 16 различных наборов блоков памяти. Для каждого набора можно переопределить назначения по умолчанию во время компиляции. Можно указать:

  • Размер блока через XCP_MEM_BLOCK_N_SIZE макрос препроцессора.

  • Количество блоков в каждом наборе через 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_SIZE < 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, в процессе сборки используются файлы по умолчанию, поддерживающие системы 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_PRINTF макрос препроцессора, реализация по умолчанию пуста.

Преобразование адреса

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

Мастер XCP извлекает адреса сигналов и параметры модели путем анализа отладочной информации, создаваемой процессом построения. Отладочная информация имеет формат DWF или 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 макросы препроцессора, реализация по умолчанию определяет стандартные функции Си, memcpy и memset.

#ifndef XCP_MEMCPY
#define XCP_MEMCPY memcpy
#endif

#ifndef XCP_MEMSET
#define XCP_MEMSET memset
#endif

Анализ аргументов командной строки

Если оконечное оборудование не поддерживает синтаксический анализ аргументов командной строки, определите макрос препроцессора EXTMODE_DISABLE_ARGS_PROCESSING.

Для замены -w , можно использовать эту команду, чтобы указать, что целевое приложение входит и остается в состоянии ожидания, пока не получит сообщение Connect от 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

См. также

| | | | | | | | |

Связанные темы

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