RAW CAN解码
RAW CAN decoding
我正在尝试使用虚拟 CAN 网络导入 CAN 数据,但在解压缩我的 CAN 数据包时得到了奇怪的结果。我正在使用 Python 3.3.7
代码:
导入套接字、系统、结构
sock = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
interface = "vcan0"
try:
sock.bind((interface,))
except OSError:
sys.stderr.write("Could not bind to interface '%s'\n" % interface)
fmt = "<IB3x8s"
while True:
can_pkt = sock.recv(16)
can_id, length, data = struct.unpack(fmt, can_pkt)
can_id &= socket.CAN_EFF_MASK
data = data[:length]
print(data, can_id , can_pkt)
所以当我有一个看起来像这样的 CAN 数据包时。
candump vcan0: vcan0 0FF [8] 77 9C 3C 21 A2 9A B9 66
output in Python: b'\xff\x00\x00\x00\x08\x00\x00\x00w\x9c<!\xa2\x9a\xb9f'
其中vcan0是接口,[x]是有效载荷中的字节数,其余是8字节的十六进制有效载荷。
我的格式有误吗? PF_CAN 是否已针对较新的 Python 版本进行了更新?当我应该为我的协议系列使用 CAN_BCM 时,我是否使用了 CAN_RAW?还是我只是想念如何解码解压后的数据?
任何方向或答案将不胜感激。
另外,这里有一些脚本输出到我采摘的 can-utils 值。如果我找不到任何东西,我可能只会收集大量数据,然后解码未正确转换的数据字节。我觉得我把事情复杂化了,可能遗漏了一个关键方面。
Python3 output == can-utils/socketCAN (hex)
M= == 4D 3D
~3 == 7E 33
p == 70
. == 2E
@ == 40
r: == 0D 3A
c == 63
5g == 35 67
y == 79
a == 61
) == 29
E == 45
M == 4D
C == 43
P> == 50 3E
SGN == 53 47 4E
8 == 38
与其费力地完成您开始的 table,不如查看任何 ASCII 代码图表。当您简单地打印一个字符串时,任何实际上是 ASCII 文本的字符都将打印为该字符:只有 unprintable 字符会显示为十六进制转义符。如果你想要一切十六进制,你需要明确要求:
import binascii
print(binascii.hexlify(data))
例如。
我确定您已经 运行 进入了 python-can library? If not we have a native python version of socketcan that correctly parse data out of CAN messages. Some of the source might help you out - or you might want to use it directly. CAN_RAW
is probably what you want, if you plan on leaving virtual can for real hardware you might also want to get the timestamp from the hardware。
并非所有常量都在 Python 的套接字模块中公开,因此还有一个 ctypes 版本,可以更轻松地试验诸如 socketcan 广播管理器之类的东西。两者的文档都是 here.
我正在尝试使用虚拟 CAN 网络导入 CAN 数据,但在解压缩我的 CAN 数据包时得到了奇怪的结果。我正在使用 Python 3.3.7
代码: 导入套接字、系统、结构
sock = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
interface = "vcan0"
try:
sock.bind((interface,))
except OSError:
sys.stderr.write("Could not bind to interface '%s'\n" % interface)
fmt = "<IB3x8s"
while True:
can_pkt = sock.recv(16)
can_id, length, data = struct.unpack(fmt, can_pkt)
can_id &= socket.CAN_EFF_MASK
data = data[:length]
print(data, can_id , can_pkt)
所以当我有一个看起来像这样的 CAN 数据包时。
candump vcan0: vcan0 0FF [8] 77 9C 3C 21 A2 9A B9 66
output in Python: b'\xff\x00\x00\x00\x08\x00\x00\x00w\x9c<!\xa2\x9a\xb9f'
其中vcan0是接口,[x]是有效载荷中的字节数,其余是8字节的十六进制有效载荷。
我的格式有误吗? PF_CAN 是否已针对较新的 Python 版本进行了更新?当我应该为我的协议系列使用 CAN_BCM 时,我是否使用了 CAN_RAW?还是我只是想念如何解码解压后的数据?
任何方向或答案将不胜感激。
另外,这里有一些脚本输出到我采摘的 can-utils 值。如果我找不到任何东西,我可能只会收集大量数据,然后解码未正确转换的数据字节。我觉得我把事情复杂化了,可能遗漏了一个关键方面。
Python3 output == can-utils/socketCAN (hex)
M= == 4D 3D
~3 == 7E 33
p == 70
. == 2E
@ == 40
r: == 0D 3A
c == 63
5g == 35 67
y == 79
a == 61
) == 29
E == 45
M == 4D
C == 43
P> == 50 3E
SGN == 53 47 4E
8 == 38
与其费力地完成您开始的 table,不如查看任何 ASCII 代码图表。当您简单地打印一个字符串时,任何实际上是 ASCII 文本的字符都将打印为该字符:只有 unprintable 字符会显示为十六进制转义符。如果你想要一切十六进制,你需要明确要求:
import binascii
print(binascii.hexlify(data))
例如。
我确定您已经 运行 进入了 python-can library? If not we have a native python version of socketcan that correctly parse data out of CAN messages. Some of the source might help you out - or you might want to use it directly. CAN_RAW
is probably what you want, if you plan on leaving virtual can for real hardware you might also want to get the timestamp from the hardware。
并非所有常量都在 Python 的套接字模块中公开,因此还有一个 ctypes 版本,可以更轻松地试验诸如 socketcan 广播管理器之类的东西。两者的文档都是 here.