我有一个小型的python项目,用于模拟已构建的支持CAN的电子设备。该项目具有外壳解释程序,可与模拟的电子设备进行交互。我现在想捕获从python-can运行实例中引发的异常,并在主外壳UI中打印友好的错误消息,而不是获取完整的堆栈跟踪以使显示变得混乱。

例如,如果我未配置can0接口时(即在执行ip link set can0 up type can bitrate 250000之前)运行脚本,则会得到如下所示的堆栈跟踪:

Failed to send: Timestamp:        0.000000        ID: 0541    000    DLC: 8    01 1a c4 13 00 00 e2 04
> Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.6/site-packages/can/notifier.py", line 39, in rx_thread
    msg = self.bus.recv(self.timeout)
  File "/usr/lib/python3.6/site-packages/can/interfaces/socketcan_native.py", line 341, in recv
    packet = capturePacket(self.socket)
  File "/usr/lib/python3.6/site-packages/can/interfaces/socketcan_native.py", line 274, in capturePacket
    cf, addr = sock.recvfrom(can_frame_size)
OSError: [Errno 100] Network is down


请注意,上面的“>”符号是我的微型shell提示。看起来很丑,对。

我首先尝试派生SocketcanNative_Bus并重写recv()方法,但是随后我的新类被拒绝,因为在/usr/lib/python3.6/site-packages/can/interfaces/interface.py中进行了一项检查,该检查可以根据一系列知名模块来验证接口类名称。因此,这可能并非完全可行。

在尝试其他愚蠢的方法之前,例如,python-can是否提供某种方法来拦截在数据包传输期间或CAN接口出现故障时Notifier线程中发生的OS错误?

请注意,由于我使用的是USB CAN适配器,因此仅在脚本启动时检查网络状态是没有意义的,因为在脚本运行时也可以拔下CAN适配器。因此,唯一相关的方法是捕获python-can模块引发的异常并在主线程中显示友好消息。

最佳答案

我仍然不知道这是否是python-can开发人员想要的,但这是我最近的工作尝试。我覆盖了类recv()实例(也称为SocketcanNative_Bus)的bus方法:

can.rc['interface'] = 'socketcan_native'
can.rc['channel'] = args[1]

from can.interfaces.socketcan_native import SocketcanNative_Bus
def recv(self, timeout=None):
    try:
        return SocketcanNative_Bus.recv(self, timeout)
    except OSError as e:
        print(str(e))
        return None

try:
    import types
    bus = can.interface.Bus()
    bus.recv = types.MethodType(recv, bus)

except OSError as e:
    print('Error {0}: {1}'.format(e.errno, e.strerror), file=sys.stderr)


我使用Python的bus动态覆盖了recv()实例的方法types.MethodType()。如elsewhere on Stackoverflow所述,它称为patching

关于python - 如何从python-can接口(interface)中捕获CAN总线异常,例如“网络故障”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43139998/

10-10 17:24
查看更多