2017-12-04 5 views
0

직렬 인터페이스를 통해 컨트롤러의 펌웨어를 업데이트하려고합니다. 이렇게하려면 컨트롤러에 재부팅 메시지를 보내고 (문제 없음) 다른 문자 (문자 'w')를 시작하여 쓰기 모드로 시작할 수 있도록 시작해야합니다. 이것은 장치가 다시 시작될 때 w 키를 계속 눌러 minicom 유틸리티로 쉽게 수행됩니다.온라인 상태가 될 때까지 장치에 일련 메시지를 보냅니다.

대신 파이썬 코드를 사용하여이 기능을 구현하고 싶습니다. 그러나 장치가 연결되어 있지 않아 예외를 throw하지 않고 장치가 작동 될 때까지 메시지를 보내는 방법을 알아낼 수 없습니다.

이 내가 시도 것을이지만 (pyserial과) 작동하지 않습니다

serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?) 

가 나는 또한 루프에서 메시지를 보내는 시도 :

def send_w(serial_port, baud_rate): 
    msgw = "w_" 
    ans = "" 
    ser = serial.Serial(port=serial_port, baudrate=baud_rate,timeout = 10) 
    ser.write(msgw) 
    ans = ser.read(24) 
    ser.close() 
    print(ans) 
    return ans 

def set_firmware_version(serial_port, baud_rate): 
    s = "" 
    try: 
     with serial.Serial(serial_port,baud_rate,timeout=1) as ser: 
      msgr = "%reset "+sk+"_" 
      ser.write(msgr) 
      ser.close() 
      print("reset") 
    except (IOError) as e: 
     print("Error in: set_firmware_version") 
     print(e) 
     return s 
    time.sleep(1) 
    send_w(serial_port, baud_rate) 

set_firmware_version(sp,br) 

이 다음과 같은 오류를 제공합니다 짧은 제한 시간이 있었지만 동일한 문제가있었습니다. 메시지를 계속 보내고 장치를 찾을 수없는 경우 예외를 무시하는 방법이 있습니까?

도움이 될 것입니다.

전체 역 추적 :

Traceback (most recent call last): 
    File "mc_config.py", line 69, in <module> 
    set_firmware_version(sp,br) 
    File "mc_config.py", line 64, in set_firmware_version 
    send_w(serial_port, baud_rate) 
    File "mc_config.py", line 46, in send_w 
    ans = ser.read(24) 
    File "/home/avidbots/.local/lib/python2.7/site-packages/serial/serialposix.py", line 501, in read 
    'device reports readiness to read but returned no data ' 
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?) 

(내가 우분투를 16.04와 파이썬을 사용하고 3)

답변

1

당신이 try에 제외 코드를 삽입 한 다음 except serial.serialutil.SerialException {...} 블록 예외를 잡으면?

분명히 w을 제출할 상당한 시간이 있습니다 (그렇지 않은 경우 "프레스 w"방법은 자주 작동하지 않습니다). 그러면 귀하의 요구 사항은 전송하는 데 절대적으로 필요한 코드 부분 만 다시 시도하는 것입니다 w이므로 부팅 상태에서 시스템을 "잡을"정도로 빨리 보내십시오. 백 트레이스에서 예외가 send_w에 발생했음을 보여주기 때문에/except 블록을 추가하고 while 루프를 추가하여 set_firmware_version 끝에 한 줄을 추가 할 수 있습니다. 대신 그냥이의

: 당신은 참고로, 그 예외를 노출하기 위해 수입을 변경해야 할 수도 있습니다

while True: 
    try: 
    send_w(serial_port, baud_rate) 
    break 
    except serial.serialutil.SerialException: 
    pass # retry 

이 같은

send_w(serial_port, baud_rate) 

뭔가 문제를 해결할 수 있습니다. 그리고 가능한 예외를 너무 많이 잡는 지 고려해야 할 수도 있습니다. 예외가 재 시도되지 않아야하는 다른 오류를 나타낼 수도 있습니다. 작은 잠자기 시간을 추가해야 할 수도 있습니다. 이는 본질적으로 바쁜 대기 루프 (https://en.wikipedia.org/wiki/Busy_waiting)입니다.

+1

고맙습니다. 비슷한 점이 있습니다. 함수를 호출하기 전에 수면을 제거하고 send_w의 제한 시간을 0.1로 단축하고 break 문 대신 루프에서 종료 조건을 설정했습니다. 패스가 예외였습니다! – cmperezg

관련 문제