Skip to content

Commit 4b300a6

Browse files
committed
Add FD support to canutils
Remove RTR tests for FD frames since they doesn't exist and thus cannot be represented in the canutils log format. See "CAN with Flexible Data-Rate, version 1.0, Bosch, April 17th, 2012, pp.11": "The REMOTE TRANSMISSION REQUEST (RTR) bit only exists in CAN format frames. [...] There are no REMOTE FRAMES in CAN FD format."
1 parent ef47091 commit 4b300a6

3 files changed

Lines changed: 37 additions & 18 deletions

File tree

can/io/canutils.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
CAN_ERR_BUSERROR = 0x00000080
1919
CAN_ERR_DLC = 8
2020

21+
CANFD_BRS = 0x01
22+
CANFD_ESI = 0x02
2123

2224
class CanutilsLogReader(BaseIOHandler):
2325
"""
@@ -47,13 +49,24 @@ def __iter__(self):
4749

4850
timestamp, channel, frame = temp.split()
4951
timestamp = float(timestamp[1:-1])
50-
canId, data = frame.split("#")
52+
canId, data = frame.split("#", maxsplit=1)
5153
if channel.isdigit():
5254
channel = int(channel)
5355

5456
isExtended = len(canId) > 3
5557
canId = int(canId, 16)
5658

59+
is_fd = False
60+
brs = False
61+
esi = False
62+
63+
if data and data[0] == "#":
64+
is_fd = True
65+
fd_flags = int(data[1])
66+
brs = bool(fd_flags & CANFD_BRS)
67+
esi = bool(fd_flags & CANFD_ESI)
68+
data = data[2:]
69+
5770
if data and data[0].lower() == "r":
5871
isRemoteFrame = True
5972

@@ -79,6 +92,9 @@ def __iter__(self):
7992
arbitration_id=canId & 0x1FFFFFFF,
8093
is_extended_id=isExtended,
8194
is_remote_frame=isRemoteFrame,
95+
is_fd=is_fd,
96+
bitrate_switch=brs,
97+
error_state_indicator=esi,
8298
dlc=dlc,
8399
data=dataBin,
84100
channel=channel,
@@ -126,20 +142,25 @@ def on_message_received(self, msg):
126142

127143
channel = msg.channel if msg.channel is not None else self.channel
128144

145+
framestr = "(%f) %s" % (timestamp, channel)
146+
129147
if msg.is_error_frame:
130-
self.file.write(
131-
"(%f) %s %08X#0000000000000000\n"
132-
% (timestamp, channel, CAN_ERR_FLAG | CAN_ERR_BUSERROR)
133-
)
148+
framestr += " %08X#" % (CAN_ERR_FLAG | CAN_ERR_BUSERROR)
149+
elif msg.is_extended_id:
150+
framestr += " %08X#" % (msg.arbitration_id)
134151
else:
135-
arbitration_id_str = ("%08X" if msg.is_extended_id else "%03X") % msg.arbitration_id
152+
framestr += " %03X#" % (msg.arbitration_id)
136153

137-
if msg.is_remote_frame:
138-
self.file.write(
139-
"(%f) %s %s#R\n" % (timestamp, channel, arbitration_id_str)
140-
)
141-
else:
142-
self.file.write(
143-
"(%f) %s %s#%s\n"
144-
% (timestamp, channel, arbitration_id_str, msg.data.hex().upper())
145-
)
154+
if msg.is_remote_frame:
155+
framestr += "R\n"
156+
else:
157+
if msg.is_fd:
158+
fd_flags = 0
159+
if msg.bitrate_switch:
160+
fd_flags |= CANFD_BRS
161+
if msg.error_state_indicator:
162+
fd_flags |= CANFD_ESI
163+
framestr += "#%X" % fd_flags
164+
framestr += "%s\n" % (msg.data.hex().upper())
165+
166+
self.file.write(framestr)

test/data/example_data.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,6 @@ def sort_messages(messages):
112112
[
113113
Message(is_fd=True, data=range(64)),
114114
Message(is_fd=True, data=range(8)),
115-
Message(is_fd=True, bitrate_switch=True, is_remote_frame=True),
116-
Message(is_fd=True, error_state_indicator=True, is_remote_frame=True),
117115
Message(is_fd=True, data=range(8), bitrate_switch=True),
118116
Message(is_fd=True, data=range(8), error_state_indicator=True),
119117
]

test/logformats_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ def _setup_instance(self):
662662
super()._setup_instance_helper(
663663
can.CanutilsLogWriter,
664664
can.CanutilsLogReader,
665-
check_fd=False,
665+
check_fd=True,
666666
test_append=True,
667667
check_comments=False,
668668
preserves_channel=False,

0 commit comments

Comments
 (0)