如何从 python-can 接口中捕获 CAN 总线异常,例如 'Network down'?
How can I trap CAN bus exceptions such as 'Network down' from within python-can interfaces?
我有一个小的 python 项目来模拟我构建的支持 CAN 的电子设备。该项目有一个 shell 解释器来与模拟电子设备进行交互。我现在想捕获从 python-can
运行ning 实例中抛出的异常,并在主 shell 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()
方法,但随后我的新 class 被拒绝,因为 /usr/lib/python3.6/site-packages/can/interfaces/interface.py
中有一个验证接口 class 名称与知名模块列表的对比。所以这可能不太可行。
在我尝试其他任何愚蠢的事情之前,python-can
是否提供了一些方法来拦截 OS 线程在数据包传输期间或 CAN 接口关闭时发生的 OS 错误, 例如?
请注意,由于我使用的是 USB CAN 适配器,因此仅在脚本启动时检查网络状态毫无意义,因为 CAN 适配器也可以在脚本 运行s 时拔掉。所以唯一相关的方法是捕获 python-can
模块抛出的异常并在主线程中显示友好消息。
我仍然不知道这是否是 python-can
开发人员的意图,但这是我最近的工作尝试。我正在覆盖 class SocketcanNative_Bus
实例的 recv()
方法,又名 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 的 types.MethodType()
动态覆盖 bus
实例的方法 recv()
。它被称为 patching
,如 elsewhere on Whosebug 所述。
我有一个小的 python 项目来模拟我构建的支持 CAN 的电子设备。该项目有一个 shell 解释器来与模拟电子设备进行交互。我现在想捕获从 python-can
运行ning 实例中抛出的异常,并在主 shell 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()
方法,但随后我的新 class 被拒绝,因为 /usr/lib/python3.6/site-packages/can/interfaces/interface.py
中有一个验证接口 class 名称与知名模块列表的对比。所以这可能不太可行。
在我尝试其他任何愚蠢的事情之前,python-can
是否提供了一些方法来拦截 OS 线程在数据包传输期间或 CAN 接口关闭时发生的 OS 错误, 例如?
请注意,由于我使用的是 USB CAN 适配器,因此仅在脚本启动时检查网络状态毫无意义,因为 CAN 适配器也可以在脚本 运行s 时拔掉。所以唯一相关的方法是捕获 python-can
模块抛出的异常并在主线程中显示友好消息。
我仍然不知道这是否是 python-can
开发人员的意图,但这是我最近的工作尝试。我正在覆盖 class SocketcanNative_Bus
实例的 recv()
方法,又名 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 的 types.MethodType()
动态覆盖 bus
实例的方法 recv()
。它被称为 patching
,如 elsewhere on Whosebug 所述。