簡體   English   中英

如何從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運行實例中拋出的異常並在主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()方法,但后來我的新類被拒絕,因為在/usr/lib/python3.6/site-packages/can/interfaces/interface.py中檢查驗證了接口類根據眾所周知的模塊列表命名。 所以這可能不是那么順利。

在我嘗試其他任何愚蠢的事情之前, python-can提供一些方法來攔截數據包傳輸過程中或者當CAN接口出現故障時Notifier線程中出現的操作系統錯誤?

請注意,由於我使用的是USB CAN適配器,因此僅在腳本啟動時檢查網絡狀態是沒有意義的,因為在腳本運行時也可以拔掉CAN適配器。 所以唯一相關的方法是捕獲python-can模塊拋出的異常並在主線程中顯示友好消息。

我仍然不知道這是否是python-can開發人員的意圖,但這是我最近的工作嘗試。 我正在覆蓋類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() types.MethodType() 它被稱為patchingStackoverflow上的其他地方所述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM