def __init__(self, tx_id, rx_id, connection_mode=0, channel=None): """Sets up a CAN bus instance with a filter and a notifier. :param tx_id: Id for outgoing messages :param rx_id: Id for incoming messages :param connection_mode: Connection mode for the xcp-protocol. Only set if a custom mode is needed. :param channel: The channel for the can adapter. Only needed for Usb2can on Windows. """ self._reader = BufferedReader() if platform.system() == "Windows": from can.interfaces.usb2can import Usb2canBus self._bus = Usb2canBus(channel=channel) else: from can.interface import Bus self._bus = Bus() self._bus.set_filters([{ "can_id": rx_id, "can_mask": rx_id + 0x100, "extended": False }]) self._notifier = Notifier(self._bus, [self._reader]) self._tx_id = tx_id self._rx_id = rx_id self._conn_mode = connection_mode
def setup_can(self, async_loop=None): for i in range(len(Cfg.Can.CAN_CHS)): # can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000, data_bitrate=2000000, fd=True) bus = Bus(bustype=Cfg.Can.CAN_BUS, channel=Cfg.Can.CAN_CHS[i], fd=True) self.log.info(f'Can message recv on {bus.channel_info}') # filter bus.set_filters(Cfg.Can.CAN_FILTERS[i]) self._buses.append(bus) self._notifier = Notifier(self._buses, [ self.parse_msg, ])
def __init__(self, dmm_parametername = None) -> None: os.system("sudo /sbin/ip link set can0 up type can bitrate 250000") self._can_monitor = CanBusMonitor() self._bus = can.interface.Bus(channel='can0', bustype='socketcan', bitrate=250000) self._notifier = Notifier(self._bus, [self._can_monitor]) print("") #clear the line # power supply is required if not os.path.exists('/dev/ttyUSBrd6018'): raise ValueError('No Riden RD6018 Detected') powersupply_port = '/dev/ttyUSBrd6018' self._powersupply = Riden(powersupply_port) self._powersupply_monitor = RidenMonitor(rd60xx=self._powersupply) self._powersupply_monitor.start() # DMM is optional depending on test if dmm_parametername: if not os.path.exists('/dev/ttyUSBut61e'): raise ValueError('No UT61E Detected') dmm_port = '/dev/ttyUSBut61e' self._dmm_monitor = DMMMonitor(dmm_port) self._dmm_monitor.parametername = dmm_parametername else: self._dmm_monitor = None # binary monitor is required self._bin_monitor = BinaryMonitor() # setup logger self._logger = InstrumentLogger() self._logger.addinstrument(self._powersupply_monitor) if self._dmm_monitor: self._logger.addinstrument(self._dmm_monitor) self._logger.addinstrument(self._bin_monitor) self._logger.addinstrument(self._can_monitor)
from uds import Uds from can import Bus, Listener, Notifier from time import sleep def callback_onReceive(msg): if (msg.arbitration_id == 0x600): print("Bootloader Receive:", list(msg.data)) if (msg.arbitration_id == 0x7E0): print("PCM Receive:", list(msg.data)) if __name__ == "__main__": recvBus = Bus("virtualInterface", bustype="virtual") listener = Listener() notifier = Notifier(recvBus, [listener], 0) listener.on_message_received = callback_onReceive a = Uds() a.send([0x22, 0xf1, 0x8C], responseRequired=False) sleep(2)
def onCallback_receive2(msg): print("Received: {0} on ID: {1} on anotherBus".format( list(msg.data), hex(msg.arbitration_id))) pass if __name__ == "__main__": bus = can.interface.Bus('virtualInterface', bustype='virtual') bus2 = can.interface.Bus('anotherBus', bustype='virtual') listener = Listener() listener.on_message_received = onCallback_receive notifier = Notifier(bus, [listener], 0) listener2 = Listener() listener2.on_message_received = onCallback_receive2 notifier2 = Notifier(bus2, [listener2], 0) a = Uds() a.send([0x22, 0xF1, 0x8C], responseRequired=False) b = Uds("bootloader.ini") b.send([0x22, 0xF1, 0x80], responseRequired=False) c = Uds("bootloader2.ini") c.send([0x22, 0xF1, 0x81], responseRequired=False) try:
def run(self): need_run = True while need_run: bus_notifier = None poller = None try: interface = self.__bus_conf["interface"] channel = self.__bus_conf["channel"] kwargs = self.__bus_conf["backend"] self.__bus = ThreadSafeBus(interface=interface, channel=channel, **kwargs) reader = BufferedReader() bus_notifier = Notifier(self.__bus, [reader]) log.info("[%s] Connected to CAN bus (interface=%s,channel=%s)", self.get_name(), interface, channel) if self.__polling_messages: poller = Poller(self) # Poll once to check if network is not down. # It would be better to have some kind of a ping message to check a bus state. poller.poll() # Initialize the connected flag and reconnect count only after bus creation and sending poll messages. # It is expected that after these operations most likely the bus is up. self.__connected = True self.__reconnect_count = 0 while not self.__stopped: message = reader.get_message() if message is not None: # log.debug("[%s] New CAN message received %s", self.get_name(), message) self.__process_message(message) self.__check_if_error_happened() except Exception as e: log.error("[%s] Error on CAN bus: %s", self.get_name(), str(e)) finally: try: if poller is not None: poller.stop() if bus_notifier is not None: bus_notifier.stop() if self.__bus is not None: log.debug( "[%s] Shutting down connection to CAN bus (state=%s)", self.get_name(), self.__bus.state) self.__bus.shutdown() except Exception as e: log.error( "[%s] Error on shutdown connection to CAN bus: %s", self.get_name(), str(e)) self.__connected = False if not self.__stopped: if self.__is_reconnect_enabled(): retry_period = self.__reconnect_conf["period"] log.info( "[%s] Next attempt to connect will be in %f seconds (%s attempt left)", self.get_name(), retry_period, "infinite" if self.__reconnect_conf["maxCount"] is None else self.__reconnect_conf["maxCount"] - self.__reconnect_count + 1) time.sleep(retry_period) else: need_run = False log.info( "[%s] Last attempt to connect has failed. Exiting...", self.get_name()) else: need_run = False log.info("[%s] Stopped", self.get_name())
class BMSTestFixture: def __init__(self, dmm_parametername = None) -> None: os.system("sudo /sbin/ip link set can0 up type can bitrate 250000") self._can_monitor = CanBusMonitor() self._bus = can.interface.Bus(channel='can0', bustype='socketcan', bitrate=250000) self._notifier = Notifier(self._bus, [self._can_monitor]) print("") #clear the line # power supply is required if not os.path.exists('/dev/ttyUSBrd6018'): raise ValueError('No Riden RD6018 Detected') powersupply_port = '/dev/ttyUSBrd6018' self._powersupply = Riden(powersupply_port) self._powersupply_monitor = RidenMonitor(rd60xx=self._powersupply) self._powersupply_monitor.start() # DMM is optional depending on test if dmm_parametername: if not os.path.exists('/dev/ttyUSBut61e'): raise ValueError('No UT61E Detected') dmm_port = '/dev/ttyUSBut61e' self._dmm_monitor = DMMMonitor(dmm_port) self._dmm_monitor.parametername = dmm_parametername else: self._dmm_monitor = None # binary monitor is required self._bin_monitor = BinaryMonitor() # setup logger self._logger = InstrumentLogger() self._logger.addinstrument(self._powersupply_monitor) if self._dmm_monitor: self._logger.addinstrument(self._dmm_monitor) self._logger.addinstrument(self._bin_monitor) self._logger.addinstrument(self._can_monitor) @property def powersupply(self) -> Riden: return self._powersupply @property def powersupply_monitor(self) -> RidenMonitor: return self._powersupply_monitor @property def dmm_monitor(self) -> DMMMonitor: return self._dmm_monitor @property def can_monitor(self) -> CanBusMonitor: return self._can_monitor @property def bin_monitor(self) -> BinaryMonitor: return self._bin_monitor @property def logger(self) -> InstrumentLogger: return self._logger def start(self) -> None: """Starts any Instrument threads""" if self.dmm_monitor: self.dmm_monitor.start() def stop(self) -> None: """Stops any Instrument threads, stops logging""" if self.dmm_monitor: self.dmm_monitor.stop() self._notifier.remove_listener(self._can_monitor) self._bus.shutdown() os.system("sudo /sbin/ip link set can0 down")
class CanProxy: def __init__(self, on_msg=None): self.log = logging.getLogger(__name__) self._status = {'can0': 0, 'can1': 0} self._buses = [] self._error_count = 0 self._on_msg = on_msg def on_start(self): self.init_msg_handler() self.setup_can() def on_stop(self): self._msg_hdl.stop_diag() self.stop_can() def setup_can(self, async_loop=None): for i in range(len(Cfg.Can.CAN_CHS)): # can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000, data_bitrate=2000000, fd=True) bus = Bus(bustype=Cfg.Can.CAN_BUS, channel=Cfg.Can.CAN_CHS[i], fd=True) self.log.info(f'Can message recv on {bus.channel_info}') # filter bus.set_filters(Cfg.Can.CAN_FILTERS[i]) self._buses.append(bus) self._notifier = Notifier(self._buses, [ self.parse_msg, ]) def stop_can(self): self._notifier.stop() for bus in self._buses: bus.shutdown() self._buses.clear() def init_msg_handler(self): hdl = MessageHandler() #self._msg_hdl.start_log() cfg_path = os.path.join(Cfg.AD_HMI_CFG_DIR, 'can_config.json') self.log.info(f'Using config: {cfg_path}') hdl.read_json_file(cfg_path) hdl.get_message_list() hdl.initial_display_signal_list() self._msg_hdl = hdl def parse_msg(self, msg): ''' Parse received message :param msg: (msg.timestamp, msg.channel, msg.arbitration_id, msg.dlc, msg.data, msg.is_error_frame, msg.is_extended_id, msg.is_remote_frame) :return: ''' # self.log.debug(msg) if msg.is_error_frame: self._error_count += 1 if self._msg_hdl: rslt = self._msg_hdl.message_analysis(msg) # print(msg, 'rslt', rslt) if self._on_msg: self._on_msg(msg.arbitration_id, rslt) #################################################################################################################### # Message Sending #################################################################################################################### def send_msg(self, msg): ''' :param bus_name: name of the channel, e.g. 'can0', 'can1' :param msg: :return: ''' bus = None # find the bus for _bus in self._buses: if _bus.channel == msg.channel: bus = _bus break try: if bus: bus.send(msg) self.log.info(f'Msg send on {bus.channel_info}, msg: {msg}') return True except can.CanError: self.log.warning( f'Msg send failed on {bus.channel_info}, msg: {msg}') return False def send_periodic_msg(self, bus): print("Starting to send a message every 200ms. Initial data is zeros") # msg = can.Message(arbitration_id=0x0cf02200, data=[11, 22, 33, 44, 55, 66]) msg = can.Message(arbitration_id=0x1245, data=[11, 22, 33, 44, 55, 66]) self.task = can.send_periodic(bus, msg, 0.20) time.sleep(2) self.task.stop() print("stopped cyclic send") def test_send_msg(self): msg = can.Message( arbitration_id=0x123, data=[0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], extended_id=False, is_fd=True, is_remote_frame=False) msg.channel = 'can0' self.send_msg(msg)