def __iter__(self): tail = b"" while True: data = self.fp.read(OBJ_HEADER_STRUCT.size) if not data: # EOF break header = OBJ_HEADER_STRUCT.unpack(data) #print(header) assert header[0] == b"LOBJ", "Parse error" obj_type = header[4] obj_data_size = header[3] - OBJ_HEADER_STRUCT.size obj_data = self.fp.read(obj_data_size) # Read padding bytes self.fp.read(obj_data_size % 4) if obj_type == LOG_CONTAINER: uncompressed_size = header[7] data = zlib.decompress(obj_data, 15, uncompressed_size) if tail: data = tail + data pos = 0 while pos + OBJ_HEADER_STRUCT.size < len(data): header = OBJ_HEADER_STRUCT.unpack_from(data, pos) #print(header) assert header[0] == b"LOBJ", "Parse error" obj_size = header[3] if pos + obj_size > len(data): # Object continues in next log container break obj_type = header[4] timestamp = header[7] / 1000000000.0 + self.start_timestamp if obj_type == CAN_MESSAGE: assert obj_size == OBJ_HEADER_STRUCT.size + CAN_MSG_STRUCT.size (channel, flags, dlc, can_id, can_data) = CAN_MSG_STRUCT.unpack_from( data, pos + OBJ_HEADER_STRUCT.size) msg = Message(timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, extended_id=bool(can_id & CAN_MSG_EXT), is_remote_frame=bool(flags & REMOTE_FLAG), dlc=dlc, data=can_data[:dlc], channel=channel) yield msg elif obj_type == CAN_ERROR: assert obj_size == OBJ_HEADER_STRUCT.size + CAN_ERROR_STRUCT.size channel, length = CAN_ERROR_STRUCT.unpack_from( data, pos + OBJ_HEADER_STRUCT.size) msg = Message(timestamp=timestamp, is_error_frame=True, channel=channel) yield msg pos += obj_size # Add padding bytes pos += obj_size % 4 # Save remaing data that could not be processed tail = data[pos:] self.fp.close()
def __iter__(self): for line in self.file: logger.debug("ASCReader: parsing line: '%s'", line.splitlines()[0]) temp = line.strip() if not temp or not temp[0].isdigit(): continue try: (timestamp, channel, dummy) = temp.split(None, 2) # , frameType, dlc, frameData except ValueError: # we parsed an empty comment continue timestamp = float(timestamp) if dummy.strip()[0:10] == 'ErrorFrame': msg = Message(timestamp=timestamp, is_error_frame=True) yield msg elif not channel.isdigit() or dummy.strip()[0:10] == 'Statistic:': pass elif dummy[-1:].lower() == 'r': (can_id_str, _) = dummy.split(None, 1) (can_id_num, is_extended_id) = self._extract_can_id(can_id_str) msg = Message(timestamp=timestamp, arbitration_id=can_id_num & CAN_ID_MASK, extended_id=is_extended_id, is_remote_frame=True) yield msg else: try: # this only works if dlc > 0 and thus data is availabe (can_id_str, _, _, dlc, data) = dummy.split(None, 4) except ValueError: # but if not, we only want to get the stuff up to the dlc (can_id_str, _, _, dlc) = dummy.split(None, 3) # and we set data to an empty sequence manually data = '' dlc = int(dlc) frame = bytearray() data = data.split() for byte in data[0:dlc]: frame.append(int(byte, 16)) (can_id_num, is_extended_id) = self._extract_can_id(can_id_str) msg = Message(timestamp=timestamp, arbitration_id=can_id_num & CAN_ID_MASK, extended_id=is_extended_id, is_remote_frame=False, dlc=dlc, data=frame) yield msg
def recv(self, timeout=None): start_time = timeout_clock() if timeout is None: timeout = 0 rx_msg = Message() log.debug("Trying to read a msg") result = None while result is None: result = self.m_objPCANBasic.Read(self.m_PcanHandle) if result[0] == PCAN_ERROR_QRCVEMPTY or result[ 0] == PCAN_ERROR_BUSLIGHT or result[ 0] == PCAN_ERROR_BUSHEAVY: if timeout_clock() - start_time >= timeout: return None else: result = None time.sleep(0.001) elif result[0] != PCAN_ERROR_OK: raise PcanError(self._get_formatted_error(result[0])) theMsg = result[1] itsTimeStamp = result[2] log.debug("Received a message") bIsRTR = (theMsg.MSGTYPE & PCAN_MESSAGE_RTR.value) == PCAN_MESSAGE_RTR.value bIsExt = (theMsg.MSGTYPE & PCAN_MESSAGE_EXTENDED.value) == PCAN_MESSAGE_EXTENDED.value if bIsExt: #rx_msg.id_type = ID_TYPE_EXTENDED log.debug("CAN: Extended") else: #rx_msg.id_type = ID_TYPE_STANDARD log.debug("CAN: Standard") dlc = theMsg.LEN timestamp = boottimeEpoch + ((itsTimeStamp.micros + (1000 * itsTimeStamp.millis)) / (1000.0 * 1000.0)) rx_msg = Message(timestamp=timestamp, arbitration_id=theMsg.ID, extended_id=bIsExt, is_remote_frame=bIsRTR, dlc=dlc, data=theMsg.DATA[:dlc]) return rx_msg
def __iter__(self): def extractCanId(strCanId): if strCanId[-1:].lower() == "x": isExtended = True can_id = int(strCanId[0:-1], 16) else: isExtended = False can_id = int(strCanId, 16) return (can_id, isExtended) for line in self.fp: temp = line.strip() if len(temp) == 0 or not temp[0].isdigit(): continue (time, channel, dummy) = temp.split(None, 2) # , frameType, dlc, frameData time = float(time) if dummy.strip()[0:10] == "ErrorFrame": time = float(time) msg = Message(timestamp=time, is_error_frame=True) yield msg continue if not channel.isdigit() or dummy.strip()[0:10] == "Statistic:": continue if dummy[-1:].lower() == "r": (canId, _) = dummy.split(None, 1) msg = Message(timestamp=time, arbitration_id=extractCanId(canId)[0] & CAN_ID_MASK, extended_id=extractCanId(canId)[1], is_remote_frame=True) yield msg else: (canId, direction, _, dlc, data) = dummy.split(None, 4) dlc = int(dlc) frame = bytearray() data = data.split() for byte in data[0:dlc]: frame.append(int(byte, 16)) msg = Message(timestamp=time, arbitration_id=extractCanId(canId)[0] & CAN_ID_MASK, extended_id=extractCanId(canId)[1], is_remote_frame=False, dlc=dlc, data=frame) yield msg
def __iter__(self): for line in self.file: # skip empty lines temp = line.strip() if not temp: continue timestamp, channel, frame = temp.split() timestamp = float(timestamp[1:-1]) canId, data = frame.split("#") if channel.isdigit(): channel = int(channel) isExtended = len(canId) > 3 canId = int(canId, 16) if data and data[0].lower() == "r": isRemoteFrame = True if len(data) > 1: dlc = int(data[1:]) else: dlc = 0 dataBin = None else: isRemoteFrame = False dlc = len(data) // 2 dataBin = bytearray() for i in range(0, len(data), 2): dataBin.append(int(data[i:(i + 2)], 16)) if canId & CAN_ERR_FLAG and canId & CAN_ERR_BUSERROR: msg = Message(timestamp=timestamp, is_error_frame=True) else: msg = Message( timestamp=timestamp, arbitration_id=canId & 0x1FFFFFFF, is_extended_id=isExtended, is_remote_frame=isRemoteFrame, dlc=dlc, data=dataBin, channel=channel, ) yield msg self.stop()
def recv(self, timeout=None): log.debug("Trying to read a msg") if timeout is None or len( select.select([self.socket], [], [], timeout)[0]) > 0: packet = capturePacket(self.socket) else: # socket wasn't readable or timeout occurred return None log.debug("Receiving a message") arbitration_id = packet['CAN ID'] & MSK_ARBID # Flags: EXT, RTR, ERR flags = (packet['CAN ID'] & MSK_FLAGS) >> 29 rx_msg = Message(timestamp=packet['Timestamp'], is_remote_frame=bool(flags & SKT_RTRFLG), extended_id=bool(flags & EXTFLG), is_error_frame=bool(flags & SKT_ERRFLG), arbitration_id=arbitration_id, dlc=packet['DLC'], data=packet['Data']) return rx_msg
def recv(self, timeout=None): try: # ser.read can return an empty string '' # or raise a SerialException rx_byte = self.ser.read() except serial.SerialException: return None if len(rx_byte) and ord(rx_byte) == 0xAA: s = bytearray(self.ser.read(4)) timestamp = s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24) dlc = ord(self.ser.read()) s = bytearray(self.ser.read(4)) arb_id = s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24) data = self.ser.read(dlc) rxd_byte = ord(self.ser.read()) if rxd_byte == 0xBB: # received message data okay return Message(timestamp=timestamp, arbitration_id=arb_id, dlc=dlc, data=data) else: return None else: return None
def _assemble_message(frame_data): timestamp, can_id, is_extended, is_remote, is_error, dlc, data = frame_data return Message(timestamp=timestamp, is_remote_frame=bool(is_remote), is_extended_id=bool(is_extended), is_error_frame=bool(is_error), arbitration_id=can_id, dlc=dlc, data=data)
def recv(self, timeout=None): if HAS_EVENTS: # We will utilize events for the timeout handling timeout_ms = int(timeout * 1000) if timeout is not None else INFINITE elif timeout is not None: # Calculate max time end_time = timeout_clock() + timeout log.debug("Trying to read a msg") result = None while result is None: result = self.m_objPCANBasic.Read(self.m_PcanHandle) if result[0] == PCAN_ERROR_QRCVEMPTY: if HAS_EVENTS: result = None val = WaitForSingleObject(self._recv_event, timeout_ms) if val != WAIT_OBJECT_0: return None elif timeout is not None and timeout_clock() >= end_time: return None else: result = None time.sleep(0.001) elif result[0] & (PCAN_ERROR_BUSLIGHT | PCAN_ERROR_BUSHEAVY): log.warning(self._get_formatted_error(result[0])) return None elif result[0] != PCAN_ERROR_OK: raise PcanError(self._get_formatted_error(result[0])) theMsg = result[1] itsTimeStamp = result[2] log.debug("Received a message") bIsRTR = (theMsg.MSGTYPE & PCAN_MESSAGE_RTR.value) == PCAN_MESSAGE_RTR.value bIsExt = (theMsg.MSGTYPE & PCAN_MESSAGE_EXTENDED.value) == PCAN_MESSAGE_EXTENDED.value if bIsExt: #rx_msg.id_type = ID_TYPE_EXTENDED log.debug("CAN: Extended") else: #rx_msg.id_type = ID_TYPE_STANDARD log.debug("CAN: Standard") dlc = theMsg.LEN timestamp = boottimeEpoch + ((itsTimeStamp.micros + (1000 * itsTimeStamp.millis)) / (1000.0 * 1000.0)) rx_msg = Message(timestamp=timestamp, arbitration_id=theMsg.ID, extended_id=bIsExt, is_remote_frame=bIsRTR, dlc=dlc, data=theMsg.DATA[:dlc]) return rx_msg
def __iter__(self): for line in self.fp: temp = line.strip() if temp: (timestamp, channel, frame) = temp.split() timestamp = float(timestamp[1:-1]) (canId, data) = frame.split('#') if channel.isdigit(): channel = int(channel) if len(canId) > 3: isExtended = True else: isExtended = False canId = int(canId, 16) if data and data[0].lower() == 'r': isRemoteFrame = True if len(data) > 1: dlc = int(data[1:]) else: dlc = 0 else: isRemoteFrame = False dlc = int(len(data) / 2) dataBin = bytearray() for i in range(0, 2 * dlc, 2): dataBin.append(int(data[i:(i + 2)], 16)) if canId & CAN_ERR_FLAG and canId & CAN_ERR_BUSERROR: msg = Message(timestamp=timestamp, is_error_frame=True) else: msg = Message(timestamp=timestamp, arbitration_id=canId & 0x1FFFFFFF, extended_id=isExtended, is_remote_frame=isRemoteFrame, dlc=dlc, data=dataBin, channel=channel) yield msg
def message_convert_rx(messagerx): """convert the message from the CANAL type to pythoncan type""" ID_TYPE = bool(messagerx.flags & IS_ID_TYPE) REMOTE_FRAME = bool(messagerx.flags & IS_REMOTE_FRAME) ERROR_FRAME = bool(messagerx.flags & IS_ERROR_FRAME) msgrx = Message(timestamp=messagerx.timestamp, is_remote_frame=REMOTE_FRAME, extended_id=ID_TYPE, is_error_frame=ERROR_FRAME, arbitration_id=messagerx.id, dlc=messagerx.sizeData, data=messagerx.data[:messagerx.sizeData]) return msgrx
def _parse_from_candump(self, line): line = line.strip('\n') msg_match = self.MSG_RGX.match(line) if msg_match is None: raise InvalidFrame("Wrong format: '{}'".format(line)) can_time, hex_can_id, hex_can_data = msg_match.group(1, 2, 3) can_id = int(hex_can_id, 16) try: can_data = bytes.fromhex(hex_can_data) except ValueError as err: raise InvalidFrame("Can't decode message '{}': '{}'".format(line, err)) return Message(timestamp=float(can_time), arbitration_id=can_id, data=can_data)
def recv(self, timeout=None): rx_msg = Message() log.debug("Trying to read a msg") result = self.m_objPCANBasic.Read(self.m_PcanHandle) if result[0] == PCAN_ERROR_QRCVEMPTY or result[ 0] == PCAN_ERROR_BUSLIGHT or result[0] == PCAN_ERROR_BUSHEAVY: return None elif result[0] != PCAN_ERROR_OK: raise Exception(self.GetFormattedError(result[0])) theMsg = result[1] itsTimeStamp = result[2] log.debug("I've got a message") arbitration_id = theMsg.ID bIsRTR = (theMsg.MSGTYPE & PCAN_MESSAGE_RTR.value) == PCAN_MESSAGE_RTR.value bIsExt = (theMsg.MSGTYPE & PCAN_MESSAGE_EXTENDED.value) == PCAN_MESSAGE_EXTENDED.value # Flags: EXT, RTR, ERR #flags = (PYCAN_RTRFLG if bIsRTR else 0) | (PYCAN_STDFLG if not bIsExt else 0) if bIsExt: #rx_msg.id_type = ID_TYPE_EXTENDED log.debug("CAN: Extended") else: #rx_msg.id_type = ID_TYPE_STANDARD log.debug("CAN: Standard") rx_msg.arbitration_id = arbitration_id rx_msg.id_type = bIsExt rx_msg.is_remote_frame = bIsRTR rx_msg.dlc = theMsg.LEN #rx_msg.flags = flags rx_msg.data = theMsg.DATA rx_msg.timestamp = boottimeEpoch + ((itsTimeStamp.micros + (1000 * itsTimeStamp.millis)) / (1000.0 * 1000.0)) return rx_msg
async def test_get_message(self): messages = [await self.candump_handler.get_message() for _ in range(7)] expected_messages = [ Message(timestamp=1499184018.469421, arbitration_id=0x0, is_extended_id=True, dlc=0, data=[]), Message(timestamp=1499184018.471357, arbitration_id=0x0, is_extended_id=True, dlc=8, data=[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]), Message(timestamp=1499184018.472199, arbitration_id=0xfff, is_extended_id=True, dlc=8, data=[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]), Message(timestamp=1499184018.473352, arbitration_id=0x1, is_extended_id=True, dlc=8, data=[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1]), Message(timestamp=1499184018.474749, arbitration_id=0x100, is_extended_id=True, dlc=8, data=[0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]), Message(timestamp=1499184018.475778, arbitration_id=0xabc, is_extended_id=True, dlc=3, data=[0x12, 0xaf, 0x49]), Message(timestamp=1499184018.478492, arbitration_id=0x743, is_extended_id=True, dlc=8, data=[0x9f, 0x20, 0xa1, 0x20, 0x78, 0xbc, 0xea, 0x98]) ] for i in range(0, len(messages)): self.assertTrue(messages[i].equals(expected_messages[i])) with self.assertRaises(InvalidFrame): await self.candump_handler.get_message() with self.assertRaises(EOFError): await self.candump_handler.get_message()
def __iter__(self): for line in self.csv_file: timestamp, arbitration_id, extended, remote, error, dlc, data = line.split( ',') yield Message( timestamp=float(timestamp), is_remote_frame=(remote == '1'), extended_id=(extended == '1'), is_error_frame=(error == '1'), arbitration_id=int(arbitration_id, base=16), dlc=int(dlc), data=b64decode(data), ) self.csv_file.close()
def recv(self, timeout=None): """ Read a message from the serial device. :param timeout: This parameter will be ignored. The timeout value of the channel is used. :returns: Received message. .. note:: Flags like extended_id, is_remote_frame and is_error_frame will not be set over this function, the flags in the return message are the default values. :rtype: can.Message """ try: # ser.read can return an empty string '' # or raise a SerialException rx_byte = self.ser.read() except serial.SerialException: return None if len(rx_byte) and ord(rx_byte) == 0xAA: s = bytearray(self.ser.read(4)) timestamp = (struct.unpack('<I', s))[0] dlc = ord(self.ser.read()) s = bytearray(self.ser.read(4)) arb_id = (struct.unpack('<I', s))[0] data = self.ser.read(dlc) rxd_byte = ord(self.ser.read()) if rxd_byte == 0xBB: # received message data okay return Message(timestamp=timestamp / 1000, arbitration_id=arb_id, dlc=dlc, data=data)
def recv(self, timeout=None): rx_msg = Message() log.debug("Trying to read a msg") result = self.m_objPCANBasic.Read(self.m_PcanHandle) if result[0] == PCAN_ERROR_QRCVEMPTY or result[0] == PCAN_ERROR_BUSLIGHT or result[0] == PCAN_ERROR_BUSHEAVY: return None elif result[0] != PCAN_ERROR_OK: raise Exception(self.GetFormattedError(result[0])) theMsg = result[1] itsTimeStamp = result[2] log.debug("I've got a message") arbitration_id = theMsg.ID bIsRTR = (theMsg.MSGTYPE & PCAN_MESSAGE_RTR.value) == PCAN_MESSAGE_RTR.value bIsExt = (theMsg.MSGTYPE & PCAN_MESSAGE_EXTENDED.value) == PCAN_MESSAGE_EXTENDED.value # Flags: EXT, RTR, ERR #flags = (PYCAN_RTRFLG if bIsRTR else 0) | (PYCAN_STDFLG if not bIsExt else 0) if bIsExt: #rx_msg.id_type = ID_TYPE_EXTENDED log.debug("CAN: Extended") else: #rx_msg.id_type = ID_TYPE_STANDARD log.debug("CAN: Standard") rx_msg.arbitration_id = arbitration_id rx_msg.id_type = bIsExt rx_msg.is_remote_frame = bIsRTR rx_msg.dlc = theMsg.LEN #rx_msg.flags = flags rx_msg.data = theMsg.DATA rx_msg.timestamp = boottimeEpoch + ( (itsTimeStamp.micros + (1000 * itsTimeStamp.millis)) / (1000.0 * 1000.0) ) return rx_msg
def __iter__(self): # skip the header line try: next(self.file) except StopIteration: # don't crash on a file with only a header return for line in self.file: timestamp, arbitration_id, extended, remote, error, dlc, data = line.split(',') yield Message( timestamp=float(timestamp), is_remote_frame=(remote == '1'), is_extended_id=(extended == '1'), is_error_frame=(error == '1'), arbitration_id=int(arbitration_id, base=16), dlc=int(dlc), data=b64decode(data), ) self.stop()
def _create_frame_from_db_tuple(frame_data): timestamp, can_id, is_extended, is_remote, is_error, dlc, data = frame_data return Message(timestamp, is_remote, is_extended, is_error, can_id, dlc, data)
def _parse_data(self, data): """Optimized inner loop by making local copies of global variables and class members and hardcoding some values.""" unpack_obj_header_base = OBJ_HEADER_BASE_STRUCT.unpack_from obj_header_base_size = OBJ_HEADER_BASE_STRUCT.size unpack_obj_header_v1 = OBJ_HEADER_V1_STRUCT.unpack_from obj_header_v1_size = OBJ_HEADER_V1_STRUCT.size unpack_obj_header_v2 = OBJ_HEADER_V2_STRUCT.unpack_from obj_header_v2_size = OBJ_HEADER_V2_STRUCT.size unpack_can_msg = CAN_MSG_STRUCT.unpack_from unpack_can_fd_msg = CAN_FD_MSG_STRUCT.unpack_from unpack_can_fd_64_msg = CAN_FD_MSG_64_STRUCT.unpack_from can_fd_64_msg_size = CAN_FD_MSG_64_STRUCT.size unpack_can_error_ext = CAN_ERROR_EXT_STRUCT.unpack_from start_timestamp = self.start_timestamp max_pos = len(data) pos = 0 # Loop until a struct unpack raises an exception while True: self._pos = pos # Find next object after padding (depends on object type) try: pos = data.index(b"LOBJ", pos, pos + 8) except ValueError: if pos + 8 > max_pos: # Not enough data in container return raise BLFParseError("Could not find next object") header = unpack_obj_header_base(data, pos) # print(header) signature, _, header_version, obj_size, obj_type = header if signature != b"LOBJ": raise BLFParseError() # Calculate position of next object next_pos = pos + obj_size if next_pos > max_pos: # This object continues in the next container return pos += obj_header_base_size # Read rest of header if header_version == 1: flags, _, _, timestamp = unpack_obj_header_v1(data, pos) pos += obj_header_v1_size elif header_version == 2: flags, _, _, timestamp = unpack_obj_header_v2(data, pos) pos += obj_header_v2_size else: LOG.warning("Unknown object header version (%d)", header_version) pos = next_pos continue # Calculate absolute timestamp in seconds factor = 1e-5 if flags == 1 else 1e-9 timestamp = timestamp * factor + start_timestamp if obj_type == CAN_MESSAGE or obj_type == CAN_MESSAGE2: channel, flags, dlc, can_id, can_data = unpack_can_msg( data, pos) yield Message( timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, is_extended_id=bool(can_id & CAN_MSG_EXT), is_remote_frame=bool(flags & REMOTE_FLAG), is_rx=not bool(flags & DIR), dlc=dlc, data=can_data[:dlc], channel=channel - 1, ) elif obj_type == CAN_ERROR_EXT: members = unpack_can_error_ext(data, pos) channel = members[0] dlc = members[5] can_id = members[7] can_data = members[9] yield Message( timestamp=timestamp, is_error_frame=True, is_extended_id=bool(can_id & CAN_MSG_EXT), arbitration_id=can_id & 0x1FFFFFFF, dlc=dlc, data=can_data[:dlc], channel=channel - 1, ) elif obj_type == CAN_FD_MESSAGE: members = unpack_can_fd_msg(data, pos) ( channel, flags, dlc, can_id, _, _, fd_flags, valid_bytes, can_data, ) = members yield Message( timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, is_extended_id=bool(can_id & CAN_MSG_EXT), is_remote_frame=bool(flags & REMOTE_FLAG), is_fd=bool(fd_flags & 0x1), is_rx=not bool(flags & DIR), bitrate_switch=bool(fd_flags & 0x2), error_state_indicator=bool(fd_flags & 0x4), dlc=dlc2len(dlc), data=can_data[:valid_bytes], channel=channel - 1, ) elif obj_type == CAN_FD_MESSAGE_64: members = unpack_can_fd_64_msg(data, pos)[:7] channel, dlc, valid_bytes, _, can_id, _, fd_flags = members pos += can_fd_64_msg_size yield Message( timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, is_extended_id=bool(can_id & CAN_MSG_EXT), is_remote_frame=bool(fd_flags & 0x0010), is_fd=bool(fd_flags & 0x1000), bitrate_switch=bool(fd_flags & 0x2000), error_state_indicator=bool(fd_flags & 0x4000), dlc=dlc2len(dlc), data=data[pos:pos + valid_bytes], channel=channel - 1, ) pos = next_pos
def __iter__(self): for line in self.file: if isinstance(line, bytes): line = line.decode() #logger.debug("ASCReader: parsing line: '%s'", line.splitlines()[0]) temp = line.strip() if not temp or not temp[0].isdigit(): continue is_fd = False try: timestamp, channel, dummy = temp.split( None, 2) # , frameType, dlc, frameData if channel == "CANFD": timestamp, _, channel, _, dummy = temp.split(None, 4) is_fd = True except ValueError: # we parsed an empty comment continue timestamp = float(timestamp) try: # See ASCWriter channel = int(channel) - 1 except ValueError: pass if dummy.strip()[0:10].lower() == 'errorframe': msg = Message(timestamp=timestamp, is_error_frame=True, channel=channel) yield msg elif (not isinstance(channel, int) or dummy.strip()[0:10].lower() == 'statistic:' or dummy.split(None, 1)[0] == "J1939TP"): pass elif dummy[-1:].lower() == 'r': can_id_str, _ = dummy.split(None, 1) can_id_num, is_extended_id = self._extract_can_id(can_id_str) msg = Message(timestamp=timestamp, arbitration_id=can_id_num & CAN_ID_MASK, is_extended_id=is_extended_id, is_remote_frame=True, channel=channel) yield msg else: brs = None esi = None data_length = 0 direction = None try: # this only works if dlc > 0 and thus data is available if not is_fd: can_id_str, direction, _, dlc, data = dummy.split( None, 4) else: can_id_str, frame_name, brs, esi, dlc, data_length, data = dummy.split( None, 6) if frame_name.isdigit(): # Empty frame_name can_id_str, brs, esi, dlc, data_length, data = dummy.split( None, 5) except ValueError: # but if not, we only want to get the stuff up to the dlc can_id_str, direction, _, dlc = dummy.split(None, 3) # and we set data to an empty sequence manually data = '' dlc = int(dlc, 16) if is_fd: # For fd frames, dlc and data length might not be equal and # data_length is the actual size of the data dlc = int(data_length) frame = bytearray() data = data.split() for byte in data[0:dlc]: frame.append(int(byte, 16)) can_id_num, is_extended_id = self._extract_can_id(can_id_str) yield direction, Message( timestamp=timestamp, arbitration_id=can_id_num & CAN_ID_MASK, is_extended_id=is_extended_id, is_remote_frame=False, dlc=dlc, data=frame, is_fd=is_fd, channel=channel, bitrate_switch=is_fd and brs == "1", error_state_indicator=is_fd and esi == "1", ) self.stop()
def __iter__(self) -> Generator[Message, None, None]: for line in self.file: # skip empty lines temp = line.strip() if not temp: continue channel_string: str if temp[-2:].lower() in (" r", " t"): timestamp_string, channel_string, frame, is_rx_string = temp.split( ) is_rx = is_rx_string.strip().lower() == "r" else: timestamp_string, channel_string, frame = temp.split() is_rx = True timestamp = float(timestamp_string[1:-1]) can_id_string, data = frame.split("#", maxsplit=1) channel: Union[int, str] if channel_string.isdigit(): channel = int(channel_string) else: channel = channel_string is_extended = len(can_id_string) > 3 can_id = int(can_id_string, 16) is_fd = False brs = False esi = False if data and data[0] == "#": is_fd = True fd_flags = int(data[1]) brs = bool(fd_flags & CANFD_BRS) esi = bool(fd_flags & CANFD_ESI) data = data[2:] if data and data[0].lower() == "r": is_remote_frame = True if len(data) > 1: dlc = int(data[1:]) else: dlc = 0 data_bin = None else: is_remote_frame = False dlc = len(data) // 2 data_bin = bytearray() for i in range(0, len(data), 2): data_bin.append(int(data[i:(i + 2)], 16)) if can_id & CAN_ERR_FLAG and can_id & CAN_ERR_BUSERROR: msg = Message(timestamp=timestamp, is_error_frame=True) else: msg = Message( timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, is_extended_id=is_extended, is_remote_frame=is_remote_frame, is_fd=is_fd, is_rx=is_rx, bitrate_switch=brs, error_state_indicator=esi, dlc=dlc, data=data_bin, channel=channel, ) yield msg self.stop()
def __iter__(self): tail = b"" while True: data = self.file.read(OBJ_HEADER_BASE_STRUCT.size) if not data: # EOF break header = OBJ_HEADER_BASE_STRUCT.unpack(data) if header[0] != b"LOBJ": raise BLFParseError() obj_type = header[4] obj_data_size = header[3] - OBJ_HEADER_BASE_STRUCT.size obj_data = self.file.read(obj_data_size) # Read padding bytes self.file.read(obj_data_size % 4) if obj_type == LOG_CONTAINER: method, uncompressed_size = LOG_CONTAINER_STRUCT.unpack_from( obj_data) container_data = obj_data[LOG_CONTAINER_STRUCT.size:] if method == NO_COMPRESSION: data = container_data elif method == ZLIB_DEFLATE: data = zlib.decompress(container_data, 15, uncompressed_size) else: # Unknown compression method LOG.warning("Unknown compression method (%d)", method) continue if tail: data = tail + data pos = 0 while pos + OBJ_HEADER_BASE_STRUCT.size < len(data): header = OBJ_HEADER_BASE_STRUCT.unpack_from(data, pos) #print(header) if header[0] != b"LOBJ": raise BLFParseError() obj_size = header[3] # Calculate position of next object next_pos = pos + obj_size + (obj_size % 4) if next_pos > len(data): # Object continues in next log container break pos += OBJ_HEADER_BASE_STRUCT.size # Read rest of header header_version = header[2] if header_version == 1: flags, _, _, timestamp = OBJ_HEADER_V1_STRUCT.unpack_from(data, pos) pos += OBJ_HEADER_V1_STRUCT.size elif header_version == 2: flags, _, _, timestamp, _ = OBJ_HEADER_V2_STRUCT.unpack_from(data, pos) pos += OBJ_HEADER_V2_STRUCT.size else: # Unknown header version LOG.warning("Unknown object header version (%d)", header_version) pos = next_pos continue if flags == TIME_TEN_MICS: factor = 10 * 1e-6 else: factor = 1e-9 timestamp = timestamp * factor + self.start_timestamp obj_type = header[4] # Both CAN message types have the same starting content if obj_type in (CAN_MESSAGE, CAN_MESSAGE2): (channel, flags, dlc, can_id, can_data) = CAN_MSG_STRUCT.unpack_from(data, pos) msg = Message(timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, is_extended_id=bool(can_id & CAN_MSG_EXT), is_remote_frame=bool(flags & REMOTE_FLAG), dlc=dlc, data=can_data[:dlc], channel=channel - 1) yield msg elif obj_type == CAN_FD_MESSAGE: (channel, flags, dlc, can_id, _, _, fd_flags, _, can_data) = CAN_FD_MSG_STRUCT.unpack_from(data, pos) length = dlc2len(dlc) msg = Message(timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, is_extended_id=bool(can_id & CAN_MSG_EXT), is_remote_frame=bool(flags & REMOTE_FLAG), is_fd=bool(fd_flags & EDL), bitrate_switch=bool(fd_flags & BRS), error_state_indicator=bool(fd_flags & ESI), dlc=length, data=can_data[:length], channel=channel - 1) yield msg elif obj_type == CAN_FD_MESSAGE_64: ( channel, dlc, _, _, can_id, _, fd_flags ) = CAN_FD_MSG_64_STRUCT.unpack_from(data, pos)[:7] length = dlc2len(dlc) can_data = struct.unpack_from( "<{}s".format(length), data, pos + CAN_FD_MSG_64_STRUCT.size )[0] msg = Message( timestamp=timestamp, arbitration_id=can_id & 0x1FFFFFFF, is_extended_id=bool(can_id & CAN_MSG_EXT), is_remote_frame=bool(fd_flags & REMOTE_FLAG_64), is_fd=bool(fd_flags & EDL_64), bitrate_switch=bool(fd_flags & BRS_64), error_state_indicator=bool(fd_flags & ESI_64), dlc=length, data=can_data[:length], channel=channel - 1 ) yield msg elif obj_type == CAN_ERROR_EXT: (channel, _, _, _, _, dlc, _, can_id, _, can_data) = CAN_ERROR_EXT_STRUCT.unpack_from(data, pos) msg = Message(timestamp=timestamp, is_error_frame=True, is_extended_id=bool(can_id & CAN_MSG_EXT), arbitration_id=can_id & 0x1FFFFFFF, dlc=dlc, data=can_data[:dlc], channel=channel - 1) yield msg # else: # LOG.warning("Unknown object type (%d)", obj_type) pos = next_pos # save the remaining data that could not be processed tail = data[pos:] self.stop()
""" Script to run from transmitting Beaglebone to send standard CAN messages. """ import can import time from can.message import Message interface = 'vcan0' bustype = 'socketcan_ctypes' bus = can.interface.Bus(channel=interface, bustype=bustype) NO_OF_MSGS = 100 USEFUL_BITS = 64 sum = 0 for i in range(NO_OF_MSGS - 1, 0, -1): start_time = time.time() msg = Message(data=[i], arbitration_id=0x14240000) bus.send(msg) timer = time.time() - start_time sum += timer time_per_msg = sum / NO_OF_MSGS print "latency: ", time_per_msg print "throughput: ", USEFUL_BITS / time_per_msg