2017-03-31 2 views
1

필자는 내가 만든 CAN 사용 가능 전자 제품을 시뮬레이션하기위한 작은 파이썬 프로젝트를 가지고 있습니다. 프로젝트에는 시뮬레이트 된 전자 장치와 상호 작용하는 쉘 인터프리터가 있습니다. 나는 디스플레이를 깨는 전체 스택 트레이스를 얻는 대신 메인 쉘 UI에서 python-can 인스턴스를 실행하고 친숙한 오류 메시지를 인쇄하는 예외를 잡아 내고 싶습니다. can0 인터페이스가 구성되지 않은 상태에서 내 스크립트를 실행하는 경우 예를 들어python-can 인터페이스 내에서 'Network down'과 같은 CAN 버스 예외를 트랩 할 수 있습니까?

, (즉 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 

주 내 미니 - 쉘 프롬프트. 그것은보기 흉하게 보입니다.

내가 먼저 recv() 방법을 SocketcanNative_Bus을 유도하고 무시하려고 노력하지만 잘 알려진 모듈의 목록에 대해 인터페이스 클래스 이름의 유효성을 확인 /usr/lib/python3.6/site-packages/can/interfaces/interface.py에 체크 거기로 다음 내 새로운 클래스는 거부됩니다. 따라서 이것은 앞으로 나아갈 길이 아닙니다.

바보 같은 다른 것을 시도하기 전에 python-can은 데이터 패킷 전송 중 또는 CAN 인터페이스가 다운되었을 때 스레드에서 발생하는 OS 오류를 가로채는 수단을 제공합니까?

USB CAN 어댑터를 사용하고 있기 때문에 스크립트 실행 중에 CAN 어댑터가 플러그를 뽑을 수 있기 때문에 스크립트가 시작될 때만 네트워크 상태를 확인할 필요가 없습니다. 따라서 유일하게 적절한 방법은 python-can 모듈에 의해 던진 예외를 잡아 내고 주 스레드에 친숙한 메시지를 표시하는 것입니다.

답변

3

아직 개발자가 의도 한대로라면 python-can 개발자가 의도 한 바가 있지만 가장 최근의 시도입니다. 나는 일명 bus, 클래스 SocketcanNative_Bus 인스턴스의 recv() 메서드를 재정의하고 있습니다 :

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) 

는 동적으로 파이썬의 types.MethodType()를 사용하여 bus 인스턴스의 방법 recv()을 무효화한다. elsewhere on Stackoverflow으로 설명한대로 patching이라고합니다.

관련 문제