CANoe如何和其他编程语言交互数据


这篇文章记录自己在尝试CANoe使用自带的FDX协议与其他语言通讯的过程。

环境设置

.cfg文件设置

使能FDX协议

在CANoe的Options->Extensions->XIL API & FDX Protocol中使能FDX,CANoe作为UDP的Server,根据情况设置一个PortNumber。
在这里插入图片描述

创建环境变量

创建如下的环境变量,这里使用4种比较常用的数据类型
在这里插入图片描述

添加FDX Description Files

回到一开始的FDX设置页面,添加一个新的FDX描述文件,在cfg的根目录下创建一个xml文件,添加如下文字,这样CANoe就可以解析了
在这里插入图片描述

<?xml version="1.0" encoding="ISO-8859-1"?>
<canoefdxdescription version="1.0">
</canoefdxdescription>

创建加载xml文件后,辨析需要接收或发送的变量,为刚刚创建的System Varible创建如下对的字段映射表
这里我给String留了16Byte的空间,一般的字符串也够了
在这里插入图片描述

UDP报文格式

这里使用WireShark软件对DataRequest Command类型的报文进行抓包分析,其他类型的请求报文可以参考官方文档进行分析
下面这张图是Python发送的报文格式
在这里插入图片描述
下面这张图是CANoe返回的报文格式,其中蓝底的0x03代表着下面对的数据场有三段含义

  • 红底的16Byte的标识为0x0004的数据段,代表CANoe的Status
  • 黄底的8Byte的标识为0x000b的数据段,代表CANoe的Error
  • 绿底的40Byte的标识为0x0005的数据段,代表CANoe对我们上面发送的请求的回复,实际有效的数据是最后的32个Byte,对应着在XML文件中的4个数据字段
    • 0x00000001代表INT32类型的isOpenDoor变量,采用补码表示,十进制为1
    • 0x4030800000000000代表DOUBLE类型的vehSpd变量,采用IEEE754标准表示,为什么我知道,因为我刚刚手算过,十进制为16.5
    • 0xffffffec代表INT32类型的EMTorque变量,采用补码表示,十进制为-20
    • 最后面的16Byte是ASCII编码的字符串格式,解码后为String

在这里插入图片描述
CANoe当前的变量如下图所示
在这里插入图片描述
掌握了这个方法,基本上就可以在任意的编程语言下面打包拆包报文了,其他类型的交互报文类似

交互模式

这部分我们使用Python写一个UDP的Socket和CANoe进行交互
交互模式有两种

  • 一种是其他端口发送一个UDP报文,CANoe返回一个UDP报文,必须先给CANoe发送,CANoe才能回复
  • 另一种是其他端口给CANoe发送一个自由模式的请求报文,这段报文中指明了比如CANoe可以循环发送某一个数据组,或者通过CAPL来触发。必须也是其他端口先发送一个请求。

CANoe接收

Start Command

按照规定的报文格式,填充下面的数据,可以使能CANoe的Start
在这里插入图片描述

import socket
import time
client = socket.socket(socket.AF_INET,
    socket.SOCK_DGRAM) #udp协议
client.bind(('127.0.0.1', 2021))
ip_port = ('127.0.0.1', 2020)
startCommond = \
    '\x43\x41\x4E\x6F\x65\x46\x44\x58'\
    '\x02\x00\x01\x00\x00\x00\x01\x00'\
    '\x00\x04\x00\x01'.encode('utf-8')
client.sendto(startCommond, ip_port)
client.close()

python发送完上面这一段后,可以看到CANoe开始测量了

Stop Command

在这里插入图片描述

import socket
import time
client = socket.socket(socket.AF_INET,
    socket.SOCK_DGRAM) #udp协议
client.bind(('127.0.0.1', 2021))
ip_port = ('127.0.0.1', 2020)
stopCommond = \
    '\x43\x41\x4E\x6F\x65\x46\x44\x58'\
    '\x02\x00\x01\x00\x00\x00\x01\x00'\
    '\x00\x04\x00\x02'.encode('utf-8')
client.sendto(stopCommond , ip_port)
client.close()

python发送完上面这一段后,可以看到CANoe停止测量了

Key Command

这部分没有试过,先贴出来
在这里插入图片描述

DataRequest Command

在这里插入图片描述

import socket
import time
client = socket.socket(socket.AF_INET,
    socket.SOCK_DGRAM) #udp协议
client.bind(('127.0.0.1', 2021))
ip_port = ('127.0.0.1', 2020)
dataRequestCommond = \
    '\x43\x41\x4E\x6F\x65\x46\x44\x58'\
    '\x02\x00\x01\x00\x00\x00\x01\x00'\
    '\x00\x06\x00\x06\x00\x01'.encode('utf-8')
client.sendto(startCommond, ip_port)
client.close()

这部分抓包分析见上面的“UDP报文格式”部分

Status Request Command

这部分没有试,当时从其他请求中CANoe返回的报文可以看出,CANoe会发出来
在这里插入图片描述

Function Call Command

这部分没有试
在这里插入图片描述

Increment Time Command

这部分没有试
在这里插入图片描述

双方交互

DataExchange Command

这段数据场可以XML中指定的CANoe的数据
在这里插入图片描述

import socket
import time
client = socket.socket(socket.AF_INET,
    socket.SOCK_DGRAM) #udp协议
client.bind(('127.0.0.1', 2021))
ip_port = ('127.0.0.1', 2020)
dataExchangeCommond = \
    '\x43\x41\x4E\x6F\x65\x46\x44\x58'\
    '\x02\x00\x01\x00\x00\x00\x01\x00'\
    '\x00\x28\x00\x05\x00\x01\x00\x20'\
    '\x00\x00\x00\x00\x40\xA4\x12\x00'\
    '\x00\x00\x00\x00\x00\x00\x66\x34'\
    '\x41\x42\x43\x44\x45\x46\x47\x48'\
    '\x49\x50\x51\x52\x53\x54\x55'.encode('utf-8')
client.sendto(dataExchangeCommond, ip_port)
client.close()

这段数据发送后,会改变CANoe中预先设定的变量,数据变化后的CANoe数据如下图所示
在这里插入图片描述

CANoe发送

DataError Command

在这里插入图片描述

Status Command

在这里插入图片描述

Sequence Number Error Command

在这里插入图片描述

自由模式

FreeRunningRequest Command

在这里插入图片描述

FreeRunningCancel Command

在这里插入图片描述

总结

  • 使用这个功能可以让CANoe和任意编程语言交互数据
  • 在这个通讯中CANoe扮演着Slave的角色
  • 我在使用Python发送DOUBLE的16进制给CANoe的时候,WireShark总是捕捉到多发一个0x2C,不知道是不是Python写的不对,比如编码格式是不是错了。
  • 还没有试在一个局域网中两台主机交互的情况,不过应该也可以
  • Sequence number这个字段理论上其他端口在给CANoe发送的时候,应该是循环变化的,如果一直发一个固定值,CANoe会返回一个错误,提示期望的分组和收到的分组不一致,但是不影响通讯
  • 我觉得在实际使用中,FDX最好不要直接控制CAN报文,因为这相当于跨了两层协议,最好只和CANoe的环境变量交互,中间只用一个XML文件约定通讯方式,写和CANoe交互的APP的时候可以写一个xml解析的功能,让双方交互更灵活。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值