XCP 是汽车 OEM 的一项共同要求。 我发现、为 C2000器件实施 XCP-on-CAN 远非简单直接、并且似乎没有太多公开的信息、因此这篇文章旨在改善这种情况。 复杂因素是16位 C2000最小可寻址单元(MAU)。 XCP 具有一个被称为 Address_requality (AG)的设置、可以将其设置为 word 而不是常见的字节。 其背后的意图(我想)是使 XCP 能够适应不是8位 MAU 的架构。 问题是、我尝试过的 MCD (测量校准、诊断)工具不支持 AG=WORD。 例如、Vector canape。
https://support.vector.com/kb?id=kb_article_view&sysparm_article=KB0012595
MathWorks 实现了带 CANAP 的 XCP、但这仅在整个工程基于 MATLAB/Simulink 以使 Simulink 生成 A2L 文件并从 ELF 文件更新其地址时才有用。
https://uk.mathworks.com/help/ti-c2000/ug/calibrate-ecu-can-example.html
单个开发人员没问题、但对于由具有多个工具链的自动编码和手动编码模块组成的大型协作项目则不行。
也许还有其他方法可以解决这一问题、但这里是我如何让 XCP-on-CAN 在 F2800039C 上工作、尽管这应该适用于任何 C2000器件。 请随意发布更简单的解决方案或挑战以下任何一项。
默认情况下、XCP A2L 地址 n 和地址 n+1各不相同、只有8位(AG=字节)。 对于 C2000器件、地址 n 和 n+1因16位而异(AG=字)。 那么、问题是、C2000 XCP 从站(AG=WORD)如何仿真 AG=BYTE 才能与 XCP 主站通信? 一般的解决方案(不是我的发明)是将所有物理设备地址乘以2、这样:
- A2L 地址=器件地址 x 2。
- 器件地址= A2L 地址/2。
在历史上、CAape 通过称为 DSP_MODE 的专家设置支持此寻址方案、大概是用于替代 XCP AG=word 模式。 Canape DSP_MODE 将其 ASAP2数据库中的所有地址存储为物理设备地址的2 x。 当 CCP 向从器件发送一个包含地址的 CRO 时、它将在发送 CRO 之前先将 A2L 数据库地址除以2。 因此、C2000从器件接收到一个有意义的物理地址、该地址可以在不进行进一步处理的情况下解除引用。 然而、CANAPE DSP_MODE 只适用于 CCP 器件、而对于 XCP 器件则不提供该设置。 此外、CANAPE 中的地址更新只能使用旧的 COFF 链接器输出、EABI 不起作用。
因此、此处描述的 XCP 解决方案(矢量 CANAPE CCP DSP_MODE 仿真)有三个实际方面:
- A2L 文件创建/地址更新阶段应将从 CCS EABI .out 文件中提取的物理地址加倍。
- 在操作中、XCP 从器件应将接收到的 A2L 地址减半、从而在被取消引用之前计算器件地址。
- 即使是 A2L 地址也应访问设备地址的低位字节。 奇数 A2L 地址应访问器件地址的高位字节。
此方案的优势是它完全隐藏在 XCP 主站中、因此可移植到具有相同 A2L 文件的任何 MCD 工具。 我碰巧使用 CANAPE、但如果您需要免费的 MCD 工具进行基本 XCP 测试、我建议您查看 ASAP2Demo。 https://jnachbaur.de/ASAP2Demo/ASAP2.html
源声明:
Uint16_t XCP_TEST_UBYTE1 = 0x0011; Uint16_t XCP_TEST_UBYTE2 = 0x0022; uint16_t XCP_TEST_UWORD = 0x4433; uint32_t XCP_TEST_ULONG = 0x88776655; uint64_t XCP_TEST_UINT64 = 0x10FFEEDDCCBBAA99;
示例特征由链接器放在 GSRAM0中、从地址0x0000C000开始。
链接和创建 A2L 后的器件和 A2L 地址映射:

在 Canape 中查看:

步骤1)获取矢量的 XCP 示例实现。
步骤2)进行 XCP 从站源修改以实现地址减半。 请参阅随附的补丁文件。
步骤3)集成到您的应用中并可以传输层代码。
步骤4)使 A2L 文件照常运行、但将 A2L 文件中的地址排列为链接器.out 文件中的地址的两倍。 这是我写了一个 Python 脚本的最难的部分。
步骤5)将 MCD 工具与常规 XCP-on-CAN 器件(AG=byte)配合使用。 就 MCD 工具而言、从器件的运行方式将与大多数其他 ECU 一样、MAU=8位的器件类似。
- 获取矢量的 XCP 从器件实现:
- 下载: https://support.vector.com/kb?id=kb_article_view&sysparm_article=KB0011316
- 将文件夹‘XCP Basic Driver’中的所有文件复制到 C2000项目中的 XCP 源文件夹。
- 从_XCP_appl.c 中删除下划线
- 进行 XCP 从源修改以实现地址减半并实现回调:
- 应用随附的补丁文件。 右键点击"Project"->"Team"->"Apply Patch"… ->选择补丁文件->下一步->选择 XCP 源文件夹->下一步->查看更改->完成。 我的更改主要包含在__TMS320C2000__宏中。
- 使用 DWARF 进行编译和链接 3. 。 默认 DWARF 4. 导致第三方工具尝试解析.out 文件时出现问题。 请参阅该主题: https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1220659/dwarf-3-vs-dwarf-4-for-3rd-party-tools
e2e.ti.com/.../xcp_5F00_patch.zip
- 集成到您的应用中:
- 调用一次 XcpInit()。
- 当事件 x 发生时调用 XcpEvent (x)。
- 当从机从 Canape 收到 CTO 时调用 XcpCommand()。
- 调用 ApplXcpSend()时,实施代码以发送 DTO。
- 当前一步骤中的 DTO 已成功传输时调用 XcpSendCallBack ()。
- 将 A2L 文件照常配置、但将 A2L 文件中的地址排列为链接器.out 文件中物理地址的两倍。 一些解决方案:
- Vector canape:我使用 Vector 的 ASAP2工具集 v15 (ASAP2Updater.exe)来更新地址。 我意外地发现、如果我选择 map_format = 131 (ELF/DWARF Extended)、地址会对我翻一番。 这种行为由选项 ELF_ADDRESS_MODE=word 控制。 请注意、使用 Canape 地图更新功能时、选择相同的地图格式(131)不能正常工作。 可能在更高版本中仍能正常工作。
- ASAP2Demo:它已经支付了 A2L/ELF 同步附加选项、但在写入时、2 x 地址功能尚不适用于 C2000解析器、但已被请求。 我不知道这是否会成为现实。
- 脚本:下面是在您的常规地址更新工具完成后应用的 Python 脚本。 这很粗糙、但却有效。
- 照常使用 MCD 工具。 例如、Canape。
Python 脚本
# Python program to double the addresses (starting "0x") of MEASUREMENTs and CHARACTERISTICS
# in an A2L file.
# Tested with Python 3.10.
import sys
# Use Regex pattern matching.
import re
def main():
try:
in_file = open(sys.argv[1], "r")
out_file = open(sys.argv[2], "w")
# Read the input file line by line.
lines = in_file.readlines()
new_list = []
idx = 0
found_IF_DATA = False
# Loop through each line
for line in lines:
# Only start parsing after the IF_DATA section where the
# MEASUREMENTs, CHARACTERISTICs etc. are located.
if "/end IF_DATA" in line:
found_IF_DATA = True
if found_IF_DATA == True:
# From here, treat all strings beginning "0x" as addresses.
if "0x" in line:
# For debugging console output.
new_list.insert(idx, line)
idx += 1
# Get all instances of likely hex numbers in the line.
hex_num_str_list = re.findall(r'0x[0-9A-Fa-f]+', line, re.I)
# TODO : Handle occasions where more than one 0x is found in a line.
# Otherwise just process the first.
# Convert string to a number, e.g. '0xA5' -> 165.
hex_num = int(hex_num_str_list[0], 16)
# Double the address number. e.g. 165 -> 330.
hex_num = int(hex_num * 2)
# Convert address number to a string. e.g. 330 -> '0x14a'.
# TODO : Capitalize the alpha chars apart from 'x'.
hex_num_str = hex(hex_num)
# Replace the original address. e.g. '0xA5' -> '0x14a'
line = line.replace(hex_num_str_list[0], hex_num_str)
# Write the line to the output file, modified or not.
out_file.write(line)
in_file.close()
out_file.close()
# Debugging console output.
if len(new_list)==0:
print("\n\"" +"0x"+ "\" is not found!")
else:
# Print the lines containing "0x"
lineLen = len(new_list)
print("\n**** Lines containing \"" + "0x" + "\" ****\n")
for i in range(lineLen):
print(end=new_list[i])
print()
except :
print("\nInput file not found!")
if (len(sys.argv) != 3):
print("Usage:")
print("python.exe A2LAddressUpdate.py InputFile.A2L OutputFile.A2L")
else:
InputFile = sys.argv[1]
OutputFile = sys.argv[2]
main()