主要内容

自定义XCP从软件

用于Simulink的XCP通信协议金宝app®外部模式模拟是一种主从通信协议。默认情况下,软件支持XCP外部模式模拟:金宝app

  • 在您的开发计算机上使用ERT生成的代码(ert.tlc)及GRT (grt.tlc)系统目标文件。

  • 一些支持包金宝app

如果用于自定义目标硬件的系统目标文件派生自ERT或GRT系统目标文件,则可以使用提供的api来提供XCP目标连接性。XCP外部模式限制适用。

外部模式目标连接软件包括:

  • 外部模式抽象层

  • XCP从协议层

  • XCP从传输层

  • XCP平台抽象层

外部模式抽象层

要在外部模式模拟期间与Simulink通金宝app信,目标应用程序必须从外部模式抽象层调用函数。

源代码文件的父文件夹是:

matlabroot\工具箱\编码器\ xcp \ src \ \ ext_mode目标

层api是在包括\ ext_mode.h并在src \ xcp_ext_mode.c

为了与Simulink通信,目标应用程序金宝app使用由外部模式抽象层公开的服务。此流程图显示了与Simulink建立通信所需的目标应用程序步骤。金宝app

该表列出了目标应用程序在每个阶段必须调用的函数。

阶段 函数 目的

初始化

extmodeParseArgs

提取外部模式命令行参数。

modelName_initialize

初始化生成的Simulink模型代码。金宝app

extmodeInit

初始化外部模式目标连接。

主机启动请求

extmodeWaitForHostRequest

等待开发计算机的启动请求,该请求是在单击Run按钮时创建的。

运行

modelName_step

运行生成的Simulink模型代码的单个步骤。金宝app

extmodeEvent

对于模型的采样时间ID,由模型阶跃函数生成的采样信号,将包内容传递给通信协议传输层,传输到开发计算机。

extmodeBackgroundRun

从物理通信接口发送和接收数据包,并根据选定的通信协议处理数据包内容。

主机停止请求或模拟完成

extmodeStopRequested

在开发计算机上检查是否从模型接收到停止外部模式模拟的请求。在单击Stop按钮时创建请求。

extmodeSimulationComplete

检查生成的模型代码执行是否完成。
重置

modelName_terminate

终止生成的Simulink模型代码。金宝app

extmodeReset

将外部模式目标连接重置为初始状态。

这个伪代码示例展示了如何在目标应用程序中实现各种流程图阶段。在运行阶段,外部模式运行时环境至少需要两个线程:

  • 负责执行生成的模型代码的周期性线程。

  • 一种后台线程,负责运行外部模式通信栈以及发送和接收数据包。

伪代码通过运行来模拟多线程periodicThread而且extmodeBackgroundRun顺序相同而()循环。

/*------------- 伪代码示例  -------------*/ /* 定义周期性线程* /空白periodicThread (void){/ *运行模型阶跃函数* /modelName_step ();/*通知外部模式抽象层周期事件*/ extmodeEvent(PERIODIC_EVENT_IDcurrentSimulationTime);} /*目标应用程序的主要函数*/ Main (int argc, char *argv[]) {/*------------- INITIALIZE -------------*/ /*解析外部模式命令行参数*/ extmodeParseArgs(argc, argv);初始化模型*/modelName_initialize ();/*初始化外部模式目标连接*/ extmodeInit(extModeInfofinalSimulationTime);/*-------------主机启动请求-------------*/ /*等待从开发计算机接收到启动请求*/ extmodeWaitForHostRequest(EXTMODE_WAIT_FOREVER);/*------- HOST STOP REQUEST OR SIMULATION COMPLETE -------*/ /*当模拟未完成且未收到停止请求时*/ While (!extmodeSimulationComplete() && !extmodeStopRequested()) {/*------------- RUN -------------*/ periodicThread();extmodeBackgroundRun ();} /*------------- 重置  -------------*/ /* 终止模式* /modelName_terminate ();/*重置外部模式目标连通性*/ extmodeReset();返回0;}

要查看调用函数的代码,请在利用XCP通信进行外部模式仿真系统目标文件设置为ert.tlc.然后,从代码生成文件夹中,打开ert_main.c

从协议层

XCP从协议层根据自动化与测量系统标准化协会(ASAM)标准ASAM MCD-1 XCP解释XCP命令和数据。

源代码文件夹为:

matlabroot\工具箱\编码器\ xcp \ src \ \ src \奴隶\协议目标
在外部模式模拟中,构建过程自动将所需文件添加到构建信息对象

从传输层

XCP从传输层根据ASAM规范发送和接收来自通信介质的消息。

源文件夹是:

matlabroot\工具箱\编码器\ xcp \ src \目标\ \运输\ src奴隶
在外部模式模拟中,构建过程自动将所需文件添加到构建信息对象

XCP平台抽象层

XCP平台抽象层提供:

有关定制示例,请参见创建自定义抽象层

的XCP司机

XCP驱动程序通过通信通道发送和接收XCP消息。在外部模式模拟中,构建过程自动将驱动程序文件添加到构建信息对象。

XCP驱动程序是基于rtiostreamAPI。例如,基于主机的外部模式模拟使用这些rtiostream文件:

  • matlabroot\工具箱\编码器\ rtiostream \ src \ rtiostreamtcpip.c

  • matlabroot\工具箱\编码器\ rtiostream \ src \ rtiostream_serial.c

有关实现和测试an的详细信息rtiostream通信渠道,见:

对于自定义平台抽象层,必须添加您的rtiostream文件到构建信息对象.有关示例,请参见创建自定义抽象层

内存分配器

XCP从软件需要动态分配可变大小的连续内存块来保存内部数据结构。

在外部模式模拟中,构建过程自动向构建信息对象添加内存分配器文件。

xcpMemBlockSizes而且xcpMemBlockCounts预处理器宏定义内存分配。

默认的内存分配器最多可以分配和释放16组不同的内存块。对于每一组,您都可以在编译期间覆盖默认分配。您可以指定:

  • 块大小通过XCP_MEM_BLOCK_N_SIZE预处理器宏。

  • 在每组中通过的块数XCP_MEM_BLOCK_N_NUMBER预处理器宏。

例如,这些预处理器宏创建了4个64字节的块和8个256字节的块。

#定义xcp_mem_block_size 4 #定义xcp_mem_block_size

按升序配置不同集合的块大小:

XCP_MEM_BLOCK_N_SIZE<XCP_MEM_BLOCK_N+ 1 _size

最小块大小,XCP_MEM_BLOCK_1_SIZE,必须足够大以容纳指针。

配置内存分配器的对齐方式XCP_MEM_ALIGNMENT预处理器宏。例如:

#定义xcp_mem_align

其他平台抽象层功能

这个文件定义了平台抽象层接口:

matlabroot\工具箱\编码器\ xcp奴隶\ \ src \目标\ \包括\ xcp_platform.h平台
要实现自定义平台抽象层功能,请添加XCP_CUSTOM_PLATFORM构建信息对象的预处理器宏。在一个名为xcp_platform_custom.h.如果你没有定义XCP_CUSTOM_PLATFORM,构建过程使用支持Linux的默认文件金宝app®和窗户®系统。

下表描述了必须为部署在目标硬件上的XCP从软件提供的功能。

功能 细节

互斥

访问系统数据结构互斥金宝appXCP驱动程序依赖于基本的api来定义、初始化、锁定和解锁。

要支持金宝app目标硬件的互斥,请提供自定义实现。

Linux和Windows的默认实现支持互斥。金宝app

#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  #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)…#定义XCP_SLEEP(seconds,microseconds) Sleep((seconds) * 1000 \ + (((microseconds) + 1000 - 1) / 1000)) #else…#if _POSIX_C_SOURCE >= 199309L #定义XCP_SLEEP(seconds,microseconds) do {struct timespec t;\ t.tv_sec = seconds;T.tv_nsec =微秒* 1000;nanosleep(&t, NULL);} while(0) #else /* nanosleep不可用请改用select。*/ #定义XCP_SLEEP(秒,微秒)do {struct timeval t;\ T.tv_sec =秒;\ t.tv_usec =微秒;select(0, NULL, NULL, NULL, &t);} while(0) #endif /* _POSIX_C_SOURCE >= 199309L */…# endif

日志记录

为了生成诊断消息,XCP从软件需要一个自定义打印API,该API支持目标硬件提供的日志服务。金宝app如果没有定义XCP_PRINTF预处理器宏,默认实现为空。

地址转换

XCP标准将内存中的变量地址表示为带有8位扩展的32位地址。

XCP Master通过解析构建过程创建的调试信息来提取信号的地址和模型的参数。调试信息格式为“DWARF”或“PDB”。

XCP Master通过发送包含参数的XCP命令来请求访问参数和信号addressExtension而且地址

addressExtension而且地址信息被目标硬件接收后,XCP Slave必须将地址转换为目标硬件内存中变量的位置。变量位置由加载器分配,并且是特定于目标的。

使用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位硬件架构,因此金宝appaddressExtension是0。

设置和复制内存

您可以指定复制内存的优化版本,并设置内存操作。

如果没有定义XCP_MEMCPY而且XCP_MEMSET预处理宏,默认实现指定标准C函数,memcpy而且memset

# XCP_MEMCPY #定义XCP_MEMCPY memcpy #endif #

解析命令行参数

如果目标硬件不支持解析命令行参数,请定义预处理器宏金宝appEXTMODE_DISABLE_ARGS_PROCESSING

要替换- w选项,您可以使用此命令指定目标应用程序进入并保持在等待状态,直到它接收到来自Simulink的连接消息:金宝app

set_param (modelName, 'OnTargetWaitForStart', 'on');
构建过程提供了必需的选项(-DON_TARGET_WAIT_FOR_START = 1)给编译器。

创建自定义抽象层

对于构建过程,您可以定义一个post-code生成命令来创建一个自定义的平台抽象层。

  1. 指定头文件xcp_platform_custom.h.这个Linux示例定义了所需的函数。

    # XCP_PLATFORM_CUSTOM_H #define XCP_PLATFORM_CUSTOM_H /* XCP_ADDRESS_GET */ #include  #define XCP_ADDRESS_GET(addressExtension, address) (uint8_T*) ((uintptr_t) address) /* XCP_MUTEX */ #include  #define XCP_MUTEX_DEFINE(lock) pthread_mutex_t lock #define XCP_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  /* gettimeofday */ #if _POSIX_C_SOURCE >= 199309L #include  /* for nanosleep */ #else #include  #include  /* 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 =微秒* 1000;nanosleep(&t, NULL);} while(0) #else /* nanosleep不可用请改用select。*/ #定义XCP_SLEEP(秒,微秒)do {struct timeval t;\ T.tv_sec =秒;\ t.tv_usec =微秒;select(0, NULL, NULL, NULL, &t);} while(0) #endif /* _POSIX_C_SOURCE >= 199309L */ #endif . #

  2. 定义邮政编码生成命令。

    函数myXCPTargetPostCodeGenCommand buildInfo buildInfo.addDefines (“-DXCP_CUSTOM_PLATFORM”“选择”);配置默认内存分配器buildInfo.addDefines (“-DXCP_MEM_BLOCK_1_SIZE = 64”“选择”);buildInfo.addDefines (“-DXCP_MEM_BLOCK_1_NUMBER = 46 '“选择”);buildInfo.addDefines (“-DXCP_MEM_BLOCK_2_SIZE = 256”“选择”);buildInfo.addDefines (“-DXCP_MEM_BLOCK_2_NUMBER = 10”“选择”);添加我的rtiostreambuildInfo.addSourceFiles (customRtIOStreamFileName...customRtIOStreamSrcPath);%如果目标硬件不支持解析命令金宝app% line参数buildInfo.addDefines (“-DEXTMODE_DISABLE_ARGS_PROCESSING”“选择”);结束

另请参阅

|||||||||

相关的话题

外部网站